/* Minification failed. Returning unminified contents.
(13651,11-12): run-time error JS1010: Expected identifier: .
(13651,11-12): run-time error JS1195: Expected expression: .
 */
!function(i){"use strict";"function"==typeof define&&define.amd?define(["jquery"],i):"undefined"!=typeof exports?module.exports=i(require("jquery")):i(jQuery)}(function(i){"use strict";var e=window.Slick||{};(e=function(){var e=0;return function(t,o){var s,n=this;n.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:i(t),appendDots:i(t),arrows:!0,asNavFor:null,prevArrow:'<button class="slick-prev" aria-label="Previous" type="button">Previous</button>',nextArrow:'<button class="slick-next" aria-label="Next" type="button">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(e,t){return i('<button type="button" />').text(t+1)},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,focusOnChange:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnFocus:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,useTransform:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0,zIndex:1e3},n.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,scrolling:!1,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,sliding:!1,slideOffset:0,swipeLeft:null,swiping:!1,$list:null,touchObject:{},transformsEnabled:!1,unslicked:!1},i.extend(n,n.initials),n.activeBreakpoint=null,n.animType=null,n.animProp=null,n.breakpoints=[],n.breakpointSettings=[],n.cssTransitions=!1,n.focussed=!1,n.interrupted=!1,n.hidden="hidden",n.paused=!0,n.positionProp=null,n.respondTo=null,n.rowCount=1,n.shouldClick=!0,n.$slider=i(t),n.$slidesCache=null,n.transformType=null,n.transitionType=null,n.visibilityChange="visibilitychange",n.windowWidth=0,n.windowTimer=null,s=i(t).data("slick")||{},n.options=i.extend({},n.defaults,o,s),n.currentSlide=n.options.initialSlide,n.originalSettings=n.options,void 0!==document.mozHidden?(n.hidden="mozHidden",n.visibilityChange="mozvisibilitychange"):void 0!==document.webkitHidden&&(n.hidden="webkitHidden",n.visibilityChange="webkitvisibilitychange"),n.autoPlay=i.proxy(n.autoPlay,n),n.autoPlayClear=i.proxy(n.autoPlayClear,n),n.autoPlayIterator=i.proxy(n.autoPlayIterator,n),n.changeSlide=i.proxy(n.changeSlide,n),n.clickHandler=i.proxy(n.clickHandler,n),n.selectHandler=i.proxy(n.selectHandler,n),n.setPosition=i.proxy(n.setPosition,n),n.swipeHandler=i.proxy(n.swipeHandler,n),n.dragHandler=i.proxy(n.dragHandler,n),n.keyHandler=i.proxy(n.keyHandler,n),n.instanceUid=e++,n.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,n.registerBreakpoints(),n.init(!0)}}()).prototype.activateADA=function(){this.$slideTrack.find(".slick-active").attr({"aria-hidden":"false"}).find("a, input, button, select").attr({tabindex:"0"})},e.prototype.addSlide=e.prototype.slickAdd=function(e,t,o){var s=this;if("boolean"==typeof t)o=t,t=null;else if(t<0||t>=s.slideCount)return!1;s.unload(),"number"==typeof t?0===t&&0===s.$slides.length?i(e).appendTo(s.$slideTrack):o?i(e).insertBefore(s.$slides.eq(t)):i(e).insertAfter(s.$slides.eq(t)):!0===o?i(e).prependTo(s.$slideTrack):i(e).appendTo(s.$slideTrack),s.$slides=s.$slideTrack.children(this.options.slide),s.$slideTrack.children(this.options.slide).detach(),s.$slideTrack.append(s.$slides),s.$slides.each(function(e,t){i(t).attr("data-slick-index",e)}),s.$slidesCache=s.$slides,s.reinit()},e.prototype.animateHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.animate({height:e},i.options.speed)}},e.prototype.animateSlide=function(e,t){var o={},s=this;s.animateHeight(),!0===s.options.rtl&&!1===s.options.vertical&&(e=-e),!1===s.transformsEnabled?!1===s.options.vertical?s.$slideTrack.animate({left:e},s.options.speed,s.options.easing,t):s.$slideTrack.animate({top:e},s.options.speed,s.options.easing,t):!1===s.cssTransitions?(!0===s.options.rtl&&(s.currentLeft=-s.currentLeft),i({animStart:s.currentLeft}).animate({animStart:e},{duration:s.options.speed,easing:s.options.easing,step:function(i){i=Math.ceil(i),!1===s.options.vertical?(o[s.animType]="translate("+i+"px, 0px)",s.$slideTrack.css(o)):(o[s.animType]="translate(0px,"+i+"px)",s.$slideTrack.css(o))},complete:function(){t&&t.call()}})):(s.applyTransition(),e=Math.ceil(e),!1===s.options.vertical?o[s.animType]="translate3d("+e+"px, 0px, 0px)":o[s.animType]="translate3d(0px,"+e+"px, 0px)",s.$slideTrack.css(o),t&&setTimeout(function(){s.disableTransition(),t.call()},s.options.speed))},e.prototype.getNavTarget=function(){var e=this,t=e.options.asNavFor;return t&&null!==t&&(t=i(t).not(e.$slider)),t},e.prototype.asNavFor=function(e){var t=this.getNavTarget();null!==t&&"object"==typeof t&&t.each(function(){var t=i(this).slick("getSlick");t.unslicked||t.slideHandler(e,!0)})},e.prototype.applyTransition=function(i){var e=this,t={};!1===e.options.fade?t[e.transitionType]=e.transformType+" "+e.options.speed+"ms "+e.options.cssEase:t[e.transitionType]="opacity "+e.options.speed+"ms "+e.options.cssEase,!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.autoPlay=function(){var i=this;i.autoPlayClear(),i.slideCount>i.options.slidesToShow&&(i.autoPlayTimer=setInterval(i.autoPlayIterator,i.options.autoplaySpeed))},e.prototype.autoPlayClear=function(){var i=this;i.autoPlayTimer&&clearInterval(i.autoPlayTimer)},e.prototype.autoPlayIterator=function(){var i=this,e=i.currentSlide+i.options.slidesToScroll;i.paused||i.interrupted||i.focussed||(!1===i.options.infinite&&(1===i.direction&&i.currentSlide+1===i.slideCount-1?i.direction=0:0===i.direction&&(e=i.currentSlide-i.options.slidesToScroll,i.currentSlide-1==0&&(i.direction=1))),i.slideHandler(e))},e.prototype.buildArrows=function(){var e=this;!0===e.options.arrows&&(e.$prevArrow=i(e.options.prevArrow).addClass("slick-arrow"),e.$nextArrow=i(e.options.nextArrow).addClass("slick-arrow"),e.slideCount>e.options.slidesToShow?(e.$prevArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.$nextArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.prependTo(e.options.appendArrows),e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.appendTo(e.options.appendArrows),!0!==e.options.infinite&&e.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true")):e.$prevArrow.add(e.$nextArrow).addClass("slick-hidden").attr({"aria-disabled":"true",tabindex:"-1"}))},e.prototype.buildDots=function(){var e,t,o=this;if(!0===o.options.dots){for(o.$slider.addClass("slick-dotted"),t=i("<ul />").addClass(o.options.dotsClass),e=0;e<=o.getDotCount();e+=1)t.append(i("<li />").append(o.options.customPaging.call(this,o,e)));o.$dots=t.appendTo(o.options.appendDots),o.$dots.find("li").first().addClass("slick-active")}},e.prototype.buildOut=function(){var e=this;e.$slides=e.$slider.children(e.options.slide+":not(.slick-cloned)").addClass("slick-slide"),e.slideCount=e.$slides.length,e.$slides.each(function(e,t){i(t).attr("data-slick-index",e).data("originalStyling",i(t).attr("style")||"")}),e.$slider.addClass("slick-slider"),e.$slideTrack=0===e.slideCount?i('<div class="slick-track"/>').appendTo(e.$slider):e.$slides.wrapAll('<div class="slick-track"/>').parent(),e.$list=e.$slideTrack.wrap('<div class="slick-list"/>').parent(),e.$slideTrack.css("opacity",0),!0!==e.options.centerMode&&!0!==e.options.swipeToSlide||(e.options.slidesToScroll=1),i("img[data-lazy]",e.$slider).not("[src]").addClass("slick-loading"),e.setupInfinite(),e.buildArrows(),e.buildDots(),e.updateDots(),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),!0===e.options.draggable&&e.$list.addClass("draggable")},e.prototype.buildRows=function(){var i,e,t,o,s,n,r,l=this;if(o=document.createDocumentFragment(),n=l.$slider.children(),l.options.rows>1){for(r=l.options.slidesPerRow*l.options.rows,s=Math.ceil(n.length/r),i=0;i<s;i++){var d=document.createElement("div");for(e=0;e<l.options.rows;e++){var a=document.createElement("div");for(t=0;t<l.options.slidesPerRow;t++){var c=i*r+(e*l.options.slidesPerRow+t);n.get(c)&&a.appendChild(n.get(c))}d.appendChild(a)}o.appendChild(d)}l.$slider.empty().append(o),l.$slider.children().children().children().css({width:100/l.options.slidesPerRow+"%",display:"inline-block"})}},e.prototype.checkResponsive=function(e,t){var o,s,n,r=this,l=!1,d=r.$slider.width(),a=window.innerWidth||i(window).width();if("window"===r.respondTo?n=a:"slider"===r.respondTo?n=d:"min"===r.respondTo&&(n=Math.min(a,d)),r.options.responsive&&r.options.responsive.length&&null!==r.options.responsive){s=null;for(o in r.breakpoints)r.breakpoints.hasOwnProperty(o)&&(!1===r.originalSettings.mobileFirst?n<r.breakpoints[o]&&(s=r.breakpoints[o]):n>r.breakpoints[o]&&(s=r.breakpoints[o]));null!==s?null!==r.activeBreakpoint?(s!==r.activeBreakpoint||t)&&(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):null!==r.activeBreakpoint&&(r.activeBreakpoint=null,r.options=r.originalSettings,!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e),l=s),e||!1===l||r.$slider.trigger("breakpoint",[r,l])}},e.prototype.changeSlide=function(e,t){var o,s,n,r=this,l=i(e.currentTarget);switch(l.is("a")&&e.preventDefault(),l.is("li")||(l=l.closest("li")),n=r.slideCount%r.options.slidesToScroll!=0,o=n?0:(r.slideCount-r.currentSlide)%r.options.slidesToScroll,e.data.message){case"previous":s=0===o?r.options.slidesToScroll:r.options.slidesToShow-o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide-s,!1,t);break;case"next":s=0===o?r.options.slidesToScroll:o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide+s,!1,t);break;case"index":var d=0===e.data.index?0:e.data.index||l.index()*r.options.slidesToScroll;r.slideHandler(r.checkNavigable(d),!1,t),l.children().trigger("focus");break;default:return}},e.prototype.checkNavigable=function(i){var e,t;if(e=this.getNavigableIndexes(),t=0,i>e[e.length-1])i=e[e.length-1];else for(var o in e){if(i<e[o]){i=t;break}t=e[o]}return i},e.prototype.cleanUpEvents=function(){var e=this;e.options.dots&&null!==e.$dots&&(i("li",e.$dots).off("click.slick",e.changeSlide).off("mouseenter.slick",i.proxy(e.interrupt,e,!0)).off("mouseleave.slick",i.proxy(e.interrupt,e,!1)),!0===e.options.accessibility&&e.$dots.off("keydown.slick",e.keyHandler)),e.$slider.off("focus.slick blur.slick"),!0===e.options.arrows&&e.slideCount>e.options.slidesToShow&&(e.$prevArrow&&e.$prevArrow.off("click.slick",e.changeSlide),e.$nextArrow&&e.$nextArrow.off("click.slick",e.changeSlide),!0===e.options.accessibility&&(e.$prevArrow&&e.$prevArrow.off("keydown.slick",e.keyHandler),e.$nextArrow&&e.$nextArrow.off("keydown.slick",e.keyHandler))),e.$list.off("touchstart.slick mousedown.slick",e.swipeHandler),e.$list.off("touchmove.slick mousemove.slick",e.swipeHandler),e.$list.off("touchend.slick mouseup.slick",e.swipeHandler),e.$list.off("touchcancel.slick mouseleave.slick",e.swipeHandler),e.$list.off("click.slick",e.clickHandler),i(document).off(e.visibilityChange,e.visibility),e.cleanUpSlideEvents(),!0===e.options.accessibility&&e.$list.off("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().off("click.slick",e.selectHandler),i(window).off("orientationchange.slick.slick-"+e.instanceUid,e.orientationChange),i(window).off("resize.slick.slick-"+e.instanceUid,e.resize),i("[draggable!=true]",e.$slideTrack).off("dragstart",e.preventDefault),i(window).off("load.slick.slick-"+e.instanceUid,e.setPosition)},e.prototype.cleanUpSlideEvents=function(){var e=this;e.$list.off("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.off("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.cleanUpRows=function(){var i,e=this;e.options.rows>1&&((i=e.$slides.children().children()).removeAttr("style"),e.$slider.empty().append(i))},e.prototype.clickHandler=function(i){!1===this.shouldClick&&(i.stopImmediatePropagation(),i.stopPropagation(),i.preventDefault())},e.prototype.destroy=function(e){var t=this;t.autoPlayClear(),t.touchObject={},t.cleanUpEvents(),i(".slick-cloned",t.$slider).detach(),t.$dots&&t.$dots.remove(),t.$prevArrow&&t.$prevArrow.length&&(t.$prevArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.prevArrow)&&t.$prevArrow.remove()),t.$nextArrow&&t.$nextArrow.length&&(t.$nextArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.nextArrow)&&t.$nextArrow.remove()),t.$slides&&(t.$slides.removeClass("slick-slide slick-active slick-center slick-visible slick-current").removeAttr("aria-hidden").removeAttr("data-slick-index").each(function(){i(this).attr("style",i(this).data("originalStyling"))}),t.$slideTrack.children(this.options.slide).detach(),t.$slideTrack.detach(),t.$list.detach(),t.$slider.append(t.$slides)),t.cleanUpRows(),t.$slider.removeClass("slick-slider"),t.$slider.removeClass("slick-initialized"),t.$slider.removeClass("slick-dotted"),t.unslicked=!0,e||t.$slider.trigger("destroy",[t])},e.prototype.disableTransition=function(i){var e=this,t={};t[e.transitionType]="",!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.fadeSlide=function(i,e){var t=this;!1===t.cssTransitions?(t.$slides.eq(i).css({zIndex:t.options.zIndex}),t.$slides.eq(i).animate({opacity:1},t.options.speed,t.options.easing,e)):(t.applyTransition(i),t.$slides.eq(i).css({opacity:1,zIndex:t.options.zIndex}),e&&setTimeout(function(){t.disableTransition(i),e.call()},t.options.speed))},e.prototype.fadeSlideOut=function(i){var e=this;!1===e.cssTransitions?e.$slides.eq(i).animate({opacity:0,zIndex:e.options.zIndex-2},e.options.speed,e.options.easing):(e.applyTransition(i),e.$slides.eq(i).css({opacity:0,zIndex:e.options.zIndex-2}))},e.prototype.filterSlides=e.prototype.slickFilter=function(i){var e=this;null!==i&&(e.$slidesCache=e.$slides,e.unload(),e.$slideTrack.children(this.options.slide).detach(),e.$slidesCache.filter(i).appendTo(e.$slideTrack),e.reinit())},e.prototype.focusHandler=function(){var e=this;e.$slider.off("focus.slick blur.slick").on("focus.slick blur.slick","*",function(t){t.stopImmediatePropagation();var o=i(this);setTimeout(function(){e.options.pauseOnFocus&&(e.focussed=o.is(":focus"),e.autoPlay())},0)})},e.prototype.getCurrent=e.prototype.slickCurrentSlide=function(){return this.currentSlide},e.prototype.getDotCount=function(){var i=this,e=0,t=0,o=0;if(!0===i.options.infinite)if(i.slideCount<=i.options.slidesToShow)++o;else for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else if(!0===i.options.centerMode)o=i.slideCount;else if(i.options.asNavFor)for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else o=1+Math.ceil((i.slideCount-i.options.slidesToShow)/i.options.slidesToScroll);return o-1},e.prototype.getLeft=function(i){var e,t,o,s,n=this,r=0;return n.slideOffset=0,t=n.$slides.first().outerHeight(!0),!0===n.options.infinite?(n.slideCount>n.options.slidesToShow&&(n.slideOffset=n.slideWidth*n.options.slidesToShow*-1,s=-1,!0===n.options.vertical&&!0===n.options.centerMode&&(2===n.options.slidesToShow?s=-1.5:1===n.options.slidesToShow&&(s=-2)),r=t*n.options.slidesToShow*s),n.slideCount%n.options.slidesToScroll!=0&&i+n.options.slidesToScroll>n.slideCount&&n.slideCount>n.options.slidesToShow&&(i>n.slideCount?(n.slideOffset=(n.options.slidesToShow-(i-n.slideCount))*n.slideWidth*-1,r=(n.options.slidesToShow-(i-n.slideCount))*t*-1):(n.slideOffset=n.slideCount%n.options.slidesToScroll*n.slideWidth*-1,r=n.slideCount%n.options.slidesToScroll*t*-1))):i+n.options.slidesToShow>n.slideCount&&(n.slideOffset=(i+n.options.slidesToShow-n.slideCount)*n.slideWidth,r=(i+n.options.slidesToShow-n.slideCount)*t),n.slideCount<=n.options.slidesToShow&&(n.slideOffset=0,r=0),!0===n.options.centerMode&&n.slideCount<=n.options.slidesToShow?n.slideOffset=n.slideWidth*Math.floor(n.options.slidesToShow)/2-n.slideWidth*n.slideCount/2:!0===n.options.centerMode&&!0===n.options.infinite?n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)-n.slideWidth:!0===n.options.centerMode&&(n.slideOffset=0,n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)),e=!1===n.options.vertical?i*n.slideWidth*-1+n.slideOffset:i*t*-1+r,!0===n.options.variableWidth&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,!0===n.options.centerMode&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow+1),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,e+=(n.$list.width()-o.outerWidth())/2)),e},e.prototype.getOption=e.prototype.slickGetOption=function(i){return this.options[i]},e.prototype.getNavigableIndexes=function(){var i,e=this,t=0,o=0,s=[];for(!1===e.options.infinite?i=e.slideCount:(t=-1*e.options.slidesToScroll,o=-1*e.options.slidesToScroll,i=2*e.slideCount);t<i;)s.push(t),t=o+e.options.slidesToScroll,o+=e.options.slidesToScroll<=e.options.slidesToShow?e.options.slidesToScroll:e.options.slidesToShow;return s},e.prototype.getSlick=function(){return this},e.prototype.getSlideCount=function(){var e,t,o=this;return t=!0===o.options.centerMode?o.slideWidth*Math.floor(o.options.slidesToShow/2):0,!0===o.options.swipeToSlide?(o.$slideTrack.find(".slick-slide").each(function(s,n){if(n.offsetLeft-t+i(n).outerWidth()/2>-1*o.swipeLeft)return e=n,!1}),Math.abs(i(e).attr("data-slick-index")-o.currentSlide)||1):o.options.slidesToScroll},e.prototype.goTo=e.prototype.slickGoTo=function(i,e){this.changeSlide({data:{message:"index",index:parseInt(i)}},e)},e.prototype.init=function(e){var t=this;i(t.$slider).hasClass("slick-initialized")||(i(t.$slider).addClass("slick-initialized"),t.buildRows(),t.buildOut(),t.setProps(),t.startLoad(),t.loadSlider(),t.initializeEvents(),t.updateArrows(),t.updateDots(),t.checkResponsive(!0),t.focusHandler()),e&&t.$slider.trigger("init",[t]),!0===t.options.accessibility&&t.initADA(),t.options.autoplay&&(t.paused=!1,t.autoPlay())},e.prototype.initADA=function(){var e=this,t=Math.ceil(e.slideCount/e.options.slidesToShow),o=e.getNavigableIndexes().filter(function(i){return i>=0&&i<e.slideCount});e.$slides.add(e.$slideTrack.find(".slick-cloned")).attr({"aria-hidden":"true",tabindex:"-1"}).find("a, input, button, select").attr({tabindex:"-1"}),null!==e.$dots&&(e.$slides.not(e.$slideTrack.find(".slick-cloned")).each(function(t){var s=o.indexOf(t);i(this).attr({role:"tabpanel",id:"slick-slide"+e.instanceUid+t,tabindex:-1}),-1!==s&&i(this).attr({"aria-describedby":"slick-slide-control"+e.instanceUid+s})}),e.$dots.attr("role","tablist").find("li").each(function(s){var n=o[s];i(this).attr({role:"presentation"}),i(this).find("button").first().attr({role:"tab",id:"slick-slide-control"+e.instanceUid+s,"aria-controls":"slick-slide"+e.instanceUid+n,"aria-label":s+1+" of "+t,"aria-selected":null,tabindex:"-1"})}).eq(e.currentSlide).find("button").attr({"aria-selected":"true",tabindex:"0"}).end());for(var s=e.currentSlide,n=s+e.options.slidesToShow;s<n;s++)e.$slides.eq(s).attr("tabindex",0);e.activateADA()},e.prototype.initArrowEvents=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.off("click.slick").on("click.slick",{message:"previous"},i.changeSlide),i.$nextArrow.off("click.slick").on("click.slick",{message:"next"},i.changeSlide),!0===i.options.accessibility&&(i.$prevArrow.on("keydown.slick",i.keyHandler),i.$nextArrow.on("keydown.slick",i.keyHandler)))},e.prototype.initDotEvents=function(){var e=this;!0===e.options.dots&&(i("li",e.$dots).on("click.slick",{message:"index"},e.changeSlide),!0===e.options.accessibility&&e.$dots.on("keydown.slick",e.keyHandler)),!0===e.options.dots&&!0===e.options.pauseOnDotsHover&&i("li",e.$dots).on("mouseenter.slick",i.proxy(e.interrupt,e,!0)).on("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.initSlideEvents=function(){var e=this;e.options.pauseOnHover&&(e.$list.on("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.on("mouseleave.slick",i.proxy(e.interrupt,e,!1)))},e.prototype.initializeEvents=function(){var e=this;e.initArrowEvents(),e.initDotEvents(),e.initSlideEvents(),e.$list.on("touchstart.slick mousedown.slick",{action:"start"},e.swipeHandler),e.$list.on("touchmove.slick mousemove.slick",{action:"move"},e.swipeHandler),e.$list.on("touchend.slick mouseup.slick",{action:"end"},e.swipeHandler),e.$list.on("touchcancel.slick mouseleave.slick",{action:"end"},e.swipeHandler),e.$list.on("click.slick",e.clickHandler),i(document).on(e.visibilityChange,i.proxy(e.visibility,e)),!0===e.options.accessibility&&e.$list.on("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),i(window).on("orientationchange.slick.slick-"+e.instanceUid,i.proxy(e.orientationChange,e)),i(window).on("resize.slick.slick-"+e.instanceUid,i.proxy(e.resize,e)),i("[draggable!=true]",e.$slideTrack).on("dragstart",e.preventDefault),i(window).on("load.slick.slick-"+e.instanceUid,e.setPosition),i(e.setPosition)},e.prototype.initUI=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.show(),i.$nextArrow.show()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.show()},e.prototype.keyHandler=function(i){var e=this;i.target.tagName.match("TEXTAREA|INPUT|SELECT")||(37===i.keyCode&&!0===e.options.accessibility?e.changeSlide({data:{message:!0===e.options.rtl?"next":"previous"}}):39===i.keyCode&&!0===e.options.accessibility&&e.changeSlide({data:{message:!0===e.options.rtl?"previous":"next"}}))},e.prototype.lazyLoad=function(){function e(e){i("img[data-lazy]",e).each(function(){var e=i(this),t=i(this).attr("data-lazy"),o=i(this).attr("data-srcset"),s=i(this).attr("data-sizes")||n.$slider.attr("data-sizes"),r=document.createElement("img");r.onload=function(){e.animate({opacity:0},100,function(){o&&(e.attr("srcset",o),s&&e.attr("sizes",s)),e.attr("src",t).animate({opacity:1},200,function(){e.removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading")}),n.$slider.trigger("lazyLoaded",[n,e,t])})},r.onerror=function(){e.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),n.$slider.trigger("lazyLoadError",[n,e,t])},r.src=t})}var t,o,s,n=this;if(!0===n.options.centerMode?!0===n.options.infinite?s=(o=n.currentSlide+(n.options.slidesToShow/2+1))+n.options.slidesToShow+2:(o=Math.max(0,n.currentSlide-(n.options.slidesToShow/2+1)),s=n.options.slidesToShow/2+1+2+n.currentSlide):(o=n.options.infinite?n.options.slidesToShow+n.currentSlide:n.currentSlide,s=Math.ceil(o+n.options.slidesToShow),!0===n.options.fade&&(o>0&&o--,s<=n.slideCount&&s++)),t=n.$slider.find(".slick-slide").slice(o,s),"anticipated"===n.options.lazyLoad)for(var r=o-1,l=s,d=n.$slider.find(".slick-slide"),a=0;a<n.options.slidesToScroll;a++)r<0&&(r=n.slideCount-1),t=(t=t.add(d.eq(r))).add(d.eq(l)),r--,l++;e(t),n.slideCount<=n.options.slidesToShow?e(n.$slider.find(".slick-slide")):n.currentSlide>=n.slideCount-n.options.slidesToShow?e(n.$slider.find(".slick-cloned").slice(0,n.options.slidesToShow)):0===n.currentSlide&&e(n.$slider.find(".slick-cloned").slice(-1*n.options.slidesToShow))},e.prototype.loadSlider=function(){var i=this;i.setPosition(),i.$slideTrack.css({opacity:1}),i.$slider.removeClass("slick-loading"),i.initUI(),"progressive"===i.options.lazyLoad&&i.progressiveLazyLoad()},e.prototype.next=e.prototype.slickNext=function(){this.changeSlide({data:{message:"next"}})},e.prototype.orientationChange=function(){var i=this;i.checkResponsive(),i.setPosition()},e.prototype.pause=e.prototype.slickPause=function(){var i=this;i.autoPlayClear(),i.paused=!0},e.prototype.play=e.prototype.slickPlay=function(){var i=this;i.autoPlay(),i.options.autoplay=!0,i.paused=!1,i.focussed=!1,i.interrupted=!1},e.prototype.postSlide=function(e){var t=this;t.unslicked||(t.$slider.trigger("afterChange",[t,e]),t.animating=!1,t.slideCount>t.options.slidesToShow&&t.setPosition(),t.swipeLeft=null,t.options.autoplay&&t.autoPlay(),!0===t.options.accessibility&&(t.initADA(),t.options.focusOnChange&&i(t.$slides.get(t.currentSlide)).attr("tabindex",0).focus()))},e.prototype.prev=e.prototype.slickPrev=function(){this.changeSlide({data:{message:"previous"}})},e.prototype.preventDefault=function(i){i.preventDefault()},e.prototype.progressiveLazyLoad=function(e){e=e||1;var t,o,s,n,r,l=this,d=i("img[data-lazy]",l.$slider);d.length?(t=d.first(),o=t.attr("data-lazy"),s=t.attr("data-srcset"),n=t.attr("data-sizes")||l.$slider.attr("data-sizes"),(r=document.createElement("img")).onload=function(){s&&(t.attr("srcset",s),n&&t.attr("sizes",n)),t.attr("src",o).removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading"),!0===l.options.adaptiveHeight&&l.setPosition(),l.$slider.trigger("lazyLoaded",[l,t,o]),l.progressiveLazyLoad()},r.onerror=function(){e<3?setTimeout(function(){l.progressiveLazyLoad(e+1)},500):(t.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),l.$slider.trigger("lazyLoadError",[l,t,o]),l.progressiveLazyLoad())},r.src=o):l.$slider.trigger("allImagesLoaded",[l])},e.prototype.refresh=function(e){var t,o,s=this;o=s.slideCount-s.options.slidesToShow,!s.options.infinite&&s.currentSlide>o&&(s.currentSlide=o),s.slideCount<=s.options.slidesToShow&&(s.currentSlide=0),t=s.currentSlide,s.destroy(!0),i.extend(s,s.initials,{currentSlide:t}),s.init(),e||s.changeSlide({data:{message:"index",index:t}},!1)},e.prototype.registerBreakpoints=function(){var e,t,o,s=this,n=s.options.responsive||null;if("array"===i.type(n)&&n.length){s.respondTo=s.options.respondTo||"window";for(e in n)if(o=s.breakpoints.length-1,n.hasOwnProperty(e)){for(t=n[e].breakpoint;o>=0;)s.breakpoints[o]&&s.breakpoints[o]===t&&s.breakpoints.splice(o,1),o--;s.breakpoints.push(t),s.breakpointSettings[t]=n[e].settings}s.breakpoints.sort(function(i,e){return s.options.mobileFirst?i-e:e-i})}},e.prototype.reinit=function(){var e=this;e.$slides=e.$slideTrack.children(e.options.slide).addClass("slick-slide"),e.slideCount=e.$slides.length,e.currentSlide>=e.slideCount&&0!==e.currentSlide&&(e.currentSlide=e.currentSlide-e.options.slidesToScroll),e.slideCount<=e.options.slidesToShow&&(e.currentSlide=0),e.registerBreakpoints(),e.setProps(),e.setupInfinite(),e.buildArrows(),e.updateArrows(),e.initArrowEvents(),e.buildDots(),e.updateDots(),e.initDotEvents(),e.cleanUpSlideEvents(),e.initSlideEvents(),e.checkResponsive(!1,!0),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),e.setPosition(),e.focusHandler(),e.paused=!e.options.autoplay,e.autoPlay(),e.$slider.trigger("reInit",[e])},e.prototype.resize=function(){var e=this;i(window).width()!==e.windowWidth&&(clearTimeout(e.windowDelay),e.windowDelay=window.setTimeout(function(){e.windowWidth=i(window).width(),e.checkResponsive(),e.unslicked||e.setPosition()},50))},e.prototype.removeSlide=e.prototype.slickRemove=function(i,e,t){var o=this;if(i="boolean"==typeof i?!0===(e=i)?0:o.slideCount-1:!0===e?--i:i,o.slideCount<1||i<0||i>o.slideCount-1)return!1;o.unload(),!0===t?o.$slideTrack.children().remove():o.$slideTrack.children(this.options.slide).eq(i).remove(),o.$slides=o.$slideTrack.children(this.options.slide),o.$slideTrack.children(this.options.slide).detach(),o.$slideTrack.append(o.$slides),o.$slidesCache=o.$slides,o.reinit()},e.prototype.setCSS=function(i){var e,t,o=this,s={};!0===o.options.rtl&&(i=-i),e="left"==o.positionProp?Math.ceil(i)+"px":"0px",t="top"==o.positionProp?Math.ceil(i)+"px":"0px",s[o.positionProp]=i,!1===o.transformsEnabled?o.$slideTrack.css(s):(s={},!1===o.cssTransitions?(s[o.animType]="translate("+e+", "+t+")",o.$slideTrack.css(s)):(s[o.animType]="translate3d("+e+", "+t+", 0px)",o.$slideTrack.css(s)))},e.prototype.setDimensions=function(){var i=this;!1===i.options.vertical?!0===i.options.centerMode&&i.$list.css({padding:"0px "+i.options.centerPadding}):(i.$list.height(i.$slides.first().outerHeight(!0)*i.options.slidesToShow),!0===i.options.centerMode&&i.$list.css({padding:i.options.centerPadding+" 0px"})),i.listWidth=i.$list.width(),i.listHeight=i.$list.height(),!1===i.options.vertical&&!1===i.options.variableWidth?(i.slideWidth=Math.ceil(i.listWidth/i.options.slidesToShow),i.$slideTrack.width(Math.ceil(i.slideWidth*i.$slideTrack.children(".slick-slide").length))):!0===i.options.variableWidth?i.$slideTrack.width(5e3*i.slideCount):(i.slideWidth=Math.ceil(i.listWidth),i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0)*i.$slideTrack.children(".slick-slide").length)));var e=i.$slides.first().outerWidth(!0)-i.$slides.first().width();!1===i.options.variableWidth&&i.$slideTrack.children(".slick-slide").width(i.slideWidth-e)},e.prototype.setFade=function(){var e,t=this;t.$slides.each(function(o,s){e=t.slideWidth*o*-1,!0===t.options.rtl?i(s).css({position:"relative",right:e,top:0,zIndex:t.options.zIndex-2,opacity:0}):i(s).css({position:"relative",left:e,top:0,zIndex:t.options.zIndex-2,opacity:0})}),t.$slides.eq(t.currentSlide).css({zIndex:t.options.zIndex-1,opacity:1})},e.prototype.setHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.css("height",e)}},e.prototype.setOption=e.prototype.slickSetOption=function(){var e,t,o,s,n,r=this,l=!1;if("object"===i.type(arguments[0])?(o=arguments[0],l=arguments[1],n="multiple"):"string"===i.type(arguments[0])&&(o=arguments[0],s=arguments[1],l=arguments[2],"responsive"===arguments[0]&&"array"===i.type(arguments[1])?n="responsive":void 0!==arguments[1]&&(n="single")),"single"===n)r.options[o]=s;else if("multiple"===n)i.each(o,function(i,e){r.options[i]=e});else if("responsive"===n)for(t in s)if("array"!==i.type(r.options.responsive))r.options.responsive=[s[t]];else{for(e=r.options.responsive.length-1;e>=0;)r.options.responsive[e].breakpoint===s[t].breakpoint&&r.options.responsive.splice(e,1),e--;r.options.responsive.push(s[t])}l&&(r.unload(),r.reinit())},e.prototype.setPosition=function(){var i=this;i.setDimensions(),i.setHeight(),!1===i.options.fade?i.setCSS(i.getLeft(i.currentSlide)):i.setFade(),i.$slider.trigger("setPosition",[i])},e.prototype.setProps=function(){var i=this,e=document.body.style;i.positionProp=!0===i.options.vertical?"top":"left","top"===i.positionProp?i.$slider.addClass("slick-vertical"):i.$slider.removeClass("slick-vertical"),void 0===e.WebkitTransition&&void 0===e.MozTransition&&void 0===e.msTransition||!0===i.options.useCSS&&(i.cssTransitions=!0),i.options.fade&&("number"==typeof i.options.zIndex?i.options.zIndex<3&&(i.options.zIndex=3):i.options.zIndex=i.defaults.zIndex),void 0!==e.OTransform&&(i.animType="OTransform",i.transformType="-o-transform",i.transitionType="OTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.MozTransform&&(i.animType="MozTransform",i.transformType="-moz-transform",i.transitionType="MozTransition",void 0===e.perspectiveProperty&&void 0===e.MozPerspective&&(i.animType=!1)),void 0!==e.webkitTransform&&(i.animType="webkitTransform",i.transformType="-webkit-transform",i.transitionType="webkitTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.msTransform&&(i.animType="msTransform",i.transformType="-ms-transform",i.transitionType="msTransition",void 0===e.msTransform&&(i.animType=!1)),void 0!==e.transform&&!1!==i.animType&&(i.animType="transform",i.transformType="transform",i.transitionType="transition"),i.transformsEnabled=i.options.useTransform&&null!==i.animType&&!1!==i.animType},e.prototype.setSlideClasses=function(i){var e,t,o,s,n=this;if(t=n.$slider.find(".slick-slide").removeClass("slick-active slick-center slick-current").attr("aria-hidden","true"),n.$slides.eq(i).addClass("slick-current"),!0===n.options.centerMode){var r=n.options.slidesToShow%2==0?1:0;e=Math.floor(n.options.slidesToShow/2),!0===n.options.infinite&&(i>=e&&i<=n.slideCount-1-e?n.$slides.slice(i-e+r,i+e+1).addClass("slick-active").attr("aria-hidden","false"):(o=n.options.slidesToShow+i,t.slice(o-e+1+r,o+e+2).addClass("slick-active").attr("aria-hidden","false")),0===i?t.eq(t.length-1-n.options.slidesToShow).addClass("slick-center"):i===n.slideCount-1&&t.eq(n.options.slidesToShow).addClass("slick-center")),n.$slides.eq(i).addClass("slick-center")}else i>=0&&i<=n.slideCount-n.options.slidesToShow?n.$slides.slice(i,i+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"):t.length<=n.options.slidesToShow?t.addClass("slick-active").attr("aria-hidden","false"):(s=n.slideCount%n.options.slidesToShow,o=!0===n.options.infinite?n.options.slidesToShow+i:i,n.options.slidesToShow==n.options.slidesToScroll&&n.slideCount-i<n.options.slidesToShow?t.slice(o-(n.options.slidesToShow-s),o+s).addClass("slick-active").attr("aria-hidden","false"):t.slice(o,o+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"));"ondemand"!==n.options.lazyLoad&&"anticipated"!==n.options.lazyLoad||n.lazyLoad()},e.prototype.setupInfinite=function(){var e,t,o,s=this;if(!0===s.options.fade&&(s.options.centerMode=!1),!0===s.options.infinite&&!1===s.options.fade&&(t=null,s.slideCount>s.options.slidesToShow)){for(o=!0===s.options.centerMode?s.options.slidesToShow+1:s.options.slidesToShow,e=s.slideCount;e>s.slideCount-o;e-=1)t=e-1,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t-s.slideCount).prependTo(s.$slideTrack).addClass("slick-cloned");for(e=0;e<o+s.slideCount;e+=1)t=e,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t+s.slideCount).appendTo(s.$slideTrack).addClass("slick-cloned");s.$slideTrack.find(".slick-cloned").find("[id]").each(function(){i(this).attr("id","")})}},e.prototype.interrupt=function(i){var e=this;i||e.autoPlay(),e.interrupted=i},e.prototype.selectHandler=function(e){var t=this,o=i(e.target).is(".slick-slide")?i(e.target):i(e.target).parents(".slick-slide"),s=parseInt(o.attr("data-slick-index"));s||(s=0),t.slideCount<=t.options.slidesToShow?t.slideHandler(s,!1,!0):t.slideHandler(s)},e.prototype.slideHandler=function(i,e,t){var o,s,n,r,l,d=null,a=this;if(e=e||!1,!(!0===a.animating&&!0===a.options.waitForAnimate||!0===a.options.fade&&a.currentSlide===i))if(!1===e&&a.asNavFor(i),o=i,d=a.getLeft(o),r=a.getLeft(a.currentSlide),a.currentLeft=null===a.swipeLeft?r:a.swipeLeft,!1===a.options.infinite&&!1===a.options.centerMode&&(i<0||i>a.getDotCount()*a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else if(!1===a.options.infinite&&!0===a.options.centerMode&&(i<0||i>a.slideCount-a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else{if(a.options.autoplay&&clearInterval(a.autoPlayTimer),s=o<0?a.slideCount%a.options.slidesToScroll!=0?a.slideCount-a.slideCount%a.options.slidesToScroll:a.slideCount+o:o>=a.slideCount?a.slideCount%a.options.slidesToScroll!=0?0:o-a.slideCount:o,a.animating=!0,a.$slider.trigger("beforeChange",[a,a.currentSlide,s]),n=a.currentSlide,a.currentSlide=s,a.setSlideClasses(a.currentSlide),a.options.asNavFor&&(l=(l=a.getNavTarget()).slick("getSlick")).slideCount<=l.options.slidesToShow&&l.setSlideClasses(a.currentSlide),a.updateDots(),a.updateArrows(),!0===a.options.fade)return!0!==t?(a.fadeSlideOut(n),a.fadeSlide(s,function(){a.postSlide(s)})):a.postSlide(s),void a.animateHeight();!0!==t?a.animateSlide(d,function(){a.postSlide(s)}):a.postSlide(s)}},e.prototype.startLoad=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.hide(),i.$nextArrow.hide()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.hide(),i.$slider.addClass("slick-loading")},e.prototype.swipeDirection=function(){var i,e,t,o,s=this;return i=s.touchObject.startX-s.touchObject.curX,e=s.touchObject.startY-s.touchObject.curY,t=Math.atan2(e,i),(o=Math.round(180*t/Math.PI))<0&&(o=360-Math.abs(o)),o<=45&&o>=0?!1===s.options.rtl?"left":"right":o<=360&&o>=315?!1===s.options.rtl?"left":"right":o>=135&&o<=225?!1===s.options.rtl?"right":"left":!0===s.options.verticalSwiping?o>=35&&o<=135?"down":"up":"vertical"},e.prototype.swipeEnd=function(i){var e,t,o=this;if(o.dragging=!1,o.swiping=!1,o.scrolling)return o.scrolling=!1,!1;if(o.interrupted=!1,o.shouldClick=!(o.touchObject.swipeLength>10),void 0===o.touchObject.curX)return!1;if(!0===o.touchObject.edgeHit&&o.$slider.trigger("edge",[o,o.swipeDirection()]),o.touchObject.swipeLength>=o.touchObject.minSwipe){switch(t=o.swipeDirection()){case"left":case"down":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide+o.getSlideCount()):o.currentSlide+o.getSlideCount(),o.currentDirection=0;break;case"right":case"up":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide-o.getSlideCount()):o.currentSlide-o.getSlideCount(),o.currentDirection=1}"vertical"!=t&&(o.slideHandler(e),o.touchObject={},o.$slider.trigger("swipe",[o,t]))}else o.touchObject.startX!==o.touchObject.curX&&(o.slideHandler(o.currentSlide),o.touchObject={})},e.prototype.swipeHandler=function(i){var e=this;if(!(!1===e.options.swipe||"ontouchend"in document&&!1===e.options.swipe||!1===e.options.draggable&&-1!==i.type.indexOf("mouse")))switch(e.touchObject.fingerCount=i.originalEvent&&void 0!==i.originalEvent.touches?i.originalEvent.touches.length:1,e.touchObject.minSwipe=e.listWidth/e.options.touchThreshold,!0===e.options.verticalSwiping&&(e.touchObject.minSwipe=e.listHeight/e.options.touchThreshold),i.data.action){case"start":e.swipeStart(i);break;case"move":e.swipeMove(i);break;case"end":e.swipeEnd(i)}},e.prototype.swipeMove=function(i){var e,t,o,s,n,r,l=this;return n=void 0!==i.originalEvent?i.originalEvent.touches:null,!(!l.dragging||l.scrolling||n&&1!==n.length)&&(e=l.getLeft(l.currentSlide),l.touchObject.curX=void 0!==n?n[0].pageX:i.clientX,l.touchObject.curY=void 0!==n?n[0].pageY:i.clientY,l.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(l.touchObject.curX-l.touchObject.startX,2))),r=Math.round(Math.sqrt(Math.pow(l.touchObject.curY-l.touchObject.startY,2))),!l.options.verticalSwiping&&!l.swiping&&r>4?(l.scrolling=!0,!1):(!0===l.options.verticalSwiping&&(l.touchObject.swipeLength=r),t=l.swipeDirection(),void 0!==i.originalEvent&&l.touchObject.swipeLength>4&&(l.swiping=!0,i.preventDefault()),s=(!1===l.options.rtl?1:-1)*(l.touchObject.curX>l.touchObject.startX?1:-1),!0===l.options.verticalSwiping&&(s=l.touchObject.curY>l.touchObject.startY?1:-1),o=l.touchObject.swipeLength,l.touchObject.edgeHit=!1,!1===l.options.infinite&&(0===l.currentSlide&&"right"===t||l.currentSlide>=l.getDotCount()&&"left"===t)&&(o=l.touchObject.swipeLength*l.options.edgeFriction,l.touchObject.edgeHit=!0),!1===l.options.vertical?l.swipeLeft=e+o*s:l.swipeLeft=e+o*(l.$list.height()/l.listWidth)*s,!0===l.options.verticalSwiping&&(l.swipeLeft=e+o*s),!0!==l.options.fade&&!1!==l.options.touchMove&&(!0===l.animating?(l.swipeLeft=null,!1):void l.setCSS(l.swipeLeft))))},e.prototype.swipeStart=function(i){var e,t=this;if(t.interrupted=!0,1!==t.touchObject.fingerCount||t.slideCount<=t.options.slidesToShow)return t.touchObject={},!1;void 0!==i.originalEvent&&void 0!==i.originalEvent.touches&&(e=i.originalEvent.touches[0]),t.touchObject.startX=t.touchObject.curX=void 0!==e?e.pageX:i.clientX,t.touchObject.startY=t.touchObject.curY=void 0!==e?e.pageY:i.clientY,t.dragging=!0},e.prototype.unfilterSlides=e.prototype.slickUnfilter=function(){var i=this;null!==i.$slidesCache&&(i.unload(),i.$slideTrack.children(this.options.slide).detach(),i.$slidesCache.appendTo(i.$slideTrack),i.reinit())},e.prototype.unload=function(){var e=this;i(".slick-cloned",e.$slider).remove(),e.$dots&&e.$dots.remove(),e.$prevArrow&&e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.remove(),e.$nextArrow&&e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.remove(),e.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden","true").css("width","")},e.prototype.unslick=function(i){var e=this;e.$slider.trigger("unslick",[e,i]),e.destroy()},e.prototype.updateArrows=function(){var i=this;Math.floor(i.options.slidesToShow/2),!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&!i.options.infinite&&(i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false"),0===i.currentSlide?(i.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-i.options.slidesToShow&&!1===i.options.centerMode?(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-1&&!0===i.options.centerMode&&(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")))},e.prototype.updateDots=function(){var i=this;null!==i.$dots&&(i.$dots.find("li").removeClass("slick-active").end(),i.$dots.find("li").eq(Math.floor(i.currentSlide/i.options.slidesToScroll)).addClass("slick-active"))},e.prototype.visibility=function(){var i=this;i.options.autoplay&&(document[i.hidden]?i.interrupted=!0:i.interrupted=!1)},i.fn.slick=function(){var i,t,o=this,s=arguments[0],n=Array.prototype.slice.call(arguments,1),r=o.length;for(i=0;i<r;i++)if("object"==typeof s||void 0===s?o[i].slick=new e(o[i],s):t=o[i].slick[s].apply(o[i].slick,n),void 0!==t)return t;return o}});
;
(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD module
    define(factory);
  } else if (typeof exports === 'object') {
    // CommonJS-like environment (i.e. Node)
    module.exports = factory();
  } else {
    // Browser global
    root.transformicons = factory();
  }
}(this || window, function () {

  // ####################
  // MODULE TRANSFORMICON
  // ####################
  'use strict';

  var
    tcon = {}, // static class
    _transformClass = 'tcon-transform',

    // const
    DEFAULT_EVENTS = {
      transform : ['click'],
      revert : ['click']
    };

  // ##############
  // private methods
  // ##############

  /**
  * Normalize a selector string, a single DOM element or an array of elements into an array of DOM elements.
  * @private
  *
  * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements
  * @returns {array} Array of DOM elements
  */
  var getElementList = function (elements) {
    if (typeof elements === 'string') {
      return Array.prototype.slice.call(document.querySelectorAll(elements));
    } else if (typeof elements === 'undefined' || elements instanceof Array) {
      return elements;
    } else {
      return [elements];
    }
  };

  /**
  * Normalize a string with eventnames separated by spaces or an array of eventnames into an array of eventnames.
  * @private
  *
  * @param {(string|array)} elements - String with eventnames separated by spaces or array of eventnames
  * @returns {array} Array of eventnames
  */
  var getEventList = function (events) {
    if (typeof events === 'string') {
      return events.toLowerCase().split(' ');
    } else {
      return events;
    }
  };

  /**
  * Attach or remove transformicon events to one or more elements.
  * @private
  *
  * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be toggled
  * @param {object} [events] - An Object containing one or more special event definitions
  * @param {boolean} [remove=false] - Defines wether the listeners should be added (default) or removed.
  */
  var setListeners = function (elements, events, remove) {
    var
      method = (remove ? 'remove' : 'add') + 'EventListener',
      elementList = getElementList(elements),
      currentElement = elementList.length,
      eventLists = {};

    // get events or use defaults
    for (var prop in DEFAULT_EVENTS) {
      eventLists[prop] = (events && events[prop]) ? getEventList(events[prop]) : DEFAULT_EVENTS[prop];
    }
    
    // add or remove all events for all occasions to all elements
    while(currentElement--) {
      for (var occasion in eventLists) {
        var currentEvent = eventLists[occasion].length;
        while(currentEvent--) {
          elementList[currentElement][method](eventLists[occasion][currentEvent], handleEvent);
        }
      }
    }
  };

  /**
  * Event handler for transform events.
  * @private
  *
  * @param {object} event - event object
  */
  var handleEvent = function (event) {
    tcon.toggle(event.currentTarget);
  };

  // ##############
  // public methods
  // ##############

  /**
  * Add transformicon behavior to one or more elements.
  * @public
  *
  * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be toggled
  * @param {object} [events] - An Object containing one or more special event definitions
  * @param {(string|array)} [events.transform] - One or more events that trigger the transform. Can be an Array or string with events seperated by space.
  * @param {(string|array)} [events.revert] - One or more events that trigger the reversion. Can be an Array or string with events seperated by space.
  * @returns {transformicon} transformicon instance for chaining
  */
  tcon.add = function (elements, events) {
    setListeners(elements, events);
    return tcon;
  };

  /**
  * Remove transformicon behavior from one or more elements.
  * @public
  *
  * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be toggled
  * @param {object} [events] - An Object containing one or more special event definitions
  * @param {(string|array)} [events.transform] - One or more events that trigger the transform. Can be an Array or string with events seperated by space.
  * @param {(string|array)} [events.revert] - One or more events that trigger the reversion. Can be an Array or string with events seperated by space.
  * @returns {transformicon} transformicon instance for chaining
  */
  tcon.remove = function (elements, events) {
    setListeners(elements, events, true);
    return tcon;
  };

  /**
  * Put one or more elements in the transformed state.
  * @public
  *
  * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be transformed
  * @returns {transformicon} transformicon instance for chaining
  */
  tcon.transform = function (elements) {
    getElementList(elements).forEach(function(element) {
      element.classList.add(_transformClass);
    });
    return tcon;
  };

  /**
  * Revert one or more elements to the original state.
  * @public
  *
  * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be reverted
  * @returns {transformicon} transformicon instance for chaining
  */
  tcon.revert = function (elements) {
    getElementList(elements).forEach(function(element) {
      element.classList.remove(_transformClass);
    });
    return tcon;
  };
  
  /**
  * Toggles one or more elements between transformed and original state.
  * @public
  *
  * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be toggled
  * @returns {transformicon} transformicon instance for chaining
  */
  tcon.toggle = function (elements) {
    getElementList(elements).forEach(function(element) {
      tcon[element.classList.contains(_transformClass) ? 'revert' : 'transform'](element);
    });
    return tcon;
  };

  return tcon;
}));
;
/*
 * jQuery.appear
 * https://github.com/bas2k/jquery.appear/
 * http://code.google.com/p/jquery-appear/
 * http://bas2k.ru/
 *
 * Copyright (c) 2009 Michael Hixson
 * Copyright (c) 2012-2014 Alexander Brovikov
 * Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
 */
(function($) {
    $.fn.appear = function(fn, options) {

        var settings = $.extend({

            //arbitrary data to pass to fn
            data: undefined,

            //call fn only on the first appear?
            one: true,

            // X & Y accuracy
            accX: 0,
            accY: 0

        }, options);

        return this.each(function() {

            var t = $(this);

            //whether the element is currently visible
            t.appeared = false;

            if (!fn) {

                //trigger the custom event
                t.trigger('appear', settings.data);
                return;
            }

            var w = $(window);

            //fires the appear event when appropriate
            var check = function() {

                //is the element hidden?
                if (!t.is(':visible')) {

                    //it became hidden
                    t.appeared = false;
                    return;
                }

                //is the element inside the visible window?
                var a = w.scrollLeft();
                var b = w.scrollTop();
                var o = t.offset();
                var x = o.left;
                var y = o.top;

                var ax = settings.accX;
                var ay = settings.accY;
                var th = t.height();
                var wh = w.height();
                var tw = t.width();
                var ww = w.width();

                if (y + th + ay >= b &&
                    y <= b + wh + ay &&
                    x + tw + ax >= a &&
                    x <= a + ww + ax) {

                    //trigger the custom event
                    if (!t.appeared) t.trigger('appear', settings.data);

                } else {

                    //it scrolled out of view
                    t.appeared = false;
                }
            };

            //create a modified fn with some additional logic
            var modifiedFn = function() {

                //mark the element as visible
                t.appeared = true;

                //is this supposed to happen only once?
                if (settings.one) {

                    //remove the check
                    w.unbind('scroll', check);
                    var i = $.inArray(check, $.fn.appear.checks);
                    if (i >= 0) $.fn.appear.checks.splice(i, 1);
                }

                //trigger the original fn
                fn.apply(this, arguments);
            };

            //bind the modified fn to the element
            if (settings.one) t.one('appear', settings.data, modifiedFn);
            else t.bind('appear', settings.data, modifiedFn);

            //check whenever the window scrolls
            w.scroll(check);

            //check whenever the dom changes
            $.fn.appear.checks.push(check);

            //check now
            (check)();
        });
    };

    //keep a queue of appearance checks
    $.extend($.fn.appear, {

        checks: [],
        timeout: null,

        //process the queue
        checkAll: function() {
            var length = $.fn.appear.checks.length;
            if (length > 0) while (length--) ($.fn.appear.checks[length])();
        },

        //check the queue asynchronously
        run: function() {
            if ($.fn.appear.timeout) clearTimeout($.fn.appear.timeout);
            $.fn.appear.timeout = setTimeout($.fn.appear.checkAll, 20);
        }
    });

    //run checks when these methods are called
    $.each(['append', 'prepend', 'after', 'before', 'attr',
        'removeAttr', 'addClass', 'removeClass', 'toggleClass',
        'remove', 'css', 'show', 'hide'], function(i, n) {
        var old = $.fn[n];
        if (old) {
            $.fn[n] = function() {
                var r = old.apply(this, arguments);
                $.fn.appear.run();
                return r;
            }
        }
    });

})(jQuery);
;
/*
 Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net
*/
(function(){var b,f;b=this.jQuery||window.jQuery;f=b(window);b.fn.stick_in_parent=function(d){var A,w,J,n,B,K,p,q,k,E,t;null==d&&(d={});t=d.sticky_class;B=d.inner_scrolling;E=d.recalc_every;k=d.parent;q=d.offset_top;p=d.spacer;w=d.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=b(document);null==w&&(w=!0);J=function(a,d,n,C,F,u,r,G){var v,H,m,D,I,c,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k));
if(!g.length)throw"failed to find stick parent";v=m=!1;(h=null!=p?p&&a.closest(p):b("<div />"))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q,
u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),e<F&&(m=!1,c=q,null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),
h.detach()),b={position:"",width:"",top:""},a.css(b).removeClass(t).trigger("sticky_kit:unstick")),B&&(b=f.height(),u+q>b&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}),
a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize",
y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n<K;n++)d=this[n],J(b(d));return this}}).call(this);;
// ###################################
// AcuityBrands - JS                    
// ###################################



/* #################### SCROLL TO TOP OF PAGE ON LOAD #################### */
$('.scroll-to-top').click(function () {
    $('html,body').animate({ scrollTop: 0 }, 300);
});

//$(document).ready(function () {
//    $('.tile').on('inview', function (event, isInView) {
//        if (isInView) {
//            $(this).hide().fadeIn(2000);
//        } else {
//            $(this).hide();
//        }
//    });
//});

$(document).ready(function () {
    $('.tilecomponent').appear(function () {
        var delayTimer = this.dataset.delay;
        var animationTimer = this.dataset.animation;
        $(this).hide().delay(parseInt(delayTimer)).fadeTo(parseInt(animationTimer), 1, function () {
            // Animation complete.
        });//fadeIn(parseInt(animationTimer));
    });
});

/* #################### FAST TRAVEL #################### */
/* ########## BODY PADDING ########## */
function fastTravelBodyPadding() {
    var fastTravelHeight = $('.fast-travel').innerHeight();
    var headerHeight = $('header').innerHeight();
    var fastTravelPadding = fastTravelHeight + headerHeight;
    $('body.with-fast-travel').css('padding-top', fastTravelPadding);
}
$(document).ready(function () { fastTravelBodyPadding(); });
$(window).on("resize", function (e) {
    var onLoadWidth = $(window).width();
    fastTravelBodyPadding(onLoadWidth);
});


/* ########## HIDE/SHOW ########## */
$('.fast-travel span').click(function () {
    $(this).closest('.fast-travel').toggleClass('fast-travel--open');
});


/* ########## ANCHOR LINK EASING ########## */
$(function () {
    $('a[href*="#"]:not([href="#"])').click(function () {
        if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
            var target = $(this.hash);
            target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
            if (target.length) {
                $('html, body').animate({
                    scrollTop: target.offset().top - 100
                }, 500);
                return false;
            }
        }
    });
});



/* #################### ESC KEY PRESS #################### */
$(document).keyup(function (e) {
    if (e.keyCode == 27) {
        $('body').removeClass('image-list-modal-open nav-open search-bar__category--open info-bar__login__dropdown--open info-bar__about__dropdown--open photo-gallery__modal--open search-open'); // info-modal-open
        $('header nav li').removeClass('sub-nav-open tertiary-nav-open');
        $('.tcon').removeClass('tcon-transform');
        // $('.info-modal').removeClass('info-modal--open');
    }
});



/* #################### SHADE #################### */
$('.shade').click(function () {
    $('body').removeClass('nav-open search-bar__category--open info-bar__login__dropdown--open info-bar__about__dropdown--open search-open');
    $('header nav li').removeClass('sub-nav-open tertiary-nav-open');
    $('.tcon').removeClass('tcon-transform');
});



/* #################### INFO MODAL #################### */
$('.carts__item--modal-trigger').click(function () {
    var triggerClicked = $(this).attr('id');
    $('body').addClass('info-modal-open');
    $('.info-modal').each(function () {
        if ($(this).attr('data-info-modal') == triggerClicked) {
            $(this).addClass('info-modal--open');
        }
    });
});

$('.info-modal__content__close').click(function () {
    $('body').removeClass('info-modal-open');
    $('.info-modal').removeClass('info-modal--open');
});



/* #################### INFO BAR DROPDOWNS #################### */
$('.info-bar__links > li.info-bar__links__with-dropdown').mouseenter(function () {
    $('body').addClass('info-bar-links-dropdown-open');
    $(this).addClass('info-bar__links__dropdown--open');
});
$('.info-bar__links > li.info-bar__links__with-dropdown').mouseleave(function () {
    $('body').removeClass('info-bar-links-dropdown-open');
    $(this).removeClass('info-bar__links__dropdown--open');
});

// $('.info-bar__links > li.info-bar__links__with-dropdown').hover(function() {
//    $('body').toggleClass('info-bar-links-dropdown-open');
//    $(this).toggleClass('info-bar__links__dropdown--open');
// });



/* #################### HAMBURGER #################### */
transformicons.add('.tcon');

// function iosNoScroll(e) {
//    e.preventDefault();
// }

$('.hamburger').click(function () {
    if ($('body').hasClass('nav-open')) {
        // document.removeEventListener('touchmove', iosNoScroll, { passive: false });
        $('body').removeClass('nav-open search-bar__category--open');
        $('header nav li').removeClass('sub-nav-open tertiary-nav-open');
    } else {
        // document.addEventListener('touchmove', iosNoScroll, { passive: false });
        $('body').addClass('nav-open');
    }
});



/* #################### MOBILE SEARCH BAR #################### */
$('.mobile-search-trigger').click(function () {
    $('body').addClass('search-open');
});

$('.mobile-search-close').click(function () {
    $('body').removeClass('search-open');
});



/* #################### RESPONSIVE NAV #################### */
function responsiveNav() {
    if (window.innerWidth <= 1079) {

        // unbind
        $('nav > ul > li.has-sub-nav, nav > ul > li.has-sub-nav > a, .header__main__sub-nav > .back, .header__main__sub-nav > li, .header__main__sub-nav > li.has-tertiary-nav, .header__main__sub-nav > li.has-tertiary-nav > a, .header__main__tertiary-nav > .back, .header__main__tertiary-nav li').unbind();

        // sub-nav height auto
        $('.header__main__sub-nav').css('height', 'calc(100vh - 40px)'); // 114

        // close tertiary-nav's
        $('.has-tertiary-nav').removeClass('tertiary-nav-open');

        // open and close sub-nav
        $('nav > ul > li.has-sub-nav > a').click(function () {
            $(this).closest('.has-sub-nav').addClass('sub-nav-open');
        });
        $('.header__main__sub-nav > .back').click(function () {
            $(this).closest('.has-sub-nav').removeClass('sub-nav-open');
        });

        // open and close tertiary-nav
        $('.header__main__sub-nav > li.has-tertiary-nav > a').click(function () {
            $(this).closest('.has-tertiary-nav').addClass('tertiary-nav-open');
        });
        $('.header__main__tertiary-nav > .back').click(function () {
            $(this).closest('.has-tertiary-nav').removeClass('tertiary-nav-open');
        });

    } else {

        // unbind
        $('nav > ul > li.has-sub-nav, nav > ul > li.has-sub-nav > a, .header__main__sub-nav > .back, .header__main__sub-nav > li, .header__main__sub-nav > li.has-tertiary-nav, .header__main__sub-nav > li.has-tertiary-nav > a, .header__main__tertiary-nav > .back, .header__main__tertiary-nav li').unbind();

        // close tertiary-nav's
        // $('.first-with-sub-nav').addClass('tertiary-nav-open');

        // nav ul mouse enter
        $('nav > ul').mouseenter(function () {
            $('body').removeClass('search-bar__category--open');
        });

        // nav li mouse enter
        $('nav > ul > li.has-sub-nav').mouseenter(function () {
            $(this).find('.header__main__sub-nav').css('height', 'auto');
            var subNavHeight = $(this).find('.header__main__sub-nav').innerHeight();
            $('body').removeClass('search-bar__category--open');
            $('body').addClass('nav-open');
            $('nav > ul > li.has-sub-nav').removeClass('sub-nav-open');
            $(this).addClass('sub-nav-open');
            // set sub-nav height to that of its tallest tertiary-nav
            $(this).find('.header__main__tertiary-nav').css('height', 'auto');
            var tallestTertiary = -1;
            $(this).find('.header__main__tertiary-nav').each(function () {
                tallestTertiary = tallestTertiary > $(this).innerHeight() ? tallestTertiary : $(this).innerHeight();
            });
            if (subNavHeight >= tallestTertiary) {
                $(this).find('.header__main__sub-nav').css('height', subNavHeight);
                $(this).find('.header__main__tertiary-nav').css('height', subNavHeight);
                $(this).find('.thumbnail').css('height', subNavHeight);
            } else {
                if (tallestTertiary <= 0) {
                    $(this).find('.header__main__sub-nav').css('height', 'auto');
                    $(this).find('.header__main__tertiary-nav').css('height', 'auto');
                } else {
                    $(this).find('.header__main__sub-nav').css('height', tallestTertiary);
                    $(this).find('.header__main__tertiary-nav').css('height', tallestTertiary);
                }
                $(this).find('.thumbnail').css('height', tallestTertiary);
            }
        });

        // nav li mouse leave
        $('nav > ul > li.has-sub-nav').mouseleave(function () {
            $('body').removeClass('nav-open');
            $('nav > ul > li.has-sub-nav').removeClass('sub-nav-open');
        });

        // open close tertiary-nav
        $('.header__main__sub-nav > li').hover(function () {
            if ($(this).hasClass('first-with-sub-nav')) {
                $(this).siblings().removeClass('tertiary-nav-open');
                $(this).addClass('tertiary-nav-open');
            } else {
                $(this).siblings().removeClass('tertiary-nav-open');
                $(this).addClass('tertiary-nav-open');
            }
        });

        // tertiary thumbnail mouse enter
        $('.header__main__tertiary-nav li').mouseenter(function () {
            $('.header__main__tertiary-nav li').removeClass('visible-thumbnail');
            $(this).addClass('visible-thumbnail');
        });

        // tertiary thumbnail mouse leave
        $('.header__main__tertiary-nav li').mouseleave(function () {
            $('.header__main__tertiary-nav li').removeClass('visible-thumbnail');
        });

    }
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    responsiveNav(onLoadWidth);
});



/* #################### SCROLLED HEADER #################### */
function scrolledHeader() {
    var scrollAmmount = $(window).scrollTop();

    if (scrollAmmount >= 100) {
        $('body').addClass('header-scrolled');
    } else {
        $('body').removeClass('header-scrolled');
    }
}
$(document).ready(function () {
    scrolledHeader();
    $(window).scroll(scrolledHeader);
});



/* #################### SEARCH BAR #################### */
/* ########## CATEGORY DROPDOWN ########## */
/* ########## OPEN */
$('.search-bar__category span').click(function () {
    $('body').removeClass('search-bar__predictive--open');
    $('body').toggleClass('search-bar__category--open');
});

/* ########## CLOSE / CHANGE TEXT */
// $('.search-bar__category li').click(function(e) {
//    $('body').removeClass('search-bar__category--open');
//    setTimeout(function(){
//       $('.search-bar__category span').text($(e.currentTarget).text())
//       searchBarResizeLoad();
//    }, 250);
// });


/* ########## PREDICTIVE RESULTS ########## */
$('.search-bar .search-bar__input').focus(function () {
    $('body').removeClass('search-bar__category--open');
    $('body').addClass('search-bar__predictive--open');
});

$('.search-bar .search-bar__input').blur(function () {
    $('body').removeClass('search-bar__predictive--open');
});



/* #################### FOOTER #################### */
/* ########## ACCORDION ########## */
$('.footer__link-list__link--subhead').click(function () {
    if ($(this).closest('.footer__link-list__sub-list').hasClass('accordion-open')) {
        $(this).closest('.footer__link-list__sub-list').removeClass('accordion-open');
    } else {
        $('.footer__link-list__sub-list').removeClass('accordion-open');
        $(this).closest('.footer__link-list__sub-list').addClass('accordion-open');
    }
});


/* ########## STICKY ########## */
function stickyFooter() {
    var footerHeight = $('footer').innerHeight();
    $('.content-area').css('padding-bottom', footerHeight);
    $('footer').css({ 'position': 'absolute', 'bottom': '0', 'left': '0', 'z-index': '401' });
}
$(window).on("load resize", function (e) {
    // var onLoadWidth = $(window).width();
    // stickyFooter(onLoadWidth);
    setTimeout(stickyFooter, 250);
});



/* #################### HERO LINKS TALLEST HEIGHT #################### */
function heroLinksTallest() {
    if (window.innerWidth >= 992) {
        $('.hero__links__wrapper').css('height', 'auto');
        var tallestHeroLink = -1;
        $('.hero__links__wrapper').each(function () {
            tallestHeroLink = tallestHeroLink > $(this).innerHeight() ? tallestHeroLink : $(this).innerHeight();
        });
        $('.hero__links__wrapper').css('height', tallestHeroLink);
    } else {
        $('.hero__links__wrapper').css('height', 'auto');
    }
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    heroLinksTallest(onLoadWidth);
});

// function heroLinksTallest(){
//    if (window.innerWidth >= 992) {
//       $('.hero__links a').css('height', 'auto');
//       var tallestHeroLink = -1;
//       $('.hero__links a > div').each(function() {
//          tallestHeroLink = tallestHeroLink > $(this).innerHeight() ? tallestHeroLink : $(this).innerHeight();
//       });
//       $('.hero__links a').css('height', tallestHeroLink);
//    } else {
//       $('.hero__links a').css('height', 'auto');
//    }
// }
// $(window).on("load resize",function(e){
//    var onLoadWidth = $(window).width();
//    heroLinksTallest(onLoadWidth);
// });



/* #################### BOX LINKS TALLEST HEIGHT #################### */
function boxLinksTallest() {
    if (window.innerWidth >= 576) {
        $('.box-links__link').css('height', 'auto');
        var tallestBoxLink = -1;
        $('.box-links__link').each(function () {
            tallestBoxLink = tallestBoxLink > $(this).innerHeight() ? tallestBoxLink : $(this).innerHeight();
        });
        $('.box-links__link').css('height', tallestBoxLink);
    } else {
        $('.box-links__link').css('height', 'auto');
    }
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    boxLinksTallest(onLoadWidth);
});



/* #################### SEARCH RESULTS PAGE #################### */
/* ########## FILTERS ########## */
/* ########## TOGGLE SINGLE */
$('.search-results__filter > p').click(function () {
    $(this).parent().toggleClass('filter-open');
});

/* ########## TOGGLE ALL */
$('.expand-all-filters').click(function () {
    $(this).toggleClass('filters-expanded');

    if ($(this).hasClass('filters-expanded')) {
        $('.search-results__filter').addClass('filter-open');
    } else {
        $('.search-results__filter').removeClass('filter-open');
    }
});

/* ########## SHOW MORE */
$('.search-results__filter .show-more').click(function () {
    $(this).parent().toggleClass('all-filters-shown');
});

/* ########## RESPONSIVE */
function responsiveFilter() {
    if (window.innerWidth <= 767) {

        // unbind
        $('.search-results__filter-headline').unbind();

        // close all filters
        $('.search-results__filter').removeClass('filter-open');

        // open/close filters
        $('.search-results__filter-headline').click(function () {
            $(this).parent().toggleClass('filters-closed-mobile');
        });

    } else {

        // unbind
        $('.search-results__filter-headline').unbind();

        // show first 3 filters
        $('.search-results__filter:first-child, .search-results__filter:nth-child(2), .search-results__filter:nth-child(3)').addClass('filter-open');

    }
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    responsiveFilter(onLoadWidth);
});


/* ########## RESIZE SELECT ON OPTION SELECT ########## */
function resizeSelectLoad() {
    $('.resizing_select').each(function () {
        var tmpSelectWidth = $(this).parent().children('.width_tmp_select').width();
        $(this).width(tmpSelectWidth);
    });
}
$(window).on("load", function (e) {
    var onLoadWidth = $(window).width();
    resizeSelectLoad(onLoadWidth);
});

function resizeSelectResize() {
    $('.resizing_select').each(function () {
        var selectWidth = $(this).innerWidth();
        var tmpOption = $(this).parent().children().children('.width_tmp_option');
        var tmpSelect = $(this).parent().children('.width_tmp_select');
        $(this).change(function () {
            $(tmpOption).html($(this).children('option:selected').text());
            $(this).width($(tmpSelect).width());
            var selectWidth = $(this).innerWidth();
        });
    });
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    resizeSelectResize(onLoadWidth);
});


/* ########## SWITCH VIEW - BOOTSTRAP CLASSES ########## */
$('.search-results__options__switch-view li').click(function () {
    $('.search-results__options__switch-view li').removeClass('current-view');
    $(this).addClass('current-view');

    if ($(this).hasClass('view__list')) {
        // view classes
        $('.search-results').removeClass('search-results--grid-view search-results--mini-grid-view');
        $('.search-results').addClass('search-results--list-view');
        // item bootstrap classes
        $('.item__search-results').removeClass('col-lg-4 col-mini-grid');
        $('.item__search-results').addClass('col-md-12');
        // image, info, buttons bootstrap classes
        $('.item__search-results .item__search-results__image').addClass('col-md-3');
        $('.item__search-results .item__search-results__info').addClass('col-md-6 col-lg-7');
        $('.item__search-results > .row > .compare-download-buttons').addClass('col-md-3 col-lg-2');
        // rerun height calcs
        searchResultsHeights();
    } else if ($(this).hasClass('view__grid')) {
        // view classes
        $('.search-results').removeClass('search-results--mini-grid-view search-results--list-view');
        $('.search-results').addClass('search-results--grid-view');
        // item bootstrap classes
        $('.item__search-results').removeClass('col-md-12 col-mini-grid');
        $('.item__search-results').addClass('col-lg-4');
        // image, info, buttons bootstrap classes
        $('.item__search-results .item__search-results__image').removeClass('col-md-3');
        $('.item__search-results .item__search-results__info').removeClass('col-md-6 col-lg-7');
        $('.item__search-results > .row > .compare-download-buttons').removeClass('col-md-3 col-lg-2');
        // rerun height calcs
        searchResultsHeights();
    } else if ($(this).hasClass('view__grid-mini')) {
        // view classes
        $('.search-results').removeClass('search-results--grid-view search-results--list-view');
        $('.search-results').addClass('search-results--mini-grid-view');
        // item bootstrap classes
        $('.item__search-results').removeClass('col-md-12 col-lg-4');
        $('.item__search-results').addClass('col-mini-grid'); // $('.item__search-results').addClass('col-lg-4 col-xl-3');
        // image, info, buttons bootstrap classes
        $('.item__search-results .item__search-results__image').removeClass('col-md-3');
        $('.item__search-results .item__search-results__info').removeClass('col-md-6 col-lg-7');
        $('.item__search-results > .row > .compare-download-buttons').removeClass('col-md-3 col-lg-2');
        // rerun height calcs
        searchResultsHeights();
    }

    // LIST VIEW
    // col-6 col-md-12               item
    //   col-12 col-md-3             image
    //   col-12 col-md-6 col-lg-7    info
    //   col-12 col-md-3 col-lg-2    buttons
    //      col-12                   button
    //      col-12                   button

    // GRID VIEW
    // col-6 col-lg-4                item
    //   col-12                      image
    //   col-12                      info
    //   col-12                      buttons
    //      col-6                    button
    //      col-6                    button

    // GRID MINI VIEW
    // col-6 col-lg-4 col-xl-3       item
    //   col-12                      image
    //   col-12                      info
    //   col-12                      buttons
    //      col-6                    button
    //      col-6                    button
});


/* ########## LIKEY HEART SWAP ########## */
$('.likey').click(function () {
    $(this).toggleClass('liked');
});


/* ########## HEIGHTS ADJUSTMENTS ########## */
function searchResultsHeights() {

    $('.item__info__align-bottom').removeClass('absolute-position');

    if (window.innerWidth >= 768) {
        if ($('.search-results').hasClass('search-results--list-view')) {
            $('.item__search-results__image').css('height', 'auto');
            $('.item__search-results__info').css('height', 'auto');
            $('.item__info__align-bottom').css({ 'position': 'static', 'bottom': 'auto' });
        } else {
            /* ########## IMAGE ########## */
            $('.item__search-results__image').css('height', 'auto');
            $('.item__info__align-bottom').css({ 'position': 'static', 'bottom': 'auto' });
            var tallestSRImage = -1;
            $('.item__search-results__image').each(function () {
                tallestSRImage = tallestSRImage > $(this).innerHeight() ? tallestSRImage : $(this).innerHeight();
            });
            if (tallestSRImage > 0) {
                $('.item__search-results__image').css('height', tallestSRImage);
            }
            /* ########## INFO ########## */
            $('.item__search-results__info').css('height', 'auto');
            $('.item__info__align-bottom').css({ 'position': 'static', 'bottom': 'auto' });
            var tallestSRInfo = -1;
            $('.item__search-results__info').each(function () {
                tallestSRInfo = tallestSRInfo > $(this).innerHeight() ? tallestSRInfo : $(this).innerHeight();
            });
            if (tallestSRInfo > 0) {
                $('.item__search-results__info').css('height', tallestSRInfo);
            }

            $('.item__info__align-bottom').css({ 'position': 'absolute', 'bottom': '15px' });
            $('.item__info__align-bottom').addClass('absolute-position');
        }
    } else {
        /* ########## IMAGE ########## */
        $('.item__search-results__image').css('height', 'auto');
        $('.item__info__align-bottom').css({ 'position': 'static', 'bottom': 'auto' });
        var tallestSRImage = -1;
        $('.item__search-results__image').each(function () {
            tallestSRImage = tallestSRImage > $(this).innerHeight() ? tallestSRImage : $(this).innerHeight();
        });
        if (tallestSRImage > 0) {
            $('.item__search-results__image').css('height', tallestSRImage);
        }
        /* ########## INFO ########## */
        $('.item__search-results__info').css('height', 'auto');
        var tallestSRInfo = -1;
        $('.item__search-results__info').each(function () {
            tallestSRInfo = tallestSRInfo > $(this).innerHeight() ? tallestSRInfo : $(this).innerHeight();
        });
        if (tallestSRInfo > 0) {
            $('.item__search-results__info').css('height', tallestSRInfo);
        }
    }
    $('.search-results-all__products-slider .slick-track').css('height', 'auto');
    var stHeight = $('.search-results-all__products-slider .slick-track').height();
    $('.search-results-all__products-slider .slick-slide').css('height', stHeight + 'px');
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    searchResultsHeights(onLoadWidth);
});


/* ########## QUICK VIEW OPEN CLOSE ########## */
$('.quick-view').click(function () {
    $(this).closest('.item__search-results').addClass('modal-open');
});

$('.close-qv-modal').click(function () {
    $(this).closest('.item__search-results').removeClass('modal-open');
});


/* ########## QUICK VIEW SLIDER ########## */
$(document).ready(function () {
    $('.quick-view-modal__slider-top').on('init', function () {
        $('.quick-view-modal__slider-top').css({ visibility: 'visible' });
    });

    $('.quick-view-modal__slider-bottom').on('init', function () {
        $('.quick-view-modal__slider-bottom').css({ visibility: 'visible' });
    });

    // $('.quick-view-modal__slider-top').slick({
    //    slidesToShow: 1,
    //    slidesToScroll: 1,
    //    arrows: false,
    //    dots: false,
    //    fade: true,
    //    asNavFor: '.quick-view-modal__slider-bottom'
    // });

    $('.quick-view-modal__slider-bottom').slick({
        slidesToShow: 4,
        slidesToScroll: 4,
        // asNavFor: '.quick-view-modal__slider-top',
        arrows: true,
        dots: false,
        infinite: true,
        focusOnSelect: true
    });
});


/* ########## SEARCH RESULTS DOUBLE ZERO ########## */
// function tallestSRDoubleZero(){
//    if (window.innerWidth >= 992) {
//       $('.search-results-double-zero__heading').css('height', 'auto');
//       var tallestDoubleZero = -1;
//       $('.search-results-double-zero__heading').each(function() {
//          tallestDoubleZero = tallestDoubleZero > $(this).innerHeight() ? tallestDoubleZero : $(this).innerHeight();
//       });
//       $('.search-results-double-zero__heading').css('height', tallestDoubleZero);
//    } else {
//       $('.search-results-double-zero__heading').css('height', 'auto');
//    }
// }
// $(window).on("load resize",function(e){
//    var onLoadWidth = $(window).width();
//    tallestSRDoubleZero(onLoadWidth);
// });

$(document).ready(function () {
    $(".video-full-width video").each(function (index, video) {
        var newWidth = window.innerWidth;
        video.style.width = newWidth + "px";
        console.log("setting the new width: " + newWidth + "px");
    });

    $(".video-full-width iframe").each(function (index, video) {
        var newWidth = window.innerWidth;
        video.style.width = newWidth + "px";
        console.log("setting the new width: " + newWidth + "px");
    });  
});

$(document).ready(function () {
    $(".product__video-gallery").slick({
        slidesToShow: 4,
        slidesToScroll: 4,
        // asNavFor: '.quick-view-modal__slider-top',
        arrows: true,
        dots: false,
        infinite: false,
        focusOnSelect: false,
    });
    
    $(".video-selector__options").slick({
        slidesToShow: window.innerWidth > 767 ? 4 : 2,
        slidesToScroll: window.innerWidth > 767 ? 4 : 2,
        arrows: true,
        dots: false,
        infinite: true,
        focusOnSelect: false,
    });
    
});

$(document).ready(function () {
    var options = document.getElementsByClassName("video-selector__options__item__image");
    for (var i = 0; i < options.length; ++i) {
        options[i].addEventListener("click", function (e) {

            var dataVideo = e.target.parentNode.parentNode.getAttribute("data-video");

            var videoId = dataVideo.replace("video-", "");
            console.log("selected id: " + videoId);
            var selectorVideos = document.querySelector(".video-selector__videos").childNodes;

            for (var j = 0; j < selectorVideos.length; ++j) {
                if (selectorVideos[j].nodeName === "DIV") {
                    selectorVideos[j].classList.remove("video-selector__videos__selected");

                    var selectorVideoId = selectorVideos[j].id;
                    console.log(selectorVideoId);
                    var id = selectorVideoId.replace("video-");
                    console.log(id)
                    console.log("looped id: " + id);
                    if (id.replace("undefined", "") === videoId) {
                        selectorVideos[j].classList.add("video-selector__videos__selected");
                    }
                }
            }
        });
    }
});

$(document).ready(function () {
    $(".comparison-slider").each(function (index, slider) {

        waitForSliderWidth(slider);

        var fullpage = $(".comp_" + slider.id + ".full-page-slider").length > 0;
        var sliderWidth = 0;
        if (fullpage) {

            sliderWidth = $(slider).width();
        } else {

            sliderWidth = $(".comp_" + slider.id + " .container-fluid").width();
        }
        var imageOne = $(".comp_" + slider.id + " .slider-image-one");
        var imageOneWidth = imageOne.width();
        var imageTwo = $(".comp_" + slider.id + " .slider-image-two");
        $(".comp_" + slider.id + " .img-comp-container").width(imageOneWidth);

        var sliderContainer = document.getElementsByClassName("slidercontainer_" + slider.id);

        if (sliderContainer[0].style.height == '0px') {
            var highestNum;
            if (imageOne.Height() > imageTwo.Height()) {
                highestNum = imageOne.Height();
            } else {
                highestNum = imageTwo.height();
            }
            sliderContainer[0].style.height = highestNum + 'px';
        }
        
        if (imageOneWidth > sliderWidth) {

            imageOne.width(sliderWidth);
            imageTwo.width(sliderWidth);
            //$(".comp_" + slider.id + " .img-comp-container").height(imageOne.height());
            $(".comp_" + slider.id + " .img-comp-container").width(sliderWidth);
        }
        initComparisons(slider.id, slider);

    });

});

function waitForSliderWidth(slider) {
    var imageOne = $(".comp_" + slider.id + " .slider-image-one");
    var imageOneWidth = imageOne.width();

    var imageTwo = $(".comp_" + slider.id + " .slider-image-two");
    var imageTwoWidth = imageTwo.width();

    var fullpage = $(".comp_" + slider.id + ".full-page-slider").length > 0;
    if (fullpage) {

        sliderWidth = $(slider).width();
    } else {
        sliderWidth = $(".comp_" + slider.id + " .container-fluid").width();
    }


    if (imageOneWidth > 0 && imageTwoWidth > 0 && sliderWidth > 0) {
        // we can continue
    } else {
        setTimeout(waitForSliderWidth(slider), 150); 
    }
}


function initComparisons(uniqueId, slider) {
    waitForSliderWidth(slider);
    var x, i;
    /*find all elements with an "overlay" class:*/
    x = document.getElementsByClassName("overlay_" + uniqueId);

    for (i = 0; i < x.length; i++) {
        /*once for each "overlay" element:
        pass the "overlay" element as a parameter when executing the compareImages function:*/
        compareImages(x[i], uniqueId);

    }

    var rightLabel = $("#" + uniqueId + ".right-label");
    if (rightLabel.length > 0) {
        var rightLabelWidth = slider.offsetWidth - rightLabel[0].offsetWidth - 10;
        rightLabel.css("width", rightLabelWidth + "px");
    }

    var rightImageWidth = document.querySelector(".img-comp_" + uniqueId).querySelector("img").style.width;
    function compareImages(img, uniqueId) {
        var slider, img, clicked = 0, w, h;
        /*get the width and height of the img element*/
        w = img.offsetWidth;
        h = img.offsetHeight;
        /*set the width of the img element to 50%:*/
        img.style.width = (w / 2) + "px";
        /*create slider:*/
        slider = document.createElement("DIV");
        slider.setAttribute("class", "img-comp-slider");
        slider.innerHTML = '<i class="fa fa-caret-left"></i>Slide<i class="fa fa-caret-right"></i>'

        var rightLabel = document.querySelector(".img-comp_" + uniqueId).querySelector("span");
        var initialRightLabelWidth = rightLabel.offsetWidth;
        if (initialRightLabelWidth - 20 > (w / 2)) {
            var widthNumber = Math.ceil(w / 2) - 30;
            rightLabel.style.width = widthNumber + "px";
        }

        /*insert slider*/
        img.parentElement.insertBefore(slider, img);
        if (h == 0) {
            var sliderContainer = document.getElementsByClassName("slidercontainer_" + uniqueId);
            h = sliderContainer[0].style.height.replace('px', '');
            h = h - 150;
        }
        /*position the slider in the middle:*/
        slider.style.top = (h / 2) - (slider.offsetHeight / 2) + "px";
        slider.style.left = (w / 2) - (slider.offsetWidth / 2) - 5 + "px";
        /*execute a function when the mouse button is pressed:*/
        slider.addEventListener("mousedown", slideReady);
        /*and another function when the mouse button is released:*/
        window.addEventListener("mouseup", slideFinish);
        /*or touched (for touch screens:*/
        slider.addEventListener("touchstart", slideReady);
        /*and released (for touch screens:*/
        window.addEventListener("touchend", slideFinish);
        function slideReady(e) {
            /*prevent any other actions that may occur when moving over the image:*/
            e.preventDefault();
            /*the slider is now clicked and ready to move:*/
            clicked = 1;
            /*execute a function when the slider is moved:*/
            window.addEventListener("mousemove", slideMove);
            window.addEventListener("touchmove", slideMove);
        }
        function slideFinish() {
            /*the slider is no longer clicked:*/
            clicked = 0;
        }
        function slideMove(e) {
            var pos;
            /*if the slider is no longer clicked, exit this function:*/
            if (clicked == 0) return false;
            /*get the cursor's x position:*/
            pos = getCursorPos(e)
            /*prevent the slider from being positioned outside the image:*/
            var offset = w * .10;
            if (pos < offset) pos = offset;
            if (pos > (w - offset)) pos = (w - offset);
            /*execute a function that will resize the overlay image according to the cursor:*/
            slide(pos);
        }
        function getCursorPos(e) {
            var a, x = 0;
            e = e || window.event;
            if (e.touches) {
                e = e.touches[0];
            }
            /*get the x positions of the image:*/
            a = img.getBoundingClientRect();
            /*calculate the cursor's x coordinate, relative to the image:*/
            x = e.pageX - a.left;
            /*consider any page scrolling:*/
            x = x - window.pageXOffset;
            return x;
        }
        function slide(x) {
            /*resize the image:*/
            img.style.width = x + "px";
            /*position the slider:*/
            slider.style.left = img.offsetWidth - (slider.offsetWidth / 2) + "px";
            var widthNumber = Number(rightImageWidth.replace("px", ""));
            if ((widthNumber - x - 20) < initialRightLabelWidth) {
                rightLabel.style.width = widthNumber - x - 20 + "px";
            } else {
                var newWidth = initialRightLabelWidth + 10;
                rightLabel.style.width = newWidth + "px";
                console.log("initialRightLabelWidth: " + initialRightLabelWidth);
                console.log("rightLabel.style.width: " + rightLabel.style.width);
            }
        }
    }
}

/* #################### IMAGE LIST MODAL #################### */
$('.image-list img').click(function () {
    $('body').addClass('image-list-modal-open');
    var imageSelected = $(this).attr('src');;
    $('.image-list-modal__image').attr('src', imageSelected);
});

$('.image-list-modal').click(function () {
    $('body').removeClass('image-list-modal-open');
});


/* ########## PRODUCT CARD DROPDOWNS ########## */
$('.downloads').click(function () {
    $('.family').removeClass('family-dropdown-open');
    if ($(this).hasClass('download-dropdown-open')) {
        $('.downloads').removeClass('download-dropdown-open');
    } else {
        $('.downloads').removeClass('download-dropdown-open');
        $(this).addClass('download-dropdown-open');
    }
});

$('.family').click(function () {
    $('.downloads').removeClass('download-dropdown-open');
    if ($(this).hasClass('family-dropdown-open')) {
        $('.family').removeClass('family-dropdown-open');
    } else {
        $('.family').removeClass('family-dropdown-open');
        $(this).addClass('family-dropdown-open');
    }
});


/* ########## TOGGLE SWITCH ########## */
$('.toggle-switch__target').click(function () {
    $(this).toggleClass('toggle-switch--toggled');
});


/* ########## PRODUCT SLIDER ########## */
$(document).ready(function () {
    $('.search-results-all__products-slider').slick({
        slidesToShow: 4,
        slidesToScroll: 4,
        arrows: true,
        dots: false,
        fade: false,
        infinite: false,
        responsive: [
            {
                breakpoint: 768,
                settings: {
                    slidesToShow: 2,
                    slidesToScroll: 2,
                    arrows: false,
                    dots: true
                }
            }
        ]
    });
    //   productSliderHeight();
});

// function productSliderHeight(){
//    $('.search-results-all__products-slider .slick-track').css('height', 'auto');
//    searchResultsHeights();
//    var stHeight = $('.search-results-all__products-slider .slick-track').height();
//    $('.search-results-all__products-slider .slick-slide').css('height',stHeight + 'px' );
// }
// $(window).on("load resize",function(e){
//    var onLoadWidth = $(window).width();
//    productSliderHeight(onLoadWidth);
// });

// $(document).ready(function() { // RDA REQUESTED REMOVAL
//    $('.product-info__product-image .product-image__current-image .current-image__image').css('display', 'block');
// });



/* #################### PRODUCT ACCORDION #################### */
$('.product-accordion__trigger').click(function () {
    $(this).parent().toggleClass('product-accordion--open');
});



/* #################### PRODUCT IMAGE SLIDER #################### */
$(document).ready(function () {
    $('.product-info__product-image .product-image__slider').slick({
        autoplay: false,
        infinite: false,
        arrows: true,
        dots: false,
        slidesToShow: 4,
        slidesToScroll: 4,
        vertical: true,
        verticalSwiping: true,
        centerMode: false,
        responsive: [
            {
                breakpoint: 768,
                settings: {
                    vertical: false,
                    verticalSwiping: false
                }
            }
        ]
    });

    // var maxHeight = -1;
    // $('.product-info__product-image .product-image__slider .slick-slide').each(function() {
    //   if ($(this).height() > maxHeight) {
    //     maxHeight = $(this).height();
    //   }
    // });
    // $('.product-info__product-image .product-image__slider .slick-slide').each(function() {
    //   if ($(this).height() < maxHeight) {
    //     $(this).css('margin', Math.ceil((maxHeight-$(this).height())/2) + 'px 0');
    //   }
    // });

    $('.product-info__product-image .slick-slide').each(function (index) {
        $(this).on("click", function () {
            if ($(this).hasClass('product-image__slider__image')) {
                var imageSrc = $(this).attr('data-image');
                $('.current-image__image, .current-image__video, .current-image__360').css('display', 'none');
                $('#' + imageSrc).css('display', 'block');
                $('.product-image__slider .slick-slide').removeClass('slider__selected-image');
                $(this).addClass('slider__selected-image');
            } else if ($(this).hasClass('product-image__slider__video')) {
                var videoSRC = $(this).attr('data-video');
                $('.current-image__video, .current-image__360, .current-image__image').css('display', 'none');
                $('#' + videoSRC).css('display', 'block');
                $('.product-info__product-image .slick-slide').removeClass('slider__selected-image');
                $(this).addClass('slider__selected-image');
            } else if ($(this).hasClass('product-image__slider__360')) {
                var src360 = $(this).attr('data-360');
                $('.current-image__image, .current-image__360, .current-image__video').css('display', 'none');
                $('#' + src360).css('display', 'block');
                $('.product-info__product-image .slick-slide').removeClass('slider__selected-image');
                $(this).addClass('slider__selected-image');
            }
        });
    });

    $('.quick-view-modal__slider-bottom .slick-slide').each(function (index) {
        $(this).on("click", function () {
            if ($(this).hasClass('product-image__slider__image')) {
                var imgSRC = $(this).find('img').attr("src");
                $('.current-image__video, .current-image__360').css('display', 'none');
                $('.current-image__image').css('display', 'block');
                $('.current-image__image').attr('src', imgSRC);
                $('.quick-view-modal__slider-bottom .slick-slide').removeClass('slider__selected-image');
                $(this).addClass('slider__selected-image');
            } else if ($(this).hasClass('product-image__slider__video')) {
                var videoSRC = $(this).attr('data-video');
                $('.current-image__video, .current-image__360, .current-image__image').css('display', 'none');
                $('#' + videoSRC).css('display', 'block');
                $('.quick-view-modal__slider-bottom .slick-slide').removeClass('slider__selected-image');
                $(this).addClass('slider__selected-image');
            } else if ($(this).hasClass('product-image__slider__360')) {
                var src360 = $(this).attr('data-360');
                $('.current-image__image, .current-image__360, .current-image__video').css('display', 'none');
                $('#' + src360).css('display', 'block');
                $('.quick-view-modal__slider-bottom .slick-slide').removeClass('slider__selected-image');
                $(this).addClass('slider__selected-image');
            }
        });
    });
});

$('.product-image__current-image > img').click(function () {
    $(this).parent().addClass('modal-open');
});

$('.product-image__modal').click(function () {
    $(this).parent().removeClass('modal-open');
});



/* #################### SHARE #################### */
$('.share > span').click(function () {
    $(this).parent().toggleClass('share--open');
});



/* ########## COMPARE WIDTHS ########## */
function compareWidths() {
    if (window.innerWidth >= 992) {
        $('.compare table td').css({ 'width': 'auto', 'min-width': 'auto' });
    } else {
        var windowWidth = $(window).innerWidth() / 2;
        $('.compare table td').css({ 'width': '45vw', 'min-width': '45vw' });
    }
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    compareWidths(onLoadWidth);
});



/* #################### PHOTO GALLERY #################### */
$('.photo-gallery__filters').on('click', 'button', function () {
    $(this).closest('.photo-gallery__filters').find('button').removeClass('btn-blue');
    $(this).closest('.photo-gallery__filters').find('button').addClass('btn-primary');
    $(this).removeClass('btn-primary');
    $(this).addClass('btn-blue');
    var filterValue = $(this).attr('data-filter');
    var updatedFilterValue = filterValue.substring(1);
    if (updatedFilterValue == '') {
        $(this).closest('.photo-gallery').find('.photo-gallery__slider').slick('slickUnfilter');
    } else {
        $(this).closest('.photo-gallery').find('.photo-gallery__slider').slick('slickUnfilter');
        $(this).closest('.photo-gallery').find('.photo-gallery__slider').slick('slickFilter', $('.photo-gallery__slider .' + updatedFilterValue));
    }
});


// function photoGalleryInfoHeight(){
//    $('.photo-gallery .photo-gallery__info').css('height', 'auto');
//    var tallestInfo = -1;
//    $('.photo-gallery .photo-gallery__info').each(function() {
//       tallestInfo = tallestInfo > $(this).height() ? tallestInfo : $(this).height();
//    });
//    $('.photo-gallery .photo-gallery__info').css('height', tallestInfo);
//    console.log(tallestInfo);
// }
// $(window).on("load resize",function(e){
//    var onLoadWidth = $(window).width();
//    photoGalleryInfoHeight(onLoadWidth);
// });


// https://codepen.io/desandro/pen/e73e9ca10897063fd9e75f7f47db1a13/
function enableIsotope() {
    // for each container
    $('.photo-gallery').each(function (i, gridContainer) {
        var $gridContainer = $(gridContainer);
        // init isotope for container
        var $grid = $gridContainer.find('.isotope-grid').imagesLoaded(function () {
            $grid.isotope({
                itemSelector: '.photo-gallery__photo-item',
                transitionDuration: 0,
                layoutMode: 'fitRows'
            });
        });
        // initi filters for container
        $gridContainer.find('.photo-gallery__filters').on('click', 'button', function () {
            var filterValue = $(this).attr('data-filter');
            $grid.isotope({ filter: filterValue, transitionDuration: 0 });
        });
    });
};
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    enableIsotope(onLoadWidth);
});




/* #################### TABS #################### */
/* ########## SWITCHING INTERACTION ########## */
$('.tabs .tabs__nav li').click(function () {

    //$('.tabs .tabs__sections > div').removeClass('tabs__sections__current-section');
    var tabProgenitor = $(this).parent();
    while (!tabProgenitor.hasClass("tabs")) {
        tabProgenitor = tabProgenitor.parent();
    }

    var siblingSections = tabProgenitor.children("div:nth-child(2)").children("div.tabs__sections").children();
    siblingSections.removeClass('tabs__sections__current-section');
    $(this).siblings().removeClass('tabs__nav__current-tab');
    $(this).addClass('tabs__nav__current-tab');

    var tabClicked = $(this).attr('data-tabs-nav');

    siblingSections.each(function () {
        if ($(this).attr('data-tabs-section') === tabClicked) {
            // block
            $(this).addClass('tabs__sections__current-section');
        } else {
            // none
            $(this).removeClass('tabs__sections__current-section');
        }
    });

    resizeSelectLoad();
    enableIsotope();
    // $grid.isotope();
});


/* ########## HORIZONTAL SCROLLING ########## */
function scrolledTabs() {
    var scrollLeft = $('.tabs .tabs__draggable').scrollLeft();
    if (scrollLeft >= 5) {
        $('.tabs').addClass('tabs--scrolled');
    } else {
        $('.tabs').removeClass('tabs--scrolled');
    }
}
$(document).ready(function () {
    scrolledTabs();
    $('.tabs .tabs__draggable').scroll(scrolledTabs);
});


/* ########## RESIZE OVERFLOW ########## */
function tabsResizeOverflow() {
    var tabsWrapperWidth = $('.tabs .tabs__draggable').innerWidth();
    var tabsWidth = $('.tabs .tabs__nav').innerWidth();

    if (tabsWrapperWidth >= tabsWidth) {
        $('.tabs').removeClass('tabs--overflowed');
    } else {
        $('.tabs').addClass('tabs--overflowed');
    }
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    tabsResizeOverflow(onLoadWidth);
});



/* #################### WHO TO CALL #################### */
$('.who-to-call__results__see-more').click(function () {
    $(this).closest('.col-12').toggleClass('who-to-call__results__see-more--open');
});



/* #################### ACCORDION #################### */
$('.accordion').not('.angular-accordion').on('click', '> li > .accordion__trigger', function () {
    if ($(this).parent().hasClass('accordion--open')) {
        $(this).parent().removeClass('accordion--open');
    } else {
        $(this).parent().addClass('accordion--open');
    }
    searchResultsHeights();
});

// $('.accordion > li > .accordion__trigger').click(function() {
//    if ($(this).parent().hasClass('accordion--open')) {
//       $(this).parent().removeClass('accordion--open');
//    } else {
//       $(this).parent().addClass('accordion--open');
//    }
// });

function toggleAccordion(accordionClass) {
    var accordion = $('.' + accordionClass).first();
    if (accordion.length > 0) {
        if ($(this).parent().hasClass('accordion--open')) {
            $(this).parent().removeClass('accordion--open');
        } else {
            $(this).parent().addClass('accordion--open');
        }
        searchResultsHeights();
    }
}



/* #################### CTA - WIDTH #################### */
//$('.cta .cta__close').click(function() {
//   $('.cta').removeClass('cta--open');
//});

function ctaWidth() {
    if (window.innerWidth >= 768) {
        var buttonWidth = $('.cta .cta__button').innerWidth();
        var textWidth = buttonWidth + 40;
        $('.cta .cta__text').css('width', 'calc(100% - ' + textWidth + 'px)');
    } else {
        $('.cta .cta__text').css('width', 'auto');
    }
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    ctaWidth(onLoadWidth);
});



/* #################### INFO BAR DROPDOWN POSITION #################### */
function infoBarDropdownPos() {
    if (window.innerWidth >= 1280) {
        var windowWidth = $(window).innerWidth();
        var maxRight = (windowWidth - 1280) / 2;
        $('.info-bar__login__dropdown, .info-bar__about__dropdown').css('right', maxRight);
    } else {
        $('.info-bar__login__dropdown, .info-bar__about__dropdown').css('right', '0');
    }
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    infoBarDropdownPos(onLoadWidth);
});



/* #################### COMPARE SCROLL BAR #################### */
$(function () {
    $('.follow-scroll table').on('scroll', function (e) {
        $('.compare .table--test, .compare .compare__scrollbar').scrollLeft($('.follow-scroll table').scrollLeft());
    });
    $('.compare .compare__scrollbar').on('scroll', function (e) {
        $('.compare .table--test, .follow-scroll table').scrollLeft($('.compare .compare__scrollbar').scrollLeft());
    });
    $('.compare .table--test').on('scroll', function (e) {
        $('.compare .compare__scrollbar, .follow-scroll table').scrollLeft($('.compare .table--test').scrollLeft());
    });
});

function compareWidth() {
    var tableWidth = $('.compare .table--test tbody').innerWidth();
    $('.compare .compare__scrollbar div').css('width', tableWidth);
}
// $(document).ready(function() {
//    compareWidth();
//    // $(window).scroll(compareWidth);
// });
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    compareWidth(onLoadWidth);
});



/* #################### VIDEO SELECTOR #################### */
$('.video-selector__options__item').click(function () {
    $('.video-selector__options__item').removeClass('video-selector__options__item--selected');
    $(this).addClass('video-selector__options__item--selected');
    var videoClicked = $(this).attr('data-video');
    $('.video-selector__videos > .youtube-video-wrapper').each(function () {
        if ($(this).attr('id') === videoClicked) {
            $('.youtube-video-wrapper').removeClass('video-selector__videos__selected');
            $(this).addClass('video-selector__videos__selected');
        } else {
        }
    });
});



/* #################### PRODUCT INTRO READ MORE #################### */
$('.product-intro__info__read-more__trigger').click(function () {
    $(this).closest('.product-intro__info__read-more').toggleClass('product-intro__info__read-more--open');
});



/* #################### COMPARE STICKIED HEADER #################### */
function compareStickyHeader() {
    try {
        var scrollAmmount = $(window).scrollTop();
        var tableDistanceFromTop = $('.compare .table--test').offset().top;
        var tableHeaderHeight = $('.table--test .search-results__item__info').innerHeight() / 5;
        var scrollTrigger = tableDistanceFromTop + tableHeaderHeight;

        if (scrollAmmount >= scrollTrigger) {
            $('body').addClass('table-scrolled');
        } else {
            $('body').removeClass('table-scrolled');
        }
    } catch (error) {

    }
}
// function compareStickyHeader(){ // MINE BEFORE RDA
//    var scrollAmmount = $(window).scrollTop();
//    var tableDistanceFromTop = $('.compare .table--test').offset().top;
//    var tableHeaderHeight = $('.compare .table--test .search-results__item__info').innerHeight() / 5;
//    var scrollTrigger = tableDistanceFromTop + tableHeaderHeight;

//    if (scrollAmmount >= scrollTrigger) {
//       $('body').addClass('table-scrolled');
//    } else {
//       $('body').removeClass('table-scrolled');
//    }
// }
// $(window).on("load resize scroll",function(e){
//    var compareStickyHeader = $(window).width();
//    infoBarDropdownPos(compareStickyHeader);
// });
$(document).ready(function () {
    compareStickyHeader();
    $(window).scroll(compareStickyHeader);
});


function adjustTopMargin(tallestImage, compareClassName, offset) {
    $(compareClassName).each(function () {
        var currentTDImage = $(this).find('.item__thumbnail')[0];
        if (currentTDImage) {
            if (currentTDImage.height < tallestImage) {
                $(this).find('.item__brand').css('margin-top', (tallestImage + offset) - currentTDImage.height);
            }
        }
    });
}

function getTallestImage(currentTDElement, tallestImageHeight) {
    var currentTDImage = currentTDElement.find('.item__thumbnail')[0];
    if (currentTDImage) {
        return tallestImageHeight > currentTDImage.height ? tallestImageHeight : currentTDImage.height;
    }
    return tallestImageHeight;
}

function tableHeight() {
    $('.compare .table--test .search-results__item__info td a.height-adjust').css('height', 'auto');
    var tallestTD = -1;
    var tallestImage = -1;
    $('.compare .table--test .search-results__item__info td').each(function () {
        tallestTD = tallestTD > $(this).innerHeight() ? tallestTD : $(this).innerHeight();
        tallestImage = getTallestImage($(this), tallestImage);
    });
    $('.compare .table--test .search-results__item__info td a.height-adjust').css('height', tallestTD);
    adjustTopMargin(tallestImage, '.compare .table--test .search-results__item__info td', 0);
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    tableHeight(onLoadWidth);
});

function stickyTableHeight() {
    $('.compare .table--follow-scroll .search-results__item__info td a.height-adjust').css('height', 'auto');
    var tallestTD = -1;
    var tallestTDImage = -1;
    $('.compare .table--follow-scroll .search-results__item__info td').each(function () {
        tallestTD = tallestTD > $(this).innerHeight() ? tallestTD : $(this).innerHeight();
        tallestTDImage = getTallestImage($(this), tallestTDImage);
    });
    $('.compare .table--follow-scroll .search-results__item__info td a.height-adjust').css('height', tallestTD);
    adjustTopMargin(tallestTDImage, '.compare .table--follow-scroll .search-results__item__info td', 20);
}
$(window).on("load resize", function (e) {
    var onLoadWidth = $(window).width();
    stickyTableHeight(onLoadWidth);
});



/* #################### HOW TO BUY #################### */
$('.how-to-buy__filter-by').click(function () {
    $('.how-to-buy__list__filters').toggleClass('how-to-buy__list__filters--open');
});

// $('.how-to-buy-2__map').stick_in_parent({offset_top: 100});

$(".how-to-buy-2__map").stick_in_parent({ offset_top: 100 }).on("sticky_kit:bottom", function (e) {
    $(this).addClass("at_bottom").removeClass("is_stuck");
}).on("sticky_kit:unbottom", function (e) {
    $(this).removeClass("at_bottom").addClass("is_stuck");
});

function mapRightPosition() {
    if ($('.how-to-buy-2__map').hasClass('is_stuck')) {
        var listWidth = $('.how-to-buy-2__list').innerWidth();
        var listOffsetLeft = $('.how-to-buy-2__list').offset().left;
        var mapOffsetLeft = listWidth + listOffsetLeft;
        $('.how-to-buy-2__map').css('right', 'auto');
        $('.how-to-buy-2__map').css('left', mapOffsetLeft);
    } else {
        $('.how-to-buy-2__map').css('left', 'auto');
        $('.how-to-buy-2__map').css('right', '0');
    }
}
$(window).on("load resize scroll", function (e) {
    var onLoadWidth = $(window).width();
    mapRightPosition(onLoadWidth);
});

// function mapRightPosition(){
//    $('.how-to-buy-2__map').stick_in_parent().on('sticky_kit:bottom', function(e) {
//       $(this).addClass("at_bottom").removeClass("is_stuck");
//    }).on('sticky_kit:unbottom', function(e) {
//       $(this).removeClass('at_bottom').addClass('is_stuck');
//    });

//    if ($('.how-to-buy-2__map').hasClass('is_stuck')) {
//       var listWidth = $('.how-to-buy-2__list').innerWidth() + 30;
//       // var containerDistanceRight = $('.how-to-buy-2').offset().left;
//       $('.how-to-buy-2__map').css('right', 'auto');
//       $('.how-to-buy-2__map').css('left', listWidth);
//    } else if ($('.how-to-buy-2__map').hasClass('at_bottom')) {
//       $('.how-to-buy-2__map').css('left', 'auto');
//       $('.how-to-buy-2__map').css('right', '0');
//    }
// }
// $(window).on("load resize scroll",function(e){
//    var onLoadWidth = $(window).width();
//    mapRightPosition(onLoadWidth);
// });






/* ################################################################## */
/* ############################## 2020 ############################## */
/* ################################################################## */



/* #################### PDP 2 #################### */
/* ########## PRODUCT TILE HEIGHT MATCH ########## */
/* THIS IS BREAKING PRODUCT TILES
function productTileHeightMatch() {
    $('.product-tiles').each(function () {
        // image
        $(this).find('.product-tiles__tile__image').css('height', 'auto');
        var tallestPTileImage = -1;
        $(this).find('.product-tiles__tile__image').each(function () {
            tallestPTileImage = tallestPTileImage > $(this).innerHeight() ? tallestPTileImage : $(this).innerHeight();
        });
        $(this).find('.product-tiles__tile__image').css({ height: tallestPTileImage, opacity: '1' });
        // info
        $(this).find('.product-tiles__tile__info').css('height', 'auto');
        var tallestPTileInfo = -1;
        $(this).find('.product-tiles__tile__info').each(function () {
            tallestPTileInfo = tallestPTileInfo > $(this).innerHeight() ? tallestPTileInfo : $(this).innerHeight();
        });
        $(this).find('.product-tiles__tile__info').css('height', tallestPTileInfo);
    });
}
*/

/* ########## PRODUCT INTRO IMAGE VIEWER ########## */
$(document).ready(function () {
    $('.product-intro__image-viewer__slider').each(function () {
        $(this).on('init', function () {
            imageViewerTallestSlide();
            $(this).css({ visibility: 'visible' });
            $(this).find('.slick-slide:first-child').addClass('product-intro__image-viewer__slider__selected');
        });
        $(this).slick({
            slidesToShow: 4,
            slidesToScroll: 4,
            infinite: false,
            arrows: true,
            dots: false
        });
    });

    $('.product-intro__image-viewer__slider .slick-slide img').click(function () {
        $(this).closest('.product-intro__image-viewer__slider').find('.slick-slide').removeClass('product-intro__image-viewer__slider__selected');
        $(this).parent().addClass('product-intro__image-viewer__slider__selected');
        var imgSRC = $(this).attr('src');
        $('.product-intro__image-viewer__main-view').attr('src', imgSRC);
    });
});

function imageViewerTallestSlide() {
    $('.product-intro__image-viewer__slider').each(function () {
        $(this).find('.slick-slide').css('height', 'auto');
        var tallestSlide = -1;
        $(this).find('.slick-slide').each(function () {
            tallestSlide = tallestSlide > $(this).innerHeight() ? tallestSlide : $(this).innerHeight();
        });
        $(this).find('.slick-slide').css('height', tallestSlide);
    });
}

/* ########## PRODUCT INTRO ASSET VIEWER ########## */
function assetTallestSlide() {
    $('.product-intro__asset-viewer__slider').each(function () {
        $(this).find('.slick-slide').css('height', 'auto');
        var tallestSlide = -1;
        $(this).find('.slick-slide').each(function () {
            tallestSlide = tallestSlide > $(this).innerHeight() ? tallestSlide : $(this).innerHeight();
        });
        $(this).find('.slick-slide').css('height', tallestSlide);
        $(this).css({ opacity: '1', visibility: 'visible' });
    });
}
$(window).on('load resize', function () {
    assetTallestSlide();
});

$(document).ready(function () {
    $('.product-intro__asset-viewer__slider').each(function () {
        $(this).on('init', function () {
            $(this).find('.slick-slide:first-child').addClass('product-intro__asset-viewer__slider__selected');
        });
        $(this).slick({
            slidesToShow: 4,
            slidesToScroll: 4,
            arrows: true,
            dots: false,
            infinite: false
        });
    });

    $('.product-intro__asset-viewer__slider .slick-slide').on("click", function () {
        var hideCurrentlyDisplayedMainImageVideoOrSirv = function () {
            $('.current-image__image, .current-image__video, .product-intro__asset-viewer__window__360').css('display', 'none');
        };

        if ($(this).hasClass('product-intro__asset-viewer__slider__image')) {
            hideCurrentlyDisplayedMainImageVideoOrSirv();
            var dataImage = $(this).attr("data-image");
            $("#" + dataImage).css('display', 'flex');
            $("#" + dataImage).parent().css('display', 'block');
        } else if ($(this).hasClass('product-intro__asset-viewer__slider__video')) {
            var dataVid = $(this).attr('data-video');
            hideCurrentlyDisplayedMainImageVideoOrSirv();
            $(this).closest('.product-intro__asset-viewer').find('#' + dataVid).css('display', 'flex');
        } else if ($(this).hasClass('product-intro__asset-viewer__slider__360')) {
            var src360 = $(this).attr('data-360');
            hideCurrentlyDisplayedMainImageVideoOrSirv();
            $(this).closest('.product-intro__asset-viewer').find('#' + src360).css('display', 'flex');
        }
        $(this).closest('.product-intro__asset-viewer__slider').find('.slick-slide').removeClass('product-intro__asset-viewer__slider__selected');
        $(this).addClass('product-intro__asset-viewer__slider__selected');
    });
});

/* ########## PRODUCT TILES SLIDER ########## */
$(document).ready(function () {
    if ($('.product-tiles--slider').length) {
        $('.product-tiles--slider').slick({
            slidesToShow: 4,
            slidesToScroll: 4,
            infinite: false,
            autoplay: false,
            arrows: true,
            dots: false,
            responsive: [{
                breakpoint: 992,
                settings: "unslick"
            }]
        });
    }
});

function productTilesSlider() {
    if ($('.product-tiles--slider').length) {
        if (window.innerWidth >= 992) {
            $('.product-tiles--slider').slick('refresh');
        } else {
            $('.product-tiles--slider').slick('unslick');
        }
    }
}


/* ########## FUNCTION HANDLING ########## */
//$(window).on('load resize', function () {
    //productTileHeightMatch();
//});

$(window).on('resize', function () {
    imageViewerTallestSlide();
    productTilesSlider();
});



/* #################### SEARCH RESULTS GRID HEIGHT #################### */
function searchResultsGridHeight() {
    if (window.innerWidth >= 768) {
        $('.search-results-grid-target').each(function () {
            // image
            $(this).find('.search-results-grid__image').css('height', 'auto');
            var tallestGridImage = -1;
            $(this).find('.search-results-grid__image').each(function () {
                tallestGridImage = tallestGridImage > $(this).innerHeight() ? tallestGridImage : $(this).innerHeight();
            });
            $(this).find('.search-results-grid__image').css({ height: tallestGridImage, opacity: '1' });
            // info
            $(this).find('.search-results-grid__info').css('height', 'auto');
            var tallestGridInfo = -1;
            $(this).find('.search-results-grid__info').each(function () {
                tallestGridInfo = tallestGridInfo > $(this).innerHeight() ? tallestGridInfo : $(this).innerHeight();
            });
            $(this).find('.search-results-grid__info').css('height', tallestGridInfo);
        });
    } else {
        $('.search-results-grid__image').css({ height: 'auto', opacity: '1' });
        $('.search-results-grid__info').css('height', 'auto');
    }
}
$(window).on('load resize', function () {
    //searchResultsGridHeight();
});



/* #################### SEARCH RESULTS GRID FAMILY ALT HEIGHT #################### */
function searchResultsGridFamilyAltHeight() {
    $('.search-results-grid-family-alt').each(function () {
        $(this).find('.search-results-grid-family-alt__image').css('height', 'auto');
        var tileHeight = $(this).innerHeight();
        var infoHeight = $(this).find('.search-results-grid-family-alt__info').innerHeight();
        var imageHeight = tileHeight - infoHeight - 45;
        $(this).find('.search-results-grid-family-alt__image').css('height', imageHeight);
    });
}
$(window).on('load resize', function () {
    //searchResultsGridFamilyAltHeight();
});



/* #################### SEARCH RESULTS GRID CTA POPUPS #################### */
$('.search-results-grid__cta__item__trigger').click(function () {
    if ($(this).closest('.search-results-grid').hasClass('search-results-grid--list')) {
        if ($(this).closest('.search-results-grid__cta__item').hasClass('search-results-grid__cta__item--open')) {
            $(this).closest('.search-results-grid--list').removeClass('search-results-grid--list--popup-open');
            $(this).closest('.search-results-grid__cta').find('.search-results-grid__cta__item').removeClass('search-results-grid__cta__item--open');
        } else {
            $(this).closest('.search-results-grid--list').addClass('search-results-grid--list--popup-open');
            $(this).closest('.search-results-grid__cta').find('.search-results-grid__cta__item').removeClass('search-results-grid__cta__item--open');
            $(this).closest('.search-results-grid__cta__item').addClass('search-results-grid__cta__item--open');
        }
    } else {
        if ($(this).closest('.search-results-grid__cta__item').hasClass('search-results-grid__cta__item--open')) {
            $(this).closest('.search-results-grid__cta').find('.search-results-grid__cta__item').removeClass('search-results-grid__cta__item--open');
        } else {
            $(this).closest('.search-results-grid__cta').find('.search-results-grid__cta__item').removeClass('search-results-grid__cta__item--open');
            $(this).closest('.search-results-grid__cta__item').addClass('search-results-grid__cta__item--open');
        }
    }
});



/* #################### SEARCH RESULTS LIST HEIGHT #################### */
function searchResultsListHeight() {
    if (window.innerWidth >= 768) {
        $('.search-results-grid--list').each(function () {
            $(this).find('.search-results-grid__image').removeClass('center-after-int');
            $(this).find('.search-results-grid__image').css({ height: 'auto', opacity: '1' });
            $(this).find('.search-results-grid--list__info-wrapper__height').css('height', 'auto');
            var imageHeight = $(this).find('.search-results-grid--list__image-wrapper').innerHeight();
            var infoWrapHeight = $(this).find('.search-results-grid--list__info-wrapper').innerHeight();
            if (imageHeight > infoWrapHeight) {
                var infoHeightBefore = $(this).find('.search-results-grid--list__info-wrapper__height').innerHeight();
                var infoHeightAdjust = imageHeight - infoWrapHeight + infoHeightBefore + 16;
                $(this).find('.search-results-grid--list__info-wrapper__height').css('height', infoHeightAdjust);
            } else if (imageHeight < infoWrapHeight) {
                $(this).find('.search-results-grid__image').css({ height: infoWrapHeight, opacity: '1' })
                $(this).find('.search-results-grid__image').addClass('center-after-int');
            } else if (imageHeight == infoWrapHeight) {
                $(this).find('.search-results-grid__image').css({ height: 'auto', opacity: '1' });
                $(this).find('.search-results-grid--list__info-wrapper__height').css('height', 'auto');
            }
        });
    } else {
        $('.search-results-grid--list .search-results-grid__image').removeClass('center-after-int');
        $('.search-results-grid--list .search-results-grid__image').css({ height: 'auto', opacity: '1' });
        $('.search-results-grid--list .search-results-grid--list__info-wrapper__height').css('height', 'auto');
    }
}
$(window).on('load resize', function () {
    //searchResultsListHeight();
});



/* #################### SEARCH RESULTS FILTERS #################### */
/* ########## MOBILE OPEN/CLOSE ########## */
$('.search-results-options__filter-mobile-trigger').click(function () {
    $('.search-results-options__filters').addClass('search-results-options__filters--open');
    $('body').addClass('search-results-options-filters-open');
});

$('.search-results-options__filters__header__close').click(function () {
    $('.search-results-options__filters').removeClass('search-results-options__filters--open');
    $('body').removeClass('search-results-options-filters-open');
});


/* ########## ACCORDIONS/DROPDOWNS OPEN/CLOSE ########## */
$('.search-results-options__filters__content__options__list__item__trigger').click(function () {
    if ($(this).closest('.search-results-options__filters__content__options__list__item').hasClass('search-results-options__filters__content__options__list__item--open')) {
        $(this).closest('.search-results-options__filters__content__options__list__item').removeClass('search-results-options__filters__content__options__list__item--open');
    } else {
        $('.search-results-options__filters__content__options__list__item').removeClass('search-results-options__filters__content__options__list__item--open');
        $(this).closest('.search-results-options__filters__content__options__list__item').addClass('search-results-options__filters__content__options__list__item--open');
    }
});


/* ########## STICKY SCROLL ########## */
/*  This functionality is already in place on our site
function stickySearchFilter() {
    var scrollAmmount = $(window).scrollTop();
    var triggerTopDistance = $('.search-results-options-scroll-trigger').offset().top;
    var headerHeight = $('.header__main').innerHeight();
    var scrollTrigger = triggerTopDistance - headerHeight;
    if (scrollAmmount >= scrollTrigger) {
        $('body').addClass('search-results-options-scrolled');
    } else {
        $('body').removeClass('search-results-options-scrolled');
    }
}
$(document).ready(function () {
    stickySearchFilter();
    $(window).scroll(stickySearchFilter);
});
*/

function hideHeader(headerClass) {
    $('#heading-section-' + headerClass).hide();
}


/* #################### SEARCH RESULTS CATEGORIES #################### */
/* ########## MOBILE OPEN/CLOSE ########## */
$('.search-results-options__categories-mobile-trigger').click(function () {
    $('.plp-categories').addClass('plp-categories--open');
    $('body').addClass('plp-categories-open');
});

$('.plp-categories__header__close').click(function () {
    $('.plp-categories').removeClass('plp-categories--open');
    $('body').removeClass('plp-categories-open');
});



/* #################### STICKY SIDEBAR #################### */
function stickySidebar() {
    if ($('.sticky-sidebar').length) {
        var heightMatchHeight = $('.sticky-sidebar-height-match').innerHeight();
        var sidebarHeight = $('.sticky-sidebar').innerHeight();

        if (window.innerWidth >= 768) {
            if (sidebarHeight < heightMatchHeight) {
                $('.sticky-sidebar').stick_in_parent({ offset_top: 164 });
            }
        } else {
            $('.sticky-sidebar').trigger('sticky_kit:detach');
        }
    }
}
$(window).on("load resize", function () {
    stickySidebar();
});



/* #################### SEARCH RESULTS - QUICK VIEW MODAL #################### */
/* ########## OPEN/CLOSE ########## */
$('body').on('click', '.search-results-grid__image__quick-view-trigger', function () {
    $(this).closest('.search-results-grid').addClass('search-results-grid--quick-view-open');
    $('body').addClass('quick-view-open');
});

$('.search-results-grid__quick-view-modal__close').click(function () {
    $(this).closest('.search-results-grid').removeClass('search-results-grid--quick-view-open');
    $('body').removeClass('quick-view-open');
});


/* ########## CTA POPUPS ########## */
$('.product-intro__info__cta__item__trigger').click(function () {
    if ($(this).closest('.product-intro__info').hasClass('product-intro__info--list')) {
        if ($(this).closest('.product-intro__info__cta__item').hasClass('product-intro__info__cta__item--open')) {
            $(this).closest('.product-intro__info--list').removeClass('product-intro__info--list--popup-open');
            $(this).closest('.product-intro__info__cta').find('.product-intro__info__cta__item').removeClass('product-intro__info__cta__item--open');
        } else {
            $(this).closest('.product-intro__info--list').addClass('product-intro__info--list--popup-open');
            $(this).closest('.product-intro__info__cta').find('.product-intro__info__cta__item').removeClass('product-intro__info__cta__item--open');
            $(this).closest('.product-intro__info__cta__item').addClass('product-intro__info__cta__item--open');
        }
    } else {
        if ($(this).closest('.product-intro__info__cta__item').hasClass('product-intro__info__cta__item--open')) {
            $(this).closest('.product-intro__info__cta').find('.product-intro__info__cta__item').removeClass('product-intro__info__cta__item--open');
        } else {
            $(this).closest('.product-intro__info__cta').find('.product-intro__info__cta__item').removeClass('product-intro__info__cta__item--open');
            $(this).closest('.product-intro__info__cta__item').addClass('product-intro__info__cta__item--open');
        }
    }

    if ($(this).closest('.search-results-grid').find('.product-intro__info__cta__item').hasClass('product-intro__info__cta__item--open')) {
        $(this).closest('.search-results-grid').find('.product-intro').addClass('product-intro--cta-open');
    } else {
        $(this).closest('.search-results-grid').find('.product-intro').removeClass('product-intro--cta-open');
    }
});;
!function (t) { "function" == typeof define && define.amd ? define(["jquery"], t) : t("object" == typeof exports ? require("jquery") : jQuery) }(function (t) { function s(s) { var e = !1; return t('[data-notify="container"]').each(function (i, n) { var a = t(n), o = a.find('[data-notify="title"]').text().trim(), r = a.find('[data-notify="message"]').html().trim(), l = o === t("<div>" + s.settings.content.title + "</div>").html().trim(), d = r === t("<div>" + s.settings.content.message + "</div>").html().trim(), g = a.hasClass("alert-" + s.settings.type); return l && d && g && (e = !0), !e }), e } function e(e, n, a) { var o = { content: { message: "object" == typeof n ? n.message : n, title: n.title ? n.title : "", icon: n.icon ? n.icon : "", url: n.url ? n.url : "#", target: n.target ? n.target : "-" } }; a = t.extend(!0, {}, o, a), this.settings = t.extend(!0, {}, i, a), this._defaults = i, "-" === this.settings.content.target && (this.settings.content.target = this.settings.url_target), this.animations = { start: "webkitAnimationStart oanimationstart MSAnimationStart animationstart", end: "webkitAnimationEnd oanimationend MSAnimationEnd animationend" }, "number" == typeof this.settings.offset && (this.settings.offset = { x: this.settings.offset, y: this.settings.offset }), (this.settings.allow_duplicates || !this.settings.allow_duplicates && !s(this)) && this.init() } var i = { element: "body", position: null, type: "info", allow_dismiss: !0, allow_duplicates: !0, newest_on_top: !1, showProgressbar: !1, placement: { from: "top", align: "right" }, offset: 20, spacing: 10, z_index: 1031, delay: 5e3, timer: 1e3, url_target: "_blank", mouse_over: null, animate: { enter: "animated fadeInDown", exit: "animated fadeOutUp" }, onShow: null, onShown: null, onClose: null, onClosed: null, icon_type: "class", template: '<div data-notify="container" class="col-xs-11 col-sm-4 alert alert-{0}" role="alert"><button type="button" aria-hidden="true" class="close" data-notify="dismiss">&times;</button><span data-notify="icon"></span> <span data-notify="title">{1}</span> <span data-notify="message">{2}</span><div class="progress" data-notify="progressbar"><div class="progress-bar progress-bar-{0}" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div></div><a href="{3}" target="{4}" data-notify="url"></a></div>' }; String.format = function () { for (var t = arguments[0], s = 1; s < arguments.length; s++)t = t.replace(RegExp("\\{" + (s - 1) + "\\}", "gm"), arguments[s]); return t }, t.extend(e.prototype, { init: function () { var t = this; this.buildNotify(), this.settings.content.icon && this.setIcon(), "#" != this.settings.content.url && this.styleURL(), this.styleDismiss(), this.placement(), this.bind(), this.notify = { $ele: this.$ele, update: function (s, e) { var i = {}; "string" == typeof s ? i[s] = e : i = s; for (var n in i) switch (n) { case "type": this.$ele.removeClass("alert-" + t.settings.type), this.$ele.find('[data-notify="progressbar"] > .progress-bar').removeClass("progress-bar-" + t.settings.type), t.settings.type = i[n], this.$ele.addClass("alert-" + i[n]).find('[data-notify="progressbar"] > .progress-bar').addClass("progress-bar-" + i[n]); break; case "icon": var a = this.$ele.find('[data-notify="icon"]'); "class" === t.settings.icon_type.toLowerCase() ? a.removeClass(t.settings.content.icon).addClass(i[n]) : (a.is("img") || a.find("img"), a.attr("src", i[n])); break; case "progress": var o = t.settings.delay - t.settings.delay * (i[n] / 100); this.$ele.data("notify-delay", o), this.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow", i[n]).css("width", i[n] + "%"); break; case "url": this.$ele.find('[data-notify="url"]').attr("href", i[n]); break; case "target": this.$ele.find('[data-notify="url"]').attr("target", i[n]); break; default: this.$ele.find('[data-notify="' + n + '"]').html(i[n]) }var r = this.$ele.outerHeight() + parseInt(t.settings.spacing) + parseInt(t.settings.offset.y); t.reposition(r) }, close: function () { t.close() } } }, buildNotify: function () { var s = this.settings.content; this.$ele = t(String.format(this.settings.template, this.settings.type, s.title, s.message, s.url, s.target)), this.$ele.attr("data-notify-position", this.settings.placement.from + "-" + this.settings.placement.align), this.settings.allow_dismiss || this.$ele.find('[data-notify="dismiss"]').css("display", "none"), (this.settings.delay <= 0 && !this.settings.showProgressbar || !this.settings.showProgressbar) && this.$ele.find('[data-notify="progressbar"]').remove() }, setIcon: function () { "class" === this.settings.icon_type.toLowerCase() ? this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon) : this.$ele.find('[data-notify="icon"]').is("img") ? this.$ele.find('[data-notify="icon"]').attr("src", this.settings.content.icon) : this.$ele.find('[data-notify="icon"]').append('<img src="' + this.settings.content.icon + '" alt="Notify Icon" />') }, styleDismiss: function () { this.$ele.find('[data-notify="dismiss"]').css({ position: "absolute", right: "10px", top: "5px", zIndex: this.settings.z_index + 2 }) }, styleURL: function () { this.$ele.find('[data-notify="url"]').css({ backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)", height: "100%", left: 0, position: "absolute", top: 0, width: "100%", zIndex: this.settings.z_index + 1 }) }, placement: function () { var s = this, e = this.settings.offset.y, i = { display: "inline-block", margin: "0px auto", position: this.settings.position ? this.settings.position : "body" === this.settings.element ? "fixed" : "absolute", transition: "all .5s ease-in-out", zIndex: this.settings.z_index }, n = !1, a = this.settings; switch (t('[data-notify-position="' + this.settings.placement.from + "-" + this.settings.placement.align + '"]:not([data-closing="true"])').each(function () { e = Math.max(e, parseInt(t(this).css(a.placement.from)) + parseInt(t(this).outerHeight()) + parseInt(a.spacing)) }), this.settings.newest_on_top === !0 && (e = this.settings.offset.y), i[this.settings.placement.from] = e + "px", this.settings.placement.align) { case "left": case "right": i[this.settings.placement.align] = this.settings.offset.x + "px"; break; case "center": i.left = 0, i.right = 0 }this.$ele.css(i).addClass(this.settings.animate.enter), t.each(Array("webkit-", "moz-", "o-", "ms-", ""), function (t, e) { s.$ele[0].style[e + "AnimationIterationCount"] = 1 }), t(this.settings.element).append(this.$ele), this.settings.newest_on_top === !0 && (e = parseInt(e) + parseInt(this.settings.spacing) + this.$ele.outerHeight(), this.reposition(e)), t.isFunction(s.settings.onShow) && s.settings.onShow.call(this.$ele), this.$ele.one(this.animations.start, function () { n = !0 }).one(this.animations.end, function () { s.$ele.removeClass(s.settings.animate.enter), t.isFunction(s.settings.onShown) && s.settings.onShown.call(this) }), setTimeout(function () { n || t.isFunction(s.settings.onShown) && s.settings.onShown.call(this) }, 600) }, bind: function () { var s = this; if (this.$ele.find('[data-notify="dismiss"]').on("click", function () { s.close() }), this.$ele.mouseover(function () { t(this).data("data-hover", "true") }).mouseout(function () { t(this).data("data-hover", "false") }), this.$ele.data("data-hover", "false"), this.settings.delay > 0) { s.$ele.data("notify-delay", s.settings.delay); var e = setInterval(function () { var t = parseInt(s.$ele.data("notify-delay")) - s.settings.timer; if ("false" === s.$ele.data("data-hover") && "pause" === s.settings.mouse_over || "pause" != s.settings.mouse_over) { var i = (s.settings.delay - t) / s.settings.delay * 100; s.$ele.data("notify-delay", t), s.$ele.find('[data-notify="progressbar"] > div').attr("aria-valuenow", i).css("width", i + "%") } t <= -s.settings.timer && (clearInterval(e), s.close()) }, s.settings.timer) } }, close: function () { var s = this, e = parseInt(this.$ele.css(this.settings.placement.from)), i = !1; this.$ele.attr("data-closing", "true").addClass(this.settings.animate.exit), s.reposition(e), t.isFunction(s.settings.onClose) && s.settings.onClose.call(this.$ele), this.$ele.one(this.animations.start, function () { i = !0 }).one(this.animations.end, function () { t(this).remove(), t.isFunction(s.settings.onClosed) && s.settings.onClosed.call(this) }), setTimeout(function () { i || (s.$ele.remove(), s.settings.onClosed && s.settings.onClosed(s.$ele)) }, 600) }, reposition: function (s) { var e = this, i = '[data-notify-position="' + this.settings.placement.from + "-" + this.settings.placement.align + '"]:not([data-closing="true"])', n = this.$ele.nextAll(i); this.settings.newest_on_top === !0 && (n = this.$ele.prevAll(i)), n.each(function () { t(this).css(e.settings.placement.from, s), s = parseInt(s) + parseInt(e.settings.spacing) + t(this).outerHeight() }) } }), t.notify = function (t, s) { var i = new e(this, t, s); return i.notify }, t.notifyDefaults = function (s) { return i = t.extend(!0, {}, i, s) }, t.notifyClose = function (s) { "warning" === s && (s = "danger"), "undefined" == typeof s || "all" === s ? t("[data-notify]").find('[data-notify="dismiss"]').trigger("click") : "success" === s || "info" === s || "warning" === s || "danger" === s ? t(".alert-" + s + "[data-notify]").find('[data-notify="dismiss"]').trigger("click") : s ? t(s + "[data-notify]").find('[data-notify="dismiss"]').trigger("click") : t('[data-notify-position="' + s + '"]').find('[data-notify="dismiss"]').trigger("click") }, t.notifyCloseExcept = function (s) { "warning" === s && (s = "danger"), "success" === s || "info" === s || "warning" === s || "danger" === s ? t("[data-notify]").not(".alert-" + s).find('[data-notify="dismiss"]').trigger("click") : t("[data-notify]").not(s).find('[data-notify="dismiss"]').trigger("click") } });;
! function(e, n) {
    "function" == typeof define && define.amd ? define(["exports"], n) : n("undefined" != typeof exports ? exports : e.dragscroll = {})
}(this, function(e) {
    var n, t, o = window,
        l = document,
        c = "mousemove",
        r = "mouseup",
        i = "mousedown",
        m = "EventListener",
        d = "add" + m,
        s = "remove" + m,
        f = [],
        u = function(e, m) {
            for (e = 0; e < f.length;) m = f[e++], m = m.container || m, m[s](i, m.md, 0), o[s](r, m.mu, 0), o[s](c, m.mm, 0);
            for (f = [].slice.call(l.getElementsByClassName("dragscroll")), e = 0; e < f.length;) ! function(e, m, s, f, u, a) {
                (a = e.container || e)[d](i, a.md = function(n) {
                    e.hasAttribute("nochilddrag") && l.elementFromPoint(n.pageX) != a || (f = 1, m = n.clientX, s = n.clientY, n.preventDefault())
                }, 0), o[d](r, a.mu = function() {
                    f = 0
                }, 0), o[d](c, a.mm = function(o) {
                    f && ((u = e.scroller || e).scrollLeft -= n = -m + (m = o.clientX), e == l.body && ((u = l.documentElement).scrollLeft -= n))
                }, 0)
            }(f[e++])
        };
    "complete" == l.readyState ? u() : o[d]("load", u, 0), e.reset = u
});;
// Unobtrusive Ajax support library for jQuery
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// @version v3.2.6
// 
// Microsoft grants you the right to use these script files for the sole
// purpose of either: (i) interacting through your browser with the Microsoft
// website or online service, subject to the applicable licensing or use
// terms; or (ii) using the files as included with a Microsoft product subject
// to that product's license terms. Microsoft reserves all other rights to the
// files not expressly granted by Microsoft, whether by implication, estoppel
// or otherwise. Insofar as a script file is dual licensed under GPL,
// Microsoft neither took the code under GPL nor distributes it thereunder but
// under the terms set out in this paragraph. All notices and licenses
// below are for informational purposes only.

/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global window: false, jQuery: false */

(function ($) {
    var data_click = "unobtrusiveAjaxClick",
        data_target = "unobtrusiveAjaxClickTarget",
        data_validation = "unobtrusiveValidation";

    function getFunction(code, argNames) {
        var fn = window, parts = (code || "").split(".");
        while (fn && parts.length) {
            fn = fn[parts.shift()];
        }
        if (typeof (fn) === "function") {
            return fn;
        }
        argNames.push(code);
        return Function.constructor.apply(null, argNames);
    }

    function isMethodProxySafe(method) {
        return method === "GET" || method === "POST";
    }

    function asyncOnBeforeSend(xhr, method) {
        if (!isMethodProxySafe(method)) {
            xhr.setRequestHeader("X-HTTP-Method-Override", method);
        }
    }

    function asyncOnSuccess(element, data, contentType) {
        var mode;

        if (contentType.indexOf("application/x-javascript") !== -1) {  // jQuery already executes JavaScript for us
            return;
        }

        mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase();
        $(element.getAttribute("data-ajax-update")).each(function (i, update) {
            var top;

            switch (mode) {
                case "BEFORE":
                    $(update).prepend(data);
                    break;
                case "AFTER":
                    $(update).append(data);
                    break;
                case "REPLACE-WITH":
                    $(update).replaceWith(data);
                    break;
                default:
                    $(update).html(data);
                    break;
            }
        });
    }

    function asyncRequest(element, options) {
        var confirm, loading, method, duration;

        confirm = element.getAttribute("data-ajax-confirm");
        if (confirm && !window.confirm(confirm)) {
            return;
        }

        loading = $(element.getAttribute("data-ajax-loading"));
        duration = parseInt(element.getAttribute("data-ajax-loading-duration"), 10) || 0;

        $.extend(options, {
            type: element.getAttribute("data-ajax-method") || undefined,
            url: element.getAttribute("data-ajax-url") || undefined,
            cache: (element.getAttribute("data-ajax-cache") || "").toLowerCase() === "true",
            beforeSend: function (xhr) {
                var result;
                asyncOnBeforeSend(xhr, method);
                result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(element, arguments);
                if (result !== false) {
                    loading.show(duration);
                }
                return result;
            },
            complete: function () {
                loading.hide(duration);
                getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(element, arguments);
            },
            success: function (data, status, xhr) {
                asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
                getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(element, arguments);
            },
            error: function () {
                getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"]).apply(element, arguments);
            }
        });

        options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });

        method = options.type.toUpperCase();
        if (!isMethodProxySafe(method)) {
            options.type = "POST";
            options.data.push({ name: "X-HTTP-Method-Override", value: method });
        }

        // change here:
        // Check for a Form POST with enctype=multipart/form-data
        // add the input file that were not previously included in the serializeArray()
        // set processData and contentType to false
        var $element = $(element);
        if ($element.is("form") && $element.attr("enctype") == "multipart/form-data") {
            var formdata = new FormData();
            $.each(options.data, function (i, v) {
                formdata.append(v.name, v.value);
            });
            $("input[type=file]", $element).each(function () {
                var file = this;
                $.each(file.files, function (n, v) {
                    formdata.append(file.name, v);
                });
            });
            $.extend(options, {
                processData: false,
                contentType: false,
                data: formdata
            });
        }
        // end change

        $.ajax(options);
    }

    function validate(form) {
        var validationInfo = $(form).data(data_validation);
        return !validationInfo || !validationInfo.validate || validationInfo.validate();
    }

    $(document).on("click", "a[data-ajax=true]", function (evt) {
        evt.preventDefault();
        asyncRequest(this, {
            url: this.href,
            type: "GET",
            data: []
        });
    });

    $(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) {
        var name = evt.target.name,
            target = $(evt.target),
            form = $(target.parents("form")[0]),
            offset = target.offset();

        form.data(data_click, [
            { name: name + ".x", value: Math.round(evt.pageX - offset.left) },
            { name: name + ".y", value: Math.round(evt.pageY - offset.top) }
        ]);

        setTimeout(function () {
            form.removeData(data_click);
        }, 0);
    });

    $(document).on("click", "form[data-ajax=true] :submit", function (evt) {
        var name = evt.currentTarget.name,
            target = $(evt.target),
            form = $(target.parents("form")[0]);

        form.data(data_click, name ? [{ name: name, value: evt.currentTarget.value }] : []);
        form.data(data_target, target);

        setTimeout(function () {
            form.removeData(data_click);
            form.removeData(data_target);
        }, 0);
    });

    $(document).on("submit", "form[data-ajax=true]", function (evt) {
        var clickInfo = $(this).data(data_click) || [],
            clickTarget = $(this).data(data_target),
            isCancel = clickTarget && (clickTarget.hasClass("cancel") || clickTarget.attr('formnovalidate') !== undefined);
        evt.preventDefault();
        if (!isCancel && !validate(this)) {
            return;
        }
        asyncRequest(this, {
            url: this.action,
            type: this.method || "GET",
            data: clickInfo.concat($(this).serializeArray())
        });
    });
}(jQuery));
;
// Unobtrusive validation support library for jQuery and jQuery Validate
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// @version v3.2.11
!function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("<li />").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive});;
if (!Object.values) {
    Object.values = function (obj) {
        return Object.keys(obj).map(function (key) {
            return obj[key];
        });
    };
}

if (!Array.prototype.includes) {
    Object.defineProperty(Array.prototype, 'includes', {
        value: function (searchElement, fromIndex) {

            if (this == null) {
                throw new TypeError('"this" is null or not defined');
            }

            // 1. Let O be ? ToObject(this value).
            var o = Object(this);

            // 2. Let len be ? ToLength(? Get(O, "length")).
            var len = o.length >>> 0;

            // 3. If len is 0, return false.
            if (len === 0) {
                return false;
            }

            // 4. Let n be ? ToInteger(fromIndex).
            //    (If fromIndex is undefined, this step produces the value 0.)
            var n = fromIndex | 0;

            // 5. If n ≥ 0, then
            //  a. Let k be n.
            // 6. Else n < 0,
            //  a. Let k be len + n.
            //  b. If k < 0, let k be 0.
            var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

            function sameValueZero(x, y) {
                return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
            }

            // 7. Repeat, while k < len
            while (k < len) {
                // a. Let elementK be the result of ? Get(O, ! ToString(k)).
                // b. If SameValueZero(searchElement, elementK) is true, return true.
                if (sameValueZero(o[k], searchElement)) {
                    return true;
                }
                // c. Increase k by 1. 
                k++;
            }

            // 8. Return false
            return false;
        }
    });
}
// polyfill for find on IE
// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
    Object.defineProperty(Array.prototype, 'find', {
        value: function (predicate) {
            // 1. Let O be ? ToObject(this value).
            if (this == null) {
                throw new TypeError('"this" is null or not defined');
            }

            var o = Object(this);

            // 2. Let len be ? ToLength(? Get(O, "length")).
            var len = o.length >>> 0;

            // 3. If IsCallable(predicate) is false, throw a TypeError exception.
            if (typeof predicate !== 'function') {
                throw new TypeError('predicate must be a function');
            }

            // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
            var thisArg = arguments[1];

            // 5. Let k be 0.
            var k = 0;

            // 6. Repeat, while k < len
            while (k < len) {
                // a. Let Pk be ! ToString(k).
                // b. Let kValue be ? Get(O, Pk).
                // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
                // d. If testResult is true, return kValue.
                var kValue = o[k];
                if (predicate.call(thisArg, kValue, k, o)) {
                    return kValue;
                }
                // e. Increase k by 1.
                k++;
            }

            // 7. Return undefined.
            return undefined;
        },
        configurable: true,
        writable: true
    });
}

if (!Array.prototype.fill) {
    Object.defineProperty(Array.prototype, 'fill', {
        value: function (value) {

            // Steps 1-2.
            if (this == null) {
                throw new TypeError('this is null or not defined');
            }

            var O = Object(this);

            // Steps 3-5.
            var len = O.length >>> 0;

            // Steps 6-7.
            var start = arguments[1];
            var relativeStart = start >> 0;

            // Step 8.
            var k = relativeStart < 0 ?
                Math.max(len + relativeStart, 0) :
                Math.min(relativeStart, len);

            // Steps 9-10.
            var end = arguments[2];
            var relativeEnd = end === undefined ?
                len : end >> 0;

            // Step 11.
            var final = relativeEnd < 0 ?
                Math.max(len + relativeEnd, 0) :
                Math.min(relativeEnd, len);

            // Step 12.
            while (k < final) {
                O[k] = value;
                k++;
            }

            // Step 13.
            return O;
        }
    });
}

/**
 * Array.flat() polyfill
 * Adapted from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat#reduce_concat_isArray_recursivity
 */
if (!Array.prototype.flat) {
    Array.prototype.flat = function (depth) {

        'use strict';

        // If no depth is specified, default to 1
        if (depth === undefined) {
            depth = 1;
        }

        // Recursively reduce sub-arrays to the specified depth
        var flatten = function (arr, depth) {

            // If depth is 0, return the array as-is
            if (depth < 1) {
                return arr.slice();
            }

            // Otherwise, concatenate into the parent array
            return arr.reduce(function (acc, val) {
                return acc.concat(Array.isArray(val) ? flatten(val, depth - 1) : val);
            }, []);

        };

        return flatten(this, depth);

    };
}

if (!String.prototype.startsWith) {
    Object.defineProperty(String.prototype, 'startsWith', {
        value: function (search, rawPos) {
            var pos = rawPos > 0 ? rawPos | 0 : 0;
            return this.substring(pos, pos + search.length) === search;
        }
    });
}

// .closest polyfill
if (!Element.prototype.matches) {
    Element.prototype.matches =
        Element.prototype.msMatchesSelector ||
        Element.prototype.webkitMatchesSelector;
}

if (!Element.prototype.closest) {
    Element.prototype.closest = function (s) {
        var el = this;

        do {
            if (Element.prototype.matches.call(el, s)) return el;
            el = el.parentElement || el.parentNode;
        } while (el !== null && el.nodeType === 1);
        return null;
    };
}

Array.prototype.findIndex = Array.prototype.findIndex || function (callback) {
    if (this === null) {
        throw new TypeError('Array.prototype.findIndex called on null or undefined');
    } else if (typeof callback !== 'function') {
        throw new TypeError('callback must be a function');
    }
    var list = Object(this);
    // Makes sures is always has an positive integer as length.
    var length = list.length >>> 0;
    var thisArg = arguments[1];
    for (var i = 0; i < length; i++) {
        if (callback.call(thisArg, list[i], i, list)) {
            return i;
        }
    }
    return -1;
};

/**
 * String.prototype.replaceAll() polyfill
 * https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/
 * @author Chris Ferdinandi
 * @license MIT
 */
if (!String.prototype.replaceAll) {
    String.prototype.replaceAll = function (str, newStr) {

        // If a regex pattern
        if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
            return this.replace(str, newStr);
        }

        // If a string
        return this.replace(new RegExp(str, 'g'), newStr);

    };
}

if (!String.prototype.includes) {
    String.prototype.includes = function (search, start) {
        'use strict';

        if (search instanceof RegExp) {
            throw TypeError('first argument must not be a RegExp');
        }
        if (start === undefined) { start = 0; }
        return this.indexOf(search, start) !== -1;
    };
};
var app = app || {};

app.init = function () {
    var runPolling = $("#runPolling").val();

    if (app.setReturnUrl && app.setReturnUrl instanceof Function) {
        app.setReturnUrl();
    }

    app.setReturnUrlFromQueryString();
    app.initStockTicker();
    app.initYoutubeVideos();
    app.markNavMenu();
    app.updatePdfDownloadLinks();
    app.disableCardItemsClickEvent();
    app.hideCanadaNav();

    if (runPolling === "true") {
        console.log("Polling started");
        app.pollDocDownload(true);
    }

};

app.isExperienceEditing = function () {
    return (!!((typeof Sitecore !== "undefined") && (typeof Sitecore.PageModes !== "undefined") && (typeof Sitecore.PageModes.PageEditor !== "undefined")) || (document.body && document.body.getAttribute("class") === "sc-edit-mode"));
};

app.initStockTicker = function () {
    var stockTickers = $(".info-bar__ticker .stock-ticker-requires-ajax");
    if (stockTickers.length) {
        $.post(
            "/api/stockquote/getstockprice",
            null,
            function (data) {
                if (data && data.Success && data.Value) {
                    stockTickers.html("$" + data.Value);
                } else {
                    var err = "Unable to retrieve Stock Value.";
                    if (data && data.Error) {
                        err = data.Error;
                    }
                    console.log(err);
                }
            },
            "json"
        );
    }
};

// Youtube iframes block page load event. Delay setting src in order to 
// reduce page load event time
app.initYoutubeVideos = function () {
    var dataAttribute = "data-youtube-src";
    var dataAttributeJs = "youtubeSrc";
    var youtubeVideos = $("iframe[" + dataAttribute + " != '']");
    if (youtubeVideos.length) {
        $.each(youtubeVideos,
            function (index, element) {
                var video = $(element);
                video.attr("src", video.data(dataAttributeJs));
            });
    }
};

app.setCookie = function (cname, cvalue, exdays) {
    var expires;

    if (exdays > -1) {
        var d = new Date();
        d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
        expires = "expires=" + d.toUTCString();
    }

    document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;secure";
};

app.getCookie = function (cname) {
    var name = cname + "=";
    var ca = document.cookie.split(";");

    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) === " ") {
            c = c.substring(1);
        }
        if (c.indexOf(name) === 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
};

app.getPendingDownloads = function () {
    var pendingDownloadString = app.getCookie("PendingMultiDocDownloads");
    if (pendingDownloadString) {
        return JSON.parse(pendingDownloadString);
    }
    else {
        return [];
    }
};

app.doesAlertExistForDownload = function (downloadId) {
    var alertHtml = $("div.alert-success a");
    var alertExists = false;

    $.each(alertHtml,
        function (index, item) {
            if ($(item).attr("href").indexOf(downloadId) > -1 && !alertExists) {
                alertExists = true;
            }
        });

    return alertExists;
};

app.shouldQueryForCompletedDownloads = function () {
    var pendingDownloads = app.getPendingDownloads();
    var areNotDisplayed = function (download) {
        return !app.doesAlertExistForDownload(download.DownloadId);
    };
    return pendingDownloads && pendingDownloads.length && pendingDownloads.some(areNotDisplayed);
};

app.pollDocDownload = function poll(callRecursively) {
    var alertHtml = $("div.alert-success a");
    var title = $("#docReadyNotifyTitle").val();

    if (app.shouldQueryForCompletedDownloads()) {
        $.ajax({
            url: "/api/products/downloadcheck",
            type: "POST",
            dataType: "json",
            success: function (data) {
                if (data != null) {
                    $.each(data.CompletedItems,
                        function (index, completedItem) {
                            var id = completedItem.Id;
                            var productTitle = completedItem.Title;

                            if (!app.doesAlertExistForDownload(id)) {
                                var message = $("#docReadyNotifyMessage").val().replace("[title]", productTitle);
                                ShowNotification(id, title, message);
                            }
                        });
                }
            }
        });
    }

    if (callRecursively) {
        setTimeout(poll, 60000, callRecursively);
    }
};

app.markNavMenu = function () {
    if (location.pathname != "/") {
        $('nav a[href^="/' + location.pathname.split("/")[1] + '"]').parent().addClass("current-page");
    }
};

app.hideCanadaNav = function () {
    if (window.location.hostname.indexOf(".ca") > -1)
        $(".hide-in-ca").hide();
}

app.setReturnUrlFromQueryString = function () {

    if ($(".return-url-selector").length == 0) {
        return;
    }

    var returnUrl = getQueryStringParameterByName("returnurl");

    if (returnUrl == "") {
        return;
    }

    $(".return-url-selector").attr("href", function (index, href) {
        return href.replace("{returnurlplaceholder}", returnUrl.replace("/", ""));
    });
};

app.updatePdfDownloadLinks = function () {
    if (!app.isExperienceEditing()) {
        // check multiple cases because these will be provided by content authors
        $("a.forcedownload, a.forceDownload, a.ForceDownload, a.FORCEDOWNLOAD").each(function (index, element) {
            element.href = app.updateQueryString(element.href, "forceBehavior", "download");
        });
        $("a.forceopen, a.forceOpen, a.ForceOpen, a.FORCEOPEN").each(function (index, element) {
            element.href = app.updateQueryString(element.href, "forceBehavior", "open");
        });
    }
};

app.disableCardItemsClickEvent = function () {
    $(".carts__item  .item__product-description a").click(function (event) {
        event.stopPropagation();
    });
};

app.updateQueryString = function (url, key, value) {
    if (!url) {
        url = window.location.href;
    }
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
        hash;

    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null) {
            return url.replace(re, '$1' + key + "=" + value + '$2$3');
        }
        else {
            hash = url.split('#');
            url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
                url += '#' + hash[1];
            }
            return url;
        }
    }
    else {
        if (typeof value !== 'undefined' && value !== null) {
            var separator = url.indexOf('?') !== -1 ? '&' : '?';
            hash = url.split('#');
            url = hash[0] + separator + key + '=' + value;
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
                url += '#' + hash[1];
            }
            return url;
        }
        else {
            return url;
        }
    }
};

app.sendEventToGoogleAnalytics = function (eventDetails) {
    if (typeof ga !== 'undefined' && ga instanceof Function) {
        var tracker = ga.getAll()[0];
        if (tracker) {
            var trimToLength = function (eventData, length) {
                return eventData && eventData.length > length ?
                    eventData.substring(0, length) :
                    eventData;
            };
            tracker.send(
                {
                    hitType: 'event',
                    eventCategory: trimToLength(eventDetails.Category, 150),
                    eventAction: trimToLength(eventDetails.Action, 500),
                    eventLabel: trimToLength(eventDetails.Label, 500)
                });
        }
    }
};

app.isNumber = function (n) {
    return !isNaN(parseFloat(n)) && !isNaN(n - 0);
};

$(window).on("load", function () {
    app.init();
});

function ShowNotification(id, title, message) {
    var notification = $.notify({
        title: "<strong>" + title + "</strong><br/>",
        message: message,
        url: "/api/products/getdownload/" + id
    },
        {
            type: "success",
            delay: 0,
            newest_on_top: true,
            allow_dismiss: false,
            clickToHide: true
        });

    notification.$ele.on('click',
        'a[data-notify="url"]',
        function () {
            notification.close();
        });
}


function getQueryStringParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

/* #################### ESC KEY PRESS #################### */
/* ### Handling closing modals that scripts.js ignores ### */
//$(document).keyup(function (e) {
//    if (e.keyCode === 27) {
//        $('.photo-gallery__modal--open').removeClass('photo-gallery__modal--open');
//    }
//});

/* #################### PRODUCT INTRO READ MORE #################### */
$('.show-more-section > .show-more-section-expand, .show-more-section > .show-more-section-collapse').click(function () {
    $(this).parent().toggleClass('show-all');
});

// if the show more section is taller than it's rendered size, add a "show more" button
function initializeShowMoreSections() {
    var get_background_color = function (obj) {
        var real = obj.css('background-color');
        var none = 'rgba(0, 0, 0, 0)';
        if (real === none) {
            return obj.parents().filter(function () {
                return $(this).css('background-color') != none;
            }).first().css('background-color');
        } else {
            return real;
        }
    };

    alternateSectionBackgroundColors();

    $('.show-more-section').each(function (index, element) {
        var showMoreSection = $(element);
        var sectionBody = showMoreSection.find('.show-more-section-body');
        console.log("sectionBody:");
        console.log(sectionBody);
        if (sectionBody && sectionBody[0]) {
            var iconRow = document.querySelector("ul.icons.unlisted.inline");
            var iconRowHeight = -45;
            if (iconRow !== null) {
                iconRowHeight = document.querySelector("ul.icons.unlisted.inline").scrollHeight;
            }
            var titleHeight = document.querySelector(".product-intro__info__wrapper").childNodes[3].scrollHeight;
            var shortDescriptionHeight = document.querySelector(".product-intro__info__wrapper").childNodes[5].scrollHeight;
            var brandNameHeight = document.querySelector(".product-intro__info__wrapper").childNodes[7].scrollHeight;
            var tabHeight = document.querySelector(".tabs > .row").scrollHeight;
            var headerHeight = titleHeight + shortDescriptionHeight + brandNameHeight + tabHeight + iconRowHeight;

            var leftPaneHeight = 541;
            console.log("leftPaneHeight:");
            console.log(leftPaneHeight);
            console.log("headerHeight:");
            console.log(headerHeight);
            var maxHeight = leftPaneHeight - headerHeight;
            sectionBody.css("max-height", maxHeight + "px");
            console.log("sectionBody[0].scrollHeight:");
            console.log(sectionBody[0].scrollHeight);
            if (sectionBody[0].scrollHeight >= maxHeight) {
                sectionBody.css("max-height", "250px");
                showMoreSection.addClass('show-buttons');
                var bgColor = get_background_color(showMoreSection);
                if (bgColor) {
                    var newCssStyles = '.show-more-section.show-buttons .show-more-section-body:before{background: linear-gradient(transparent 160px, ' + bgColor + ');}';
                    var styleSection = showMoreSection.find('style.showMoreStyling');
                    if (!styleSection || !styleSection.length) {
                        var newCssStylesWithWrapper = '<style class="showMoreStyling">' + newCssStyles + '</style>';
                        $(showMoreSection).append(newCssStylesWithWrapper);
                    }
                    else {
                        styleSection.text(newCssStyles);
                    }
                }
            }
            else
            {
                showMoreSection.removeClass('show-buttons');
            }
        }
    });
}

function alternateSectionBackgroundColors() {
    $(".pdp-section:visible").each(function (index, element) {
        if (index % 2 === 0) {
            element.style.backgroundColor = "#f2f2f2";
            if ((index + 1) === $(".pdp-section").length) {
                element.style.marginBottom = "30px";
            }
        } else {
            element.style.backgroundColor = "white";
        }
    });
}

$('.product-intro__info .tabs .tabs__nav li.overview-tab').click(initializeShowMoreSections);
$(document).ready(initializeShowMoreSections);
$(window).on('resize', initializeShowMoreSections);
;
var app = app || {};
app.angularshared = app.angularshared || {};

app.angularshared = {
    PagerService: function () {
        var service = {};

        service.GetPager = GetPager;

        return service;

        // service implementation
        function GetPager(totalItems, currentPage, pageSize) {
            // default to first page
            currentPage = currentPage || 1;

            // default page size is 12
            pageSize = pageSize || 12;

            // calculate total pages
            var totalPages = Math.ceil(totalItems / pageSize);

            var startPage, endPage;
            if (totalPages <= 8) {
                // less than 8 total pages so show all
                startPage = 1;
                endPage = totalPages;
            } else {
                // more than 8 total pages so calculate start and end pages
                if (currentPage <= 5) {
                    startPage = 1;
                    endPage = 8;
                } else if (currentPage + 3 >= totalPages) {
                    startPage = totalPages - 7;
                    endPage = totalPages;
                } else {
                    startPage = currentPage - 4;
                    endPage = currentPage + 3;
                }
            }

            // calculate start and end item indexes
            var startIndex = (currentPage - 1) * pageSize;
            var endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);

            // create an array of pages to ng-repeat in the pager control
            var pages = [];
            for (var i = startPage; i < endPage + 1; i++) {
                pages.push(i);
            }

            // return object with all pager properties required by the view
            return {
                totalItems: totalItems,
                currentPage: currentPage,
                pageSize: pageSize,
                totalPages: totalPages,
                startPage: startPage,
                endPage: endPage,
                startIndex: startIndex,
                endIndex: endIndex,
                pages: pages
            };
        }
    }
};
var app = app || {};
app.compare = app.compare || {};

app.compare = {
    init: function () {
        readJsonToDock(true);
        app.compare.initializeCompareBoxesOnSearchPage();
        setTimeout(app.compare.initializeCheckboxesOnPage, 2000);
        setTimeout(app.compare.initializeCheckboxesOnPage, 4000);
        setTimeout(app.compare.initializeCheckboxesOnPage, 6000);
        setTimeout(app.compare.initializeCheckboxesOnPage, 8000);

        $(".remove-compare").click(function () {
            var li = $(this).parent();
            removeFromCompareDock(li);
            setDockCookie();
        });

        $(".compare__remove").click(function () {
            var td = $(this).closest('.compareHeader');
            removeFromComparePage(td);
            var productCount = document.querySelectorAll('*[id^="compareFloat-"]').length;
            if (!productCount) {
                window.history.pushState({}, document.title, window.location.pathname);

                $('.compare tr:not(.search-results__item__info)').hide();
                $('.compare tr.search-results__item__info a').removeAttr("style");
                $('.share.page-intro__button').hide();
                $('.clear-all-compare-page').hide();
            }

            setPageCookie();
        });
        $(".clear-all-compare-page").click(function () {
            var td = $('.compareHeader');
            for (var i = 0; i < td.length; i++) {
                removeFromComparePage(td);
            }

            $(".compare__add-product").show();

            window.history.pushState({}, document.title, window.location.pathname);

            $('.compare tr:not(.search-results__item__info)').hide();
            $('.compare tr.search-results__item__info a').removeAttr("style");
            $('.share.page-intro__button').hide();
            $('.clear-all-compare-page').hide();
            setPageCookie();
        });
        $(".clear-all-compare").click(function () {
            var li = $('.has-compare-item');

            for (var i = 0; i < li.length; i++) {
                removeFromCompareDock($(li[i]));
            }
            setDockCookie();
        });
        $(".compare-list button").click(function () {
            window.location.href = "/products/compare";
        });

        //This removes the disablement of the Compare button before the dock is loaded
        $(".compare-checkbox").removeClass("loading");
    },
    initializeCheckboxesOnPage: function () {
        var dockJson = getDockJson();
        app.compare.initializeCheckboxesFromJson(dockJson);
    },
    initializeCheckboxesFromJson: function (dockJson) {
        var liPos = 0;
        if (dockJson && dockJson.length) {
            for (var i in dockJson) {
                var item = dockJson[i];

                if (item && typeof item === 'object') {
                    $("input.compare-" + item.id).prop('checked', true);
                }
            }
        }

        $("input[class^='compare-'").prop('disabled', false);
    },
    add: function (id, title, url, thumbnail) {
        var alreadyAdded = false;
        var slotFound = false;
        var li;
        var liId = "compare-" + id;
        var compareList = $(".compare-list__products li", parent.document);

        //Check if already in dock
        compareList.each(function () {
            if ($(this).attr("id") == liId) {
                alreadyAdded = true;
                return false;
            }
        });

        if (alreadyAdded) {
            alert($("#compareAlreadyAddedMsg").val());
            return false;
        }

        //Check for an empty slot in the dock
        compareList.each(function () {
            if (!$(this).hasClass("has-compare-item")) {
                li = $(this);
                slotFound = true;
                return false;
            }
        });

        //If there are no empty slots, the last item will be replaced
        if (!slotFound) {
            li = $(".compare-list__products li:last", parent.document);
        }

        addToCompareDock(li, id, title, url, thumbnail);
        setDockCookie();
    },
    getCompareList: function () {
        return $(".compare-list__products li", parent.document);
    },
    remove: function (id) {
        var liId = "compare-" + id;
        //Check if already in dock
        app.compare.getCompareList().each(function () {
            if ($(this).attr("id") === liId) {
                removeFromCompareDock($(this));
            }
        });
        setDockCookie();
    },
    contains: function (id) {
        var liId = "compare-" + id;
        return app.compare.getCompareList().toArray().some(function (arrItem) {
            return arrItem.id === liId;
        });
    },
    addCoveo: function (id, title, url, thumbnail, actionCause, actionType, pageAction) {
        app.compare.add(id, title, url, thumbnail);
        logBaseCoveoClickEvent(id, title, url, actionCause, actionType, pageAction);
    },
    toggleCoveo: function (checkbox, id, title, url, thumbnail, actionCause, actionType, pageAction, sendToHostPage) {
        // Send the event from the current iframe to the host page if necessary (handles updating the dock on the parent page)
        if (sendToHostPage && window.parent) {
            var compareEvent = new CustomEvent('compareToggleEvent',
                {
                    detail: {
                        checkbox: checkbox,
                        id: id,
                        title: title,
                        url: url,
                        thumbnail: thumbnail,
                        actionCause: actionCause,
                        actionType: actionType,
                        pageAction: pageAction,
                        sendToHostPage: false
                    }
                }
            );
            window.parent.document.dispatchEvent(compareEvent);
        }
        else {
            var compareListContainsId = app.compare.contains(id);
            if (compareListContainsId && !checkbox.checked) {
                app.compare.remove(id);
            }
            else if (!compareListContainsId && checkbox.checked) {
                app.compare.add(id, title, url, thumbnail);
            }
            logBaseCoveoClickEvent(id, title, url, actionCause, actionType, pageAction);
        }
    },
    handleCompareClickInIframe: function (event) {
        var info = event.detail;
        app.compare.toggleCoveo(info.checkbox, info.id, info.title, info.url, info.thumbnail, info.actionCause, info.actionType, info.pageAction, false);
    },
    initializeCompareBoxesOnSearchPage: function () {
        if (typeof(Coveo) !== 'undefined' && Coveo && $('.CoveoSearchInterface.ablSearch.search-results.v2-search').length > 0) {
            Coveo.$('.CoveoSearchInterface.ablSearch.search-results.v2-search').on('newResultsDisplayed', function (e, args) {
                app.compare.initializeCheckboxesOnPage();
            });
        }
    }
};

document.addEventListener('compareToggleEvent', app.compare.handleCompareClickInIframe, false);

$(window).on("load", function () {
    app.compare.init();
});

function addToCompareDock(li, id, title, url, thumbnail) {
    li.find(".compare-link").attr("href", url);

    var compareImage = document.createElement("img");
    var imageClassNames = document.createAttribute("class");
    imageClassNames.value = "compare-image";
    compareImage.setAttributeNode(imageClassNames);

    var imageSource = document.createAttribute("src");
    imageSource.value = thumbnail;
    compareImage.setAttributeNode(imageSource);
    li.append(compareImage);

    var compareName = document.createElement("p");
    var paragraphClassNames = document.createAttribute("class");
    paragraphClassNames.value = "compare-name";
    compareName.setAttributeNode(paragraphClassNames);
    compareName.innerText = title;
    li.append(compareName);

    var checkboxId = "compare-" + id;
    li.attr("id", checkboxId);
    li.addClass("has-compare-item");
    buttonShowHide();

    // check any associated compare checkboxes on the page related to this product
    if (checkboxId) {
        $("input." + checkboxId).prop('checked', true);
    }

    if (!$("body", parent.document).hasClass("compare-list-open")) {
        $("body", parent.document).addClass("compare-list-open");
        $(".footer-container").addClass("product-compare-list-open");
    }
}

function removeFromCompareDock(li) {
    li.find(".compare-link").removeAttr("href");
    li.find(".compare-image").remove();
    li.find(".compare-name").remove();
    var oldId = li.prop('id');
    li.removeAttr("id", "");
    li.removeClass("has-compare-item");
    buttonShowHide();
    //uncheck any associated compare checkboxes on the page related to this product
    if (oldId) {
        $("input." + oldId).prop('checked', false);
    }

    if (!$(".compare-list__products li").hasClass("has-compare-item")) {
        $("body").removeClass("compare-list-open");
        $(".footer-container").removeClass("product-compare-list-open");
    }
}

function removeFromComparePage(td) {
    var id = td.attr("id");
    var closeSource = "Head";
    var closeDest = "Float";

    if (id.indexOf("Float") > -1) {
        closeSource = "Float";
        closeDest = "Head";
    }

    var addId = "add__" + id;
    var destId = id.replace(closeSource, closeDest);
    var addDestId = destId.replace(closeSource, closeDest);
    var specClass = id.replace(closeSource, "Spec");

    $(td).remove();
    $("#" + addId).removeClass("hide");
    $("#" + destId).remove();
    $("#" + addDestId).removeClass("hide");
    $("." + specClass).empty();
}

function setDockCookie() {
    var jsonStr = saveDockToJson();
    jsonStr = jsonStr.replace(/,/g, "%2C");

    app.setCookie("CompareDock", jsonStr, -1);
}

function saveDockToJson() {
    var jsonStr = "";

    $(".compare-list__products li", parent.document).each(function () {
        if ($(this).hasClass("has-compare-item")) {
            li = $(this);
            var url = li.find(".compare-link").attr("href");
            var thumbnail = li.find(".compare-image").attr("src");
            var title = JSON.stringify(li.find(".compare-name").html());
            var id = li.attr("id").replace("compare-", "");

            if (jsonStr !== "") {
                jsonStr = jsonStr + ",";
            }

            jsonStr = jsonStr + '{ "id": "' + id + '", "title": ' + title + ', "url": "' + url + '", "thumbnail": "' + thumbnail + '" }';
        }
    });

    jsonStr = "[" + jsonStr + "]";

    return jsonStr;
}

function setPageCookie() {
    var jsonStr = savePageToJson();
    jsonStr = jsonStr.replace(/,/g, "%2C");
    app.setCookie("CompareDock", jsonStr, -1);
}

function savePageToJson() {
    var jsonStr = "";

    $(".search-results__item__info.compareHead td").each(function () {
        if (!$(this).hasClass("compare__add-product")) {
            td = $(this);
            var url = td.find(".item__product-name").attr("href");
            var thumbnail = td.find(".item__thumbnail").attr("src");
            var title = td.find(".item__product-name").html();
            var id = td.attr("id").replace("compareHead-", "");

            if (jsonStr !== "") {
                jsonStr = jsonStr + ",";
            }

            jsonStr = jsonStr + '{ "id": "' + id + '", "title": "' + title + '", "url": "' + url + '", "thumbnail": "' + thumbnail + '" }';
        }
    });

    jsonStr = "[" + jsonStr + "]";

    return jsonStr;
}

function getDockJson() {
    var cookieValue = app.getCookie("CompareDock");
    var decodedCookieValue = cookieValue.split("%2C").join(",");

    if (decodedCookieValue === "") {
        return false;
    }

    return JSON.parse(decodedCookieValue);
}

function readJsonToDock(initializeCheckboxes) {
    var dockJson = getDockJson();

    if (initializeCheckboxes) {
        app.compare.initializeCheckboxesFromJson(dockJson);
    }

    if (!dockJson) {
        return;
    }

    var liPos = 0;

    for (var i in dockJson) {
        var item = dockJson[i];
        if (item && typeof item === 'object') {
            liPos = liPos + 1;
            var li = $(".compare-list__products li:nth-child(" + liPos + ")");

            addToCompareDock(li, item.id, item.title, item.url, item.thumbnail);

        }
    }
}

function buttonShowHide() {
    var numItems = $(".compare-list__products li.has-compare-item").length;
    var button = $(".compare-list__wrapper button");
    var clearAll = $(".clear-all-compare");
    if (numItems > 1) {
        button.show();
        clearAll.show();
    } else {
        button.hide();
        clearAll.hide();
    }
}



function logCoveoClickEventDocuments(id, title, url, documentName, actionCause, actionType) {
    try {
        if (!Coveo) {
            return;
        }

        let metadata = {
            product_id: id,
            product_title: title,
            product_url: url,
            product_document_name: documentName
        };

        logCoveoClickEvent(actionCause, actionType, metadata, '.CoveoSearchInterface.ablSearch.search-results');
    } catch (e) {
        return;
    }
}

function toggleProductTrigger(clicked_element) {
    if (clicked_element.classList.contains('search-results-grid__cta__item--open')) {
        clicked_element.classList.remove('search-results-grid__cta__item--open');
    }
    else {
            clicked_element.classList.add('search-results-grid__cta__item--open');
    }
}

function logAltSearchCoveoClickEvent(id, title, url, actionCause, actionType, pageAction, coveoSearchInterface) {
    try {
        if (!Coveo) {
            return;
        }

        let metadata = getCoveoClickEventMetadata(id, title, url, pageAction);

        logCoveoClickEvent(actionCause, actionType, metadata, coveoSearchInterface);

    } catch (e) {
        return;
    }
}

function logBaseCoveoClickEvent(id, title, url, actionCause, actionType, pageAction) {
    try {
        if (!Coveo) {
            return;
        }

        let metadata = getCoveoClickEventMetadata(id, title, url, pageAction);

        logCoveoClickEvent(actionCause, actionType, metadata, '.CoveoSearchInterface.ablSearch.search-results');

    } catch (e) {
        return;
    }
}

function logCoveoClickEvent(actionCause, actionType, metadata, coveoSearchInterface) {
    try {
        if (!Coveo) {
            return;
        }

        let element = Coveo.$$(document).find(coveoSearchInterface);
        let customEventCause = { name: actionCause, type: actionType };

        Coveo.logCustomEvent(element, customEventCause, metadata);
    } catch (e) {
        return;
    }
}

function getCoveoClickEventMetadata(id, title, url, pageAction) {
    try {

        return metadata = {
            product_id: id,
            product_title: title,
            product_url: url,
            page_action: pageAction
        };

    } catch (e) {
        return;
    }
};
var app = app || {};
app.cta = app.cta || {};

app.cta = {
    onClose: function () {
        console.log("Inside ctaClosure method");
        var id = $("#ctaFloatId").val();
        var daysToDismiss = $("#ctaDtd").val();
        console.log("ctaId: " + id);

        $.post(
            "/api/calltoaction/setevent",
            {ctaId: id, ctaDtd: daysToDismiss},
            function (data) {
                if (data && data.Success) {
                    console.log("Returned from Controller");
                } else {
                    var err = "Unable to set cta event.";

                    if (data && data.Error) {
                        err = data.Error;
                    }

                    console.log(err);
                }
            },
            "json"
        );
    }
}

$(window).on("load", function () {
    $(".cta .cta__close").click(function () {
        if (!$(this).hasClass("scEnabledChrome")) {
            $('.cta').removeClass('cta--open');
            app.cta.onClose();
        }
    });
});;
var app = app || {};
app.tabs = app.tabs || {};
var lastPos = 0;
var mainTab = null;

app.tabs = {
    createTabSet: function (tabSectionId) {
        var tabSetId = "#tab-set-" + tabSectionId;

        $(tabSetId + " .tabs__sections").children().each(function () {
            if ($(this).length === 0) {
                $(this).parents(".tabs").hide();
            }
        });

        var startTabHighlighted = false;
        var windowAnchor = window.location.hash;
        

        if (windowAnchor != null && windowAnchor != "") {
            windowAnchor = windowAnchor.replace('#', '');
            $(tabSetId + " .tabs__sections > div").each(function (index) {
                if ($(this).attr("data-tab-anchor") == windowAnchor) {
                    startTabHighlighted = true;
                    mainTab = $(this);                    
                }
            });
        }
        else {
            windowAnchor = "NoAnchor";
        }

        $(tabSetId + " .tabs__sections > div").each(function (index) {
            //if there are no renderings in the tab's placeholder, don't create a clickable tab at the top
            if ($(this).html().trim() === "") {
                return;
            }
            var listItem = $("<a></a>");
            $(listItem).attr("data-tabs-nav", $(this).attr("data-tabs-section") + "-" + tabSectionId);
            if ($(this).attr("data-tab-anchor") != null && $(this).attr("data-tab-anchor") != "") {
                $(listItem).attr("href", "#" + $(this).attr("data-tab-anchor"));
            }
            $(listItem).attr("title", $(this).attr("data-tab-hover"));
            $(listItem).text($(this).attr("data-tab-name"));
            var tabId = $(this).attr("data-tab-anchor");
            if (!startTabHighlighted || windowAnchor == tabId) {
                $(listItem).addClass("tabs__nav__current-tab");
            }

            var tabDiv = $(this);
            $(listItem).click(function () {
                $(tabDiv).removeClass('tabs__sections__current-section');
                $(tabDiv).siblings().removeClass('tabs__sections__current-section');

                $(this).siblings().removeClass('tabs__nav__current-tab');
                $(this).addClass('tabs__nav__current-tab');

                var tabId = $(this).attr("data-tab-anchor");

                lastPos = $(window).scrollTop();
                if (!tabId && (location.hash.replace('#', '')) != '') {
                    location.hash = '';
                }
                $(window).scrollTop(lastPos);

                var tabClicked = $(this).attr('data-tabs-nav');

                $(tabDiv).parent().children().each(function () {
                    if ($(this).attr('data-tabs-section') === tabClicked) {
                        $(this).addClass('tabs__sections__current-section');
                    }
                });

                resizeSelectLoad();
                // Notify child isotope grids to resize themselves
                $(tabDiv).find(".isotope-grid").isotope();
            });

            $(this).parents(".tabs").find("ul.tabs__nav").append(listItem);

            $(this).attr("data-tabs-section", $(this).attr("data-tabs-section") + "-" + tabSectionId);
            if (!startTabHighlighted || windowAnchor == tabId) {
                $(this).addClass("tabs__sections__current-section");
                startTabHighlighted = true;
                if (windowAnchor == tabId) {
                    windowAnchor = "NoAnchor";
                }
            }
        });

        $(document).ready(function () {
            if (mainTab) {
                setTimeout(function () {
                var mainTabDistance = window.pageYOffset + mainTab.get(0).getBoundingClientRect().top;
                console.log(mainTabDistance);
                    $(window).scrollTop(mainTabDistance - 160);
                }, 1200); //delay needed for this function to take control, not sure why
            }
        });

        //reload any photo galleries in the tabs so they use the full height of the tab
        //if ($(tabSetId + " .tabs__sections .isotope-grid").length > 0) {
        //    $(tabSetId + " .tabs__sections .isotope-grid").isotope('layout');
        //}
    }
};;
var app = app || {};
app.photogallery = app.photogallery || {};

app.photogallery = {
    init: function () {
        document.addEventListener("DOMContentLoaded", function () {
            app.photogallery.lazyLoadImages();
        });
    },
    setBackgroundForImage: function (lazyLoadedImage) {
        var lazyLoadedImg = $(lazyLoadedImage);
        var parentDiv = lazyLoadedImg.closest('div');
        parentDiv.css('background-image', 'url(' + lazyLoadedImg.prop('src') + ')');
        parentDiv.addClass('lazy-loaded-image');
        parentDiv.removeClass("lazy");
    },
    lazyLoadImages: function (componentSelector, dataSrcAttributeName, forceLoadNow) {
        var selector = componentSelector ? componentSelector + " img.lazy" : "img.lazy";
        var dataSourceAttributeName = dataSrcAttributeName || 'src';

        var lazyImages = [].slice.call(document.querySelectorAll(selector));
        if ("IntersectionObserver" in window) {
            let lazyImageObserver = new IntersectionObserver(function (entries, observer) {
                entries.forEach(function (entry) {
                    if (entry.isIntersecting) {
                        let lazyImage = entry.target;
                        lazyImage.src = lazyImage.dataset[dataSourceAttributeName];
                        lazyImage.classList.remove("lazy");
                        lazyImageObserver.unobserve(lazyImage);
                        app.photogallery.setBackgroundForImage(lazyImage);
                    }
                });
            });

            lazyImages.forEach(function (lazyImage) {
                lazyImageObserver.observe(lazyImage);
            });
        } else {
            // Fall back for browsers that don't have Insersection Observer
            let active = false;

            const lazyLoad = function () {
                if (active === false) {
                    active = true;

                    setTimeout(function () {
                        lazyImages.forEach(function (lazyImage) {
                            if ((lazyImage.getBoundingClientRect().top <= window.innerHeight && lazyImage.getBoundingClientRect().bottom >= 0) && getComputedStyle(lazyImage).display !== "none") {
                                lazyImage.src = lazyImage.dataset[dataSourceAttributeName];
                                lazyImage.classList.remove("lazy");
                                // lazyImage.setAttribute("style", "width: 100%");
                                lazyImage.parentElement.classList.remove("lazy");

                                app.photogallery.setBackgroundForImage(lazyImage);

                                lazyImages = lazyImages.filter(function (image) {
                                    return image !== lazyImage;
                                });

                                if (lazyImages.length === 0) {
                                    document.removeEventListener("scroll", lazyLoad);
                                    window.removeEventListener("resize", lazyLoad);
                                    window.removeEventListener("orientationchange", lazyLoad);
                                }
                            }
                        });

                        active = false;
                    }, 200);
                }
            };

            document.addEventListener("scroll", lazyLoad);
            window.addEventListener("load", lazyLoad);
            window.addEventListener("resize", lazyLoad);
            window.addEventListener("orientationchange", lazyLoad);
            $('.photo-gallery__filters').on('click', 'button', function () {
                lazyLoad();
            });

            if (forceLoadNow) {
                lazyLoad();
            }
        }
    }
};

/* #################### PHOTO GALLERY #################### */
/* ########## FILTER ANIMATIONS ########## */
var $grid = $('.isotope-grid').isotope({
    itemSelector: '.photo-gallery__photo-item',
    layoutMode: 'fitRows',
    transitionDuration: 0 
});

/* ########## SLIDER ########## */
$(document).ready(function () {
    $('.photo-gallery__slider').slick({
        slidesToShow: 1,
        slidesToScroll: 1,
        arrows: true,
        dots: false,
        fade: true
    });
});


/* ########## FILTER SLIDER ########## */
$('.photo-gallery__filters').on('click', 'button', function () {

    var parentPhotoGallery = $(this).closest('.photo-gallery');
    parentPhotoGallery.find('.photo-gallery__filters button').removeClass('btn-blue');
    parentPhotoGallery.find('.photo-gallery__filters button').addClass('btn-primary');

    $(this).removeClass('btn-primary');
    $(this).addClass('btn-blue');
    var filterValue = $(this).attr('data-filter');
    $grid.isotope({ filter: filterValue, transitionDuration: 0  });
    parentPhotoGallery.find('.light-gallery-modal.photo-gallery-unfiltered').data('lightGallery').destroy(true);
    var categorySelector = filterValue.replace('*', '') + ' .gallery-launcher';

    parentPhotoGallery.find('.light-gallery-modal.photo-gallery-unfiltered').lightGallery({
        thumbnail: true,
        animatedThumb: false,
        showThumbByDefault: false,
        selector: categorySelector,
        subHtmlSelectorRelative: false,
        share: false,
        galleryId: this.id,
        iframeMaxWidth: '45%',
        exThumbImage: 'data-exthumbimage'
    });
    var updatedFilterValue = filterValue.substring(1);
    if (updatedFilterValue == '') {
        $(this).closest('.photo-gallery').find('.photo-gallery__slider').slick('slickUnfilter');
    } else {
        $(this).closest('.photo-gallery').find('.photo-gallery__slider').slick('slickUnfilter');
        $(this).closest('.photo-gallery').find('.photo-gallery__slider').slick('slickFilter', $(this).closest('.photo-gallery').find('.photo-gallery__slider .' + updatedFilterValue));
    }

});

$('.photo-gallery .photo-gallery__modal__close').click(function () {
    $(this).closest('.photo-gallery').removeClass('photo-gallery__modal--open');
});

$('.tabs__nav li').click(function () {

    var tabProgenitor = $(this).parent();
    while (!tabProgenitor.hasClass("tabs")) {
        tabProgenitor = tabProgenitor.parent();
    }

    var siblingSections = tabProgenitor.children("div:nth-child(2)").children("div.tabs__sections").children();
    siblingSections.removeClass('tabs__sections__current-section');
    $(this).siblings().removeClass('tabs__nav__current-tab');
    $(this).addClass('tabs__nav__current-tab');

    var tabClicked = $(this).attr('data-tabs-nav');

    siblingSections.each(function () {
        if ($(this).attr('data-tabs-section') === tabClicked) {
            // block
            $(this).addClass('tabs__sections__current-section');
        } else {
            // none
            $(this).removeClass('tabs__sections__current-section');
        }
    });

    enableIsotope();
    // $grid.isotope();
});

$(document).ready(function () {
    //$('.light-gallery-modal').lightGallery({
    //    thumbnail: true,
    //    animatedThumb: false,
    //    showThumbByDefault: false,
    //    selector: '.photo-gallery__photo-item',
    //    subHtmlSelectorRelative: true,
    //    share: false,
    //    galleryId : this.id
    //});

    $('.light-gallery-modal.photo-gallery-unfiltered').each(function (index, element) {
        $(element).lightGallery({
            thumbnail: true,
            animatedThumb: false,
            showThumbByDefault: false,
            selector: '.gallery-launcher',
            subHtmlSelectorRelative: false,
            share: false,
            galleryId: element.id,
            iframeMaxWidth: '45%',
            exThumbImage: 'data-exthumbimage'
        });
    });
    $(".gallery-control").on("click", function (event) {
        console.log("triggered special gallery-control click event");
        event.preventDefault();
        $(event.currentTarget.parentElement).find('img').trigger("click");
    });
});;
var app = app || {};
app.products = app.products || {};

app.products = {
    init: function () {
        // show/hide angular accordions after they have been compiled
        var coveoMandatorySection = $(".coveo-search-interface-mandatory-section");
        if (coveoMandatorySection.length == 0) {
            angular.element(function () {
                ShowHiddenAccordionsIfNotEmpty();
                if (location.href.indexOf('#') !== -1) {
                    var tag = '#' + location.href.split("#")[1];
                    location.href = '#';
                    location.href = tag;
                }

            });
        }

        $(".accordion .hide-item").hide();
        $(".product-page-accordion .hide-item").hide();

        $(".accordion .load-more button").click(function () {
            $(".accordion .load-more").hide();
            $(".accordion .hide-item").show();
        });

    }
};

function ShowHiddenAccordionsV2IfNotEmpty() {
    $($("li.d-none div.accordion__content").get().reverse()).each(function () {
        if (this.id.length > 0) {
            var id = "#" + this.id;

            if ($(id).text().trim().length > 0 || $(id)[0].innerHTML.indexOf('iframe') != -1) {
                $(id).parent().removeClass("d-none");
                $(id).closest("ul.accordion").parent().find("div.product-section-heading").removeClass("d-none");
                $(id).closest(".product-page-accordion").addClass("non-empty-accordion");
            }
        }
    });
}

function ShowHiddenAccordionsIfNotEmpty() {
    $($(".product-page-accordion.d-none div.accordion__content").get().reverse()).each(function () {
        if (this.id.length > 0) {
            var id = "#" + this.id;

            if ($(id).text().trim().length > 0 || $(id)[0].innerHTML.indexOf('iframe') != -1) {
                //if nested accordion, need to show ul
                //otherwise, show section
                if ($(id).parent().parent().hasClass("accordion--secondary")) {
                    $(id).parent().parent().removeClass("d-none");
                }
                else {
                    if ($(id).children("ul.accordion--secondary").length > 0) {
                        //if an accordion has nested accordions and some are visible, then we want to show the parent accordion
                        if ($(id).children("ul.accordion--secondary").length > $(id).children("ul.d-none").length) {
                            $(id).parents("section").removeClass("d-none");
                        }
                    }
                    else {
                        $(id).parents("section").removeClass("d-none");
                    }
                }
            }
        }
    });
}

$(window).on("load", function () {
    app.products.init();
});

(function () {

    function MultiTypeDocumentsAccordionController($scope) {
        $scope.documents = [];
        $scope.documentCount = 0;
        $scope.emailCheckedCount = 0;
        $scope.downloadCheckedCount = 0;
        $scope.selectAllEmailChecked = false;
        $scope.selectAllDownloadChecked = false;
        $scope.multipleDocumentTypes = false;
        $scope.hideUpdatedColumn = false;
        $scope.hideDownloadColumn = false;
        var renderingSelector = '';
        $scope.init = function (renderingSelectorParam, mailToHref, multipleDocumentTypes, hideUpdatedColumn, hideDownloadColumn) {
            renderingSelector = renderingSelectorParam;
            $scope.mailToUrl = mailToHref;
            $scope.multipleDocumentTypes = multipleDocumentTypes;
            $scope.hideUpdatedColumn = hideUpdatedColumn;
            $scope.hideDownloadColumn = hideDownloadColumn;
            gatherDocuments();
        };

        $scope.EmailCheckboxChanged = function (document) {
            if (document.emailChecked) {
                $scope.emailCheckedCount++;

                if ($scope.emailCheckedCount === $scope.documentCount) {
                    $scope.selectAllEmailChecked = true;
                }
            } else {
                $scope.emailCheckedCount--;

                if ($scope.emailCheckedCount !== $scope.documentCount) {
                    $scope.selectAllEmailChecked = false;
                }
            }
        };

        $scope.DownloadCheckboxChanged = function (document) {
            if (document.downloadChecked) {
                $scope.downloadCheckedCount++;

                if ($scope.downloadCheckedCount === $scope.documentCount) {
                    $scope.selectAllDownloadChecked = true;
                }
            } else {
                $scope.downloadCheckedCount--;

                if ($scope.downloadCheckedCount !== $scope.documentCount) {
                    $scope.selectAllDownloadChecked = false;
                }
            }
        };

        var gatherDocuments = function () {
            if (!renderingSelector) {
                return;
            }

            var documents = $(renderingSelector + ' .document-row').toArray().map(function (documentRow) {
                return {
                    DocumentId: documentRow.dataset.documentId,
                    DomElement: documentRow
                };
            })

            documents = documents ? documents : [];

            $scope.documents = documents;
            $scope.documentCount = documents.length;

            ShowHiddenAccordionsIfNotEmpty();
            ShowHiddenAccordionsV2IfNotEmpty();
        };

        $scope.SelectAllEmailChanged = function () {
            var newSelectAllEmailValue = $scope.selectAllEmailChecked;

            $scope.documents.forEach(function (document) {
                document.emailChecked = newSelectAllEmailValue;
            })

            $scope.emailCheckedCount = $scope.documents.filter(function (document) {
                return document.emailChecked;
            }).length;
        };

        $scope.SelectAllDownloadChanged = function () {
            var newSelectAllDownloadValue = $scope.selectAllDownloadChecked;

            $scope.documents.forEach(function (document) {
                document.downloadChecked = newSelectAllDownloadValue;
            })

            $scope.downloadCheckedCount = $scope.documents.filter(function (document) {
                return document.downloadChecked;
            }).length;
        };

        var getDocumentDetailsFromDom = function (document) {
            return {
                DocumentId: document.DocumentId,
                DocumentType: document.DomElement.querySelector(".document-type").innerText,
                DocumentTitle: document.DomElement.querySelector(".document-title").innerText,
                DocumentDescription: document.DomElement.querySelector(".document-description").innerText,
                DocumentUrl: document.DomElement.querySelector(".document-link").href
            }
        }

        var getDocumentTextToEmail = function (document) {
            if (!document) {
                return '';
            }
            var docDetails = getDocumentDetailsFromDom(document);
            var documentDetailsArr = [docDetails.DocumentType, docDetails.DocumentTitle, docDetails.DocumentDescription, docDetails.DocumentUrl];
            var documentDetailsToShow = documentDetailsArr.filter(function (value) {
                return !!value;
            });

            return documentDetailsToShow.map(function (docDetail) {
                return docDetail.trim();
            }).join(' - ');
        };

        $scope.createEmail = function () {
            var emailDocumentText = "";
            angular.forEach($scope.documents,
                function (document, index) {
                    if (document.emailChecked) {
                        var textToEmail = getDocumentTextToEmail(document);

                        if (textToEmail && textToEmail.length > 0) {
                            //putting each url on a new line and encoding special characters in the mailto link
                            emailDocumentText += "%0A" + encodeURIComponent(textToEmail);
                        }

                    }
                });
            parent.location = $scope.mailToUrl + emailDocumentText;
        };

        $scope.createDownload = function () {
            var concatenatedIds = "";
            angular.forEach($scope.documents,
                function (document, index) {
                    if (document.downloadChecked) {
                        concatenatedIds += document.DocumentId + ",";
                    }
                });

            concatenatedIds = concatenatedIds.replace(/,\s*$/, "");
            var productTitle = $("#productTitle").val();

            $.ajax({
                url: "/api/products/downloaddocs",
                data: { ids: concatenatedIds, title: productTitle },
                type: "POST",
                dataType: 'json',
                xhrFields: {
                    withCredentials: true
                }
            });

            // Wait 10 seconds and check the server - may not need to wait a full minute
            setTimeout(app.pollDocDownload, 15000, false);

            var title = $("#docNotifyTitle").val();
            var message = $("#docNotifyMessage").val();

            $.notify({
                title: '<strong>' + title + '</strong><br/>',
                message: message
            },
                {
                    newest_on_top: true
                });
        };
    }

    function PhotometryAndBIMAccordionController($scope, $attrs, pagerService) {
        $scope.pager = {};
        $scope.setPage = setPage;
        $scope.pageSize = 12;
        $scope.photometryBIMData = null;
        $scope.filters = [];
        $scope.photometryItems = [];
        $scope.photometryId = $attrs.photometryId;
        $scope.mailToUrl = $attrs.mailToUrl;
        var maxEmailUrlLength = parseInt($attrs.maxEmailUrlLength);
        $scope.maxEmailUrlLength = (isNaN(maxEmailUrlLength) || maxEmailUrlLength <= 0) ? 2000 : maxEmailUrlLength;
        $scope.emailLinkTooLongMessage = $attrs.emailLinkTooLongMessage;
        $scope.iesLabel = $attrs.iesLabel ? $attrs.iesLabel.trim().toUpperCase() : '.IES';
        $scope.bimLabel = $attrs.bimLabel ? $attrs.bimLabel.trim().toUpperCase() : 'BIM';

        $scope.searchQuery = "";
        $scope.topIESSelected = false;
        $scope.topZipSelected = false;
        $scope.zipFileCheckedCount = 0;
        $scope.iesFileCheckedCount = 0;

        $scope.photometryDoesNotExist = function () {
            return $scope.photometryBIMData && (!$scope.photometryItems || !$scope.photometryItems.length);
        };

        var itemFieldsToSearch = ['Catalog'];

        $scope.SetupPhotometryData = function (photometryAndBIMData) {
            $scope.$apply(function () {

                angular.forEach(photometryAndBIMData.PhotometryItems, function (photometryItem, key) {
                    angular.forEach(photometryItem.Files, function (FileItem, keytwo) {
                        if (photometryAndBIMData.PhotometryItems[key].Files[keytwo].Value.includes("http://")) {
                            photometryAndBIMData.PhotometryItems[key].Files[keytwo].Value = photometryAndBIMData.PhotometryItems[key].Files[keytwo].Value.replace("http://", "https://");
                        }
                    });
                    angular.forEach(photometryItem.Tools, function (ToolItem, keytwo) {
                        if (photometryAndBIMData.PhotometryItems[key].Tools[keytwo].Value.includes("http://")) {
                            photometryAndBIMData.PhotometryItems[key].Tools[keytwo].Value = photometryAndBIMData.PhotometryItems[key].Tools[keytwo].Value.replace("http://", "https://");
                        }
                    });
                    if (photometryAndBIMData.PhotometryItems[key].Report.includes("http://")) {
                        photometryAndBIMData.PhotometryItems[key].Report = photometryAndBIMData.PhotometryItems[key].Report.replace("http://", "https://");
                    }
                });

                $scope.photometryBIMData = photometryAndBIMData;
                $scope.filters = photometryAndBIMData.Filters;
                $scope.photometryItems = photometryAndBIMData.PhotometryItems;
                if ($scope.photometryItems && $scope.photometryItems.length > 0) {
                    $scope.filteredPhotometryItems = $scope.photometryItems;
                    $scope.setPage(1);
                }
            });
        };

        $scope.ZipCheckboxChanged = function (photometryItem) {
            if (photometryItem.ZipFileChecked) {
                $scope.zipFileCheckedCount++;
            }
            else {
                $scope.zipFileCheckedCount--;
                if ($scope.zipFileCheckedCount === 0) {
                    $scope.topZipSelected = false;
                }
            }
        };

        $scope.IESCheckboxChanged = function (photometryItem) {
            if (photometryItem.IESFileChecked) {
                $scope.iesFileCheckedCount++;
            }
            else {
                $scope.iesFileCheckedCount--;
                if ($scope.iesFileCheckedCount === 0) {
                    $scope.topIESSelected = false;
                }
            }
        };

        $scope.TopIESCheckboxChanged = function () {
            angular.forEach($scope.filteredPhotometryItems, function (photometryItem, key) {
                if (photometryItem.IESFileChecked !== $scope.topIESSelected) {
                    if ($scope.topIESSelected) {
                        $scope.iesFileCheckedCount++;
                    }
                    else {
                        $scope.iesFileCheckedCount--;
                    }
                    photometryItem.IESFileChecked = $scope.topIESSelected;
                }

            });
        };

        $scope.TopZipCheckboxChanged = function () {
            angular.forEach($scope.filteredPhotometryItems, function (photometryItem, key) {
                if (photometryItem.Files.length > 1 && photometryItem.ZipFileChecked !== $scope.topZipSelected) {
                    if ($scope.topZipSelected) {
                        $scope.zipFileCheckedCount++;
                    }
                    else {
                        $scope.zipFileCheckedCount--;
                    }
                    photometryItem.ZipFileChecked = $scope.topZipSelected;
                }
            });
        };

        $scope.createEmail = function () {
            var concatenatedUrls = "";
            var getPhotometryEmailText = function (photometryItem, label, fileUrlIndex) {
                var photometryDescription = photometryItem.Catalog ? photometryItem.Catalog.trim() : '';
                var emailTextPieces = [label, photometryDescription, photometryItem.Files[fileUrlIndex].Value.replace(/&/g, "%26")];
                return emailTextPieces.filter(function (element) {
                    return !!element;
                }).join(' - ');
            };

            angular.forEach($scope.filteredPhotometryItems, function (photometryItem, index) {
                if (photometryItem.IESFileChecked) {
                    //putting each url on a new line and escaping & character in the mailto link
                    concatenatedUrls += "%0A" + getPhotometryEmailText(photometryItem, $scope.iesLabel, 0);
                }
                if (photometryItem.ZipFileChecked) {
                    //putting each url on a new line and escaping & character in the mailto link
                    concatenatedUrls += "%0A" + getPhotometryEmailText(photometryItem, $scope.bimLabel, 1);
                }
            });

            var emailLink = $scope.mailToUrl + concatenatedUrls;

            if (emailLink.length > $scope.maxEmailUrlLength) {
                $.notify({
                    title: '<strong>Notify</strong>',
                    message: $scope.emailLinkTooLongMessage
                }, {
                        type: 'warning'
                    });

            }
            parent.location = emailLink;
        };

        $scope.clearFilters = function ($event) {
            $event.preventDefault();
            angular.forEach($scope.filters, function (photometryItem, index) {
                photometryItem.selected = null;
            });
            $scope.searchQuery = "";
            resetSelectedItems();
        };

        $scope.$watch('searchQuery', function (newValue, oldValue, scope) {
            if (newValue !== oldValue) {
                $scope.filteredPhotometryItems = WildcardSearchFilter($scope.photometryItems, itemFieldsToSearch, $scope.searchQuery, $scope.filters);
                setPage(1, true);
                resetSelectedItems();
            }
        });
        $scope.$watch('pageSize', function (newValue, oldValue, scope) {
            if (newValue !== oldValue) {
                setPage(1, true);
            }
        });
        $scope.$watch('filters', function (newValue, oldValue, scope) {
            if (newValue !== oldValue) {
                $scope.filteredPhotometryItems = WildcardSearchFilter($scope.photometryItems, itemFieldsToSearch, $scope.searchQuery, $scope.filters);
                setPage(1, true);
                resetSelectedItems();
            }
        }, true);

        //$scope.$on('generalAccordionOpened', function () {
        //    fetchPhotometryData();
        //});

        if ($scope.directChildInitializers) {
            $scope.directChildInitializers.push(fetchPhotometryData);
        }
        else {
            fetchPhotometryData();
        }

        function fetchPhotometryData() {
            if ($scope.photometryId && !$scope.photometryBIMData) {
                $.post(
                    '/api/products/getphotometrydata',
                    {
                        photometryId: $scope.photometryId
                    },
                    function (data) {
                        if (data && data.Success && data.Value) {
                            var parsedData = JSON.parse(data.Value);
                            if (parsedData) {
                                $scope.SetupPhotometryData(parsedData);
                            }
                            else {
                                console.log('Photometry Error: Unable to parse photometry data.');
                            }
                        }
                        else {
                            var responseErr = 'Photometry Error: Unable to retrieve photometry data.';
                            if (data && data.Error) {
                                responseErr = 'Photometry Error:' + data.Error;
                            }
                            console.log(responseErr);
                        }
                    },
                    'json'
                );
            }
        }

        function resetSelectedItems() {
            $scope.zipFileCheckedCount = 0;
            $scope.iesFileCheckedCount = 0;
            $scope.topIESSelected = false;
            $scope.topZipSelected = false;
            angular.forEach($scope.filteredPhotometryItems, function (photometryItem, index) {
                photometryItem.IESFileChecked = false;
                photometryItem.ZipFileChecked = false;
            });
        }
        function setPage(page, filtersChanged) {
            if (page < 1 || (page > $scope.pager.totalPages && !filtersChanged)) {
                return;
            }

            // get pager object from service
            if ($scope.filteredPhotometryItems) {
                $scope.pager = pagerService.GetPager($scope.filteredPhotometryItems.length, page, $scope.pageSize);
            }
            else {
                $scope.pager = pagerService.GetPager($scope.photometryItems.length, page, $scope.pageSize);
            }

            $scope.photometryBIMData.FamilyZipUrl = $scope.photometryBIMData.FamilyZipUrl == null ? "" : $scope.photometryBIMData.FamilyZipUrl.replace("http://", "https://");
            $scope.photometryBIMData.FamilyBimZipUrl = $scope.photometryBIMData.FamilyBimZipUrl == null ? "" : $scope.photometryBIMData.FamilyBimZipUrl.replace("http://", "https://");
                       

            // get current page of items
            $scope.pagedPhotometryItems = $scope.filteredPhotometryItems.slice($scope.pager.startIndex, $scope.pager.endIndex + 1);
        }
    }

    function AccordionController($scope, $attrs, $timeout) {
        $scope.isOpen = $attrs.openByDefault === "true";

        if (window.location.hash && $attrs.accordionId) {
            var elementToJumpTo = window.location.hash.replace('#', '');
            if (elementToJumpTo && elementToJumpTo.toLowerCase() === $attrs.accordionId.toLowerCase()) {
                $scope.isOpen = true;
            }
        }

        var initializeChildren = function () {
            if ($scope.directChildInitializers.length) {
                $scope.directChildInitializers.forEach(function (initFn) {
                    initFn();
                });
            }
        };

        $scope.toggleOpen = function () {
            $scope.isOpen = !$scope.isOpen;
            if ($scope.isOpen) {
                initializeChildren();
            }
        };

        $scope.directChildInitializers = [];

        $scope.initAccordion = function () {
            if ($scope.isOpen) {
                initializeChildren();
            }
        };

        $timeout(function () { $scope.initAccordion(); });
    }

    function SkuListController($scope, $http, pagerService) {
        $scope.hideSection = true;
        $scope.pageData = [];
        $scope.numPerPage = 10;
        $scope.page = 0;
        $scope.totalPages = 0;
        $scope.totalItems = 0;
        $scope.stockedItemsAvailability = [];
        $scope.filteredStockedItemsAvailability = [];
        $scope.breadcrumbs = [];
        $scope.pager = null;
        $scope.requestPending = false;
        $scope.showError = false;
        $scope.showClearAllButton = false;
        $scope.shouldDisplayComponent = false;

        $scope.init = function (productId, itemsPerPage) {
            $scope.productId = productId;
            $scope.numPerPage = itemsPerPage;
            fetchSeriesData();
        };

        var searchableItemFields = ['CATALOG_NUMBER', 'CI_CODE', 'LONG_DESCRIPTION'];

        $scope.searchTerm = '';

        function loadPage(pagejump) {
            $scope.pager = pagerService.GetPager($scope.filteredStockedItemsAvailability.length, pagejump, $scope.numPerPage);
            $scope.pageData = $scope.filteredStockedItemsAvailability.slice($scope.pager.startIndex, $scope.pager.endIndex + 1);

            $scope.page = $scope.pager.currentPage;
            $scope.totalPages = $scope.pager.totalPages;
        }

        $scope.next = function () {
            if ($scope.pager.currentPage < $scope.pager.totalPages) {
                loadPage($scope.page + 1);
            }
        };

        $scope.prev = function () {
            if ($scope.pager.currentPage > 0) {
                loadPage($scope.page - 1);
            }
        };

        $scope.skipto = function (pagejump) {
            if (pagejump > 0 && pagejump <= $scope.pager.totalPages) {
                loadPage(pagejump);
            }
        };

        

        $scope.getNumPerPageToDisplay = function () {
            return Math.min($scope.numPerPage, $scope.totalItems);
        };

        $scope.getMinimumDisplayedIndex = function () {
            return $scope.pager ? $scope.pager.startIndex + 1 : 0;
        };

        $scope.getMaximumDisplayedIndex = function () {
            return $scope.pager ? $scope.pager.endIndex + 1 : 0;
        };

        $scope.$watch('distFilterValues.CatalogSearchTerm', function (newValue, oldValue, scope) {
            if (newValue !== oldValue && typeof (oldValue) != "undefined") {
                $scope.FilterResultSet("");
            }
        });

        $scope.$watch('distFilterValues.DescriptionSearchTerm', function (newValue, oldValue, scope) {
            if (newValue !== oldValue && typeof (oldValue) != "undefined") {
                $scope.FilterResultSet("");
            }
        });

        $scope.$watch('searchTerm', function (newValue, oldValue, scope) {
            if (newValue !== oldValue) {
                performSearchFiltering(newValue, searchableItemFields);
            }
        });

        var performSearchFiltering = function (searchTerm, fieldsToSearch) {
            $scope.filteredStockedItemsAvailability = WildcardSearchFilter($scope.filteredStockedItemsAvailability, fieldsToSearch, searchTerm, null);
            loadPage(1);
        };

        function fetchSeriesData() {

            function GetDistinctList(arrFieldName) {

                //var distinctList = $scope.stockedItemsAvailability.map(function (arrElement) {
                //    return arrElement[arrFieldName];
                //}).filter(function (value, index, self) {
                //    return value.length > 0 && self.indexOf(value) === index;
                //}).map(function (distinctElement) {
                //        return { CheckboxValue: distinctElement, IsChecked: false };
                //});

                var columnList = [];

                $scope.stockedItemsAvailability.forEach(function (arrElement) {
                    if (arrElement[arrFieldName] == null) {
                        arrElement[arrFieldName] = '';
                    }
                    arrElement[arrFieldName].split(',').forEach(function (splitElement) {
                        columnList.push(splitElement);
                    });
                });

                var distinctList = columnList.filter(function (value, index, self) {
                    return value.length > 0 && self.indexOf(value) === index;
                }).map(function (distinctElement) {
                    return { CheckboxValue: distinctElement, IsChecked: false };
                });

                return distinctList;
            }

            function GetDaysToShipValue(fieldValue) {
                var daysToShip = "";

                switch (fieldValue) {
                    case "CL":
                        daysToShip = "1-2 days - while supplies last";
                        break;
                    case "DS":
                        daysToShip = "5-7 days";
                        break;
                    case "LA":
                        daysToShip = "1-2 days - while supplies last";
                        break;
                    case "LQ":
                        daysToShip = "1-2 days";
                        break;
                    case "ST":
                        daysToShip = "1-2 days";
                        break;
                }

                return daysToShip;
            }

            function AddNewDataFields(skuData) {

                skuData.forEach(function (element, index) {
                    element["DAYS_TO_SHIP"] = GetDaysToShipValue(element.INVENTORY_TYPE);
                    element["PROGRAMS"] = "";
                    element["ICONS"] = [];

                    if (element.INVENTORY_TYPE == "DS") {
                        element.PROGRAMS = "Design2Ship";
                        element.ICONS.push("/-/media/abl/shared-content/images/labels/quick-ship.png");
                    }

                    if (element.COMPL_LISTING.toUpperCase().indexOf("ENERGY STAR") >= 0) {
                        element.ICONS.push("/-/media/abl/shared-content/images/labels/energy-star.png");
                    }
                });

                return skuData;
            }

            var callbackFunc = function (response) {
                $scope.requestPending = false;

                var responseData = response && response.data ? response.data : null;

                console.log('SKU component received server response');
                if (responseData && responseData.Success && responseData.Value && responseData.Value.length) {
                    $scope.shouldDisplayComponent = true;
                    $scope.stockedItemsAvailability = $scope.filteredStockedItemsAvailability = AddNewDataFields(responseData.Value);
                    $scope.totalPages = Math.ceil($scope.stockedItemsAvailability.length / $scope.numPerPage);
                    $scope.totalItems = $scope.stockedItemsAvailability.length;

                    console.log('SKU component success. Result count: ' + $scope.totalItems);
                    $scope.distFilterValues = {
                        CatalogSearchTerm: "",
                        DescriptionSearchTerm: "",
                        ComplianceListing: GetDistinctList("COMPL_LISTING"),
                        Programs: GetDistinctList("PROGRAMS"),
                        Lightsource: GetDistinctList("LIGHTSOURCE"),
                        Environmental: GetDistinctList("ENV_LISTING"),
                        DaysToShip: GetDistinctList("DAYS_TO_SHIP")
                    };

                    loadPage(1);
                } else if (responseData && responseData.Error) {
                    $scope.showError = true;
                    $scope.shouldDisplayComponent = false;
                    console.log('SKU component error: ' + responseData.Error);
                } else {
                    console.log('SKU component received an empty response.');
                }
            };

            $scope.ClearAllFilters = function () {

                for (var filter in $scope.distFilterValues) {
                    var temp = "";
                    if ((typeof $scope.distFilterValues[filter]).toLowerCase() == "object") {
                        $scope.distFilterValues[filter].forEach(function (ckBox) {
                            ckBox.IsChecked = false;
                        });
                    }
                    else {
                        $scope.distFilterValues[filter] = "";
                    }
                }

                $scope.breadcrumbs = [];
                $scope.showClearAllButton = false;
                $scope.filteredStockedItemsAvailability = $scope.stockedItemsAvailability;
                $scope.totalItems = $scope.filteredStockedItemsAvailability.length;
                loadPage(1);

            };

            function ToggleBreadcrumb(checkboxItem) {

                if (checkboxItem) {
                    if (checkboxItem.IsChecked) {
                        $scope.breadcrumbs.push({ BreadcrumbLabel: checkboxItem.CheckboxValue, CheckboxHash: checkboxItem.$$hashKey });
                    }
                    else {
                        var index = GetIndexPosition($scope.breadcrumbs, "BreadcrumbLabel", checkboxItem.CheckboxValue);

                        if (index > -1) {
                            $scope.breadcrumbs.splice(index, 1);
                        }

                    }
                }
            }

            function RemoveBreadcrumbByHash(checkboxHash) {
                var index = GetIndexPosition($scope.breadcrumbs, "CheckboxHash", checkboxHash);

                if (index > -1) {
                    $scope.breadcrumbs.splice(index, 1);
                }

            }

            function GetIndexPosition(listItem, searchField, valueToMatch) {
                //findIndex is the preferred method here, but IE does not support it
                //const index = $scope.breadcrumbs.findIndex(function (element) {
                //    return element.CheckboxHash == checkboxHash;
                //});

                var index = -1;

                for (var i = 0; i < listItem.length; ++i) {
                    if (listItem[i][searchField] == valueToMatch) {
                        index = i;
                        break;
                    }
                }

                return index;
            }

            function ClearCheckboxByHash(checkboxHash) {
                var jumpOut = false;

                for (var filter in $scope.distFilterValues) {

                    var currentFilter = $scope.distFilterValues[filter];

                    if ((typeof currentFilter).toLowerCase() == "object") {

                        for (ckBoxElement = 0; ckBoxElement < currentFilter.length; ckBoxElement++) {

                            if (currentFilter[ckBoxElement].$$hashKey == checkboxHash) {

                                currentFilter[ckBoxElement].IsChecked = false;
                                jumpOut = true;
                                break;
                            }
                        }
                    }
                    if (jumpOut) {
                        break;
                    }
                }

            }


            function AnyFiltersSelected() {
                var selectedFilterFound = false;

                for (var filter in $scope.distFilterValues) {

                    var currentFilter = $scope.distFilterValues[filter];

                    if ((typeof currentFilter).toLowerCase() == "object") {

                        for (ckBoxElement = 0; ckBoxElement < currentFilter.length; ckBoxElement++) {

                            if (currentFilter[ckBoxElement].IsChecked) {
                                return true;
                            }
                        }
                    }
                    else {
                        if (currentFilter.trim().length > 0) {
                            return true;
                        }
                    }
                }

                return selectedFilterFound;
            }

            $scope.ClearCheckbox = function (checkboxHash) {

                ClearCheckboxByHash(checkboxHash);

                RemoveBreadcrumbByHash(checkboxHash);

                $scope.FilterResultSet("");
            };

            $scope.FilterResultSet = function (checkboxItem) {
                $scope.filteredStockedItemsAvailability = FilterResultItems($scope.stockedItemsAvailability, checkboxItem);
                $scope.totalItems = $scope.filteredStockedItemsAvailability.length;
                var title = checkboxItem.CheckboxValue;
                var labelNode = document.querySelector("label[title='" + title + "']");
                if (labelNode && labelNode.classList.contains("checkbox")) {
                    labelNode.parentElement.parentElement.parentElement.classList.remove("show");
                }

                $scope.showClearAllButton = AnyFiltersSelected();

                loadPage(1);
            };

            function columnMatch(element, index, array) {
                return element == true;
            }

            function FilterResultItems(items, checkboxItem) {
                var filteredResults = [];

                var catalogRegEx = $scope.distFilterValues.CatalogSearchTerm.length > 0 ? GetQueryRegularExpresion($scope.distFilterValues.CatalogSearchTerm) : "";
                var longDescRegEx = $scope.distFilterValues.DescriptionSearchTerm.length > 0 ? GetQueryRegularExpresion($scope.distFilterValues.DescriptionSearchTerm) : "";

                ToggleBreadcrumb(checkboxItem);

                for (var i = 0; i < items.length; i++) {
                    var itemFilterMatch;

                    var categoryMatches = [];

                    categoryMatches.push(FindStringMatch(catalogRegEx, $scope.distFilterValues.CatalogSearchTerm, items[i].CATALOG_NUMBER));

                    categoryMatches.push(FindStringMatch(longDescRegEx, $scope.distFilterValues.DescriptionSearchTerm, items[i].LONG_DESCRIPTION));

                    categoryMatches.push(FindCheckboxMatch($scope.distFilterValues.ComplianceListing, items[i].COMPL_LISTING));

                    categoryMatches.push(FindCheckboxMatch($scope.distFilterValues.Programs, items[i].PROGRAMS));

                    categoryMatches.push(FindCheckboxMatch($scope.distFilterValues.Lightsource, items[i].LIGHTSOURCE));

                    categoryMatches.push(FindCheckboxMatch($scope.distFilterValues.Environmental, items[i].ENV_LISTING));

                    categoryMatches.push(FindCheckboxMatch($scope.distFilterValues.DaysToShip, items[i].DAYS_TO_SHIP));

                    if (categoryMatches.every(columnMatch)) {
                        filteredResults.push(items[i]);
                    }
                }

                return filteredResults;

            }

            function FindStringMatch(regExpression, queryStr, columnData) {
                var isMatch = true;

                if (queryStr.length > 0) {
                    isMatch = columnData && regExpression.test(columnData);
                }

                return isMatch;
            }

            function FindCheckboxMatch(checkboxFilters, columnData) {
                var isMatch = true;

                for (var y = 0; y < checkboxFilters.length; y++) {
                    if (checkboxFilters[y].IsChecked) {
                        var arrColumnData = columnData.split(',');

                        for (var z = 0; z < arrColumnData.length; z++) {
                            isMatch = arrColumnData[z] == checkboxFilters[y].CheckboxValue;

                            if (isMatch)
                                break;
                        }
                        //isMatch = columnData == checkboxFilters[y].CheckboxValue;

                        if (isMatch) 
                            break;
                    }
                }

                return isMatch;
            }

            var callbackErrorFunc = function () {
                $scope.requestPending = false;
                $scope.showError = true;
                $scope.shouldDisplayComponent = false;
                console.log("SKU component error. Received non-200 response from Sitecore. Inspect server logs for more details.");
            };


            $scope.requestPending = true;
            $http(
                {
                    url: '/api/products/series',
                    method: 'POST',
                    data: {
                        productId: $scope.productId
                    },
                    dataType: 'json'
                })
                .then(callbackFunc, callbackErrorFunc);
            console.log("SKU component request sent. Waiting on server response.");
        }

        $('.sku-list .pagination a').click(function (event) {
            event.preventDefault();
        });
    }

    function CompatibleProductsController($scope) {
        $scope.CompatibleProductCategories = [];
        $scope.init = function (productId) {
            $scope.productId = productId;
            fetchCompatibleProducts();
        };

        function fetchCompatibleProducts() {
            $.post(
                '/api/products/getcompatibleproducts',
                {
                    productId: $scope.productId
                },
                function (data) {
                    if (data && data.Success && data.Value) {
                        var compatibleProductCategoryData = data.Value.CompatibleProductCategories;
                        if (compatibleProductCategoryData.length) {
                            $scope.$apply(function () {
                                $scope.CompatibleProductCategories = compatibleProductCategoryData;
                            });
                            ShowHiddenAccordionsIfNotEmpty();
                            ShowHiddenAccordionsV2IfNotEmpty();
                        }
                    } else {
                        if (data && data.Error) {
                            console.log('Compatible Products Error: ' + data.Error);
                        }
                    }
                },
                'json'
            ).fail(function () {
                console.log("No compatible products");
            }
            );
        }
    }

    function WildcardSearchFilter(items, itemFieldsToInspect, query, filters) {
        //first, filter results based on what is typed into the search box
        filters = filters || [];
        var textboxFiltered = [];
        itemFieldsToInspect = itemFieldsToInspect || [];

        if (query === "") {
            textboxFiltered = items;
        }
        else {
            //escape regex reserved characters in user input
            var input = query.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');

            //convert % wildcard character to its regex equivalent
            input = input.replace(/%/g, ".+?");

            var inputRegex = new RegExp(input, "i");

            for (var wildCardItemCounter = 0; wildCardItemCounter < items.length; wildCardItemCounter++) {
                var item = items[wildCardItemCounter];
                var filterFunction = function (fieldName) {
                    return item[fieldName] && inputRegex.test(item[fieldName]);
                };

                if (itemFieldsToInspect.some(filterFunction)){
                    textboxFiltered.push(item);
                }
            }
        }

        //second, filter results based on search filters selected in the dropdowns
        var fullyFiltered = filters ? [] : textboxFiltered;
        for (var i = 0; i < textboxFiltered.length; i++) {
            var filteredItem = textboxFiltered[i];
            var includeInResults = true;

            //loop through each of the filters
            //if an item doesn't match any of the filter values, we don't include it
            for (var j = 0; j < filters.length; j++) {
                if (filters[j].selected !== undefined && filters[j].selected !== null && filteredItem.Catalog.indexOf(filters[j].selected.Value) < 0) {
                    includeInResults = false;
                    break;
                }
            }
            if (includeInResults) {
                fullyFiltered.push(filteredItem);
            }
        }

        return fullyFiltered;
    }

    function GetQueryRegularExpresion(query) {
        //escape regex reserved characters in user input
        var input = query.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');

        //convert % wildcard character to its regex equivalent
        input = input.replace(/%/g, ".+?");

        return new RegExp(input, "i");
    }

    var mtdaApp = angular.module("multiTypeDocumentsAccordion", []);
    mtdaApp.controller("MultiTypeDocumentsAccordionController", ["$scope", MultiTypeDocumentsAccordionController]);

    var photometryModule = angular.module("photometryAndBIMAccordion", []);
    photometryModule.factory('pagerService', app.angularshared.PagerService);
    photometryModule.controller("photometryAndBIMAccordionController", ["$scope", "$attrs", "pagerService", PhotometryAndBIMAccordionController]);

    var compatibleProductsModule = angular.module("compatibleProductsAccordion", []);
    compatibleProductsModule.controller("CompatibleProductsController", ["$scope", CompatibleProductsController]);

    var generalAccordionModule = angular.module("generalAccordion", []);
    generalAccordionModule.controller("AccordionController", ["$scope", "$attrs", "$timeout", AccordionController]);

    var skuListModule = angular.module("skuList", []);
    skuListModule.factory('pagerService', app.angularshared.PagerService);
    skuListModule.controller("SkuListController", ["$scope", '$http', "pagerService", SkuListController]);

    angular.module('acuityApp', ['multiTypeDocumentsAccordion', 'photometryAndBIMAccordion', 'compatibleProductsAccordion', 'generalAccordion', 'skuList']);
})();
;
var app = app || {};
app.login = app.login || {};

app.login = {
    getUrlParameter: function getUrlParameter(sParam) {
        var sPageURL = decodeURIComponent(window.location.search.substring(1)),
            sURLVariables = sPageURL.split('&'),
            sParameterName,
            sReturnValue,
            i;

        for (i = 0; i < sURLVariables.length; i++) {
            sParameterName = sURLVariables[i].split('=');

            if (sParameterName[0].toLowerCase() === sParam.toLowerCase()) {
                if (sParameterName[1] === undefined) {
                    return true;
                }

                if (!(sParameterName[2] === undefined)) {
                    sReturnValue = sParameterName[1] + "=" + sParameterName[2];
                } else {
                    sReturnValue = sParameterName[1];
                }

                return sReturnValue;
            }
        }
    },
    onSuccess: function (status) {
        if (status.Success) {
            var returnUrl = app.login.getUrlParameter("returnurl");
            if (!returnUrl)
                returnUrl = "/";
            window.location.replace(returnUrl);
        } else {
            $('.loginFailureText').show();
            $('#login-submit-button').prop('disabled', false);
            $('#loadingIcon').hide();
        }
    },
    onFailure: function (xhr, status, error) {
        try {
            var data = $.parseJSON(xhr.responseText);
            var errors = {};
            for (var i = 0; i < data.length; i++) {
                errors[data[i].Name] = data[i].Message;
            }
            var validator = $('form.login-form').validate({ errorClass: "text-danger", errorLabelContainer: "#loginFailureMessages" });

            //Show validation errors if we get any
            validator.showErrors(errors);
        } catch (e) {
            //show generic error message for other error types
            $('#loginFailureMessages').html("Internal Error. Please contact Administrator.");
        }
        $('#login-submit-button').prop('disabled', false);
        $('#loadingIcon').hide();

    },
    onBegin: function () {
        $('#login-submit-button').prop('disabled', true);
        $('#loadingIcon').show();
    },
    postData: function (actionUrl, method, data) {
        var formToSubmit = $('<form id="app-login-postdata-form" action="' + actionUrl + '" method="' + method.toLowerCase() + '"></form>');
        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                formToSubmit.append('<input type="hidden" name="' + key + '" id="' + key + '" value="' + data[key] + '" />');
            }
        }
        $('body').append(formToSubmit);
        formToSubmit.submit();
    }
};

$("#login-submit-button").click(function () {
    $('.loginFailureText').hide();
});

//$('a#logout-btn').click(function (event) {
//    event.preventDefault();
//    $.post("/api/login/logoutuser", { pageId: $("header").attr("data-pageId") }, function (data) {
//        if (data.redirectUrl == "") {
//            window.location.reload();
//        }
//        else {
//            window.location.replace(data.redirectUrl);
//        }
//    });
//});

$('a#logout-btn').click(function (event) {
    var pageId = $("header").attr("data-pageId");
    app.login.postData('/api/login/logoutuser', 'post', { 'pageId': pageId });
});

//$(".info-bar__links__dropdown a i.fa-sign-out-alt, .header__main__sub-nav a i.fa-sign-out-alt").parent().click(function (event) {
//    event.preventDefault();
//    $.post("/api/login/logoutuser", { pageId : $("header").attr("data-pageId") }, function (data) {
//        if (data.redirectUrl == "") {
//            window.location.reload();
//        }
//        else {
//            window.location.replace(data.redirectUrl);
//        }
//    });
//});

$(".info-bar__links__dropdown a i.fa-sign-out-alt, .header__main__sub-nav a i.fa-sign-out-alt").parent().click(function (event) {
    var pageId = $("header").attr("data-pageId");
    app.login.postData('/api/login/logoutuser', 'post', { 'pageId': pageId });
});;
var app = app || {};

(function () {

    function RegistrationController($scope, $http) {
        $scope.componentId = '';
        $scope.uiModel = {};
        $scope.uiModel.dynamicServerError = '';
        $scope.uiModel.registrationRequestPending = false;
        $scope.uiModel.userEmailAddress = '';
        $scope.uiModel.successfulRegistrationMessage = '';
        $scope.uiModel.genericErrorMessage = 'There has been an error creating your account. Please try again later.';

        $scope.init = function (componentId, genericErrorMessageId, language) {
            $scope.componentId = componentId;

            var errorHtml = $(genericErrorMessageId).html();
            if (errorHtml) {
                $scope.uiModel.genericErrorMessage = errorHtml;
            }
        };

        $scope.canSubmitForm = function () {
            return $scope['register_' + $scope.componentId].$valid && $scope.uiModel.userEmailAddress && !$scope.uiModel.registrationRequestPending;
        };
        
        $scope.submitRegistration = function () {
            $scope.uiModel.dynamicServerError = '';
            $scope.uiModel.registrationRequestPending = true;
            var errorHandler = function (data) {
                var responseErr = $scope.uiModel.genericErrorMessage;
                if (data && data.Error) {
                    responseErr = data.Error;
                }
                $scope.uiModel.dynamicServerError = responseErr;
            };
            $http(
                {
                    url: '/api/registration/submit',
                    method: 'POST',
                    data: {
                        RegistrationComponentId: $scope.componentId,
                        EmailAddress: $scope.uiModel.userEmailAddress
                    },
                    dataType: 'json'
                })
                .then(function (response) {
                    var serverData = response && response.data ? response.data : null;
                    if (serverData && serverData.Success) {
                        $scope.uiModel.dynamicServerError = '';
                        $scope.uiModel.successfulRegistrationMessage = serverData.Value;
                    } else {
                        errorHandler(response);
                    }
                    $scope.uiModel.registrationRequestPending = false;
                }, function (response) {
                    var errorObject = response && response.data ? response.data : null;
                    errorHandler(errorObject);
                    $scope.uiModel.registrationRequestPending = false;
                });
        };

    }

    var registrationModule = angular.module('registration', ['ngSanitize']);
    registrationModule.controller('RegistrationController', ['$scope', '$http', RegistrationController]);
    angular.module('acuityApp').requires.push('registration');
})();;
var app = app || {};
app.maps = app.maps || {};


function initMap() {
    var args = app.maps.data;
    var initLat = 35.8669864;
    var initLng = -78.8548692;
    var map;
    var markers = [];
    var agents = [];
    var foundAgents = [];
    var foundPlace;
    var activeInfowindow = null;
    var service;
    var preventEnter = false;
    var userLatLong = {};
    var queryType = null;
    var availableFilters = [];
    var agentsById = [];
    var mostRecentlyFoundGooglePlacesResponse = null;

    var options = {
        initChecked: args.initChecked, key: args.key, defaultZoom: args.defaultZoom, distance: args.distance
    };

    var isFilterEnabledByDefault = function (filterClass) {
        var filterClassLowered = filterClass ? filterClass.toLowerCase() : "";
        return args.DefaultEnabledFilters && args.DefaultEnabledFilters.length && args.DefaultEnabledFilters.some(function (element) {
            return element && element.toLowerCase() === filterClassLowered;
        });
    };

    var filterTypes = {
        US_Agents: {
            isSelected: isFilterEnabledByDefault('us-agents'),
            name: 'US Agents',
            url: args.USAgentBingServiceEndpoint,
            class: 'us-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAADnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIytbQhFDAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        Showrooms: {
            isSelected: isFilterEnabledByDefault('showrooms'),
            name: 'Showrooms',
            url: args.ShowRoomsBingServiceEndpoint,
            class: 'showrooms',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAK/SURBVFhHrZfNbhMxFIU9maEpElFLUtJUhBVtaWiaghALKrEpCx4EiSfhKXgKXgB2rPiR6I+CEroARmoa0gQoqJtJhnsyHglaX/vO0E8aXdujsU+OfW3Hi+NYSbn/vHqFQn370sP229P36mfwO3nxF5VoTm3ONtWr6HWDquGbp/1fyRs3IjGpiKXxQvvQHySNApqFFbU36YpFOcVoIav0vJs25OMePR2XoIKORi5ICMD3q7o/FqsYok7P/wpJQT/oj4UVg19RHZfbunohbHjLbZs7NmfqfX+oizxL47J67G+pWlTWLTy78ScE1h2jmKkr0bzVFWQK0Tj0h6VnT154vWBYojoWqpVHwQO2X2M2kZg1CuxHLW9F7cTd0tns0FNgXfAL43k18L+f+xYYndkOtqyukJCGqTPd1qGHdYiEIBinyiim4PFLaT2ZnnBaMZAKomlOGjJgHtWyD9YK1XRAFry/O3NL1+QYxcQ2NUKOT0e6JIefD4bepJ8uVBa8/+wf6Zoco5iXyYlrZH/SRWD3ijSjvgU/koYMZHYG3KDT2+SOJLUXaZMkjAnAiQmvRxVdPM9XukZcjmZOaPC1VJRECGgWG2wCsFcIDETBeTZVopKqR1X1JeipkeGyZQB71Edd/gfbNIV0mdJFnuPgRH2YPRAJwc5NsHuU9XIldScDrCvAtYDDPDupifUClhPvCpBcOy/KHasrQJLaYWU8p4v5aHk3EayuAKcYpOGdYlPX8rETHxhP+bNInLHuyC5qSUY6XQEiMUSo0zIzPX8gcgWIxKAzXKh0VcxidBVB5AqQOgNCnZ5ijoKR2BUgFoNO9ycdsTvXxtlcAVmcAeFGkqZOWsXb7IHIkUkMOt+lNNVVK3kyMKszwHmAbnrLCJmmCDiPAxOCI8K59ZvI4wwIub+zrr8yNnI5Ayzu5HJFKaX+ACVzGC8gqwlhAAAAAElFTkSuQmCC'
        },
        //            Distributors: {
        //            isSelected: false,
        //                name: 'Distributors',
        //                url: args.DistributorsBingServiceEndpoint,
        //                class: 'distributors',
        //                icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAABoc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3poc3oDI3gdAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        //            },
        Non_Utility_Lighting: {
            isSelected: isFilterEnabledByDefault('non-utility-lighting'),
            name: 'Non Utility Lighting',
            url: args.NonUtilityLightingServiceEndpoint,
            class: 'non-utility-lighting',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAAD8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vztLCaBLAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        Utility_Lighting: {
            isSelected: isFilterEnabledByDefault('utility-lighting'),
            name: 'Utility Lighting',
            url: args.UtilityLightingBingServiceEndpoint,
            class: 'utility-lighting',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAAAAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZnt2EIjAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        Rep_Non_Utility_Lighting: {
            isSelected: isFilterEnabledByDefault('rep-non-utility-lighting'),
            name: 'Rep Non Utility Lighting',
            url: args.RepNonUtilityLightingServiceEndpoint,
            class: 'rep-non-utility-lighting',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAAD8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vztLCaBLAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        Rep_Utility_Lighting: {
            isSelected: isFilterEnabledByDefault('rep-utility-lighting'),
            name: 'Rep Utility Lighting',
            url: args.RepUtilityLightingBingServiceEndpoint,
            class: 'rep-utility-lighting',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAAAAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZnt2EIjAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        Canada: {
            isSelected: isFilterEnabledByDefault('canada-agents'),
            name: 'Canada Agents',
            url: args.CanadaBingServiceEndpoint,
            class: 'canada-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVmSURBVFhHnZhrbBRVFMfPzOy2hW5TlErbbcFqFRYsBUrtKoUKbenDYGtFbbLdYPtFgyYawPgBjcZXQkp8oGg0Jo2oiX5oQq0JWiWibUI0gqlWi3yASFvQIKWBPvY5ez3nzkx3uzszO8Mvmczrzp3/nHPuOWdXYIyBXUY+/4JN/PEnXPl7DILXpiEwOweLclyQm3cz5N+2ApaW3g5lPp+gDreMLTE/dR9kw729EBkbBweLgRSLqXfiCIIAs5IDlt1dAd6H26F0l9+yKMti+vx+dv77E5Apy+A0EMHnEpR7AhPheoYT7mxrg5bDhy0JsiTmg5ZWNn36F8gNR9UrhKjuU4VpREQRgg4JVjc2wv09PWkFaTMa0tvuY3OnfoXFXEfi8Bhaw/xDyII54QiMDnwHXz3zdNqvNhUzdKCbnTs5BK5ICCcmNTGI4ffRRlhzsYiujcFIXz9M9Hxs+oCpm15cW8aWTF4FVzTMY4Cg0WT+kCSBZ9MmKKjcCHluN0yOT8Do4CD8NzKMVkTh6nhCxvEBHF9QVQW+vqOG7jIUc/rV19jxDz+C7GgIMvDLCJo0iu+I3JIPO57bByv9u1ImPv7Uk+y3vi8hK5oU6BjYk5mLoO3A6+DpSH2OMHTT8I+DaN4oSAlaowKuEGcmPLp3r64Qov699wVaQQGnxFcYDRJxr1nq0oVxvtdDV8yZzz5ll8+eQXNHFuSSsFMET3MTFHc+pitEg5Zyzh2rYA7zTRStGUPrkwfoZRcvTCiDdNAVI+IEemDkwJotm9Uzcyq3bYMgipFV2UxUDqampvheD/23JgRfMmR6K+TfWszji6nDRXQ3ZYKZqWvKBR1038pAVo/iWFvGca7+exkc6OHkVCSiq40wvENfRPlEE0FBKFm0ChEMhNWj+CtozuzsHPUsFV0xng6/IC52oYUc874mSaLM4PcTP/DzdPz87TG+AAQsqDJ/WiHfXagepWJomQ3bG2AaC50sOOYTXpYcgXMDAzDa3W3qs6O7d7PQ+BhPDZRrcJHzJU64iwrUo1QMxbgxqypvJMdjHcIjSutLgyE4duhd+HrPHl1B3zzxODvf3w/ZEZk/o200mKGb84qK8Egf03LwVl0dk8/+BS4sdrQaNCgTh0RM757VULr5XmDOLGCBWTiFBTH6z0XIiqB7EuKLykdAEmFNU5Np9TYVc/LgG2zonbfhJrSGEVrRTBRLzPc3SAjzDfU2nS+/AkVdxgkzbT/zZmUlc05cwkwsY3dnPlYPEns9IxOKa2vB98kRQyGEYcxobH2wFWawzsTUVWUXEYNfxppW0dCoXjEmrWWIl8rXstwrk9jXJHZ6C6F5krOz0jqI2Dp4TVsHjbSWIWra23n/YoZemaAqT9X7vtYW9Yo5lsQUlZSoR6nwLK3jQroSlgRYUrYOg7YrrVUIS2IoI9+FVXjGiUkQTU8zaxsvgLFUV9MVah/W125VLljAkhiiorYOAg7sT9D09CLaqE/RRMXBbhBzbkhygmtFCVTve3bhbRMsi6GGqvieagg54nPzXIL7hXbBph3dM4fVubq5Wb1mDctiCG/LDoigZZJJXpFhjKFoQSGsf2G/ZasQtsR4/D7BXb4O5hxOnuIJvQCO4HLe8tBO9cw6tsQQdY/shFmnA5Ogck4Ne2LTTlMyQYJly5er59axLaa4s0vIXrkKXaHkHS1mKH7IWtMZEpTX13Ir8gE2sC2GqGqqR1coYuiNtFHcxDCegg5czjU1/J5dLJUDPQ55vUzE30Dxv0aUfx0K0SodR8wLohE3ZBmipqWVB7L2U4QgN21s2K6e2eeGxWx4fr9Q0tjA//JQYkUE7wPNPFurQ2wC8D/fT+lbfdMtXQAAAABJRU5ErkJggg=='
        },
        Mexico: {
            isSelected: isFilterEnabledByDefault('mexico-agents'),
            name: 'Mexico Agents',
            url: args.MexicoBingServiceEndpoint,
            class: 'mexico-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAABv0lEQVRYw8WYzytEURiGnxkzfgwiRk2KYjGxUVJCVixYWYqFnfIXyJIlS6UslD9gpCQb1sIOsaHZkGYnTUxC09ic2Uz3nHvPj3vnrbP5uu/p6dxzvu87J4a5MsAI0Ad0AQXgBbgDvohAcWAR+AAqinEvQENTBnjzgagdJ0DSNcgo8KcJUh3PQLsrkH5DiFqghC1II/DuAKYC5GxhNhSTH4lVi4tvk8A4kFd4hkxBmhWTril8DcCZxHdjCjMtmXA/gDcp8o6XP2UCsyeZLOjJmJX4J1RJTKYxj9gt8BkQ5koSHzCB8dpslxor+61IFdowP5K9EFQxSfzXBObJIzajAdMqiRdMYC48YlkgHRBmXhJ/NDlNWUXx81MKKHp4yyIPaSsGvEqAdhR7okWcOi/flk05mFNk4QdgSuSdJqAbWAZKCk+nbTNVdFQoD120ECuOYHpdwDRaNFbVce6y01u3hBl2CdNmAXIfRkO+awgzGQZMjwFIQZGPrHWsCbMQ5t1pUAOkZJr6dXQdEGY1iivuaACQsigRkSjvA7NJhJr1gemIEiauuGkeUActhVkQdZXweKfJUUelgVPxy7ZtXxr+Abq+az3ocubyAAAAAElFTkSuQmCC'
        },
        DGLogik: {
            isSelected: isFilterEnabledByDefault('dg-logik'),
            name: 'DG Logik',
            url: args.DGLogikServiceEndpoint,
            class: 'dg-logik',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAAAKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNWuuOBeAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        AgentDistributors: {
            isSelected: isFilterEnabledByDefault('agentdistributors-agents'),
            name: 'Distributors',
            url: args.AgentDistributorServiceEndpoint,
            class: 'agentdistributors-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAABb2lDQ1BpY2MAACiRdZG9S0JRGMZ/2YdhhUMNEQ0OFg0JUhGNYZBLNZhBX4tevRro7XKvEtIatDQIDVFLX0P/Qa1Ba0EQFEFES/9AX0vI7T0qKKHncu774znneTnnOeCay2hZuy0IWSNnRcIh3/LKqs/9jptOOpjAE9Nsc35xNkrT8fNIi6oPAdWr+b6GoyuRtDVo6RSe1EwrJzwtPLeVMxXvCfdp6VhC+ER41JIDCt8qPV7hN8WpCn8ptqKRGXCpnr5UHcfrWEtbWeERYX82k9eq51E36U4aS4tSB2QOYhMhTAgfcfJskCFHQKohmTX2Bcu+BTbFo8nfpIAljhRp8Y6KmpeuSam66En5MhRU7v/ztPXxsUr37hC0vzrO5xC496FUdJzfU8cpnUHrC1wbNf+m5DT1LXqxpvmPwbsDlzc1LX4AV7vQ/2zGrFhZapXp0nX4uICeFei9B89aJavqOudPEN2WJ7qDwyMYlv3e9T/anGf5rZDDpAAAAAlwSFlzAAALEgAACxIB0t1+/AAAASZJREFUWAnVlNENwyAQQ5su0UG6SsfsKhmkU7S6DySEsO/sBKnhJ8mBfQ8Tsd3M8fo8v0j6fuwbmmN1ScQAZk1UqDKMCtLDVaFKMEdAGlQFKIU5A6QKdG8LZ88zQWb+Y43CjIvRd+UIQpttDh5TJkQAri5grWQQSBiyuZhnsBZMmLKRASGtDOM2QgB9XYbpxezdgV4Gw/4NtIllMKghq8swzo4ZQD8nw/Ri9O4C25degMx+0gxkpmmbgjCxIDNuJsqTwSw5JgTHQEJDYTIxaurWKYxrOtNVNpbCVExmzZ1aCuOYjprqhkowVbMRQv0uwaim7np6z4ymzr2jpHrdZCIpJR0llfC+djLVdNRU/i6ZJcfkpGIn4zaLhmycnswRUBvmSFOUzg+Zz1vmN7RuhwAAAABJRU5ErkJggg=='
        },
        International: {
            isSelected: isFilterEnabledByDefault('international-agents'),
            name: 'International Agents',
            url: args.InternationalBingServiceEndpoint,
            class: 'international-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAANjSURBVFhHtZc9aBRBFMdndy5fhDQKYkAsgwgpJIhFECxUNJJG0CKmsokfhQQLFcSgWGg6L0QMfhDQHFiIASMRDKKEhIBsoRYiSKwEiSAK5uOyt7P+n/cC7s3O7uzG/OCY92Y3m//8583bO0dk5GbPyBYMHUuy0F0uyDYlnM3Im/H56YbhQnPF/1iv1Cvk3oVS3wJGa6zFkIhQiLNlKU82BsE2njayIuUc7ruG0FqUlRgSsuq6o1jxYZ6yRglRcoXotxGUKoaEYJUTWOVunspM4DhPZBieSRMkeYyFhJRdd6xRqb08lQs4sxNb3HqgvXtm6sPEIk9r4D4zWNG5BqX2c7ousAW9GDqqWTzGbeI6mUed0EmJBa5N4fosHjKH2uhEcXc1BcEuvqyB7Z7Bdh81bZfRmYrj9JuElF35A0MXXDtxsdQ3gIdPXir1XYaQQ9iOR9W7dCCkE4PRnVgx5IrvyiOcajSooJcE1K6Qcrh0nk4QT2n4jruPQw2TMx1NQaWd4wh0MjB41UyHBOGh/ctSfuKpCIt1dTs41Egs4DhwRO/XOlILXa9TapzTCFjMVg41MouxpRCGbzisZROPGhsmBuzhsZYKjxobJgZtwdQSfvGoYRLjoeqXOI7gu+5pOm2cxkLXleMc5zQCaukLhxqxYqgAVwqSTo0GHtaN4aBJEM2jRw2hp2znqQgt/upnDjWM29Ti+/McxvEQn8FaQZQHwimieGNdIdCHZjnUSHwdoFdMo6u28ZTGsiy8l6F6ieO+iu2jGjkGR1qrV3Xg2FMIPWVqDUYxxI2ekau44Qqn/4MuCJnkWCPxNEHIMF5u3zhdFzhdLzAYOzeRKIY76QNO1wVeukXT9qyRKIZAPdzCqn5zmgu4S0Wb6AqRKoZXc6ea5QNFfT3NFSJVDAGL6adHLuDKOwyprhBWYoCHo/uc40zAlXEbVwgrMVzIw5xagz5Frf92NUvH1hnCw9fN1xxbAVfGbF0hrMXQQ/F1c5DTVFAr39Gnhji1IoszhId/8pbjRLCt97K4QmQSQw+H9QOcJoL+NM2hNVmdITzTl+016IWIweo4/0tmMezOY05jwZv5btYtIvI4s/YC/cppBJsXoolcYmjV9UEwymkEmxeiiVxiCPxhEV35Gad/4Z+2uVwRQog/ultUIbWsTqEAAAAASUVORK5CYII='
        }
    };

    var scope = ('#how-to-buy-container');

    var urlString = options.data;
    var bingKey = options.key;
    var initCheckedBoolean = /^true$/i.test(options.initChecked);

    // if geolocate is enabled
    if (initCheckedBoolean) {
        geoLocate();
    } else {
        initMapAndSearch({ lat: initLat, lng: initLng }, options.defaultZoom);
    }

    function isEmpty(obj) {
        return Object.keys(obj).length === 0;
    }

    // created functions
    $(function () {
        $("input[name='howToBuyMap']").click(function () {
            var checkedButton = document.querySelector('input[name="howToBuyMap"]:checked').value;
            if (checkedButton) {
                var searchText = document.querySelector('input[name="howToBuyMap"]:checked').dataset.searchtext;
                $("#how-to-buy-2__search-input").removeAttr("disabled");
                $("#how-to-buy-2__search-input")[0].placeholder = searchText;
            }
            else {
                $("#how-to-buy-2__search-input").attr("disabled", "disabled");
                $("#how-to-buy-2__search-input")[0].placeholder = "";
            }
        });
    });

    $(function () {
        $('.fa-info-circle').click(function () {
            var infoBoxString = this.dataset.tooltip;
            var infoBoxes = $("#" + infoBoxString);
            var infoBox = infoBoxes[0];
            if (infoBox && infoBox.className == 'tooltip-text-hidden') {
                infoBox.className = 'tooltip-text-shown';
            }
            else {
                infoBox.className = 'tooltip-text-hidden';
            }

        });
    });



    function createDirectionLink(address) {
        var encodeUrl = encodeURI(address);
        if (isEmpty(userLatLong)) {
            return "https://www.google.com/maps/dir/?api=1&destination=" + encodeUrl;
        }
        return "https://www.google.com/maps/dir/?api=1&origin=" + userLatLong.lat + "," + userLatLong.lng + "&destination=" + encodeUrl;
    }

    // builds infowindows, attaches event listeners, adds markers and init sidebar 
    function buildStoreInfoContent(result, markerZIndex, filterType, loadAll) {
        var hasDodgeCodes = result.DodgeCodes !== undefined && filterType !== undefined && filterType.name === "US Agents";

        if (hasDodgeCodes) {
            var dodgeCodes = result.DodgeCodes.split(';');
        }

        if (!hasDodgeCodes || (dodgeCodes.length > 1 && !dodgeCodes.includes("0"))) {
            var infoContent;
            var id = (Math.floor(Math.random() * (1000 - 1 + 1) + 1)).toString(),
                business = result.Business,
                address1 = result.AddressLine1,
                address2 = result.AddressLine2,
                city = result.Locality,
                state = result.AdminDistrict,
                zip = result.PostalCode,
                country = result.CountryRegion ? result.CountryRegion : '',
                salesId = result.SalesId,
                salesPhone = result.Phone,
                salesWeb = result.Web,
                salesAgentName = result.AgentName;
            var infoLinks;
            var concatAddress = $.grep([address1, address2], Boolean).join(", ");
            var cityStateZip = city + ', ' + state + ' ' + zip + ' ' + country;
            var selectedFilter = filterType;

            var salesContent = salesPhone + "<br />"
                + salesId + "<br />"
                + "<a href='" + addHttp(salesWeb) + "' target='_blank'>" + salesWeb + "</a>";

            infoContent = "<li class='gm-style " + selectedFilter.class + "'" + "data-id='" + id + ">'";
            infoContent += "<div class='place-name'>" + business + "</div>";
            if (typeof city === 'undefined' || city == "") {
                cityStateZip = "";
            }
            infoContent += "<div class='address'>" + concatAddress + ", " + cityStateZip + "</div>";


            var listContent = "<li data-id='" + id + "' class='" + selectedFilter.class + "'>";
            listContent += "<a href='#' onclick='return false;' class='list-business-name'>" + business + "</a>";
            listContent += "<p>" + concatAddress + "</p>";
            if (cityStateZip !== "") {
                listContent += "<p>" + cityStateZip + "</p>";
            }

            if ((selectedFilter.name === "US Agents" || selectedFilter.name === "International Agents") && typeof salesId !== 'undefined') {
                listContent += "<p>Agent #: " + salesId + "</p>";
                infoContent += "<div class='address'>Agent #: " + salesId + "</div>";
            }

            if (salesWeb !== "" && typeof salesWeb !== 'undefined') {
                if (salesWeb.indexOf("@") > -1) {
                    listContent += "<p><a href='mailto:" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='mailto:" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";
                } else if (salesWeb.indexOf("http") > -1) {
                    listContent += "<p><a href='" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";

                } else {
                    listContent += "<p><a href='http://" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='http://" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";

                }
            }

            if (salesPhone !== "" && typeof salesPhone !== 'undefined') {
                listContent += "<p>" + salesPhone + "</p>";
                infoContent += "<div class='address'>" + salesPhone + "</div>";
            }

            if (salesAgentName !== "" && typeof salesAgentName !== 'undefined') {
                listContent += "<p> Agent: " + salesAgentName + "</p>";
                infoContent += "<div class='address'> Agent: " + salesAgentName + "</div>";
            }

            listContent += "</li>";
            infoContent += "</li></div></div>";
            var address = concatAddress + ", " + cityStateZip;
            infoLinks = "<div class='navigate'>";
            infoLinks += "<a target='_blank' href='" + createDirectionLink(address) + "' class='navigate-link'>";
            infoLinks += "<div class='navigate-tex'>  Get Direction </div></a></div>";

            var info = new google.maps.InfoWindow({
                content: infoContent + infoLinks,
                maxWidth: 400
            });

            addMarker(result, info, id, selectedFilter, markerZIndex);
            if (!loadAll)
                appendItemListMarkup(listContent);
        }
    }

    // closes active info window
    function closeActiveInfowindows() {
        if (activeInfowindow != null) {
            activeInfowindow.close();
        }
    }

    // Adds a marker to the map and push to the array.
    function addMarker(result, info, id, selectedFilter, markerZIndex) {
        var marker = new google.maps.Marker({
            position: { lat: result.Latitude, lng: result.Longitude },
            map: map,
            animation: google.maps.Animation.DROP,
            title: id,
            icon: selectedFilter.icon,
            category: selectedFilter.class,
            zIndex: markerZIndex ? markerZIndex : undefined
        });
        marker.addListener('click', function () {
            closeActiveInfowindows();
            highlightListing(marker, info);
            info.open(map, marker);
            activeInfowindow = info;

            sendMarkerClickEventToGoogleAnalytics(marker, result.Business);
        });
        map.addListener('click', function () {
            info.close();
        });
        markers.push(marker);
    }

    // Sets the map on all markers in the array.
    function setMapOnAll(mapValue) {
        for (var i = 0; i < markers.length; i++) {
            markers[i].setMap(mapValue);
        }
    }

    // Removes the markers from the map, but keeps them in the array.
    function clearMarkers() {
        setMapOnAll(null);
    }

    // Shows any markers currently in the array.
    function showMarkers() {
        setMapOnAll(map);

        if (markers.length > 1) {
            var bounds = new google.maps.LatLngBounds();
            markers.forEach(function (marker) {
                bounds.extend(new google.maps.LatLng(marker.position.lat(), marker.position.lng()));
            });
            map.fitBounds(bounds);

        } else if (markers.length === 1) {
            zoomHere(markers[0]);
        }
    }

    // Deletes all markers in the array by removing references to them.
    function deleteMarkers() {
        clearMarkers();
        markers = [];
    }

    // Zoom '15' for selected marker
    function zoomHere(marker) {
        map.setZoom(15);
        map.panTo(marker.position);
    }

    // Clear items sidebar
    function resetSidebar() {
        $('.items-list', $(scope)).empty();
    }

    // append list items markup
    function appendItemListMarkup(listing) {
        hideSpinner();
        $('.items-list', $(scope)).append(listing);
    }

    // helper method used for marker click bind event
    function highlightListing(marker) {
        var thisId = marker.title;
        $('.items-list li', $(scope)).each(function () {
            if ($(this).attr('data-id') === thisId) {
                $('.items-list li', $(scope)).removeClass('active');
                $(this).addClass('active');
            }
        });
    }

    function getUrlPiecesFromDataFolderString(string) {
        if (string.indexOf(",") !== -1) {
            return string.split(",");
        }
        else {
            return [string];
        }
    }

    // shows pins nearby passed lat and lng
    function loadPinsNearby(lat, lng, distance) {
        distance = distance !== "" ? distance : 100;
        var urlPieces = getUrlPiecesFromDataFolderString(urlString);
        for (x in urlPieces) {
            var urlPiece = urlPieces[x];
            var baseUrl = "https://spatial.virtualearth.net/REST/v1/data/" + urlPiece + "?";
            var filter = "spatialFilter=nearby(" + lat + "," + lng + "," + distance + ")";
            var options = "&$top=250&$format=json&jsonp=?";
            var key = "&key=" + bingKey;

            var url = baseUrl + filter + options + key;
            loadPinsFromUrl(url);
        }
    }

    // loads pins by calling getJSON function for passed url
    function loadPinsFromUrl(url, filterFunc, filterArgs) {
        hideResultMessages();
        $.getJSON(url, function (data) {
            $.each(data["d"].results, function (key, value) {

                //filter pins and check if the search type belongs 
                if (typeof (filterFunc) === 'function') {
                    if (!filterFunc.call(this, value, filterArgs, filterArgs2))
                        return true;
                }
                buildStoreInfoContent(value[0]);
            });

            if (markers.length > 0) {
                hideResultMessages();
                showMarkers();
            } else {
                resetSidebar();
                showNoResultsText();
            }
        });
    }

    function showSpinner() {
        $('.how-to-buy-2__list__addresses', $(scope)).html('<i class="fa fa-spinner fa-spin"></i>');
    }

    function hideSpinner() {
        $('.how-to-buy-2__list__addresses .fa-spinner', $(scope)).remove();
    }

    function displayFilterType(checkBoxfilterArr, filterType, searchedRegionInfo, markerZIndex) {
        var hasAnyFilteredResults = false;
        var isFilterTypeSelected = checkBoxfilterArr.find(function (element) {
            return element == filterType.class;
        });
        if (isFilterTypeSelected !== undefined) {
            var uniqueArr = [];
            $.each(filterType.data,
                function (index, data) {
                    var matchingItems = $.grep(uniqueArr, function (item) {
                        return item.Business === data.Business && item.AddressLine1 === data.AddressLine1
                            && item.AddressLine2 === data.AddressLine2 && item.AddressLine3 === data.AddressLine3
                            && item.Web === data.Web;
                    });
                    if (matchingItems.length === 0) {
                        buildStoreInfoContent(data, markerZIndex, filterType, searchedRegionInfo.loadAll);
                        hasAnyFilteredResults = true;
                        uniqueArr.push(data);
                    }
                });
        }
        return hasAnyFilteredResults;
    }

    function getSearchTerm() {
        var searchInput = $('#how-to-buy-2__search-input');
        if (searchInput && searchInput.val()) {
            return searchInput.val();
        }
        else {
            return '';
        }
    }

    function getSelectedFiltersAsString() {
        var selectedFilterTypes = $(".how-to-buy-2__filters :radio:checked").map(function (index, element) {
            return element.value;
        }).toArray();
        return selectedFilterTypes.join(', ');
    }

    function sendNoResultsDataToGoogleAnalytics() {
        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Search - No Results Found - '.concat(
                'Page: "' + window.location.href + '"',
                ' . Search Term: "' + getSearchTerm() + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"'),
            Label: 'How To Buy Search - No Results Found'
        });
    }

    function sendMarkerClickEventToGoogleAnalytics(marker, businessName) {
        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Map Click - '.concat(
                'Page: "' + window.location.href + '"',
                ' Business: "' + businessName + '"',
                ' . Search Term: "' + getSearchTerm() + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"'),
            Label: 'How To Buy Map Click'
        });
    }

    function clearStoredFilterData() {
        Object.values(filterTypes).forEach(function (filterValue) {
            filterValue.allFilterData = [];
            filterValue.wasRadialSearchPerformed = false;
        });
    }

    function loadSearchByRegionDataToView(checkBoxfilterArr, searchedRegionInfo) {
        var generateMapEntry = function (requestFunc, filterToPopulate, optionalFilterFunc) {
            return {
                requestFunc: requestFunc,
                filter: filterToPopulate,
                optionalFilterFunc: optionalFilterFunc
            };
        };

        clearStoredFilterData();

        var getShowRoomData = function (isFollowupRequest) { return getShowroomsByRegion(searchedRegionInfo, isFollowupRequest); };
        var getHlpNonUtilityData = function (isFollowupRequest) { return getHlpNonUtility(searchedRegionInfo, isFollowupRequest); };
        var getRepNonUtilityData = function (isFollowupRequest) { return getRepNonUtility(searchedRegionInfo, isFollowupRequest); };
        var getUsAgentData = function (isFollowupRequest) { return getUSAgents(searchedRegionInfo, isFollowupRequest); };
        var getHlpUtilityData = function (isFollowupRequest) { return getHlpUtility(searchedRegionInfo, isFollowupRequest); };
        var getRepUtilityData = function (isFollowupRequest) { return getRepUtility(searchedRegionInfo, isFollowupRequest); };
        var getCanadaData = function (isFollowupRequest) { return getCanadaAgents(searchedRegionInfo, isFollowupRequest); };
        var getMexicoData = function (isFollowupRequest) { return getMexicoAgents(searchedRegionInfo, isFollowupRequest); };
        var getDistributorData = function (isFollowupRequest) { return getDistributors(searchedRegionInfo, isFollowupRequest); };
        var getInternationalData = function (isFollowupRequest) { return getInternationalAgents(searchedRegionInfo, isFollowupRequest); };
        var getDgLogikData = function (isFollowupRequest) { return getDGLogikAgents(searchedRegionInfo, isFollowupRequest); };

        var internationalDataFilterFunc = function (data) {
            if (agentsById.length > 0) {
                var index = data.d.results.map(function (e) { return e.Id; }).indexOf(agentsById[0].Id);
                if (index !== -1) {
                    data.d.results.splice(index, 1);
                }
            }

            filterTypes.International.data = data.d.results;
        };

        var requestDataMap = [
            generateMapEntry(getHlpNonUtilityData, filterTypes.Non_Utility_Lighting),
            generateMapEntry(getRepNonUtilityData, filterTypes.Rep_Non_Utility_Lighting),
            generateMapEntry(getUsAgentData, filterTypes.US_Agents),
            generateMapEntry(getHlpUtilityData, filterTypes.Utility_Lighting),
            generateMapEntry(getRepUtilityData, filterTypes.Rep_Utility_Lighting),
            generateMapEntry(getCanadaData, filterTypes.Canada),
            generateMapEntry(getMexicoData, filterTypes.Mexico),
            generateMapEntry(getDistributorData, filterTypes.AgentDistributors),
            generateMapEntry(getShowRoomData, filterTypes.Showrooms),
            generateMapEntry(getDgLogikData, filterTypes.DGLogik),
            generateMapEntry(getInternationalData, filterTypes.International, internationalDataFilterFunc)
        ].filter(function (requestData) {
            // only send new requests when the filter is selected and the search term has changed since the last request
            return requestData.filter.isSelected && requestData.filter.hasResultsForSearchTerm !== searchedRegionInfo.searchTerm;
        });

        var updateFilterDataFromResponse = function (responseData, filter, isFollowupRequestData) {
            if (responseData && responseData.d && responseData.d.results && responseData.d.results.length) {
                if (filter.optionalFilterFunc) {
                    filter.optionalFilterFunc(responseData);
                }
                else {
                    filter.allFilterData = filter.allFilterData.concat(responseData.d.results);
                }

                if (isFollowupRequestData) {
                    filter.wasRadialSearchPerformed = true;
                }
            }
        };

        var storeResultsForInMemoryFilter = function (responseData, filter) {
            if (responseData && responseData.d && responseData.d.results && responseData.d.results.length) {
                filter.allResultsForDataSource = responseData.d.results;
            }
        };

        var filterResultsInMemory = function (results, regionSearchInfo) {
            var searchTerm = regionSearchInfo.searchTerm;
            if (!searchTerm || !searchTerm.length || !regionSearchInfo.isPostalRegion) {
                return [];
            }

            function getZipCodesForResult(searchResult) {
                var allTerritoryZipCodes = [];

                if (searchResult["Territory1"]) {
                    for (var i = 1; i < 21; i++) {
                        if (searchResult["Territory" + i]) {
                            allTerritoryZipCodes = allTerritoryZipCodes.concat(searchResult["Territory" + i].split(';'));
                        }
                    }
                }

                return allTerritoryZipCodes;
            }


            searchTerm = searchTerm.trim();
            return results.filter(function (result) {
                return getZipCodesForResult(result).includes(searchTerm.trim());
            });
        };

        var collapseFilterResponseData = function (filter, regionSearchInfo) {
            var serverResponseData = filter.allFilterData;
            var inMemorySearchHits = filter.allResultsForDataSource ? filterResultsInMemory(filter.allResultsForDataSource, regionSearchInfo) : [];

            var dataPointsToRender = inMemorySearchHits;
            filter.hasTerritoryMatch = inMemorySearchHits && inMemorySearchHits.length > 0;
            if (!inMemorySearchHits || !inMemorySearchHits.length) {
                dataPointsToRender = dataPointsToRender.concat(serverResponseData);
            }
            filter.hasResultsForSearchTerm = regionSearchInfo.searchTerm;
            // get uniques by id
            return dataPointsToRender.map(function (filterDataItem) {
                return {
                    id: filterDataItem.Id,
                    filterData: filterDataItem
                };
            }).filter(function (value, index, self) {
                return self.findIndex(function (element) {
                    return element.id === value.id;
                }) === index;
            }).map(function (item) {
                return item.filterData;
            });
        };

        var promisesForAllFilters = [];

        requestDataMap.forEach(function (element) {
            var executedRequestData = element.requestFunc();
            executedRequestData = executedRequestData && Array.isArray(executedRequestData) ? executedRequestData : [executedRequestData];

            var requestSuccessHandler = function (responseData, requestItem) {
                var processResultsAsFilteredByServer = !requestItem.isClientFilterRequest;
                var processResultsAsClientFilter = requestItem.isClientFilterRequest || requestItem.isBlankQuery;
                if (processResultsAsFilteredByServer) {
                    updateFilterDataFromResponse(responseData, element.filter);
                }
                if (processResultsAsClientFilter) {
                    storeResultsForInMemoryFilter(responseData, element.filter);
                }
            };

            var failureHandler = function (responseData, failedFilterClass) {
                console.log('Request for ' + failedFilterClass + ' failed.');
            };

            var createDeferredPromiseForRequest = function (request) {
                return request ? $.Deferred() : null;
            };

            var primaryRequestsWithDeferred = executedRequestData.map(function (requestItem) {
                return {
                    requestItem: requestItem,
                    deferredPromise: createDeferredPromiseForRequest(requestItem.request)
                };
            });

            primaryRequestsWithDeferred.forEach(function (requestWithDeferredPromise) {
                requestWithDeferredPromise.requestItem.request.done(function (responseData) {
                    requestSuccessHandler(responseData, requestWithDeferredPromise.requestItem);
                    requestWithDeferredPromise.deferredPromise.resolve();
                }).fail(function (failureData) {
                    failureHandler(failureData, element.filter.class);
                    requestWithDeferredPromise.deferredPromise.resolve();
                });
            });

            var deferredPromises = primaryRequestsWithDeferred.map(function (req) {
                return req.deferredPromise;
            });

            // aggregate results when the requests for this particular filter are finished
            var promiseForThisFilter = $.when.apply($, deferredPromises);
            promisesForAllFilters.push(promiseForThisFilter);
            promiseForThisFilter.done(function () {
                // attempt to run a wider search if there were no results for the user's search

                if (element.filter.allFilterData.length === 0) {
                    var followupRequestData = element.requestFunc(true);
                    followupRequestData = followupRequestData && Array.isArray(followupRequestData) ? followupRequestData : [followupRequestData];

                    var followupRequestsWithDeferred = followupRequestData.map(function (requestItem) {
                        return {
                            requestItem: requestItem,
                            deferredPromise: createDeferredPromiseForRequest(requestItem.request)
                        };
                    });

                    followupRequestsWithDeferred.forEach(function (followupRequestWithDeferred) {
                        followupRequestWithDeferred.requestItem.request.done(function (followupResponseData) {
                            updateFilterDataFromResponse(followupResponseData, element.filter, true);
                            followupRequestWithDeferred.deferredPromise.resolve();
                        }).fail(function (failureData) {
                            failureHandler(failureData, element.filter.class);
                            followupRequestWithDeferred.deferredPromise.resolve();
                        });
                    });

                    var followupDeferredPromises = followupRequestsWithDeferred.map(function (requestWithDeferredPromise) {
                        return requestWithDeferredPromise.deferredPromise;
                    });

                    var followupPromise = $.when.apply($, followupDeferredPromises);
                    followupPromise.done(function () {
                        element.filter.data = collapseFilterResponseData(element.filter, searchedRegionInfo);
                    });

                    element.followupPromise = followupPromise;
                }
                else {
                    element.filter.data = collapseFilterResponseData(element.filter, searchedRegionInfo);
                }
            });
        });

        // decide what to display when ALL of the requests are finished and results are processed
        $.when.apply($, promisesForAllFilters).done(
            function () {

                var followupPromises = requestDataMap.filter(function (requestMapEntry) {
                    return requestMapEntry.followupPromise;
                }).map(function (requestMapEntry) {
                    return requestMapEntry.followupPromise;
                });

                if (followupPromises && followupPromises.length) {
                    $.when.apply($, followupPromises).done(
                        function () {
                            processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo);
                        });
                } else {
                    processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo);
                }
            }
        );
    }


    function wasRadialSearchPerformed(filterTypes) {
        return Object.values(filterTypes).some(function (filter) {
            return filter && filter.data && filter.data.length && filter.wasRadialSearchPerformed;
        });
    };

    function processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo) {
        deleteMarkers();
        if (checkBoxfilterArr.length == 0) {
            hideSpinner();

            showNoResultsText();
        }

        var usResults = displayFilterType(checkBoxfilterArr, filterTypes.US_Agents, searchedRegionInfo, 990);
        var nonUtilResults = displayFilterType(checkBoxfilterArr, filterTypes.Non_Utility_Lighting, searchedRegionInfo, 980);
        var utilResults = displayFilterType(checkBoxfilterArr, filterTypes.Utility_Lighting, searchedRegionInfo, 970);
        var repNonUtilResults = displayFilterType(checkBoxfilterArr, filterTypes.Rep_Non_Utility_Lighting, searchedRegionInfo, 980);
        var repUtilResults = displayFilterType(checkBoxfilterArr, filterTypes.Rep_Utility_Lighting, searchedRegionInfo, 970);
        var canadaResults = displayFilterType(checkBoxfilterArr, filterTypes.Canada, searchedRegionInfo, 960);
        var mexicoResults = displayFilterType(checkBoxfilterArr, filterTypes.Mexico, searchedRegionInfo, 960);
        //var distributorResults = displayFilterType(checkBoxfilterArr, filterTypes.AgentDistributors, searchedRegionInfo, 960);
        var internationalResults = displayFilterType(checkBoxfilterArr, filterTypes.International, searchedRegionInfo, 950);
        var dgResults = displayFilterType(checkBoxfilterArr, filterTypes.DGLogik, searchedRegionInfo, 940);

        var showroomResults = displayFilterType(checkBoxfilterArr, filterTypes.Showrooms, searchedRegionInfo, 980);
        var distributorResults = displayFilterType(checkBoxfilterArr, filterTypes.AgentDistributors, searchedRegionInfo, 980);

        var hasAnyFilteredResults = usResults || nonUtilResults || utilResults || repNonUtilResults || repUtilResults || canadaResults
            || mexicoResults || distributorResults || internationalResults || dgResults || showroomResults;

        hideSpinner();

        var hasAnyResults = hasAnyFilteredResults || $(".how-to-buy-2__list__addresses li").length > 0;
        if (hasAnyFilteredResults && filterTypes.US_Agents.isSelected && filterTypes.US_Agents.hasTerritoryMatch) {
            showUSAgentTerritoryMatchMessage();
        }
        else if (hasAnyResults && wasRadialSearchPerformed(filterTypes)) {
            if (filterTypes.US_Agents.isSelected && searchedRegionInfo.isPostalRegion) {
                showUSAgentRadialSearchMessage();
            }
            else {
                showRadialSearchMessage();
            }
        } else if (!searchedRegionInfo.isPostalRegion && !hasAnyResults) {
            showSearchTips();
        } else if (!hasAnyResults) {
            showNoResultsText();
        }

        if (!hasAnyFilteredResults) {
            sendNoResultsDataToGoogleAnalytics();
        }

        showMarkers();
    }

    function showSearchTips() {
        hideResultMessages()
        $('.no-results-found-search-tips', $(scope)).show();
    }

    function showNoResultsText() {
        hideResultMessages()
        $('.no-results-found', $(scope)).show();
    }

    function showRadialSearchMessage() {
        hideResultMessages()
        $('.found-results-radial-search', $(scope)).show();
    }

    function showUSAgentRadialSearchMessage() {
        hideResultMessages()
        $('.found-results-radial-search-us-agents', $(scope)).show();
    }

    function showUSAgentTerritoryMatchMessage() {
        hideResultMessages()
        $('.found-us-agent-by-territory', $(scope)).show();
    }

    function hideResultMessages() {
        $('.how-to-buy-search-result-indicator', $(scope)).hide();
    }

    function getStateBoundingBoxes() {
        return {
            // xmin, ymin, xmax, ymax 
            al: [-88.473227, 30.223334, -84.88908, 35.008028],
            ak: [-179.148909, 51.214183, 179.77847, 71.365162],
            as: [-171.089874, -14.548699, -168.1433, -11.046934],
            az: [-114.81651, 31.332177, -109.045223, 37.00426],
            ar: [-94.617919, 33.004106, -89.644395, 36.4996],
            ca: [-124.409591, 32.534156, -114.131211, 42.009518],
            co: [-109.060253, 36.992426, -102.041524, 41.003444],
            mp: [144.886331, 14.110472, 146.064818, 20.553802],
            ct: [-73.727775, 40.980144, -71.786994, 42.050587],
            de: [-75.788658, 38.451013, -75.048939, 39.839007],
            dc: [-77.119759, 38.791645, -76.909395, 38.99511],
            fl: [-87.634938, 24.523096, -80.031362, 31.000888],
            ga: [-85.605165, 30.357851, -80.839729, 35.000659],
            gu: [144.618068, 13.234189, 144.956712, 13.654383],
            hi: [-178.334698, 18.910361, -154.806773, 28.402123],
            id: [-117.243027, 41.988057, -111.043564, 49.001146],
            il: [-91.513079, 36.970298, -87.494756, 42.508481],
            in: [-88.09776, 37.771742, -84.784579, 41.760592],
            ia: [-96.639704, 40.375501, -90.140061, 43.501196],
            ks: [-102.051744, 36.993016, -94.588413, 40.003162],
            ky: [-89.571509, 36.497129, -81.964971, 39.147458],
            la: [-94.043147, 28.928609, -88.817017, 33.019457],
            me: [-71.083924, 42.977764, -66.949895, 47.459686],
            md: [-79.487651, 37.911717, -75.048939, 39.723043],
            ma: [-73.508142, 41.237964, -69.928393, 42.886589],
            mi: [-90.418136, 41.696118, -82.413474, 48.2388],
            mn: [-97.239209, 43.499356, -89.491739, 49.384358],
            ms: [-91.655009, 30.173943, -88.097888, 34.996052],
            mo: [-95.774704, 35.995683, -89.098843, 40.61364],
            mt: [-116.050003, 44.358221, -104.039138, 49.00139],
            ne: [-104.053514, 39.999998, -95.30829, 43.001708],
            nv: [-120.005746, 35.001857, -114.039648, 42.002207],
            nh: [-72.557247, 42.69699, -70.610621, 45.305476],
            nj: [-75.559614, 38.928519, -73.893979, 41.357423],
            nm: [-109.050173, 31.332301, -103.001964, 37.000232],
            ny: [-79.762152, 40.496103, -71.856214, 45.01585],
            nc: [-84.321869, 33.842316, -75.460621, 36.588117],
            nd: [-104.0489, 45.935054, -96.554507, 49.000574],
            oh: [-84.820159, 38.403202, -80.518693, 41.977523],
            ok: [-103.002565, 33.615833, -94.430662, 37.002206],
            or: [-124.566244, 41.991794, -116.463504, 46.292035],
            pa: [-80.519891, 39.7198, -74.689516, 42.26986],
            pr: [-67.945404, 17.88328, -65.220703, 18.515683],
            ri: [-71.862772, 41.146339, -71.12057, 42.018798],
            sc: [-83.35391, 32.0346, -78.54203, 35.215402],
            sd: [-104.057698, 42.479635, -96.436589, 45.94545],
            tn: [-90.310298, 34.982972, -81.6469, 36.678118],
            tx: [-106.645646, 25.837377, -93.508292, 36.500704],
            vi: [-65.085452, 17.673976, -64.564907, 18.412655],
            ut: [-114.052962, 36.997968, -109.041058, 42.001567],
            vt: [-73.43774, 42.726853, -71.464555, 45.016659],
            va: [-83.675395, 36.540738, -75.242266, 39.466012],
            wa: [-124.763068, 45.543541, -116.915989, 49.002494],
            wv: [-82.644739, 37.201483, -77.719519, 40.638801],
            wi: [-92.888114, 42.491983, -86.805415, 47.080621],
            wy: [-111.056888, 40.994746, -104.05216, 45.005904],
            on: [-95.15, 41.68, -74.32, 56.86],
            qc: [-79.77, 44.99, -57.11, 62.58],
            ns: [-66.4471, 43.2718, -59.6188, 47.2351],
            nb: [-69.0535, 44.5561, -63.6147, 48.0897],
            mb: [-102.01, 49.0, -88.99, 60.0],
            bc: [-139.05, 48.22, -114.05, 60.0],
            pe: [-64.41, 45.95, -61.97, 47.06],
            sk: [-110.01, 49.0, -101.36, 60.0],
            ab: [-120.0, 49.0, -110.0, 60.0],
            nl: [-67.82, 46.6, -52.61, 60.38]
        };
    }

    function getCountryBoundingBoxes() {
        return {

            aw: [12.1702998, -70.2809842, 12.8102998, -69.6409842],
            af: [29.3772, 60.5176034, 38.4910682, 74.889862],
            ao: [-18.038945, 11.4609793, -4.3880634, 24.0878856],
            ai: [18.0615454, -63.6391992, 18.7951194, -62.7125449],
            //ALA: [59.4541578, 19.0832098, 60.87665, 21.3456556],
            al: [11.081041, -72.6598913, 11.408791, -72.4039128],
            ad: [42.4288238, 1.4135781, 42.6559357, 1.7863837],
            //ANT: [12.1544542, -68.940593, 12.1547472, -68.9403518],
            ae: [22.6444, 51.4980, 26.2822, 56.3834],
            ar: [-55.1850761, -73.5600329, -21.781168, -53.6374515],
            am: [4.3951997, -75.7854388, 4.5895768, -75.6325211],
            as: [-14.7608358, -171.2951296, -10.8449746, -167.9322899],
            aq: [-85.0511287, -180.0, -60.0, 180.0],
            tf: [-50.2187169, 39.4138676, -11.3139928, 77.8494974],
            ag: [16.7573901, -62.5536517, 17.929, -61.447857],
            au: [-55.3228175, 72.2460938, -9.0882278, 168.2249543],
            at: [46.3722761, 9.5307487, 49.0205305, 17.160776],
            az: [38.3929551, 44.7633701, 41.9502947, 51.0090302],
            bi: [-4.4693155, 29.0007401, -2.3096796, 30.8498462],
            be: [49.4969821, 2.3889137, 51.5516667, 6.408097],
            bj: [6.1730586, 5.4621058, 6.4930586, 5.7821058],
            bf: [9.4104718, -5.5132416, 15.084, 2.4089717],
            bd: [20.3756582, 88.0075306, 26.6382534, 92.6804979],
            bg: [41.2353929, 22.3571459, 44.2167064, 28.8875409],
            bh: [35.1878012, 72.5273968, 35.2278012, 72.5673968],
            bs: [20.7059846, -80.7001941, 27.4734551, -72.4477521],
            ba: [42.5553114, 15.7287433, 45.2764135, 19.6237311],
            bl: [17.670931, -63.06639, 18.1375569, -62.5844019],
            by: [51.2575982, 23.1783344, 56.17218, 32.7627809],
            bz: [15.8857286, -89.2262083, 18.496001, -87.3098494],
            bm: [32.0469651, -65.1232222, 32.5913693, -64.4109842],
            bo: [-22.8982742, -69.6450073, -9.6689438, -57.453],
            br: [-33.8689056, -73.9830625, 5.2842873, -28.6341164],
            bb: [12.845, -59.8562115, 13.535, -59.2147175],
            bn: [4.002508, 114.0758734, 5.1011857, 115.3635623],
            bt: [26.702016, 88.7464724, 28.246987, 92.1252321],
            bv: [-54.654, 2.9345531, -54.187, 3.7791099],
            bw: [-26.9059669, 19.9986474, -17.778137, 29.375304],
            cf: [25.217277, 55.1742999, 25.2194356, 55.1762608],
            ca: [41.6765556, -141.00275, 83.3362128, -52.3231981],
            cc: [-12.4055983, 96.612524, -11.6213132, 97.1357343],
            ch: [45.817995, 5.9559113, 47.8084648, 10.4922941],
            cl: [-56.725, -109.6795789, -17.4983998, -66.0753474],
            cn: [25.0671341, -99.4612273, 25.9161824, -98.421576],
            ci: [4.1621205, -8.601725, 10.740197, -2.493031],
            cm: [1.6546659, 8.3822176, 13.083333, 16.1921476],
            cd: [-4.2726671, 15.2829578, -4.2723703, 15.283136],
            cg: [-5.149089, 11.0048205, 3.713056, 18.643611],
            ck: [-22.15807, -166.0856468, -8.7168792, -157.1089329],
            co: [-4.2316872, -82.1243666, 16.0571269, -66.8511907],
            km: [-12.621, 43.025305, -11.165, 44.7451922],
            cv: [14.8031546, -25.3609478, 17.2053108, -22.6673416],
            cr: [5.3329698, -87.2722647, 11.2195684, -82.5060208],
            cu: [19.6275294, -85.1679702, 23.4816972, -73.9190004],
            cx: [-10.5698515, 105.5336422, -10.4123553, 105.7130159],
            ky: [19.0620619, -81.6313748, 19.9573759, -79.5110954],
            cy: [27.4823018, 25.6451285, 42.4823018, 40.6451285],
            cz: [48.5518083, 12.0905901, 51.0557036, 18.859216],
            de: [47.2701114, 5.8663153, 55.099161, 15.0419319],
            dj: [10.9149547, 41.7713139, 12.7923081, 43.6579046],
            dm: [15.0074207, -61.6869184, 15.7872222, -61.0329895],
            dk: [54.4516667, 7.7153255, 57.9524297, 15.5530641],
            do: [17.2701708, -72.0574706, 21.303433, -68.1101463],
            dz: [18.968147, -8.668908, 37.2962055, 11.997337],
            ec: [-5.0159314, -92.2072392, 1.8835964, -75.192504],
            eg: [22.0, 24.6499112, 31.8330854, 37.1153517],
            er: [25.2197993, 55.1720522, 25.2220008, 55.1736716],
            eh: [24.1597324, -13.7867848, 24.1997324, -13.7467848],
            es: [27.4335426, -18.3936845, 43.9933088, 4.5918885],
            ee: [57.5092997, 21.3826069, 59.9383754, 28.2100175],
            et: [3.397448, 32.9975838, 14.8940537, 47.9823797],
            fi: [59.4541578, 19.0832098, 70.0922939, 31.5867071],
            fj: [-21.9434274, -180.0, -12.2613866, 180.0],
            fk: [-53.1186766, -61.7726772, -50.7973007, -57.3662367],
            fr: [41.2632185, -5.4534286, 51.268318, 9.8678344],
            fo: [61.3915553, -7.6882939, 62.3942991, -6.2565525],
            fm: [0.827, 137.2234512, 10.291, 163.2364054],
            ga: [-4.1012261, 8.5002246, 2.3182171, 14.539444],
            gb: [25.2223186, 55.1579517, 25.2241651, 55.1606916],
            ge: [30.355757, -85.6051201, 35.0013544, -80.7514321],
            gg: [49.4155331, -2.6751703, 49.5090776, -2.501814],
            gh: [4.5392525, -3.260786, 11.1748562, 1.2732942],
            gi: [36.100807, -5.3941295, 36.180807, -5.3141295],
            gn: [38.1240893, -77.4591124, 38.1640893, -77.4191124],
            gp: [15.8320085, -61.809764, 16.5144664, -61.0003663],
            gm: [13.061, -17.0288254, 13.8253137, -13.797778],
            gw: [10.6514215, -16.894523, 12.6862384, -13.6348777],
            gq: [-1.6732196, 5.4172943, 3.989, 11.3598628],
            gr: [34.7006096, 19.2477876, 41.7488862, 29.7296986],
            gd: [11.786, -62.0065868, 12.5966532, -61.1732143],
            gl: [43.0015105, -70.907562, 43.0770931, -70.805801],
            gt: [13.6345804, -92.3105242, 17.8165947, -88.1755849],
            gf: [2.112222, -54.60278, 5.7507111, -51.6346139],
            gu: [13.182335, 144.563426, 13.706179, 145.009167],
            gy: [1.1710017, -61.414905, 8.6038842, -56.4689543],
            hk: [22.1193278, 114.0028131, 22.4393278, 114.3228131],
            hm: [-53.394741, 72.2460938, -52.7030677, 74.1988754],
            hn: [12.9808485, -89.3568207, 17.619526, -82.1729621],
            hr: [42.1765993, 13.2104814, 46.555029, 19.4470842],
            ht: [21.7470269, -78.1147805, 21.7870269, -78.0747805],
            hu: [45.737128, 16.1138867, 48.585257, 22.8977094],
            id: [-11.2085669, 94.7717124, 6.2744496, 141.0194444],
            im: [54.0539576, -4.7946845, 54.4178705, -4.3076853],
            in: [6.5546079, 68.1113787, 35.6745457, 97.395561],
            io: [-7.6454079, 71.036504, -5.037066, 72.7020157],
            ie: [51.222, -11.0133788, 55.636, -5.6582363],
            ir: [24.8465103, 44.0318908, 39.7816502, 63.3332704],
            iq: [29.0585661, 38.7936719, 37.380932, 48.8412702],
            is: [51.3863696, 0.5475318, 51.3868275, 0.5479162],
            il: [29.4533796, 34.2674994, 33.3356317, 35.8950234],
            it: [35.2889616, 6.6272658, 47.0921462, 18.7844746],
            jm: [16.5899443, -78.5782366, 18.7256394, -75.7541143],
            je: [49.1625179, -2.254512, 49.2621288, -2.0104193],
            jo: [10.5378127, 122.4078085, 10.6910595, 122.6356296],
            jp: [20.2145811, 122.7141754, 45.7112046, 154.205541],
            kz: [40.5686476, 46.4932179, 55.4421701, 87.3156316],
            ke: [-4.8995204, 33.9098987, 4.62, 41.899578],
            kg: [39.1728437, 69.2649523, 43.2667971, 80.2295793],
            kh: [9.4752639, 102.3338282, 14.6904224, 107.6276788],
            ki: [-7.0516717, -179.1645388, 7.9483283, -164.1645388],
            kn: [16.895, -63.051129, 17.6158146, -62.3303519],
            kr: [37.52806, 126.89575, 37.52816, 126.89585],
            kw: [-12.0494672, -72.8801102, -12.0094672, -72.8401102],
            la: [13.9096752, 100.0843247, 22.5086717, 107.6349989],
            lb: [40.3199193, -76.4508668, 40.355802, -76.391965],
            lr: [4.1555907, -11.6080764, 8.5519861, -7.367323],
            ly: [19.5008138, 9.391081, 33.3545898, 25.3770629],
            lc: [13.508, -61.2853867, 14.2725, -60.6669363],
            li: [47.0484291, 9.4716736, 47.270581, 9.6357143],
            lk: [25.2287738, 55.1813071, 25.2303051, 55.1828523],
            ls: [-30.6772773, 27.0114632, -28.570615, 29.4557099],
            lt: [53.8967893, 20.653783, 56.4504213, 26.8355198],
            lu: [49.4969821, 4.9684415, 50.430377, 6.0344254],
            lv: [55.6746505, 20.6715407, 58.0855688, 28.2414904],
            mo: [25.2349583, 55.1803834, 25.2368385, 55.1821684],
            mf: [17.8963535, -63.3605643, 18.1902778, -62.7644063],
            ma: [21.3365321, -17.2551456, 36.0505269, -0.998429],
            mc: [43.7247599, 7.4090279, 43.7519311, 7.4398704],
            md: [46.6744934, 29.7521496, 46.6745934, 29.7522496],
            mg: [-25.6071002, 43.2202072, -11.9519693, 50.4862553],
            mv: [25.2252959, 55.1823199, 25.2263769, 55.1837469],
            mx: [19.2726009, -99.2933416, 19.5926009, -98.9733416],
            mh: [-0.5481258, 163.4985095, 14.4518742, 178.4985095],
            mk: [40.8536596, 20.4529023, 42.3735359, 23.034051],
            ml: [10.147811, -12.2402835, 25.001084, 4.2673828],
            mt: [35.6029696, 13.9324226, 36.2852706, 14.8267966],
            mm: [9.4399432, 92.1719423, 28.547835, 101.1700796],
            me: [-29.8446455, -51.662, -29.5743342, -51.3498193],
            mn: [41.5800276, 87.73762, 52.1496, 119.931949],
            mp: [14.036565, 144.813338, 20.616556, 146.154418],
            mz: [19.038889, -96.274167, 19.078889, -96.234167],
            mr: [25.2143602, 55.1665334, 25.2163939, 55.1690669],
            ms: [16.475, -62.450667, 17.0152978, -61.9353818],
            mq: [14.3948596, -61.2290815, 14.8787029, -60.8095833],
            mu: [-20.725, 56.3825151, -10.138, 63.7151319],
            mw: [-17.1296031, 32.6703616, -9.3683261, 35.9185731],
            my: [-5.1076241, 105.3471939, 9.8923759, 120.3471939],
            yt: [-13.0210119, 45.0183298, -12.6365902, 45.2999917],
            na: [-28.96945, 11.5280384, -16.9634855, 25.2617671],
            nc: [33.0351363, -92.6876556, 33.0751363, -92.6476556],
            ne: [11.693756, 0.1689653, 23.517178, 15.996667],
            nf: [-29.333, 167.6873878, -28.796, 168.2249543],
            ng: [4.0690959, 2.676932, 13.885645, 14.678014],
            ni: [10.7076565, -87.901532, 15.0331183, -82.6227023],
            nu: [-19.0840514, -169.9383436, -19.0739661, -169.9129672],
            nl: [11.825, -52.35, 53.7253321, 7.2274985],
            no: [57.7590052, 4.0875274, 71.3848787, 31.7614911],
            np: [26.3477581, 80.0586226, 30.446945, 88.2015257],
            nr: [-0.5541334, 166.9091794, -0.5025906, 166.9589235],
            nz: [-52.8213687, -179.059153, -29.0303303, 179.3643594],
            om: [25.2268538, 55.1759911, 25.2291352, 55.1773672],
            pk: [23.5393916, 60.872855, 37.084107, 77.1203914],
            pa: [35.246906, -119.0767707, 35.286906, -119.0367707],
            pn: [-25.1306736, -130.8049862, -23.8655769, -124.717534],
            pe: [41.309511, -89.164781, 41.38197, -89.105652],
            ph: [4.2158064, 114.0952145, 21.3217806, 126.8072562],
            pw: [42.5481153, 2.9351868, 42.5844284, 2.9840518],
            pg: [-13.1816069, 136.7489081, 1.8183931, 151.7489081],
            pl: [49.0020468, 14.1229707, 55.0336963, 24.145783],
            pr: [17.9268695, -67.271492, 18.5159789, -65.5897525],
            kp: [37.5867855, 124.0913902, 43.0089642, 130.924647],
            pt: [29.8288021, -31.5575303, 42.1543112, -6.1891593],
            py: [-27.6063935, -62.6442036, -19.2876472, -54.258],
            ps: [31.2201289, 34.0689732, 32.5521479, 35.5739235],
            pf: [-28.0990232, -154.9360599, -7.6592173, -134.244799],
            qa: [25.2271767, 55.1726803, 25.2289841, 55.1741485],
            re: [-21.3897308, 55.2164268, -20.8717136, 55.8366924],
            ro: [43.618682, 20.2619773, 48.2653964, 30.0454257],
            ru: [41.1850968, 19.6389, 82.0586232, 180],
            rw: [-2.8389804, 28.8617546, -1.0474083, 30.8990738],
            sa: [14.4840316, 121.0177023, 14.4846897, 121.0265441],
            sd: [10.88, 6.48, 10.92, 6.52],
            sn: [12.2372838, -17.7862419, 16.6919712, -11.3458996],
            sg: [1.1304753, 103.6920359, 1.4504753, 104.0120359],
            gs: [-59.684, -42.354739, -53.3500755, -25.8468303],
            sh: [-16.23, -5.9973424, -15.704, -5.4234153],
            sj: [70.6260825, -9.6848146, 81.028076, 34.6891253],
            sb: [-13.2424298, 155.3190556, -4.81085, 170.3964667],
            sl: [6.755, -13.5003389, 9.999973, -10.271683],
            sv: [12.976046, -90.1790975, 14.4510488, -87.6351394],
            sm: [43.8937002, 12.4033246, 43.992093, 12.5160665],
            so: [-13.200556, 15.246667, -13.160556, 15.286667],
            pm: [46.5507173, -56.6972961, 47.365, -55.9033333],
            rs: [42.2322435, 18.8142875, 46.1900524, 23.006309],
            st: [-0.2135137, 6.260642, 1.9257601, 7.6704783],
            sr: [1.8312802, -58.070833, 6.225, -53.8433358],
            sk: [47.7314286, 16.8331891, 49.6138162, 22.56571],
            si: [45.4214242, 13.3754696, 46.8766816, 16.5967702],
            se: [55.1331192, 10.5930952, 69.0599699, 24.1776819],
            sz: [25.2156672, 55.1807318, 25.217255, 55.18286],
            sc: [25.2237725, 55.1816849, 25.2250726, 55.184065],
            sy: [27.1401861, 31.5494106, 42.1401861, 46.5494106],
            tc: [20.9553418, -72.6799046, 22.1630989, -70.8643591],
            td: [7.44107, 13.47348, 23.4975, 24.0],
            tg: [5.926547, -0.1439746, 11.1395102, 1.8087605],
            th: [5.612851, 97.3438072, 20.4648337, 105.636812],
            tj: [36.6711153, 67.3332775, 41.0450935, 75.1539563],
            tk: [-9.6442499, -172.7213673, -8.3328631, -170.9797586],
            tm: [35.129093, 52.335076, 42.7975571, 66.6895177],
            tl: [-6.3294157, 106.9549541, -6.3284839, 106.9551755],
            to: [-24.1034499, -179.3866055, -15.3655722, -173.5295458],
            tt: [9.8732106, -62.083056, 11.5628372, -60.2895848],
            tn: [30.230236, 7.5219807, 37.7612052, 11.8801133],
            tr: [35.8076804, 25.6212891, 42.297, 44.8176638],
            tv: [-10.9939389, -180.0, -5.4369611, 180.0],
            tw: [50.8832129, 6.0296969, 50.8833129, 6.0297969],
            tz: [-6.8127308, 39.2895223, -6.812538, 39.2897105],
            ug: [-1.4823179, 29.573433, 4.2340766, 35.000308],
            ua: [44.184598, 22.137059, 52.3791473, 40.2275801],
            um: [6.1779744, -162.6816297, 6.6514388, -162.1339885],
            uy: [-35.7824481, -58.4948438, -30.0853962, -53.0755833],
            us: [24.9493, -125.0011, 49.5904, -66.9326],
            usa: [24.9493, -125.0011, 49.5904, -66.9326],
            uz: [37.1821164, 55.9977865, 45.590118, 73.1397362],
            va: [41.9002044, 12.4457442, 41.9073912, 12.4583653],
            vc: [12.5166548, -61.6657471, 13.583, -60.9094146],
            ve: [0.647529, -73.3529632, 15.9158431, -59.5427079],
            vg: [17.623468, -65.159094, 18.464984, -64.512674],
            vi: [17.623468, -65.159094, 18.464984, -64.512674],
            vn: [8.1790665, 102.14441, 23.393395, 114.3337595],
            vu: [-20.4627425, 166.3355255, -12.8713777, 170.449982],
            wf: [-14.5630748, -178.3873749, -12.9827961, -175.9190391],
            ws: [40.7987372, -124.2064518, 40.8387372, -124.1664518],
            ye: [11.9084802, 41.60825, 19.0, 54.7389375],
            za: [-47.1788335, 16.3335213, -22.1250301, 38.2898954],
            zm: [-18.0765945, 21.9993509, -8.2712822, 33.701111],
            zw: [-22.4241096, 25.2373, -15.6097033, 33.0683413]
        };
    }

    // loads pins by calling getJSON function for passed url
    function loadAllJsonDataToView(searchedRegionInfo) {
        searchedRegionInfo = searchedRegionInfo ? searchedRegionInfo : getSearchedRegionInfo(null, getCurrentSearchTerm());

        agentsById = [];
        hideResultMessages();
        showSpinner();

        loadSearchByRegionDataToView(getSelectedFilters(), searchedRegionInfo);
    }

    // shows pins nearby passed lat and lng
    function getNearbyCategory(lat, lng, distance) {
        //var dist = jQuery("#proximity").val();

        //distance = dist !== "" ? dist : distance;
        distance = distance !== "" ? distance : 100;
        var urlPieces = getUrlPiecesFromDataFolderString(urlString);
        urlPieces.forEach(function (item, index) {
            var urlPiece = urlPieces[item];
            var baseUrl = "https://spatial.virtualearth.net/REST/v1/data/" + urlPiece + "?";
            var filter = "spatialFilter=nearby(" + lat + "," + lng + "," + distance + ")";
            var options = "&$top=250&$format=json&jsonp=?";
            var key = "&key=" + bingKey;

            var url = baseUrl + filter + options + key;
            loadPinsFromUrl(url);
        });
    }

    function getAllJsonData(filterTypes) {
        $.each(filterTypes, function (element, value) {

            $.getJSON(createEndPointUrl(filterTypes[element].url), function (data) {
                if (data.d.results !== undefined) {
                    return filterTypes[element].data = data.d.results;
                }
                filterTypes[element].data = "";
            });
        });
    }

    function createEndPointUrl(dataUrl) {
        var baseUrl = dataUrl + "?";
        //this statemnt does not filter anything but we have to specify something because that argument is required
        var filter = "$filter=AdminDistrict ne 'unknown'";
        var options = "&$format=json&jsonp=?";
        var key = "&key=" + bingKey;
        var totalCount = "&$top=250";
        var url = baseUrl + filter + options + key + totalCount;
        return url;
    }

    function doesFilterAlreadyHaveAllResults(filter) {
        return !filter.allResultsForDataSource || !filter.allResultsForDataSource.length;
    }

    // shows agent by id
    function getUSAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.US_Agents.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        if (!queryBuilder.hasSpatialFilter()) {
            queryBuilder = queryBuilder.withAgentSearch(searchedRegionInfo.searchTerm);
        }

        return queryBuilder.sendRequests(doesFilterAlreadyHaveAllResults(filterTypes.US_Agents));
    }

    function bundleRequestWithFilteringIntent(request, isClientFilterable, isBlankQuery) {
        return {
            request: request,
            isClientFilterRequest: isClientFilterable,
            isBlankQuery: isBlankQuery
        };
    }

    function getDistributors(searchedRegionInfo, isFollowupRequest) {

        var queryBuilder = new bingQueryBuilder(filterTypes.AgentDistributors.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch().withBusinessSearch();
        var pendingRequests = queryBuilder.sendRequests();

        if (searchedRegionInfo.searchTerm && searchedRegionInfo.searchTerm.length && !isFollowupRequest) {
            // pendingRequests.push(bundleRequestWithFilteringIntent(getDistributorsByBusinessName(searchedRegionInfo.searchTerm)));
            pendingRequests.push(bundleRequestWithFilteringIntent(getDistributorsByAgentName(searchedRegionInfo.searchTerm)));
            pendingRequests.push(bundleRequestWithFilteringIntent(getDistributorsByAgentNum(searchedRegionInfo.searchTerm)));
        }

        return pendingRequests;
    }

    function getDistributorsByBusinessName(input) {
        if (!input) {
            return false;
        }
        var pountInd = input.indexOf('#');
        if (pountInd > 0) {
            input = input.slice(0, pountInd);
        }

        var baseUrl = filterTypes.AgentDistributors.url + "?";
        var filter = "$filter=StartsWith(Business,'" + input + "') eq true";
        var options = "&$format=json&jsonp=?";
        var key = "&key=" + bingKey;
        var totalCount = "&$top=250";

        var url = baseUrl + filter + options + key + totalCount;
        return $.getJSON(url);
    }

    function getDistributorsByAgentName(input) {
        if (!input) {
            return false;
        }
        var pountInd = input.indexOf(' ');
        if (pountInd > 0) {
            input = input.slice(0, pountInd);
        }

        var baseUrl = filterTypes.AgentDistributors.url + "?";
        var filter = "$filter=StartsWith(AgentName,'" + input.toUpperCase() + "') eq true";
        var options = "&$format=json&jsonp=?";
        var key = "&key=" + bingKey;
        var totalCount = "&$top=250";

        var url = baseUrl + filter + options + key + totalCount;
        return $.getJSON(url);
    }

    function getDistributorsByAgentNum(input) {
        if (!input) {
            return false;
        }

        var pountInd = input.indexOf('#');
        var numberRegex = /^\d+\s/gi;
        var aPlusRegex = /^[a]\d+\s/gi;
        var aPlusNoSpaceRegex = /^[a]\d+/gi;
        if (pountInd > 0) {
            input = input.slice(0, pountInd);
        }
        else if (input.match(numberRegex)) {
            var sliceInd = input.indexOf(" ");
            input = input.slice(0, sliceInd);
        }
        else if (input.match(aPlusRegex)) {
            var sliceInd = input.indexOf(" ");
            input = input.slice(1, sliceInd);
        }
        else if (input.match(aPlusNoSpaceRegex)) {
            input = input.slice(1);
        }
        var baseUrl = filterTypes.AgentDistributors.url + "?";
        //$filter=SalesId Eq 'A" + id + "'";
        var filter = "$filter=AgentNum Eq '" + input + "'";
        var options = "&$format=json&jsonp=?";
        var key = "&key=" + bingKey;
        var totalCount = "&$top=250";

        var url = baseUrl + filter + options + key + totalCount;
        return $.getJSON(url);
    }

    function bingQueryBuilder(baseUrl, topXLocations, regionSearchInfo, isFollowupRequest, unsupportedSearchFields) {
        var self = this;
        this.baseUrl = baseUrl;
        this.topXLocations = topXLocations;
        this.filterClause = null;
        this.spatialFilterClause = null;
        this.additionalRequests = [];
        this.regionSearchInfo = regionSearchInfo;
        this.isFollowupRequest = isFollowupRequest;
        this.unsupportedSearchFields = unsupportedSearchFields ? unsupportedSearchFields : [];
        var combineFilterClauses = function (newFilterClause, oldFilterClause, joinWith) {
            if (!oldFilterClause) {
                return newFilterClause;
            } else {
                return {
                    joinWith: joinWith,
                    clause1: newFilterClause,
                    clause2: oldFilterClause
                };
            }
        };

        var addFilterClause = function (newFilterClause, joinWith) {
            var clonedBuilder = self.clone();
            clonedBuilder.filterClause = combineFilterClauses(newFilterClause, clonedBuilder.filterClause, joinWith);
            return clonedBuilder;
        };

        var addSpatialFilterClause = function (newSpatialFilterClause, joinWith) {
            var clonedBuilder = self.clone();
            clonedBuilder.spatialFilterClause = combineFilterClauses(newSpatialFilterClause, clonedBuilder.spatialFilterClause, joinWith);
            return clonedBuilder;
        };

        this.hasSpatialFilter = function () {
            return this.spatialFilterClause && this.spatialFilterClause.length > 0;
        };

        this.hasFilter = function () {
            return this.filterClause && this.filterClause.length > 0;
        };

        this.addAndFilter = function (filterClause) {
            return addFilterClause(filterClause, "and");
        };

        // bing does not support and/or when executing a wildcard (starts/endswith) search - execute an additional request and combine results afterwards.
        this.addWildcardFilter = function (filterClause) {
            var newAdditionalQuery = new bingQueryBuilder(this.baseUrl, this.topXLocations);
            this.additionalRequests.push(newAdditionalQuery.addAndFilter(filterClause));
            return this;
        };

        this.addOrFilter = function (filterClause) {
            return addFilterClause(filterClause, "or");
        };

        this.addSpatialFilter = function (spatialFilter) {
            return addSpatialFilterClause(spatialFilter, "and");
        };

        this.clone = function () {
            var newQueryBuilder = new bingQueryBuilder(this.baseUrl, this.topXLocations, this.regionSearchInfo, this.isFollowupRequest, this.unsupportedSearchFields);
            newQueryBuilder.filterClause = this.filterClause;
            newQueryBuilder.spatialFilterClause = this.spatialFilterClause;
            newQueryBuilder.additionalRequests = this.additionalRequests.slice(0);
            return newQueryBuilder;
        };

        this.withValidAdminDistrict = function () {
            return this.clone().addAndFilter("AdminDistrict ne 'unknown'");
        };

        this.withRadialSearch = function (latitude, longitude, radiusInKilometers) {
            if (!radiusInKilometers) {
                // 50 miles
                radiusInKilometers = 80.5;
            }
            if (latitude && longitude) {
                var spatialFilter = "nearby(" + latitude + "," + longitude + "," + radiusInKilometers + ")";
                return this.addSpatialFilter(spatialFilter);
            }
            else {
                return this;
            }
        };

        var regionFilterEnum = {
            EQUALS: 'eq',
            STARTSWITH: 'StartsWith'
        };

        function filterAgainstRegion(fieldName, region, searchTerm, filterOperator) {
            var regionNames = [region.regionCode, region.regionName, searchTerm];
            var distinctRegionNames = regionNames.filter(function (item, pos) {
                // get unique items that are 'truthy'
                return item && regionNames.indexOf(item) === pos;
            }).map(function (uniqueValue) {
                // to encode an apostrophe for bing requests, replace 1 apostrophe with 2 apostrophes
                return uniqueValue.replaceAll("'", "''");
            });

            var getFilterPiece = function (fieldName, regionName, operator) {
                if (operator === regionFilterEnum.STARTSWITH) {
                    return "StartsWith(" + fieldName.trim() + ",'" + regionName.trim() + "') eq true";
                }
                else {
                    return fieldName.trim() + " eq '" + regionName.trim() + "'";
                }
            };

            var regionFilter = distinctRegionNames.map(function (regionName) {
                return getFilterPiece(fieldName, regionName, filterOperator);
            }).join(' or ');

            regionFilter = distinctRegionNames.length > 1 ? '(' + regionFilter + ')' : regionFilter;
            return regionFilter;
        }

        this.withStateSearch = function (region, country, searchTerm) {
            var stateSearchQuery = this.addAndFilter(filterAgainstRegion('AdminDistrict', region, searchTerm));
            return stateSearchQuery.withCountrySearch(country);
        };

        this.withCitySearch = function (region, state, country, searchTerm) {
            var cityQuery = this.addAndFilter(filterAgainstRegion('Locality', region, searchTerm));
            return cityQuery.withStateSearch(state, country);
        };

        this.withPostalSearch = function (region, state, country, searchTerm) {
            var postalQueryExact = this.addAndFilter(filterAgainstRegion('PostalCode', region, searchTerm)).withStateSearch(state, country);
            var postalQueryWithStartsWith = postalQueryExact.addWildcardFilter(filterAgainstRegion('PostalCode', region, searchTerm, regionFilterEnum.STARTSWITH));
            return postalQueryWithStartsWith;
        };

        this.withBusinessSearch = function () {
            if (this.regionSearchInfo && this.regionSearchInfo.searchTerm && this.regionSearchInfo.searchTerm.length) {
                return this.addWildcardFilter("StartsWith(Business,'" + this.regionSearchInfo.searchTerm.trim() + "') eq true");
            }
            else {
                return this;
            }
        };

        this.withCountrySearch = function (country, searchTerm) {
            if (country && !this.unsupportedSearchFields.includes('CountryRegion')) {
                // google places gives responses with 'US' as country code - bing returns 'USA'
                country.regionCode = country.regionCode === 'US' ? 'USA' : country.regionCode;
                return this.addAndFilter(filterAgainstRegion('CountryRegion', country, searchTerm));
            }
            else if (country && country.regionCode && country.isMostSpecificSearchRegion && this.unsupportedSearchFields.includes('CountryRegion')) {
                var countryBoundingBox = getBoundingBoxForCountry(country.regionCode);
                if (countryBoundingBox && countryBoundingBox.length) {
                    var boundingBoxFilter = "bbox(" + countryBoundingBox.join(',') + ")";
                    return this.addSpatialFilter(boundingBoxFilter);
                }
                else {
                    return this;
                }
            }
            else {
                return this;
            }
        };

        this.withAgentSearch = function (agentNumber) {
            if (!agentNumber) {
                return this;
            }

            var regex = /^(a)?\d{3,5}/gi;
            if (!agentNumber.match(regex)) {
                return this;
            }

            var cleanedAgentNumber = agentNumber ? agentNumber.toLowerCase().trim() : '';
            if (cleanedAgentNumber.startsWith('a')) {
                cleanedAgentNumber = cleanedAgentNumber.substring(1, cleanedAgentNumber.length);
            }

            cleanedAgentNumber = ('A' + cleanedAgentNumber).toUpperCase();
            return this.addOrFilter("SalesId eq '" + cleanedAgentNumber + "'");
        };

        this.withRegionSearch = function () {
            var searchedRegionInfo = this.regionSearchInfo;
            var isFollowupRequest = this.isFollowupRequest;
            if (searchedRegionInfo.isPostalRegion && searchedRegionInfo.latitude && searchedRegionInfo.longitude) {
                if (isFollowupRequest) {
                    return this.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude);
                }
                else {
                    return this.withPostalSearch(searchedRegionInfo.region, searchedRegionInfo.getState(), searchedRegionInfo.getCountry(), searchedRegionInfo.searchTerm);
                }
            }
            else if (searchedRegionInfo.isCity) {
                if (isFollowupRequest) {
                    return this.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude);
                }
                else {
                    return this.withCitySearch(searchedRegionInfo.region, searchedRegionInfo.getState(), searchedRegionInfo.getCountry(), searchedRegionInfo.searchTerm);
                }
            }
            else if (searchedRegionInfo.isStateProvince) {
                return this.withStateSearch(searchedRegionInfo.region, searchedRegionInfo.getCountry(), searchedRegionInfo.searchTerm);
            }
            else if (searchedRegionInfo.isCountry) {
                return this.withCountrySearch(searchedRegionInfo.region, searchedRegionInfo.searchTerm);
            }
            else {
                return this;
            }
        };

        var generateFilterExpression = function (filterClause) {
            if (!filterClause) {
                return '';
            } else if (typeof filterClause === 'string') {
                return filterClause;
            } else if (typeof filterClause === 'object' && filterClause.joinWith === 'or' || filterClause.joinWith === 'and') {
                var leftSide = generateFilterExpression(filterClause.clause1).trim();
                var rightSide = generateFilterExpression(filterClause.clause2).trim();
                var combinedFilters = [leftSide, rightSide].filter(function (element) {
                    return element && element.length > 0;
                }).join(' ' + filterClause.joinWith.trim() + ' ');
                return filterClause.joinWith === 'or' ? '(' + combinedFilters + ')' : combinedFilters;
            } else {
                return '';
            }
        };

        //todo: maybe add search by agent id / number

        this.buildQuery = function () {
            var baseUrl = this.baseUrl + "?";
            var filterExpression = generateFilterExpression(this.filterClause);
            filterExpression = filterExpression && filterExpression.length ? "$filter=" + filterExpression : "";
            var spatialFilterExpression = generateFilterExpression(this.spatialFilterClause);
            spatialFilterExpression = spatialFilterExpression && spatialFilterExpression.length ? "&spatialFilter=" + spatialFilterExpression : "";
            var options = "&$format=json&jsonp=?";
            var key = "&key=" + bingKey;
            var totalCount = "&$top=" + this.topXLocations;
            if (!filterExpression && !spatialFilterExpression) {
                // there needs to be a filter expression for bing to return any results
                filterExpression = '$filter=true eq true';
            }
            var finalQuery = baseUrl + filterExpression + spatialFilterExpression + options + key + totalCount;
            return finalQuery;
        };

        this.isBlankQuery = function () {
            return !generateFilterExpression(this.filterClause) && !generateFilterExpression(this.spatialFilterClause);
        };

        function allowRequest(isFollowupRequest, searchedRegionInfo) {
            return !isFollowupRequest || (searchedRegionInfo.isPostalRegion || searchedRegionInfo.isCity);
        }

        this.sendRequests = function (gatherResultsForInMemoryFilter) {
            if (!this.baseUrl || !allowRequest(this.isFollowupRequest, this.regionSearchInfo)) {
                return [];
            }

            var isMainQueryBlank = this.isBlankQuery();
            var queryData = [];
            queryData.push({
                query: this.buildQuery(),
                isBlankQuery: isMainQueryBlank
            });

            if (this.additionalRequests && this.additionalRequests.length) {
                queryData = queryData.concat(this.additionalRequests.map(function (additionalRequest) {
                    return {
                        query: additionalRequest.buildQuery(),
                        isBlankQuery: false
                    };
                }));
            }

            var requestData = queryData.map(function (queryDataItem) {
                return bundleRequestWithFilteringIntent($.getJSON(queryDataItem.query), false, queryDataItem.isBlankQuery);
            });

            if (gatherResultsForInMemoryFilter && !isMainQueryBlank) {
                var blankQuery = new bingQueryBuilder(this.baseUrl, this.topXLocations, this.regionSearchInfo, false);
                var allResultsRequests = blankQuery.sendRequests();
                allResultsRequests.forEach(function (req) {
                    req.isClientFilterRequest = true;
                });
                requestData = requestData.concat(allResultsRequests);
            }

            return requestData;
        };
    }

    function getShowroomsByRegion(searchedRegionInfo, isFollowupRequest) {
        // CountryRegion data is missing in this data set - do not filter by it
        var queryBuilder = new bingQueryBuilder(filterTypes.Showrooms.url, 250, searchedRegionInfo, isFollowupRequest, ['CountryRegion'])
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    function getBoundingBoxForCountry(searchedCountryCode) {
        if (!searchedCountryCode) {
            return false;
        }

        var countryBoundingBoxes = getCountryBoundingBoxes();
        var matchingCountryCode = Object.keys(countryBoundingBoxes).find(function (countryCode) {
            return countryCode.toLowerCase() === searchedCountryCode.toLowerCase();
        });

        if (matchingCountryCode) {
            var boundingBox = countryBoundingBoxes[matchingCountryCode];
            return boundingBox;
        }
        else {
            return false;
        }
    }

    function getBoundingBoxForState(searchedStateCode) {
        if (!searchedStateCode) {
            return false;
        }

        var stateBoundingBoxes = getStateBoundingBoxes();
        var matchingStateCode = Object.keys(stateBoundingBoxes).find(function (stateCode) {
            return stateCode === searchedStateCode;
        });

        if (matchingStateCode) {
            var boundingBox = stateBoundingBoxes[matchingStateCode];
            // convert from xMin, yMin, xMax, yMax --> (southLatitude,westLongitude,northLatitude,eastLongitude)
            return [boundingBox[1], boundingBox[0], boundingBox[3], boundingBox[2]];
        }
        else {
            return false;
        }
    }

    // shows hlp non utility
    function getHlpNonUtility(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Non_Utility_Lighting.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();

        return queryBuilder.sendRequests(doesFilterAlreadyHaveAllResults(filterTypes.Non_Utility_Lighting));
    }

    function getRepNonUtility(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Rep_Non_Utility_Lighting.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    function getCanadaAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Canada.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    function getMexicoAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Mexico.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    function getInternationalAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.International.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        if (!queryBuilder.hasSpatialFilter()) {
            queryBuilder = queryBuilder.withAgentSearch(searchedRegionInfo.searchTerm);
        }
        return queryBuilder.sendRequests();
    }

    function getDGLogikAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.DGLogik.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    // shows hlp utility
    function getHlpUtility(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Utility_Lighting.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests(doesFilterAlreadyHaveAllResults(filterTypes.Utility_Lighting));
    }

    function getRepUtility(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Rep_Utility_Lighting.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    // if web address has no 'http' segment, add it to returned string value
    function addHttp(url) {
        if (!/^(f|ht)tps?:\/\//i.test(url)) {
            url = "http://" + url;
        }
        return url;
    }

    // returns true if the input belongs to zipcode or statecode except showroom
    //function filterByRegion(data, searchedRegionInfo) {
    //    if (!searchedRegionInfo) {
    //        return false;
    //    }
    //    else if (searchedRegionInfo && searchedRegionInfo.isStateProvince && searchedRegionInfo.regionCode === data.AdminDistrict.trim().toLowerCase()) {
    //        return true;
    //    }
    //    if (searchedRegionInfo && searchedRegionInfo.isCountry && searchedRegionInfo.regionCode === data.CountryRegion.trim().toLowerCase()) {
    //        return true;
    //    }

    //    var zips = [];
    //    zips = zips.concat(data["PostalCode"]);
    //    if (data["Territory1"]) {
    //        for (var i = 1; i < 21; i++) {
    //            zips = zips.concat(data["Territory" + i].split(';'));
    //        }
    //    }
    //    var input = $('#how-to-buy-2__search-input').val().toLowerCase();
    //    if (!searchedRegionInfo.isStateProvince && !searchedRegionInfo.isCountry) {            
    //        var filteredSpecialChars = data.Business.toLowerCase().replace(/\.|\'|and|\&|\,/g, "");

    //        //replace double space with single space after removing and or &
    //        filteredSpecialChars = filteredSpecialChars.replace("  ", " ");

    //        if (data.Business.toLowerCase().indexOf(input) !== -1) {
    //            return true;
    //        }
    //        else if (filteredSpecialChars.indexOf(input) !== -1) {
    //            return true;
    //        }

    //        if (data.Locality.toLowerCase() === input) {
    //            return true;
    //        }
    //    }
    //    if (data["PostalCode"] && input && data["PostalCode"].slice(0, 3) === input.slice(0, 3)) {
    //        return true;
    //    }
    //    var result = false;
    //    if (searchedRegionInfo.isPostalRegion) {
    //        zips.forEach(function (input) {
    //            if (input === searchedRegionInfo.regionCode) {
    //                result = true;
    //            }
    //        });
    //    }

    //    return result;

    //}

    // geolocate user browser location
    function geoLocate() {
        var etimeout = 0;
        if (navigator.geolocation) {
            etimeout = setTimeout(onError, 10000);
            navigator.geolocation.getCurrentPosition(onSuccess, onError, { timeout: 5000 });
        } else {
            initMapAndSearch({ lat: initLat, lng: initLng }, options.defaultZoom);
            console.log("Geolocation is not supported by this browser.");
        }

        function onSuccess(position) {
            clearTimeout(etimeout);
            showPosition(position);
        }

        function onError(positionError) {
            clearTimeout(etimeout);
            initMapAndSearch({ lat: initLat, lng: initLng }, options.defaultZoom);
            console.log(positionError);
        }
    }

    // helper function used by geolocate to point current position on the map
    function showPosition(position) {
        var userLat = position.coords.latitude;
        var userLng = position.coords.longitude;
        userLatLong.lat = userLat;
        userLatLong.lng = userLng;

        var center = { lat: userLat, lng: userLng };

        initMapAndSearch(center, options.geoZoom);

        //load pins
        loadPinsNearby(userLat, userLng, options.distance);
    }

    // initializing item list bindings
    function initItemListHandlers(filterTypes) {
        $('.items-list', $(scope)).on('click', 'li', function () {
            //open marker
            var id = $(this).data('id').toString();
            $('.items-list li', $(scope)).removeClass('active');
            $(this).addClass('active');

            for (var i = 0; i < markers.length; i++) {
                if (markers[i].title === id) {
                    google.maps.event.trigger(markers[i], 'click');
                    map.setCenter(markers[i].getPosition());
                    break;
                }
            }
        });
    }

    // function used for retrieveing place from textbox upon pressing 'enter' key
    function getPlaceFromTextboxValue(text) {
        deleteMarkers();
        resetSidebar();

        if (service && text && text.length) {
            service.textSearch({
                query: text //,
                // types: options
            }, function (results, status) {
                freeTextSearchCallback(results, status, text);
            });
        }
        else if (!text || !text.length) {
            loadAllJsonDataToView(getSearchedRegionInfo(null, null));
        }
    }

    function getDetailsCallback(results, status, searchTerm) {
        try {
            mostRecentlyFoundGooglePlacesResponse = results;
            loadAllJsonDataToView(getSearchedRegionInfo(results, searchTerm));
        } catch (err) {
            mostRecentlyFoundGooglePlacesResponse = null;
            console.log(err);
        }
    }

    function freeTextSearchCallback(results, status, searchTerm) {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
            if (results && results.length > 0) {
                var result = results[0];

                service.getDetails({
                    placeId: results[0].place_id
                }, function (getDetailsResults, status) {
                    getDetailsCallback(getDetailsResults, status, searchTerm);
                });
            }
            else {
                mostRecentlyFoundGooglePlacesResponse = null;
            }
        }
        else {
            mostRecentlyFoundGooglePlacesResponse = null;
            loadAllJsonDataToView(getSearchedRegionInfo(null, searchTerm));
        }
    }

    function isSearchRegionTypeRelevant(relevantTypes, regionType) {
        return relevantTypes.some(function (supportedRegionType) {
            return supportedRegionType === regionType;
        });
    }

    function getAddressComponentWeight(addressComponent, relevantTypes) {
        var weight = 0;
        var powerOfTen = 1;
        for (var i = relevantTypes.length - 1; i >= 0; i--) {
            if (addressComponent.types.find(function (addressComponentType) {
                return addressComponentType === relevantTypes[i];
            })) {
                weight += powerOfTen;
            }
            powerOfTen = powerOfTen * 10;
        }

        return weight;
    }

    function getGooglePlaceRegionTypeInList(googlePlacesResponse, relevantTypes) {
        if (!googlePlacesResponse || !googlePlacesResponse.address_components) {
            return null;
        }

        var relevantPortions = googlePlacesResponse.address_components.filter(function (addressComponent) {
            return addressComponent.types.some(function (element) {
                return isSearchRegionTypeRelevant(relevantTypes, element);
            });
        });

        var relevantAddressPortionsSorted = relevantPortions.sort(function (element1, element2) {
            return getAddressComponentWeight(element2, relevantTypes) - getAddressComponentWeight(element1, relevantTypes);
        });

        return relevantAddressPortionsSorted && relevantAddressPortionsSorted.length ? relevantAddressPortionsSorted[0] : null;
    }

    function transformPlace(googlePlace, regionType, isMostSpecificSearchRegion) {
        return {
            regionCode: googlePlace.short_name,
            regionName: googlePlace.long_name,
            regionType: regionType,
            isMostSpecificSearchRegion: isMostSpecificSearchRegion
        };
    }

    function getCountry(googlePlacesResponse) {
        var country = getGooglePlaceRegionTypeInList(googlePlacesResponse, ['country']);
        return country ? transformPlace(country, 'country') : null;
    }

    function getState(googlePlacesResponse) {
        var state = getGooglePlaceRegionTypeInList(googlePlacesResponse, ['administrative_area_level_1']);
        return state ? transformPlace(state, 'administrative_area_level_1') : null;
    }

    function isPostalCode(searchTerm) {
        var usPostalCodeRegex = /^\d{5}(?:[-\s]\d{4})?$/;
        var canadaPostalCodeRegex = /^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i;
        return usPostalCodeRegex.test(searchTerm) || canadaPostalCodeRegex.test(searchTerm);
    }

    function getSearchedRegionInfo(googlePlacesResponse, searchTerm) {
        var isSearchTermAPostalCode = isPostalCode(searchTerm);
        var supportedSearchRegionTypesInOrder = isSearchTermAPostalCode ?
            ['postal_code', 'locality', 'administrative_area_level_1', 'country'] :
            ['locality', 'postal_code', 'administrative_area_level_1', 'country'];
        var mostSpecificSearchRegion = getGooglePlaceRegionTypeInList(googlePlacesResponse, supportedSearchRegionTypesInOrder);
        var mostSpecificSearchRegionType = mostSpecificSearchRegion ? mostSpecificSearchRegion.types.find(function (searchRegionType) {
            return isSearchRegionTypeRelevant(supportedSearchRegionTypesInOrder, searchRegionType);
        }) : null;

        var isCountry = mostSpecificSearchRegionType === 'country';
        // Google Places may return zip codes even if they were not what the user was searching for
        var isPostalRegion = mostSpecificSearchRegionType === 'postal_code' && isSearchTermAPostalCode;
        var isStateProvince = mostSpecificSearchRegionType === 'administrative_area_level_1';
        var isCity = mostSpecificSearchRegionType === 'locality';

        var region = mostSpecificSearchRegion ?
            transformPlace(mostSpecificSearchRegion, mostSpecificSearchRegionType, true) :
            null;

        return {
            regionType: mostSpecificSearchRegionType,
            region: region,
            latitude: googlePlacesResponse ? googlePlacesResponse.geometry.location.lat() : null,
            longitude: googlePlacesResponse ? googlePlacesResponse.geometry.location.lng() : null,
            googlePlacesData: googlePlacesResponse,
            isCountry: isCountry,
            isPostalRegion: isPostalRegion,
            isStateProvince: isStateProvince,
            isCity: isCity,
            searchTerm: encodeURIComponent(searchTerm),
            getCountry: function () { return getCountry(googlePlacesResponse); },
            getState: function () { return getState(googlePlacesResponse); },
            loadAll: !googlePlacesResponse && (!searchTerm || !searchTerm.length)
        };
    }

    var clicksWithinLast5Seconds = 0;
    function triggerSendingSelectedFiltersToGoogleAnalytics() {
        clicksWithinLast5Seconds++;
        setTimeout(sendSelectedFiltersToGoogleAnalyticsIfDoneFiltering, 5000);
    }

    // Send an event to Google Analytics if the user hasn't selected filters in the last 5 seconds
    function sendSelectedFiltersToGoogleAnalyticsIfDoneFiltering() {
        if (clicksWithinLast5Seconds > 0) {
            clicksWithinLast5Seconds--;
        }

        if (clicksWithinLast5Seconds > 0) {
            return;
        }

        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Filters Selected: '.concat(
                'Page: "' + window.location.href + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"',
                ' . Search Term: "' + getSearchTerm() + '"'),
            Label: 'How To Buy Filters Selected'
        });
    }

    function getCurrentSearchTerm() {
        return $('#how-to-buy-2__search-input').val();
    }

    function getSelectedFilters() {
        var selectedCheckboxFilter = $(".how-to-buy-2__filters :radio:checked");
        var loadedFilters = [];
        $.each(selectedCheckboxFilter, function (index, filter) {
            loadedFilters.push(filter.value);
        });
        return loadedFilters;
    }

    // initilaize map and bindings based on location source type
    function initMapAndSearch(defaultMapCenter, defaultZoom) {

        var mapContainer = $('.map-container', $(scope)).get(0);

        map = new google.maps.Map(mapContainer, {
            zoom: defaultZoom,
            center: defaultMapCenter
        });

        google.maps.event.addDomListener(window, 'resize', function () {
            //  map.fitBounds(path_bounds);
            map.setCenter(defaultMapCenter);

        });

        service = new google.maps.places.PlacesService(map);

        //if the search is map related (non-agent id based), we will initialize searchbox listeners
        // Create the search box

        function handleSearchInputSubmission() {
            var text = getCurrentSearchTerm();

            getPlaceFromTextboxValue(text);
        }

        //By Agent IDs
        $('#how-to-buy-2__search-input', $(scope)).bind("enterKey", function (e) {
            handleSearchInputSubmission();
        });

        //for click
        $('#map-search-button', $(scope)).bind("click", function (e) {
            handleSearchInputSubmission();
        });

        $('#how-to-buy-2__search-input', $(scope)).keyup(function (e) {
            if (e.keyCode === 13) {
                $(this).trigger("enterKey");
            }
        });

        initItemListHandlers(filterTypes);

        //loadSearchByRegionDataToView(getSelectedFilters(), getSearchedRegionInfo(mostRecentlyFoundGooglePlacesResponse, null));

        var setFilterSelectedStatus = function (modifiedCheckbox) {
            var matchingFilter = Object.values(filterTypes).find(function (filter) {
                return modifiedCheckbox && filter.class === modifiedCheckbox.value;
            });
            if (matchingFilter) {
                matchingFilter.isSelected = modifiedCheckbox.checked;
            }
        };

        $(".how-to-buy-2__filters :radio").click(function () {
            setFilterSelectedStatus(this);
            triggerSendingSelectedFiltersToGoogleAnalytics();
            hideResultMessages();
            var bounds = new google.maps.LatLngBounds();
            loadSearchByRegionDataToView(getSelectedFilters(), getSearchedRegionInfo(mostRecentlyFoundGooglePlacesResponse, getCurrentSearchTerm()));
            if ($(".how-to-buy-2__filters :radio:checked").length == 0) {
                $(".how-to-buy-2__list__addresses> li").hide();

                for (var i = 0; i < markers.length; i++) {
                    markers[i].setVisible(false);
                }
                bounds.extend({ lat: initLat, lng: initLng });
            }
            if ($(".how-to-buy-2__filters :radio:checked").length > 0) {

                $(".how-to-buy-2__list__addresses> li").hide();
                for (var i = 0; i < markers.length; i++) {
                    markers[i].setVisible(false);
                }

                $(".how-to-buy-2__filters :radio:checked").each(function () {
                    $(".how-to-buy-2__list__addresses ." + $(this).val()).show();
                    for (var i = 0; i < markers.length; i++) {
                        if (markers[i].category === $(this).val()) {
                            markers[i].setVisible(true);
                            bounds.extend(markers[i].getPosition());
                        }
                    }
                });
                showMarkers();
                map.fitBounds(bounds);
            }
        });
    }
}
;
var app = app || {};
app.sqlmaps = app.sqlmaps || {};

//for bing readd $ to filter in url
function initSqlMap() {
    var args = app.sqlmaps.data;
    var initLat = 35.8669864;
    var initLng = -78.8548692;
    var map;
    var markers = [];
    var activeInfowindow = null;
    var service;
    var userLatLong = {};
    var agentsById = [];
    var SEARCH_TYPES = { ZIP_CODE: 0, CITY_STATE: 1, AGENCY_NAME: 2, AGENT_ID: 3 };
    var SEARCH_COUNTRY = { AMERICA: 0, CANADA: 1};
    var selectedSearchType = SEARCH_TYPES.ZIP_CODE;
    var selectedSearchCountry = SEARCH_COUNTRY.AMERICA;
    var ZipCityArray = new Array();
    var ZipCityCanadaArray = new Array();
    //Only used for determining when to use radial search for US Agent zip codes
    var previousInput = "";

    var options = {
        initChecked: args.initChecked, key: args.key, defaultZoom: args.defaultZoom, distance: args.distance
    };

    var isFilterEnabledByDefault = function (filterClass) {
        var filterClassLowered = filterClass ? filterClass.toLowerCase() : "";
        return args.DefaultEnabledFilters && args.DefaultEnabledFilters.length && args.DefaultEnabledFilters.some(function (element) {
            return element && element.toLowerCase() === filterClassLowered;
        });
    };

    $.ajaxSetup({
        scriptCharset: "utf-8",
        contentType: "application/json; charset=utf-8"
    });

    var filterTypes = {
        US_Agents: {
            isSelected: isFilterEnabledByDefault('us-agents'),
            name: 'US Agents',
            url: args.USAgentBingServiceEndpoint,
            class: 'us-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAADnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIytbQhFDAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        Showrooms: {
            isSelected: isFilterEnabledByDefault('showrooms'),
            name: 'Showrooms',
            url: args.ShowRoomsBingServiceEndpoint,
            class: 'showrooms',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAK/SURBVFhHrZfNbhMxFIU9maEpElFLUtJUhBVtaWiaghALKrEpCx4EiSfhKXgKXgB2rPiR6I+CEroARmoa0gQoqJtJhnsyHglaX/vO0E8aXdujsU+OfW3Hi+NYSbn/vHqFQn370sP229P36mfwO3nxF5VoTm3ONtWr6HWDquGbp/1fyRs3IjGpiKXxQvvQHySNApqFFbU36YpFOcVoIav0vJs25OMePR2XoIKORi5ICMD3q7o/FqsYok7P/wpJQT/oj4UVg19RHZfbunohbHjLbZs7NmfqfX+oizxL47J67G+pWlTWLTy78ScE1h2jmKkr0bzVFWQK0Tj0h6VnT154vWBYojoWqpVHwQO2X2M2kZg1CuxHLW9F7cTd0tns0FNgXfAL43k18L+f+xYYndkOtqyukJCGqTPd1qGHdYiEIBinyiim4PFLaT2ZnnBaMZAKomlOGjJgHtWyD9YK1XRAFry/O3NL1+QYxcQ2NUKOT0e6JIefD4bepJ8uVBa8/+wf6Zoco5iXyYlrZH/SRWD3ijSjvgU/koYMZHYG3KDT2+SOJLUXaZMkjAnAiQmvRxVdPM9XukZcjmZOaPC1VJRECGgWG2wCsFcIDETBeTZVopKqR1X1JeipkeGyZQB71Edd/gfbNIV0mdJFnuPgRH2YPRAJwc5NsHuU9XIldScDrCvAtYDDPDupifUClhPvCpBcOy/KHasrQJLaYWU8p4v5aHk3EayuAKcYpOGdYlPX8rETHxhP+bNInLHuyC5qSUY6XQEiMUSo0zIzPX8gcgWIxKAzXKh0VcxidBVB5AqQOgNCnZ5ijoKR2BUgFoNO9ycdsTvXxtlcAVmcAeFGkqZOWsXb7IHIkUkMOt+lNNVVK3kyMKszwHmAbnrLCJmmCDiPAxOCI8K59ZvI4wwIub+zrr8yNnI5Ayzu5HJFKaX+ACVzGC8gqwlhAAAAAElFTkSuQmCC'
        },
        Non_Utility_Lighting: {
            isSelected: isFilterEnabledByDefault('non-utility-lighting'),
            name: 'Non Utility Lighting',
            url: args.NonUtilityLightingServiceEndpoint,
            class: 'non-utility-lighting',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAAD8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vztLCaBLAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        Utility_Lighting: {
            isSelected: isFilterEnabledByDefault('utility-lighting'),
            name: 'Utility Lighting',
            url: args.UtilityLightingBingServiceEndpoint,
            class: 'utility-lighting',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAAAAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZnt2EIjAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        Rep_Non_Utility_Lighting: {
            isSelected: isFilterEnabledByDefault('rep-non-utility-lighting'),
            name: 'Rep Non Utility Lighting',
            url: args.RepNonUtilityLightingServiceEndpoint,
            class: 'rep-non-utility-lighting',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAAD8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vzv8vztLCaBLAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        Rep_Utility_Lighting: {
            isSelected: isFilterEnabledByDefault('rep-utility-lighting'),
            name: 'Rep Utility Lighting',
            url: args.RepUtilityLightingBingServiceEndpoint,
            class: 'rep-utility-lighting',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAAAAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZkAXZnt2EIjAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        Canada: {
            isSelected: isFilterEnabledByDefault('canada-agents'),
            name: 'Canada Agents',
            url: args.CanadaBingServiceEndpoint,
            class: 'canada-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVmSURBVFhHnZhrbBRVFMfPzOy2hW5TlErbbcFqFRYsBUrtKoUKbenDYGtFbbLdYPtFgyYawPgBjcZXQkp8oGg0Jo2oiX5oQq0JWiWibUI0gqlWi3yASFvQIKWBPvY5ez3nzkx3uzszO8Mvmczrzp3/nHPuOWdXYIyBXUY+/4JN/PEnXPl7DILXpiEwOweLclyQm3cz5N+2ApaW3g5lPp+gDreMLTE/dR9kw729EBkbBweLgRSLqXfiCIIAs5IDlt1dAd6H26F0l9+yKMti+vx+dv77E5Apy+A0EMHnEpR7AhPheoYT7mxrg5bDhy0JsiTmg5ZWNn36F8gNR9UrhKjuU4VpREQRgg4JVjc2wv09PWkFaTMa0tvuY3OnfoXFXEfi8Bhaw/xDyII54QiMDnwHXz3zdNqvNhUzdKCbnTs5BK5ICCcmNTGI4ffRRlhzsYiujcFIXz9M9Hxs+oCpm15cW8aWTF4FVzTMY4Cg0WT+kCSBZ9MmKKjcCHluN0yOT8Do4CD8NzKMVkTh6nhCxvEBHF9QVQW+vqOG7jIUc/rV19jxDz+C7GgIMvDLCJo0iu+I3JIPO57bByv9u1ImPv7Uk+y3vi8hK5oU6BjYk5mLoO3A6+DpSH2OMHTT8I+DaN4oSAlaowKuEGcmPLp3r64Qov699wVaQQGnxFcYDRJxr1nq0oVxvtdDV8yZzz5ll8+eQXNHFuSSsFMET3MTFHc+pitEg5Zyzh2rYA7zTRStGUPrkwfoZRcvTCiDdNAVI+IEemDkwJotm9Uzcyq3bYMgipFV2UxUDqampvheD/23JgRfMmR6K+TfWszji6nDRXQ3ZYKZqWvKBR1038pAVo/iWFvGca7+exkc6OHkVCSiq40wvENfRPlEE0FBKFm0ChEMhNWj+CtozuzsHPUsFV0xng6/IC52oYUc874mSaLM4PcTP/DzdPz87TG+AAQsqDJ/WiHfXagepWJomQ3bG2AaC50sOOYTXpYcgXMDAzDa3W3qs6O7d7PQ+BhPDZRrcJHzJU64iwrUo1QMxbgxqypvJMdjHcIjSutLgyE4duhd+HrPHl1B3zzxODvf3w/ZEZk/o200mKGb84qK8Egf03LwVl0dk8/+BS4sdrQaNCgTh0RM757VULr5XmDOLGCBWTiFBTH6z0XIiqB7EuKLykdAEmFNU5Np9TYVc/LgG2zonbfhJrSGEVrRTBRLzPc3SAjzDfU2nS+/AkVdxgkzbT/zZmUlc05cwkwsY3dnPlYPEns9IxOKa2vB98kRQyGEYcxobH2wFWawzsTUVWUXEYNfxppW0dCoXjEmrWWIl8rXstwrk9jXJHZ6C6F5krOz0jqI2Dp4TVsHjbSWIWra23n/YoZemaAqT9X7vtYW9Yo5lsQUlZSoR6nwLK3jQroSlgRYUrYOg7YrrVUIS2IoI9+FVXjGiUkQTU8zaxsvgLFUV9MVah/W125VLljAkhiiorYOAg7sT9D09CLaqE/RRMXBbhBzbkhygmtFCVTve3bhbRMsi6GGqvieagg54nPzXIL7hXbBph3dM4fVubq5Wb1mDctiCG/LDoigZZJJXpFhjKFoQSGsf2G/ZasQtsR4/D7BXb4O5hxOnuIJvQCO4HLe8tBO9cw6tsQQdY/shFmnA5Ogck4Ne2LTTlMyQYJly5er59axLaa4s0vIXrkKXaHkHS1mKH7IWtMZEpTX13Ir8gE2sC2GqGqqR1coYuiNtFHcxDCegg5czjU1/J5dLJUDPQ55vUzE30Dxv0aUfx0K0SodR8wLohE3ZBmipqWVB7L2U4QgN21s2K6e2eeGxWx4fr9Q0tjA//JQYkUE7wPNPFurQ2wC8D/fT+lbfdMtXQAAAABJRU5ErkJggg=='
        },
        Mexico: {
            isSelected: isFilterEnabledByDefault('mexico-agents'),
            name: 'Mexico Agents',
            url: args.MexicoBingServiceEndpoint,
            class: 'mexico-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAABv0lEQVRYw8WYzytEURiGnxkzfgwiRk2KYjGxUVJCVixYWYqFnfIXyJIlS6UslD9gpCQb1sIOsaHZkGYnTUxC09ic2Uz3nHvPj3vnrbP5uu/p6dxzvu87J4a5MsAI0Ad0AQXgBbgDvohAcWAR+AAqinEvQENTBnjzgagdJ0DSNcgo8KcJUh3PQLsrkH5DiFqghC1II/DuAKYC5GxhNhSTH4lVi4tvk8A4kFd4hkxBmhWTril8DcCZxHdjCjMtmXA/gDcp8o6XP2UCsyeZLOjJmJX4J1RJTKYxj9gt8BkQ5koSHzCB8dpslxor+61IFdowP5K9EFQxSfzXBObJIzajAdMqiRdMYC48YlkgHRBmXhJ/NDlNWUXx81MKKHp4yyIPaSsGvEqAdhR7okWcOi/flk05mFNk4QdgSuSdJqAbWAZKCk+nbTNVdFQoD120ECuOYHpdwDRaNFbVce6y01u3hBl2CdNmAXIfRkO+awgzGQZMjwFIQZGPrHWsCbMQ5t1pUAOkZJr6dXQdEGY1iivuaACQsigRkSjvA7NJhJr1gemIEiauuGkeUActhVkQdZXweKfJUUelgVPxy7ZtXxr+Abq+az3ocubyAAAAAElFTkSuQmCC'
        },
        DGLogik: {
            isSelected: isFilterEnabledByDefault('dg-logik'),
            name: 'DG Logik',
            url: args.DGLogikServiceEndpoint,
            class: 'dg-logik',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAAAKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNUKkNWuuOBeAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        },
        AgentDistributors: {
            isSelected: isFilterEnabledByDefault('agentdistributors-agents'),
            name: 'Distributors',
            url: args.AgentDistributorServiceEndpoint,
            class: 'agentdistributors-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAABb2lDQ1BpY2MAACiRdZG9S0JRGMZ/2YdhhUMNEQ0OFg0JUhGNYZBLNZhBX4tevRro7XKvEtIatDQIDVFLX0P/Qa1Ba0EQFEFES/9AX0vI7T0qKKHncu774znneTnnOeCay2hZuy0IWSNnRcIh3/LKqs/9jptOOpjAE9Nsc35xNkrT8fNIi6oPAdWr+b6GoyuRtDVo6RSe1EwrJzwtPLeVMxXvCfdp6VhC+ER41JIDCt8qPV7hN8WpCn8ptqKRGXCpnr5UHcfrWEtbWeERYX82k9eq51E36U4aS4tSB2QOYhMhTAgfcfJskCFHQKohmTX2Bcu+BTbFo8nfpIAljhRp8Y6KmpeuSam66En5MhRU7v/ztPXxsUr37hC0vzrO5xC496FUdJzfU8cpnUHrC1wbNf+m5DT1LXqxpvmPwbsDlzc1LX4AV7vQ/2zGrFhZapXp0nX4uICeFei9B89aJavqOudPEN2WJ7qDwyMYlv3e9T/anGf5rZDDpAAAAAlwSFlzAAALEgAACxIB0t1+/AAAASZJREFUWAnVlNENwyAQQ5su0UG6SsfsKhmkU7S6DySEsO/sBKnhJ8mBfQ8Tsd3M8fo8v0j6fuwbmmN1ScQAZk1UqDKMCtLDVaFKMEdAGlQFKIU5A6QKdG8LZ88zQWb+Y43CjIvRd+UIQpttDh5TJkQAri5grWQQSBiyuZhnsBZMmLKRASGtDOM2QgB9XYbpxezdgV4Gw/4NtIllMKghq8swzo4ZQD8nw/Ri9O4C25degMx+0gxkpmmbgjCxIDNuJsqTwSw5JgTHQEJDYTIxaurWKYxrOtNVNpbCVExmzZ1aCuOYjprqhkowVbMRQv0uwaim7np6z4ymzr2jpHrdZCIpJR0llfC+djLVdNRU/i6ZJcfkpGIn4zaLhmycnswRUBvmSFOUzg+Zz1vmN7RuhwAAAABJRU5ErkJggg=='
        },
        International: {
            isSelected: isFilterEnabledByDefault('international-agents'),
            name: 'International Agents',
            url: args.InternationalBingServiceEndpoint,
            class: 'international-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAANjSURBVFhHtZc9aBRBFMdndy5fhDQKYkAsgwgpJIhFECxUNJJG0CKmsokfhQQLFcSgWGg6L0QMfhDQHFiIASMRDKKEhIBsoRYiSKwEiSAK5uOyt7P+n/cC7s3O7uzG/OCY92Y3m//8583bO0dk5GbPyBYMHUuy0F0uyDYlnM3Im/H56YbhQnPF/1iv1Cvk3oVS3wJGa6zFkIhQiLNlKU82BsE2njayIuUc7ruG0FqUlRgSsuq6o1jxYZ6yRglRcoXotxGUKoaEYJUTWOVunspM4DhPZBieSRMkeYyFhJRdd6xRqb08lQs4sxNb3HqgvXtm6sPEIk9r4D4zWNG5BqX2c7ousAW9GDqqWTzGbeI6mUed0EmJBa5N4fosHjKH2uhEcXc1BcEuvqyB7Z7Bdh81bZfRmYrj9JuElF35A0MXXDtxsdQ3gIdPXir1XYaQQ9iOR9W7dCCkE4PRnVgx5IrvyiOcajSooJcE1K6Qcrh0nk4QT2n4jruPQw2TMx1NQaWd4wh0MjB41UyHBOGh/ctSfuKpCIt1dTs41Egs4DhwRO/XOlILXa9TapzTCFjMVg41MouxpRCGbzisZROPGhsmBuzhsZYKjxobJgZtwdQSfvGoYRLjoeqXOI7gu+5pOm2cxkLXleMc5zQCaukLhxqxYqgAVwqSTo0GHtaN4aBJEM2jRw2hp2znqQgt/upnDjWM29Ti+/McxvEQn8FaQZQHwimieGNdIdCHZjnUSHwdoFdMo6u28ZTGsiy8l6F6ieO+iu2jGjkGR1qrV3Xg2FMIPWVqDUYxxI2ekau44Qqn/4MuCJnkWCPxNEHIMF5u3zhdFzhdLzAYOzeRKIY76QNO1wVeukXT9qyRKIZAPdzCqn5zmgu4S0Wb6AqRKoZXc6ea5QNFfT3NFSJVDAGL6adHLuDKOwyprhBWYoCHo/uc40zAlXEbVwgrMVzIw5xagz5Frf92NUvH1hnCw9fN1xxbAVfGbF0hrMXQQ/F1c5DTVFAr39Gnhji1IoszhId/8pbjRLCt97K4QmQSQw+H9QOcJoL+NM2hNVmdITzTl+016IWIweo4/0tmMezOY05jwZv5btYtIvI4s/YC/cppBJsXoolcYmjV9UEwymkEmxeiiVxiCPxhEV35Gad/4Z+2uVwRQog/ultUIbWsTqEAAAAASUVORK5CYII='
        }
    };

    var scope = ('#how-to-buy-container');

    var urlString = options.data;
    var initCheckedBoolean = /^true$/i.test(options.initChecked);

    //load city zip code map
    function loadCityZipArray() {
        getData('/assets/json/zip-cities-3.json.txt').then(function (data) {
            ZipCityArray = eval(data);
        });
        getData('/assets/json/zip-cities-canada-2.json.txt').then(function (data) {
            ZipCityCanadaArray = eval(data);
        });
    }
    loadCityZipArray();

    // if geolocate is enabled
    if (initCheckedBoolean) {
        geoLocate();
    } else {
        initMapAndSearch({ lat: initLat, lng: initLng }, options.defaultZoom);
    }

    function isEmpty(obj) {
        return Object.keys(obj).length === 0;
    }

    var setFilterSelectedStatus = function (modifiedCheckbox) {
        var matchingFilter = Object.values(filterTypes).find(function (filter) {
            return modifiedCheckbox && filter.class === modifiedCheckbox.value;
        });
        if (matchingFilter) {
            Object.values(filterTypes).forEach(function (filter) {
                filter.isSelected = false;
            });
            matchingFilter.isSelected = modifiedCheckbox.checked;
        }
    };

    function handleSearchInputSubmission() {
        var text = getSearchTermAsString();

        getPlaceFromTextboxValue(text);
    }

    // created functions
    $(function () {
        $("input[name='howToBuyMap']").click(function () {
            hideAllSearchboxes();
            hideResultMessages();
            selectedSearchType = SEARCH_TYPES.ZIP_CODE;
            setFilterSelectedStatus(this);

            var checkedButton = document.querySelector('input[name="howToBuyMap"]:checked').value;
            if (checkedButton) {
                $(".how-to-buy-2__search .form-control").removeAttr("disabled");
                $("#how-to-buy-2__search-input-radius").hide();
                if (checkedButton === "us-agents") {
                    $(".how-to-buy-2__search .dropdown button").removeAttr("disabled");
                    $("#search-type-zip").show();
                    $("#search-type-postal").hide();
                    $("#search-type-city-state").show();
                    $("#search-type-agent-id").show();
                    $("#search-type-city-province").hide();
                    $("#dropdown-search-type").show();

                    $("#dropdownSearchTypeButton").text("Search By");
                } else if (checkedButton === "canada-agents") {
                    $(".how-to-buy-2__search .dropdown button").removeAttr("disabled");
                    $("#search-type-zip").hide();
                    $("#search-type-postal").show();
                    $("#search-type-city-state").hide();
                    $("#search-type-agent-id").show();
                    $("#search-type-city-province").show();
                    $("#dropdown-search-type").show();

                    $("#dropdownSearchTypeButton").text("Search By");
                } else if (checkedButton === "agentdistributors-agents" || checkedButton === "showrooms") {
                    $(".how-to-buy-2__search .dropdown button").removeAttr("disabled");
                    $("#search-type-zip").show();
                    $("#search-type-postal").hide();
                    $("#search-type-city-state").show();
                    $("#search-type-city-province").show();
                    $("#search-type-agent-id").hide();
                    $("#dropdown-search-type").show();

                    $("#dropdownSearchTypeButton").text("Search By");
                } else {
                    $(".how-to-buy-2__search .dropdown button").attr("disabled", "disabled");
                    $("#dropdown-search-type").hide();
                    if (checkedButton === "international-agents") {
                        $("#generic-searchbox").hide();
                        $("#map-search-button").hide();
                    } else {
                        $("#generic-searchbox").show();
                        $("#map-search-button").show();
                    }
                }
            } else {
                $(".how-to-buy-2__search .form-control").attr("disabled", "disabled");
                $(".how-to-buy-2__search .dropdown button").attr("disabled", "disabled");
            }

            triggerSendingSelectedFiltersToGoogleAnalytics();
            var bounds = new google.maps.LatLngBounds();
            handleSearchInputSubmission();
            if ($(".how-to-buy-2__filters :radio:checked").length == 0) {
                $(".how-to-buy-2__list__addresses> li").hide();

                for (var i = 0; i < markers.length; i++) {
                    markers[i].setVisible(false);
                }
                bounds.extend({ lat: initLat, lng: initLng });
            }
            if ($(".how-to-buy-2__filters :radio:checked").length > 0) {

                $(".how-to-buy-2__list__addresses> li").hide();
                for (var i = 0; i < markers.length; i++) {
                    markers[i].setVisible(false);
                }

                $(".how-to-buy-2__filters :radio:checked").each(function () {
                    $(".how-to-buy-2__list__addresses ." + $(this).val()).show();
                    for (var i = 0; i < markers.length; i++) {
                        if (markers[i].category === $(this).val()) {
                            markers[i].setVisible(true);
                            bounds.extend(markers[i].getPosition());
                        }
                    }
                });
                showMarkers();
                map.fitBounds(bounds);
            }
        });
    });

    $(function () {
        $('.fa-info-circle').click(function () {
            var infoBoxString = this.dataset.tooltip;
            var infoBoxes = $("#" + infoBoxString);
            var infoBox = infoBoxes[0];
            if (infoBox && infoBox.className == 'tooltip-text-hidden') {
                infoBox.className = 'tooltip-text-shown';
            }
            else {
                infoBox.className = 'tooltip-text-hidden';
            }

        });
    });

    function createDirectionLink(address) {
        var encodeUrl = encodeURI(address);
        if (isEmpty(userLatLong)) {
            return "https://www.google.com/maps/dir/?api=1&destination=" + encodeUrl;
        }
        return "https://www.google.com/maps/dir/?api=1&origin=" + userLatLong.lat + "," + userLatLong.lng + "&destination=" + encodeUrl;
    }

    // builds infowindows, attaches event listeners, adds markers and init sidebar 
    function buildStoreInfoContent(result, markerZIndex, filterType, loadAll) {
        var hasDodgeCodes = result.DodgeCodes !== undefined && filterType !== undefined && filterType.name === "US Agents";

        if (hasDodgeCodes) {
            var dodgeCodes = result.DodgeCodes.split(';');
        }

        if (!hasDodgeCodes || (dodgeCodes.length > 1 && !dodgeCodes.includes("0"))) {
            var infoContent;
            var id = (Math.floor(Math.random() * (1000 - 1 + 1) + 1)).toString(),
                business = result.Business,
                address1 = result.AddressLine1,
                address2 = result.AddressLine2,
                city = result.Locality,
                state = result.AdminDistrict,
                zip = result.PostalCode,
                country = result.CountryRegion ? result.CountryRegion : '',
                salesId = result.SalesId,
                salesPhone = result.Phone,
                salesWeb = result.Web,
                salesAgentName = result.AgentName;
            var infoLinks;
            var concatAddress = $.grep([address1, address2], Boolean).join(", ");
            var cityStateZip = city + ', ' + state + ' ' + zip + ' ' + country;
            var selectedFilter = filterType;

            infoContent = "<li class='gm-style " + selectedFilter.class + "'" + "data-id='" + id + ">'";
            infoContent += "<div class='place-name'>" + business + "</div>";
            if (typeof city === 'undefined' || city == "") {
                cityStateZip = "";
            }
            infoContent += "<div class='address'>" + concatAddress + ", " + cityStateZip + "</div>";


            var listContent = "<li data-id='" + id + "' class='" + selectedFilter.class + "'>";
            listContent += "<a href='#' onclick='return false;' class='list-business-name'>" + business + "</a>";
            listContent += "<p>" + concatAddress + "</p>";
            if (cityStateZip !== "") {
                listContent += "<p>" + cityStateZip + "</p>";
            }

            if ((selectedFilter.name === "US Agents" || selectedFilter.name === "International Agents" || selectedFilter.name === "Canada Agents") && typeof salesId !== 'undefined') {
                listContent += "<p>Agent #: " + salesId + "</p>";
                infoContent += "<div class='address'>Agent #: " + salesId + "</div>";
            }

            if (salesWeb !== "" && typeof salesWeb !== 'undefined') {
                if (salesWeb.indexOf("@") > -1) {
                    listContent += "<p><a href='mailto:" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='mailto:" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";
                } else if (salesWeb.indexOf("http") > -1) {
                    listContent += "<p><a href='" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";

                } else {
                    listContent += "<p><a href='http://" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='http://" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";

                }
            }

            if (salesPhone !== "" && typeof salesPhone !== 'undefined') {
                listContent += "<p>" + salesPhone + "</p>";
                infoContent += "<div class='address'>" + salesPhone + "</div>";
            }

            if (salesAgentName !== "" && typeof salesAgentName !== 'undefined') {
                listContent += "<p> Agent: " + salesAgentName + "</p>";
                infoContent += "<div class='address'> Agent: " + salesAgentName + "</div>";
            }

            listContent += "</li>";
            infoContent += "</li></div></div>";
            var address = concatAddress + ", " + cityStateZip;
            infoLinks = "<div class='navigate'>";
            infoLinks += "<a target='_blank' href='" + createDirectionLink(address) + "' class='navigate-link'>";
            infoLinks += "<div class='navigate-tex'>  Get Direction </div></a></div>";

            var info = new google.maps.InfoWindow({
                content: infoContent + infoLinks,
                maxWidth: 400
            });

            addMarker(result, info, id, selectedFilter, markerZIndex);
            if (!loadAll)
                appendItemListMarkup(listContent);
        }
    }

    // closes active info window
    function closeActiveInfowindows() {
        if (activeInfowindow != null) {
            activeInfowindow.close();
        }
    }

    // Adds a marker to the map and push to the array.
    function addMarker(result, info, id, selectedFilter, markerZIndex) {
        var marker = new google.maps.Marker({
            position: { lat: parseFloat(result.Latitude), lng: parseFloat(result.Longitude) },
            map: map,
            animation: google.maps.Animation.DROP,
            title: id,
            icon: selectedFilter.icon,
            category: selectedFilter.class,
            zIndex: markerZIndex ? markerZIndex : undefined
        });
        marker.addListener('click', function () {
            closeActiveInfowindows();
            highlightListing(marker, info);
            info.open(map, marker);
            activeInfowindow = info;

            sendMarkerClickEventToGoogleAnalytics(marker, result.Business);
        });
        map.addListener('click', function () {
            info.close();
        });
        markers.push(marker);
    }

    // Sets the map on all markers in the array.
    function setMapOnAll(mapValue) {
        for (var i = 0; i < markers.length; i++) {
            markers[i].setMap(mapValue);
        }
    }

    // Removes the markers from the map, but keeps them in the array.
    function clearMarkers() {
        setMapOnAll(null);
    }

    // Shows any markers currently in the array.
    function showMarkers() {
        setMapOnAll(map);

        if (markers.length > 1) {
            var bounds = new google.maps.LatLngBounds();
            markers.forEach(function (marker) {
                bounds.extend(new google.maps.LatLng(marker.position.lat(), marker.position.lng()));
            });
            map.fitBounds(bounds);

        } else if (markers.length === 1) {
            zoomHere(markers[0]);
        }
    }

    // Deletes all markers in the array by removing references to them.
    function deleteMarkers() {
        clearMarkers();
        markers = [];
    }

    // Zoom '15' for selected marker
    function zoomHere(marker) {
        map.setZoom(15);
        map.panTo(marker.position);
    }

    // Clear items sidebar
    function resetSidebar() {
        $('.items-list', $(scope)).empty();
    }

    // append list items markup
    function appendItemListMarkup(listing) {
        hideSpinner();
        $('.items-list', $(scope)).append(listing);
    }

    // helper method used for marker click bind event
    function highlightListing(marker) {
        var thisId = marker.title;
        $('.items-list li', $(scope)).each(function () {
            if ($(this).attr('data-id') === thisId) {
                $('.items-list li', $(scope)).removeClass('active');
                $(this).addClass('active');
            }
        });
    }

    function getUrlPiecesFromDataFolderString(string) {
        if (string.indexOf(",") !== -1) {
            return string.split(",");
        }
        else {
            return [string];
        }
    }

    // shows pins nearby passed lat and lng
    function loadPinsNearby(lat, lng, distance) {
        distance = distance !== "" ? distance : 100;
        var urlPieces = getUrlPiecesFromDataFolderString(urlString);
        for (x in urlPieces) {
            var urlPiece = urlPieces[x];
            var baseUrl = "https://spatial.virtualearth.net/REST/v1/data/" + urlPiece + "?";
            var filter = "spatialFilter=nearby(" + lat + "," + lng + "," + distance + ")";

            var url = baseUrl + filter ;
            loadPinsFromUrl(url);
        }
    }

    // loads pins by calling getJSON function for passed url
    function loadPinsFromUrl(url, filterFunc, filterArgs) {
        hideResultMessages();
        $.getJSON(url, function (data) {
            $.each(data["d"].results, function (key, value) {

                //filter pins and check if the search type belongs 
                if (typeof (filterFunc) === 'function') {
                    if (!filterFunc.call(this, value, filterArgs, filterArgs2))
                        return true;
                }
                buildStoreInfoContent(value[0]);
            });

            if (markers.length > 0) {
                hideResultMessages();
                showMarkers();
            } else {
                resetSidebar();
                showNoResultsText();
            }
        });
    }

    function showSpinner() {
        $('.how-to-buy-2__list__addresses', $(scope)).html('<i class="fa fa-spinner fa-spin"></i>');
    }

    function hideSpinner() {
        $('.how-to-buy-2__list__addresses .fa-spinner', $(scope)).remove();
    }

    function hideAllSearchboxes() {
        deleteMarkers();
        hideResultMessages();
        resetSidebar();

        $("#generic-searchbox").hide();
        $("#generic-searchbox input").val("");
        $("#zip-code-searchbox").hide();
        $("#zip-code-searchbox input").val("");
        $("#postal-code-searchbox").hide();
        $("#postal-code-searchbox input").val("");
        $("#city-state-searchbox").hide();
        $("#city-state-searchbox input").val("");
        $("#agency-name-searchbox").hide();
        $("#agency-name-searchbox input").val("");
        $("#agent-id-searchbox").hide();
        $("#agent-id-searchbox input").val("");
        $("#city-province-searchbox").hide();
        $("#city-province-searchbox input").val("");

        $("#how-to-buy-2__search-input-radius").hide();
        $("#map-search-button").hide();
    }

    function displayFilterType(checkBoxfilterArr, filterType, searchedRegionInfo, markerZIndex) {
        var hasAnyFilteredResults = false;
        var isFilterTypeSelected = checkBoxfilterArr.find(function (element) {
            return element == filterType.class;
        });
        if (isFilterTypeSelected !== undefined) {
            var uniqueArr = [];
            $.each(filterType.data,
                function (index, data) {
                    var matchingItems = $.grep(uniqueArr, function (item) {
                        return item.Business === data.Business && item.AddressLine1 === data.AddressLine1
                            && item.AddressLine2 === data.AddressLine2 && item.AddressLine3 === data.AddressLine3
                            && item.Web === data.Web;
                    });
                    if (matchingItems.length === 0) {
                        buildStoreInfoContent(data, markerZIndex, filterType, searchedRegionInfo.loadAll);
                        hasAnyFilteredResults = true;
                        uniqueArr.push(data);
                    }
                });
        }
        return hasAnyFilteredResults;
    }

    function getSearchTermAsString() {
        var searchterm = getCurrentSearchTerm();
        if (searchterm.city || searchterm.state)
            return searchterm.city + ", " + searchterm.state;
        return searchterm;
    }

    function getSelectedFiltersAsString() {
        var selectedFilterTypes = $(".how-to-buy-2__filters :radio:checked").map(function (index, element) {
            return element.value;
        }).toArray();
        var selectedCheckboxFilterTypes = $(".how-to-buy-2__filters :checkbox:checked").map(function (index, element) {
            return element.value;
        }).toArray();
        var allSelectedFilterTypes = selectedFilterTypes.concat(selectedCheckboxFilterTypes);
        return allSelectedFilterTypes.join(', ');
    }

    function sendNoResultsDataToGoogleAnalytics() {
        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Search - No Results Found - '.concat(
                'Page: "' + window.location.href + '"',
                ' . Search Term: "' + getSearchTermAsString() + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"'),
            Label: 'How To Buy Search - No Results Found'
        });
    }

    function sendMarkerClickEventToGoogleAnalytics(marker, businessName) {
        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Map Click - '.concat(
                'Page: "' + window.location.href + '"',
                ' Business: "' + businessName + '"',
                ' . Search Term: "' + getSearchTermAsString() + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"'),
            Label: 'How To Buy Map Click'
        });
    }

    function clearStoredFilterData() {
        Object.values(filterTypes).forEach(function (filterValue) {
            filterValue.allFilterData = [];
            filterValue.wasRadialSearchPerformed = false;
        });
    }

    function loadSearchByRegionDataToView(checkBoxfilterArr, searchedRegionInfo) {
        var generateMapEntry = function (requestFunc, filterToPopulate, optionalFilterFunc) {
            return {
                requestFunc: requestFunc,
                filter: filterToPopulate,
                optionalFilterFunc: optionalFilterFunc
            };
        };

        clearStoredFilterData();

        var getShowRoomData = function (isFollowupRequest) { return getShowroomsByRegion(searchedRegionInfo, isFollowupRequest); };
        var getHlpNonUtilityData = function (isFollowupRequest) { return getHlpNonUtility(searchedRegionInfo, isFollowupRequest); };
        var getRepNonUtilityData = function (isFollowupRequest) { return getRepNonUtility(searchedRegionInfo, isFollowupRequest); };
        var getUsAgentData = function (isFollowupRequest) { return getUSAgents(searchedRegionInfo, isFollowupRequest); };
        var getHlpUtilityData = function (isFollowupRequest) { return getHlpUtility(searchedRegionInfo, isFollowupRequest); };
        var getRepUtilityData = function (isFollowupRequest) { return getRepUtility(searchedRegionInfo, isFollowupRequest); };
        var getCanadaData = function (isFollowupRequest) { return getCanadaAgents(searchedRegionInfo, isFollowupRequest); };
        var getMexicoData = function (isFollowupRequest) { return getMexicoAgents(searchedRegionInfo, isFollowupRequest); };
        var getDistributorData = function (isFollowupRequest) { return getDistributors(searchedRegionInfo, isFollowupRequest); };
        var getInternationalData = function (isFollowupRequest) { return getInternationalAgents(searchedRegionInfo, isFollowupRequest); };
        var getDgLogikData = function (isFollowupRequest) { return getDGLogikAgents(searchedRegionInfo, isFollowupRequest); };

        var internationalDataFilterFunc = function (data) {
            if (agentsById.length > 0) {
                var index = data.map(function (e) { return e.Id; }).indexOf(agentsById[0].Id);
                if (index !== -1) {
                    data.splice(index, 1);
                }
            }

            filterTypes.International.data = data;
        };

        var requestDataMap = [
            generateMapEntry(getHlpNonUtilityData, filterTypes.Non_Utility_Lighting),
            generateMapEntry(getRepNonUtilityData, filterTypes.Rep_Non_Utility_Lighting),
            generateMapEntry(getUsAgentData, filterTypes.US_Agents),
            generateMapEntry(getHlpUtilityData, filterTypes.Utility_Lighting),
            generateMapEntry(getRepUtilityData, filterTypes.Rep_Utility_Lighting),
            generateMapEntry(getCanadaData, filterTypes.Canada),
            generateMapEntry(getMexicoData, filterTypes.Mexico),
            generateMapEntry(getDistributorData, filterTypes.AgentDistributors),
            generateMapEntry(getShowRoomData, filterTypes.Showrooms),
            generateMapEntry(getDgLogikData, filterTypes.DGLogik),
            generateMapEntry(getInternationalData, filterTypes.International, internationalDataFilterFunc)
        ].filter(function (requestData) {
            // only send new requests when the filter is selected and the search term has changed since the last request
            return requestData.filter.isSelected && requestData.filter.hasResultsForSearchTerm !== searchedRegionInfo.searchTerm;
        });

        var updateFilterDataFromResponse = function (responseData, filter, isFollowupRequestData) {
            if (responseData && responseData.length) {
                if (selectedSearchType == SEARCH_TYPES.CITY_STATE && getSearchTermAsString().length > 0 && filterTypes.US_Agents.isSelected) {
                    searchedLocation = getCurrentSearchTerm();

                    var cityZips = ZipCityArray.filter(function (o) {
                        return (searchedLocation.city.toUpperCase() === o.primary_city.toUpperCase() && searchedLocation.state === o.state);
                    }).map(function (a) { return a.zip; });

                    responseData = responseData.filter(function (element) {
                        var allTerritoryZipCodes = "";
                        if (element["Territory1"]) {
                            for (var i = 1; i < 21; i++) {
                                if (element["Territory" + i]) {
                                    allTerritoryZipCodes = allTerritoryZipCodes.concat(element["Territory" + i]);
                                    allTerritoryZipCodes += ";";
                                }
                            }
                        }
                        return cityZips.find(function (zip) {
                            return allTerritoryZipCodes.includes(zip);
                        });
                    });
                }

                if (filter.optionalFilterFunc) {
                    filter.optionalFilterFunc(responseData);
                }
                else {
                    filter.allFilterData = filter.allFilterData.concat(responseData);
                }

                if (isFollowupRequestData) {
                    filter.wasRadialSearchPerformed = true;
                }
            }
        };

        var storeResultsForInMemoryFilter = function (responseData, filter) {
            if (responseData && responseData.length) {
                filter.allResultsForDataSource = responseData;
            }
        };

        var promisesForAllFilters = [];

        requestDataMap.forEach(function (element) {
            var executedRequestData = element.requestFunc();
            executedRequestData = executedRequestData && Array.isArray(executedRequestData) ? executedRequestData : [executedRequestData];

            var requestSuccessHandler = function (responseData, requestItem) {
                var processResultsAsFilteredByServer = !requestItem.isClientFilterRequest;
                var processResultsAsClientFilter = requestItem.isClientFilterRequest || requestItem.isBlankQuery;
                if (processResultsAsFilteredByServer) {
                    updateFilterDataFromResponse(responseData, element.filter);
                }
                if (processResultsAsClientFilter) {
                    storeResultsForInMemoryFilter(responseData, element.filter);
                }
            };

            var failureHandler = function (responseData, failedFilterClass) {
                console.log('Request for ' + failedFilterClass + ' failed.');
            };

            var createDeferredPromiseForRequest = function (request) {
                return request ? $.Deferred() : null;
            };

            var primaryRequestsWithDeferred = executedRequestData.map(function (requestItem) {
                return {
                    requestItem: requestItem,
                    deferredPromise: createDeferredPromiseForRequest(requestItem.request)
                };
            });

            primaryRequestsWithDeferred.forEach(function (requestWithDeferredPromise) {
                requestWithDeferredPromise.requestItem.request.done(function (responseData) {
                    requestSuccessHandler(responseData, requestWithDeferredPromise.requestItem);
                    requestWithDeferredPromise.deferredPromise.resolve();
                }).fail(function (failureData) {
                    failureHandler(failureData, element.filter.class);
                    requestWithDeferredPromise.deferredPromise.resolve();
                });
            });

            var deferredPromises = primaryRequestsWithDeferred.map(function (req) {
                return req.deferredPromise;
            });

            // aggregate results when the requests for this particular filter are finished
            var promiseForThisFilter = $.when.apply($, deferredPromises);
            promisesForAllFilters.push(promiseForThisFilter);
            promiseForThisFilter.done(function () {
                // attempt to run a wider search if there were no results for the user's search

                if (element.filter.allFilterData.length === 0) {
                    var followupRequestData = element.requestFunc(true);
                    followupRequestData = followupRequestData && Array.isArray(followupRequestData) ? followupRequestData : [followupRequestData];

                    var followupRequestsWithDeferred = followupRequestData.map(function (requestItem) {
                        return {
                            requestItem: requestItem,
                            deferredPromise: createDeferredPromiseForRequest(requestItem.request)
                        };
                    });

                    followupRequestsWithDeferred.forEach(function (followupRequestWithDeferred) {
                        followupRequestWithDeferred.requestItem.request.done(function (followupResponseData) {
                            updateFilterDataFromResponse(followupResponseData, element.filter, true);
                            followupRequestWithDeferred.deferredPromise.resolve();
                        }).fail(function (failureData) {
                            failureHandler(failureData, element.filter.class);
                            followupRequestWithDeferred.deferredPromise.resolve();
                        });
                    });

                    var followupDeferredPromises = followupRequestsWithDeferred.map(function (requestWithDeferredPromise) {
                        return requestWithDeferredPromise.deferredPromise;
                    });

                    var followupPromise = $.when.apply($, followupDeferredPromises);
                    followupPromise.done(function () {
                        element.filter.data = element.filter.allFilterData;
                    });

                    element.followupPromise = followupPromise;
                }
                else {
                    element.filter.data = element.filter.allFilterData;
                }
            });
        });

        // decide what to display when ALL of the requests are finished and results are processed
        $.when.apply($, promisesForAllFilters).done(
            function () {

                var followupPromises = requestDataMap.filter(function (requestMapEntry) {
                    return requestMapEntry.followupPromise;
                }).map(function (requestMapEntry) {
                    return requestMapEntry.followupPromise;
                });

                if (followupPromises && followupPromises.length) {
                    $.when.apply($, followupPromises).done(
                        function () {
                            processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo);
                        });
                } else {
                    processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo);
                }
            }
        );
    }


    function wasRadialSearchPerformed(filterTypes) {
        return Object.values(filterTypes).some(function (filter) {
            return filter && filter.data && filter.data.length && filter.wasRadialSearchPerformed;
        });
    };

    function processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo) {
        deleteMarkers();
        if (checkBoxfilterArr.length == 0) {
            hideSpinner();

            showNoResultsText();
        }

        var usResults = displayFilterType(checkBoxfilterArr, filterTypes.US_Agents, searchedRegionInfo, 990);
        var nonUtilResults = displayFilterType(checkBoxfilterArr, filterTypes.Non_Utility_Lighting, searchedRegionInfo, 980);
        var utilResults = displayFilterType(checkBoxfilterArr, filterTypes.Utility_Lighting, searchedRegionInfo, 970);
        var repNonUtilResults = displayFilterType(checkBoxfilterArr, filterTypes.Rep_Non_Utility_Lighting, searchedRegionInfo, 980);
        var repUtilResults = displayFilterType(checkBoxfilterArr, filterTypes.Rep_Utility_Lighting, searchedRegionInfo, 970);
        var canadaResults = displayFilterType(checkBoxfilterArr, filterTypes.Canada, searchedRegionInfo, 960);
        var mexicoResults = displayFilterType(checkBoxfilterArr, filterTypes.Mexico, searchedRegionInfo, 960);
        var internationalResults = displayFilterType(checkBoxfilterArr, filterTypes.International, searchedRegionInfo, 950);
        var dgResults = displayFilterType(checkBoxfilterArr, filterTypes.DGLogik, searchedRegionInfo, 940);

        var showroomResults = displayFilterType(checkBoxfilterArr, filterTypes.Showrooms, searchedRegionInfo, 980);
        var distributorResults = displayFilterType(checkBoxfilterArr, filterTypes.AgentDistributors, searchedRegionInfo, 980);

        var hasAnyFilteredResults = usResults || nonUtilResults || utilResults || repNonUtilResults || repUtilResults || canadaResults
            || mexicoResults || distributorResults || internationalResults || dgResults || showroomResults;

        hideSpinner();

        var hasAnyResults = hasAnyFilteredResults || $(".how-to-buy-2__list__addresses li").length > 0;
        if (hasAnyFilteredResults && filterTypes.US_Agents.isSelected && filterTypes.US_Agents.hasTerritoryMatch) {
            showUSAgentTerritoryMatchMessage();
        }
        else if(filterTypes.International.isSelected){
            showInternationalMessage();
        }
        else if (hasAnyResults && wasRadialSearchPerformed(filterTypes)) {
            if (filterTypes.US_Agents.isSelected && searchedRegionInfo.isPostalRegion) {
                showUSAgentRadialSearchMessage();
            }
            else {
                showRadialSearchMessage();
            }
        } else if (!hasAnyResults) {
            if (filterTypes.AgentDistributors.isSelected
                && (selectedSearchType == SEARCH_TYPES.ZIP_CODE || selectedSearchType == SEARCH_TYPES.CITY_STATE))
                showNoResultsDistributorText();
            else if (filterTypes.Showrooms.isSelected
                && (selectedSearchType == SEARCH_TYPES.ZIP_CODE || selectedSearchType == SEARCH_TYPES.CITY_STATE))
                showNoResultsShowroomText();
            else if (filterTypes.Mexico.isSelected)
                showNoResultsMexicoText();
            else if (filterTypes.US_Agents.isSelected && selectedSearchType == SEARCH_TYPES.ZIP_CODE) {
                showNoResultsUSZipText();
                $("#how-to-buy-2__search-input-radius").show();
                previousInput = getCurrentSearchTerm();
            }else
                showNoResultsText();
        }

        if (!hasAnyFilteredResults) {
            sendNoResultsDataToGoogleAnalytics();
        }

        showMarkers();
    }

    function showSearchTips() {
        hideResultMessages()
        $('.no-results-found-search-tips', $(scope)).show();
    }

    function showNoResultsText() {
        hideResultMessages()
        $('.no-results-found', $(scope)).show();
    }

    function showNoResultsDistributorText() {
        hideResultMessages()
        $('.no-results-found-distributor', $(scope)).show();
    }

    function showNoResultsShowroomText() {
        hideResultMessages()
        $('.no-results-found-showroom', $(scope)).show();
    }

    function showNoResultsMexicoText() {
        hideResultMessages()
        $('.no-results-found-mexico', $(scope)).show();
    }

    function showNoResultsUSZipText() {
        hideResultMessages()
        $('.no-results-found-uszip', $(scope)).show();
    }

    function showIncorrectFormatText() {
        hideResultMessages()
        $('.incorrect-format', $(scope)).show();
    }

    function showInvalidRadiusText() {
        hideResultMessages()
        $('.invalid-radius', $(scope)).show();
    }

    function showRadialSearchMessage() {
        hideResultMessages()
        $('.found-results-radial-search', $(scope)).show();
    }

    function showUSAgentRadialSearchMessage() {
        hideResultMessages()
        $('.found-results-radial-search-us-agents', $(scope)).show();
    }

    function showUSAgentTerritoryMatchMessage() {
        hideResultMessages()
        $('.found-us-agent-by-territory', $(scope)).show();
    }

    function showInternationalMessage() {
        hideResultMessages()
        $('.international-instructions', $(scope)).show();
    }

    function hideResultMessages() {
        $('.how-to-buy-search-result-indicator', $(scope)).hide();
    }

    function getCountryBoundingBoxes() {
        return {

            aw: [12.1702998, -70.2809842, 12.8102998, -69.6409842],
            af: [29.3772, 60.5176034, 38.4910682, 74.889862],
            ao: [-18.038945, 11.4609793, -4.3880634, 24.0878856],
            ai: [18.0615454, -63.6391992, 18.7951194, -62.7125449],
            //ALA: [59.4541578, 19.0832098, 60.87665, 21.3456556],
            al: [11.081041, -72.6598913, 11.408791, -72.4039128],
            ad: [42.4288238, 1.4135781, 42.6559357, 1.7863837],
            //ANT: [12.1544542, -68.940593, 12.1547472, -68.9403518],
            ae: [22.6444, 51.4980, 26.2822, 56.3834],
            ar: [-55.1850761, -73.5600329, -21.781168, -53.6374515],
            am: [4.3951997, -75.7854388, 4.5895768, -75.6325211],
            as: [-14.7608358, -171.2951296, -10.8449746, -167.9322899],
            aq: [-85.0511287, -180.0, -60.0, 180.0],
            tf: [-50.2187169, 39.4138676, -11.3139928, 77.8494974],
            ag: [16.7573901, -62.5536517, 17.929, -61.447857],
            au: [-55.3228175, 72.2460938, -9.0882278, 168.2249543],
            at: [46.3722761, 9.5307487, 49.0205305, 17.160776],
            az: [38.3929551, 44.7633701, 41.9502947, 51.0090302],
            bi: [-4.4693155, 29.0007401, -2.3096796, 30.8498462],
            be: [49.4969821, 2.3889137, 51.5516667, 6.408097],
            bj: [6.1730586, 5.4621058, 6.4930586, 5.7821058],
            bf: [9.4104718, -5.5132416, 15.084, 2.4089717],
            bd: [20.3756582, 88.0075306, 26.6382534, 92.6804979],
            bg: [41.2353929, 22.3571459, 44.2167064, 28.8875409],
            bh: [35.1878012, 72.5273968, 35.2278012, 72.5673968],
            bs: [20.7059846, -80.7001941, 27.4734551, -72.4477521],
            ba: [42.5553114, 15.7287433, 45.2764135, 19.6237311],
            bl: [17.670931, -63.06639, 18.1375569, -62.5844019],
            by: [51.2575982, 23.1783344, 56.17218, 32.7627809],
            bz: [15.8857286, -89.2262083, 18.496001, -87.3098494],
            bm: [32.0469651, -65.1232222, 32.5913693, -64.4109842],
            bo: [-22.8982742, -69.6450073, -9.6689438, -57.453],
            br: [-33.8689056, -73.9830625, 5.2842873, -28.6341164],
            bb: [12.845, -59.8562115, 13.535, -59.2147175],
            bn: [4.002508, 114.0758734, 5.1011857, 115.3635623],
            bt: [26.702016, 88.7464724, 28.246987, 92.1252321],
            bv: [-54.654, 2.9345531, -54.187, 3.7791099],
            bw: [-26.9059669, 19.9986474, -17.778137, 29.375304],
            cf: [25.217277, 55.1742999, 25.2194356, 55.1762608],
            ca: [41.6765556, -141.00275, 83.3362128, -52.3231981],
            cc: [-12.4055983, 96.612524, -11.6213132, 97.1357343],
            ch: [45.817995, 5.9559113, 47.8084648, 10.4922941],
            cl: [-56.725, -109.6795789, -17.4983998, -66.0753474],
            cn: [25.0671341, -99.4612273, 25.9161824, -98.421576],
            ci: [4.1621205, -8.601725, 10.740197, -2.493031],
            cm: [1.6546659, 8.3822176, 13.083333, 16.1921476],
            cd: [-4.2726671, 15.2829578, -4.2723703, 15.283136],
            cg: [-5.149089, 11.0048205, 3.713056, 18.643611],
            ck: [-22.15807, -166.0856468, -8.7168792, -157.1089329],
            co: [-4.2316872, -82.1243666, 16.0571269, -66.8511907],
            km: [-12.621, 43.025305, -11.165, 44.7451922],
            cv: [14.8031546, -25.3609478, 17.2053108, -22.6673416],
            cr: [5.3329698, -87.2722647, 11.2195684, -82.5060208],
            cu: [19.6275294, -85.1679702, 23.4816972, -73.9190004],
            cx: [-10.5698515, 105.5336422, -10.4123553, 105.7130159],
            ky: [19.0620619, -81.6313748, 19.9573759, -79.5110954],
            cy: [27.4823018, 25.6451285, 42.4823018, 40.6451285],
            cz: [48.5518083, 12.0905901, 51.0557036, 18.859216],
            de: [47.2701114, 5.8663153, 55.099161, 15.0419319],
            dj: [10.9149547, 41.7713139, 12.7923081, 43.6579046],
            dm: [15.0074207, -61.6869184, 15.7872222, -61.0329895],
            dk: [54.4516667, 7.7153255, 57.9524297, 15.5530641],
            do: [17.2701708, -72.0574706, 21.303433, -68.1101463],
            dz: [18.968147, -8.668908, 37.2962055, 11.997337],
            ec: [-5.0159314, -92.2072392, 1.8835964, -75.192504],
            eg: [22.0, 24.6499112, 31.8330854, 37.1153517],
            er: [25.2197993, 55.1720522, 25.2220008, 55.1736716],
            eh: [24.1597324, -13.7867848, 24.1997324, -13.7467848],
            es: [27.4335426, -18.3936845, 43.9933088, 4.5918885],
            ee: [57.5092997, 21.3826069, 59.9383754, 28.2100175],
            et: [3.397448, 32.9975838, 14.8940537, 47.9823797],
            fi: [59.4541578, 19.0832098, 70.0922939, 31.5867071],
            fj: [-21.9434274, -180.0, -12.2613866, 180.0],
            fk: [-53.1186766, -61.7726772, -50.7973007, -57.3662367],
            fr: [41.2632185, -5.4534286, 51.268318, 9.8678344],
            fo: [61.3915553, -7.6882939, 62.3942991, -6.2565525],
            fm: [0.827, 137.2234512, 10.291, 163.2364054],
            ga: [-4.1012261, 8.5002246, 2.3182171, 14.539444],
            gb: [25.2223186, 55.1579517, 25.2241651, 55.1606916],
            ge: [30.355757, -85.6051201, 35.0013544, -80.7514321],
            gg: [49.4155331, -2.6751703, 49.5090776, -2.501814],
            gh: [4.5392525, -3.260786, 11.1748562, 1.2732942],
            gi: [36.100807, -5.3941295, 36.180807, -5.3141295],
            gn: [38.1240893, -77.4591124, 38.1640893, -77.4191124],
            gp: [15.8320085, -61.809764, 16.5144664, -61.0003663],
            gm: [13.061, -17.0288254, 13.8253137, -13.797778],
            gw: [10.6514215, -16.894523, 12.6862384, -13.6348777],
            gq: [-1.6732196, 5.4172943, 3.989, 11.3598628],
            gr: [34.7006096, 19.2477876, 41.7488862, 29.7296986],
            gd: [11.786, -62.0065868, 12.5966532, -61.1732143],
            gl: [43.0015105, -70.907562, 43.0770931, -70.805801],
            gt: [13.6345804, -92.3105242, 17.8165947, -88.1755849],
            gf: [2.112222, -54.60278, 5.7507111, -51.6346139],
            gu: [13.182335, 144.563426, 13.706179, 145.009167],
            gy: [1.1710017, -61.414905, 8.6038842, -56.4689543],
            hk: [22.1193278, 114.0028131, 22.4393278, 114.3228131],
            hm: [-53.394741, 72.2460938, -52.7030677, 74.1988754],
            hn: [12.9808485, -89.3568207, 17.619526, -82.1729621],
            hr: [42.1765993, 13.2104814, 46.555029, 19.4470842],
            ht: [21.7470269, -78.1147805, 21.7870269, -78.0747805],
            hu: [45.737128, 16.1138867, 48.585257, 22.8977094],
            id: [-11.2085669, 94.7717124, 6.2744496, 141.0194444],
            im: [54.0539576, -4.7946845, 54.4178705, -4.3076853],
            in: [6.5546079, 68.1113787, 35.6745457, 97.395561],
            io: [-7.6454079, 71.036504, -5.037066, 72.7020157],
            ie: [51.222, -11.0133788, 55.636, -5.6582363],
            ir: [24.8465103, 44.0318908, 39.7816502, 63.3332704],
            iq: [29.0585661, 38.7936719, 37.380932, 48.8412702],
            is: [51.3863696, 0.5475318, 51.3868275, 0.5479162],
            il: [29.4533796, 34.2674994, 33.3356317, 35.8950234],
            it: [35.2889616, 6.6272658, 47.0921462, 18.7844746],
            jm: [16.5899443, -78.5782366, 18.7256394, -75.7541143],
            je: [49.1625179, -2.254512, 49.2621288, -2.0104193],
            jo: [10.5378127, 122.4078085, 10.6910595, 122.6356296],
            jp: [20.2145811, 122.7141754, 45.7112046, 154.205541],
            kz: [40.5686476, 46.4932179, 55.4421701, 87.3156316],
            ke: [-4.8995204, 33.9098987, 4.62, 41.899578],
            kg: [39.1728437, 69.2649523, 43.2667971, 80.2295793],
            kh: [9.4752639, 102.3338282, 14.6904224, 107.6276788],
            ki: [-7.0516717, -179.1645388, 7.9483283, -164.1645388],
            kn: [16.895, -63.051129, 17.6158146, -62.3303519],
            kr: [37.52806, 126.89575, 37.52816, 126.89585],
            kw: [-12.0494672, -72.8801102, -12.0094672, -72.8401102],
            la: [13.9096752, 100.0843247, 22.5086717, 107.6349989],
            lb: [40.3199193, -76.4508668, 40.355802, -76.391965],
            lr: [4.1555907, -11.6080764, 8.5519861, -7.367323],
            ly: [19.5008138, 9.391081, 33.3545898, 25.3770629],
            lc: [13.508, -61.2853867, 14.2725, -60.6669363],
            li: [47.0484291, 9.4716736, 47.270581, 9.6357143],
            lk: [25.2287738, 55.1813071, 25.2303051, 55.1828523],
            ls: [-30.6772773, 27.0114632, -28.570615, 29.4557099],
            lt: [53.8967893, 20.653783, 56.4504213, 26.8355198],
            lu: [49.4969821, 4.9684415, 50.430377, 6.0344254],
            lv: [55.6746505, 20.6715407, 58.0855688, 28.2414904],
            mo: [25.2349583, 55.1803834, 25.2368385, 55.1821684],
            mf: [17.8963535, -63.3605643, 18.1902778, -62.7644063],
            ma: [21.3365321, -17.2551456, 36.0505269, -0.998429],
            mc: [43.7247599, 7.4090279, 43.7519311, 7.4398704],
            md: [46.6744934, 29.7521496, 46.6745934, 29.7522496],
            mg: [-25.6071002, 43.2202072, -11.9519693, 50.4862553],
            mv: [25.2252959, 55.1823199, 25.2263769, 55.1837469],
            mx: [19.2726009, -99.2933416, 19.5926009, -98.9733416],
            mh: [-0.5481258, 163.4985095, 14.4518742, 178.4985095],
            mk: [40.8536596, 20.4529023, 42.3735359, 23.034051],
            ml: [10.147811, -12.2402835, 25.001084, 4.2673828],
            mt: [35.6029696, 13.9324226, 36.2852706, 14.8267966],
            mm: [9.4399432, 92.1719423, 28.547835, 101.1700796],
            me: [-29.8446455, -51.662, -29.5743342, -51.3498193],
            mn: [41.5800276, 87.73762, 52.1496, 119.931949],
            mp: [14.036565, 144.813338, 20.616556, 146.154418],
            mz: [19.038889, -96.274167, 19.078889, -96.234167],
            mr: [25.2143602, 55.1665334, 25.2163939, 55.1690669],
            ms: [16.475, -62.450667, 17.0152978, -61.9353818],
            mq: [14.3948596, -61.2290815, 14.8787029, -60.8095833],
            mu: [-20.725, 56.3825151, -10.138, 63.7151319],
            mw: [-17.1296031, 32.6703616, -9.3683261, 35.9185731],
            my: [-5.1076241, 105.3471939, 9.8923759, 120.3471939],
            yt: [-13.0210119, 45.0183298, -12.6365902, 45.2999917],
            na: [-28.96945, 11.5280384, -16.9634855, 25.2617671],
            nc: [33.0351363, -92.6876556, 33.0751363, -92.6476556],
            ne: [11.693756, 0.1689653, 23.517178, 15.996667],
            nf: [-29.333, 167.6873878, -28.796, 168.2249543],
            ng: [4.0690959, 2.676932, 13.885645, 14.678014],
            ni: [10.7076565, -87.901532, 15.0331183, -82.6227023],
            nu: [-19.0840514, -169.9383436, -19.0739661, -169.9129672],
            nl: [11.825, -52.35, 53.7253321, 7.2274985],
            no: [57.7590052, 4.0875274, 71.3848787, 31.7614911],
            np: [26.3477581, 80.0586226, 30.446945, 88.2015257],
            nr: [-0.5541334, 166.9091794, -0.5025906, 166.9589235],
            nz: [-52.8213687, -179.059153, -29.0303303, 179.3643594],
            om: [25.2268538, 55.1759911, 25.2291352, 55.1773672],
            pk: [23.5393916, 60.872855, 37.084107, 77.1203914],
            pa: [35.246906, -119.0767707, 35.286906, -119.0367707],
            pn: [-25.1306736, -130.8049862, -23.8655769, -124.717534],
            pe: [41.309511, -89.164781, 41.38197, -89.105652],
            ph: [4.2158064, 114.0952145, 21.3217806, 126.8072562],
            pw: [42.5481153, 2.9351868, 42.5844284, 2.9840518],
            pg: [-13.1816069, 136.7489081, 1.8183931, 151.7489081],
            pl: [49.0020468, 14.1229707, 55.0336963, 24.145783],
            pr: [17.9268695, -67.271492, 18.5159789, -65.5897525],
            kp: [37.5867855, 124.0913902, 43.0089642, 130.924647],
            pt: [29.8288021, -31.5575303, 42.1543112, -6.1891593],
            py: [-27.6063935, -62.6442036, -19.2876472, -54.258],
            ps: [31.2201289, 34.0689732, 32.5521479, 35.5739235],
            pf: [-28.0990232, -154.9360599, -7.6592173, -134.244799],
            qa: [25.2271767, 55.1726803, 25.2289841, 55.1741485],
            re: [-21.3897308, 55.2164268, -20.8717136, 55.8366924],
            ro: [43.618682, 20.2619773, 48.2653964, 30.0454257],
            ru: [41.1850968, 19.6389, 82.0586232, 180],
            rw: [-2.8389804, 28.8617546, -1.0474083, 30.8990738],
            sa: [14.4840316, 121.0177023, 14.4846897, 121.0265441],
            sd: [10.88, 6.48, 10.92, 6.52],
            sn: [12.2372838, -17.7862419, 16.6919712, -11.3458996],
            sg: [1.1304753, 103.6920359, 1.4504753, 104.0120359],
            gs: [-59.684, -42.354739, -53.3500755, -25.8468303],
            sh: [-16.23, -5.9973424, -15.704, -5.4234153],
            sj: [70.6260825, -9.6848146, 81.028076, 34.6891253],
            sb: [-13.2424298, 155.3190556, -4.81085, 170.3964667],
            sl: [6.755, -13.5003389, 9.999973, -10.271683],
            sv: [12.976046, -90.1790975, 14.4510488, -87.6351394],
            sm: [43.8937002, 12.4033246, 43.992093, 12.5160665],
            so: [-13.200556, 15.246667, -13.160556, 15.286667],
            pm: [46.5507173, -56.6972961, 47.365, -55.9033333],
            rs: [42.2322435, 18.8142875, 46.1900524, 23.006309],
            st: [-0.2135137, 6.260642, 1.9257601, 7.6704783],
            sr: [1.8312802, -58.070833, 6.225, -53.8433358],
            sk: [47.7314286, 16.8331891, 49.6138162, 22.56571],
            si: [45.4214242, 13.3754696, 46.8766816, 16.5967702],
            se: [55.1331192, 10.5930952, 69.0599699, 24.1776819],
            sz: [25.2156672, 55.1807318, 25.217255, 55.18286],
            sc: [25.2237725, 55.1816849, 25.2250726, 55.184065],
            sy: [27.1401861, 31.5494106, 42.1401861, 46.5494106],
            tc: [20.9553418, -72.6799046, 22.1630989, -70.8643591],
            td: [7.44107, 13.47348, 23.4975, 24.0],
            tg: [5.926547, -0.1439746, 11.1395102, 1.8087605],
            th: [5.612851, 97.3438072, 20.4648337, 105.636812],
            tj: [36.6711153, 67.3332775, 41.0450935, 75.1539563],
            tk: [-9.6442499, -172.7213673, -8.3328631, -170.9797586],
            tm: [35.129093, 52.335076, 42.7975571, 66.6895177],
            tl: [-6.3294157, 106.9549541, -6.3284839, 106.9551755],
            to: [-24.1034499, -179.3866055, -15.3655722, -173.5295458],
            tt: [9.8732106, -62.083056, 11.5628372, -60.2895848],
            tn: [30.230236, 7.5219807, 37.7612052, 11.8801133],
            tr: [35.8076804, 25.6212891, 42.297, 44.8176638],
            tv: [-10.9939389, -180.0, -5.4369611, 180.0],
            tw: [50.8832129, 6.0296969, 50.8833129, 6.0297969],
            tz: [-6.8127308, 39.2895223, -6.812538, 39.2897105],
            ug: [-1.4823179, 29.573433, 4.2340766, 35.000308],
            ua: [44.184598, 22.137059, 52.3791473, 40.2275801],
            um: [6.1779744, -162.6816297, 6.6514388, -162.1339885],
            uy: [-35.7824481, -58.4948438, -30.0853962, -53.0755833],
            us: [24.9493, -125.0011, 49.5904, -66.9326],
            usa: [24.9493, -125.0011, 49.5904, -66.9326],
            uz: [37.1821164, 55.9977865, 45.590118, 73.1397362],
            va: [41.9002044, 12.4457442, 41.9073912, 12.4583653],
            vc: [12.5166548, -61.6657471, 13.583, -60.9094146],
            ve: [0.647529, -73.3529632, 15.9158431, -59.5427079],
            vg: [17.623468, -65.159094, 18.464984, -64.512674],
            vi: [17.623468, -65.159094, 18.464984, -64.512674],
            vn: [8.1790665, 102.14441, 23.393395, 114.3337595],
            vu: [-20.4627425, 166.3355255, -12.8713777, 170.449982],
            wf: [-14.5630748, -178.3873749, -12.9827961, -175.9190391],
            ws: [40.7987372, -124.2064518, 40.8387372, -124.1664518],
            ye: [11.9084802, 41.60825, 19.0, 54.7389375],
            za: [-47.1788335, 16.3335213, -22.1250301, 38.2898954],
            zm: [-18.0765945, 21.9993509, -8.2712822, 33.701111],
            zw: [-22.4241096, 25.2373, -15.6097033, 33.0683413]
        };
    }

    // loads pins by calling getJSON function for passed url
    function loadAllJsonDataToView(searchedRegionInfo) {
        searchedRegionInfo = searchedRegionInfo ? searchedRegionInfo : getSearchedRegionInfo(null, getCurrentSearchTerm());

        agentsById = [];
        hideResultMessages();
        showSpinner();

        loadSearchByRegionDataToView(getSelectedFilters(), searchedRegionInfo);
    }
    
    function doesFilterAlreadyHaveAllResults(filter) {
        return !filter.allResultsForDataSource || !filter.allResultsForDataSource.length;
    }

    // shows agent by id
    function getUSAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.US_Agents.url, 250, searchedRegionInfo, isFollowupRequest);
        var searchTerm = getCurrentSearchTerm();

        if (searchTerm) {
            if (previousInput === searchTerm) {
                var searchRadius = getSelectedSearchRadius();
                var loc = getLocationLatLong(searchTerm);
                if (loc)
                    queryBuilder = queryBuilder.withRadialSearch(loc.lat, loc.long, searchRadius);
                else
                    queryBuilder = queryBuilder.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude, searchRadius);
            } else {
                previousInput = "";
                $("#how-to-buy-2__search-input-radius").hide();
                switch (selectedSearchType) {
                    case SEARCH_TYPES.ZIP_CODE:
                        queryBuilder = queryBuilder.withTerritorySearch(searchTerm);
                        break;
                    case SEARCH_TYPES.AGENCY_NAME:
                        queryBuilder = queryBuilder.withBusinessSearch(searchTerm);
                        break;
                    case SEARCH_TYPES.AGENT_ID:
                        queryBuilder = queryBuilder.withAgentSearch(searchTerm);
                        break;
                }
            }
        }

        return queryBuilder.sendRequests(doesFilterAlreadyHaveAllResults(filterTypes.US_Agents));
    }

    function bundleRequestWithFilteringIntent(request, isClientFilterable, isBlankQuery) {
        return {
            request: request,
            isClientFilterRequest: isClientFilterable,
            isBlankQuery: isBlankQuery
        };
    }

    function getLocationLatLong(searchTerm){
        if (searchTerm.city) {
            for (var i in ZipCityArray) {
                var loc = ZipCityArray[i];
                if (loc.primary_city === searchTerm.city && loc.state === searchTerm.state)
                    return { lat: loc.lat, long: loc.long };
            }

            for (var i in ZipCityCanadaArray) {
                var loc = ZipCityCanadaArray[i];
                if (loc.city === searchTerm.city && loc.province === searchTerm.state)
                    return { lat: loc.lat, long: loc.long };
            }
        } else {
            if (isPostalCode(searchTerm)) {
                for (var i in ZipCityArray) {
                    var loc = ZipCityArray[i];
                    if (loc.zip === searchTerm || loc.zip === parseInt(searchTerm))
                        return { lat: loc.lat, long: loc.long };
                }
            } else {
                for (var i in ZipCityCanadaArray) {
                    var loc = ZipCityCanadaArray[i];
                    if (loc.postal.indexOf(searchTerm.substring(0,3)) > -1)
                        return { lat: loc.lat, long: loc.long };
                }
            }
        }
        return null;
    }

    function getDistributors(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.AgentDistributors.url, 250, searchedRegionInfo, isFollowupRequest);
        var searchTerm = getCurrentSearchTerm();
        var searchRadius = getSelectedSearchRadius();

        if (searchTerm) {
            switch (selectedSearchType) {
                case SEARCH_TYPES.ZIP_CODE:
                    var loc = getLocationLatLong(searchTerm);
                    if (loc)
                        queryBuilder = queryBuilder.withRadialSearch(loc.lat, loc.long, searchRadius);
                    else
                        queryBuilder = queryBuilder.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude, searchRadius);
                    break;
                case SEARCH_TYPES.CITY_STATE:
                    var loc = getLocationLatLong(searchTerm);
                    if (loc) {
                        queryBuilder = queryBuilder.withRadialSearch(loc.lat, loc.long, searchRadius)
                            .withCityStateSearch(searchTerm.city, searchTerm.state);
                    }else {
                        queryBuilder = queryBuilder.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude, searchRadius)
                            .withCityStateSearch(searchTerm.city, searchTerm.state);
                    }
                    break;
                case SEARCH_TYPES.AGENCY_NAME:
                    queryBuilder = queryBuilder.withBusinessSearch(searchTerm);
                    break;
            }
        }

        return queryBuilder.sendRequests();
    }

    function bingQueryBuilder(baseUrl, topXLocations, regionSearchInfo, isFollowupRequest, unsupportedSearchFields) {
        var self = this;
        this.baseUrl = baseUrl;
        this.topXLocations = topXLocations;
        this.filterClause = null;
        this.spatialFilterClause = null;
        this.additionalRequests = [];
        this.regionSearchInfo = regionSearchInfo;
        this.isFollowupRequest = isFollowupRequest;
        this.unsupportedSearchFields = unsupportedSearchFields ? unsupportedSearchFields : [];
        var combineFilterClauses = function (newFilterClause, oldFilterClause, joinWith) {
            if (!oldFilterClause) {
                return newFilterClause;
            } else {
                return {
                    joinWith: joinWith,
                    clause1: newFilterClause,
                    clause2: oldFilterClause
                };
            }
        };

        var addFilterClause = function (newFilterClause, joinWith) {
            var clonedBuilder = self.clone();
            clonedBuilder.filterClause = combineFilterClauses(newFilterClause, clonedBuilder.filterClause, joinWith);
            return clonedBuilder;
        };

        var addSpatialFilterClause = function (newSpatialFilterClause, joinWith) {
            var clonedBuilder = self.clone();
            clonedBuilder.spatialFilterClause = combineFilterClauses(newSpatialFilterClause, clonedBuilder.spatialFilterClause, joinWith);
            return clonedBuilder;
        };

        this.hasSpatialFilter = function () {
            return this.spatialFilterClause && this.spatialFilterClause.length > 0;
        };

        this.hasFilter = function () {
            return this.filterClause && this.filterClause.length > 0;
        };

        this.addAndFilter = function (filterClause) {
            return addFilterClause(filterClause, "and");
        };

        // bing does not support and/or when executing a wildcard (starts/endswith) search - execute an additional request and combine results afterwards.
        this.addWildcardFilter = function (filterClause) {
            var newAdditionalQuery = new bingQueryBuilder(this.baseUrl, this.topXLocations);
            this.additionalRequests.push(newAdditionalQuery.addAndFilter(filterClause));
            return this;
        };

        this.addOrFilter = function (filterClause) {
            return addFilterClause(filterClause, "or");
        };

        this.addSpatialFilter = function (spatialFilter) {
            return addSpatialFilterClause(spatialFilter, "or");
        };

        this.clone = function () {
            var newQueryBuilder = new bingQueryBuilder(this.baseUrl, this.topXLocations, this.regionSearchInfo, this.isFollowupRequest, this.unsupportedSearchFields);
            newQueryBuilder.filterClause = this.filterClause;
            newQueryBuilder.spatialFilterClause = this.spatialFilterClause;
            newQueryBuilder.additionalRequests = this.additionalRequests.slice(0);
            return newQueryBuilder;
        };

        this.withValidAdminDistrict = function () {
            return this.clone().addAndFilter("AdminDistrict ne 'unknown'");
        };

        this.withRadialSearch = function (latitude, longitude, radius) {
            var MILES_TO_KILOMETERS = 1.61;
            if (!radius)
                radius = 50;
            var radiusInKilometers = radius * MILES_TO_KILOMETERS;

            if (latitude && longitude) {
                var spatialFilter = "nearby(" + latitude + "," + longitude + "," + radiusInKilometers + ")";
                return this.addSpatialFilter(spatialFilter);
            }
            else {
                return this;
            }
        };

        var regionFilterEnum = {
            EQUALS: 'eq',
            STARTSWITH: 'StartsWith'
        };

        function filterAgainstRegion(fieldName, region, searchTerm, filterOperator) {
            var regionNames = [region.regionCode, region.regionName, searchTerm];
            var distinctRegionNames = regionNames.filter(function (item, pos) {
                // get unique items that are 'truthy'
                return item && regionNames.indexOf(item) === pos;
            }).map(function (uniqueValue) {
                // to encode an apostrophe for bing requests, replace 1 apostrophe with 2 apostrophes
                return uniqueValue.replaceAll("'", "''");
            });

            var getFilterPiece = function (fieldName, regionName, operator) {
                if (operator === regionFilterEnum.STARTSWITH) {
                    return "StartsWith(" + fieldName.trim() + ",'" + regionName.trim() + "') eq true";
                }
                else {
                    return fieldName.trim() + " eq '" + regionName.trim() + "'";
                }
            };

            var regionFilter = distinctRegionNames.map(function (regionName) {
                return getFilterPiece(fieldName, regionName, filterOperator);
            }).join(' or ');

            regionFilter = distinctRegionNames.length > 1 ? '(' + regionFilter + ')' : regionFilter;
            return regionFilter;
        }

        this.withStateSearch = function (region, country, searchTerm) {
            var stateSearchQuery = this.addAndFilter(filterAgainstRegion('AdminDistrict', region, searchTerm));
            return stateSearchQuery.withCountrySearch(country);
        };

        this.withCitySearch = function (region, state, country, searchTerm) {
            var cityQuery = this.addAndFilter(filterAgainstRegion('Locality', region, searchTerm));
            return cityQuery.withStateSearch(state, country);
        };

        this.withCityStateSearch = function (city, state) {
            return this.addAndFilter("(AdminDistrict eq '" + state + "') and (Locality eq '" + city + "')")
        }

        this.withPostalSearch = function (region, state, country, searchTerm) {
            var postalQueryExact = this.addAndFilter(filterAgainstRegion('PostalCode', region, searchTerm)).withStateSearch(state, country);
            var postalQueryWithStartsWith = postalQueryExact.addWildcardFilter(filterAgainstRegion('PostalCode', region, searchTerm, regionFilterEnum.STARTSWITH));
            return postalQueryWithStartsWith;
        };

        this.withBusinessSearch = function (businessName) {
            if (businessName == undefined) {
                if (this.regionSearchInfo && this.regionSearchInfo.searchTerm && this.regionSearchInfo.searchTerm.length) {
                    return this.addWildcardFilter("Contains(Business,'" + this.regionSearchInfo.searchTerm.trim() + "') eq true");
                }
                else {
                    return this;
                }
            }
            return this.addAndFilter("Contains(Business,'" + businessName + "') eq true");
        };

        this.withCountrySearch = function (country, searchTerm) {
            if (country && !this.unsupportedSearchFields.includes('CountryRegion')) {
                // google places gives responses with 'US' as country code - bing returns 'USA'
                country.regionCode = country.regionCode === 'US' ? 'USA' : country.regionCode;
                return this.addAndFilter(filterAgainstRegion('CountryRegion', country, searchTerm));
            }
            else if (country && country.regionCode && country.isMostSpecificSearchRegion && this.unsupportedSearchFields.includes('CountryRegion')) {
                var countryBoundingBox = getBoundingBoxForCountry(country.regionCode);
                if (countryBoundingBox && countryBoundingBox.length) {
                    var boundingBoxFilter = "bbox(" + countryBoundingBox.join(',') + ")";
                    return this.addSpatialFilter(boundingBoxFilter);
                }
                else {
                    return this;
                }
            }
            else {
                return this;
            }
        };

        this.withAgentSearch = function (agentNumber) {
            if (!agentNumber) {
                return this;
            }

            var regex = /^(a)?\d{3,5}/gi;
            if (!agentNumber.match(regex)) {
                return this;
            }

            var cleanedAgentNumber = agentNumber ? agentNumber.toLowerCase().trim() : '';
            if (cleanedAgentNumber.startsWith('a')) {
                cleanedAgentNumber = cleanedAgentNumber.substring(1, cleanedAgentNumber.length);
            }

            cleanedAgentNumber = ('A' + cleanedAgentNumber).toUpperCase();
            return this.addOrFilter("SalesId eq '" + cleanedAgentNumber + "'");
        };
        this.withTerritorySearch = function (territory) {
            if (!territory) {
                return this;
            }            
            return this.addOrFilter("Territory eq '" + territory + "'");
        };

        this.withRegionSearch = function () {
            var searchedRegionInfo = this.regionSearchInfo;
            var isFollowupRequest = this.isFollowupRequest;
            if (searchedRegionInfo.isPostalRegion && searchedRegionInfo.latitude && searchedRegionInfo.longitude) {
                if (isFollowupRequest) {
                    return this.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude);
                }
                else {
                    return this.withPostalSearch(searchedRegionInfo.region, searchedRegionInfo.getState(), searchedRegionInfo.getCountry(), searchedRegionInfo.searchTerm);
                }
            }
            else if (searchedRegionInfo.isCity) {
                if (isFollowupRequest) {
                    return this.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude);
                }
                else {
                    return this.withCitySearch(searchedRegionInfo.region, searchedRegionInfo.getState(), searchedRegionInfo.getCountry(), searchedRegionInfo.searchTerm);
                }
            }
            else if (searchedRegionInfo.isStateProvince) {
                return this.withStateSearch(searchedRegionInfo.region, searchedRegionInfo.getCountry(), searchedRegionInfo.searchTerm);
            }
            else if (searchedRegionInfo.isCountry) {
                return this.withCountrySearch(searchedRegionInfo.region, searchedRegionInfo.searchTerm);
            }
            else {
                return this;
            }
        };

        var generateFilterExpression = function (filterClause) {
            if (!filterClause) {
                return '';
            } else if (typeof filterClause === 'string') {
                return filterClause;
            } else if (typeof filterClause === 'object' && filterClause.joinWith === 'or' || filterClause.joinWith === 'and') {
                var leftSide = generateFilterExpression(filterClause.clause1).trim();
                var rightSide = generateFilterExpression(filterClause.clause2).trim();
                var combinedFilters = [leftSide, rightSide].filter(function (element) {
                    return element && element.length > 0;
                }).join(' ' + filterClause.joinWith.trim() + ' ');
                return filterClause.joinWith === 'or' ? '(' + combinedFilters + ')' : combinedFilters;
            } else {
                return '';
            }
        };

        //todo: maybe add search by agent id / number

        this.buildQuery = function () {
            var baseUrl = this.baseUrl + "?";
            var filterExpression = generateFilterExpression(this.filterClause);
            filterExpression = filterExpression && filterExpression.length ? "filter=" + filterExpression : "";
            var spatialFilterExpression = generateFilterExpression(this.spatialFilterClause);
            spatialFilterExpression = spatialFilterExpression && spatialFilterExpression.length ? "&spatialFilter=" + spatialFilterExpression : "";
            if (!filterExpression && !spatialFilterExpression) {
                // there needs to be a filter expression for bing to return any results
                filterExpression = 'filter=true eq true';
            }
            var finalQuery = baseUrl + filterExpression + spatialFilterExpression;
            return finalQuery;
        };

        this.isBlankQuery = function () {
            return !generateFilterExpression(this.filterClause) && !generateFilterExpression(this.spatialFilterClause);
        };

        function allowRequest(isFollowupRequest, searchedRegionInfo) {
            return !isFollowupRequest || (searchedRegionInfo.isPostalRegion || searchedRegionInfo.isCity);
        }

        this.sendRequests = function (gatherResultsForInMemoryFilter) {
            if (!this.baseUrl || !allowRequest(this.isFollowupRequest, this.regionSearchInfo)) {
                return [];
            }

            var isMainQueryBlank = this.isBlankQuery();
            var queryData = [];
            queryData.push({
                query: this.buildQuery(),
                isBlankQuery: isMainQueryBlank
            });

            if (this.additionalRequests && this.additionalRequests.length) {
                queryData = queryData.concat(this.additionalRequests.map(function (additionalRequest) {
                    return {
                        query: additionalRequest.buildQuery(),
                        isBlankQuery: false
                    };
                }));
            }

            var requestData = queryData.map(function (queryDataItem) {
                return bundleRequestWithFilteringIntent($.ajax({ url: queryDataItem.query, dataType: "text json", type: "GET" }), false, queryDataItem.isBlankQuery);
            });

            if (gatherResultsForInMemoryFilter && !isMainQueryBlank) {
                var blankQuery = new bingQueryBuilder(this.baseUrl, this.topXLocations, this.regionSearchInfo, false);
                var allResultsRequests = blankQuery.sendRequests();
                allResultsRequests.forEach(function (req) {
                    req.isClientFilterRequest = true;
                });
                requestData = requestData.concat(allResultsRequests);
            }

            return requestData;
        };
    }

    function getShowroomsByRegion(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Showrooms.url, 250, searchedRegionInfo, isFollowupRequest)
        var searchTerm = getCurrentSearchTerm();
        var searchRadius = getSelectedSearchRadius();

        if (searchTerm) {
            switch (selectedSearchType) {
                case SEARCH_TYPES.ZIP_CODE:
                    var loc = getLocationLatLong(searchTerm);
                    if (loc)
                        queryBuilder = queryBuilder.withRadialSearch(loc.lat, loc.long, searchRadius);
                    else
                        queryBuilder = queryBuilder.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude, searchRadius);
                    break;
                case SEARCH_TYPES.CITY_STATE:
                    var loc = getLocationLatLong(searchTerm);
                    if (loc) {
                        queryBuilder = queryBuilder.withRadialSearch(loc.lat, loc.long, searchRadius)
                            .withCityStateSearch(searchTerm.city, searchTerm.state);
                    } else {
                        queryBuilder = queryBuilder.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude, searchRadius)
                            .withCityStateSearch(searchTerm.city, searchTerm.state);
                    }
                    break;
                case SEARCH_TYPES.AGENCY_NAME:
                    queryBuilder = queryBuilder.withBusinessSearch(searchTerm);
                    break;
            }
        }

        return queryBuilder.sendRequests();
    }

    function getBoundingBoxForCountry(searchedCountryCode) {
        if (!searchedCountryCode) {
            return false;
        }

        var countryBoundingBoxes = getCountryBoundingBoxes();
        var matchingCountryCode = Object.keys(countryBoundingBoxes).find(function (countryCode) {
            return countryCode.toLowerCase() === searchedCountryCode.toLowerCase();
        });

        if (matchingCountryCode) {
            var boundingBox = countryBoundingBoxes[matchingCountryCode];
            return boundingBox;
        }
        else {
            return false;
        }
    }

    // shows hlp non utility
    function getHlpNonUtility(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Non_Utility_Lighting.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();

        var searchTerm = getCurrentSearchTerm();
        if (isPostalCode(searchTerm))
            queryBuilder = queryBuilder.addWildcardFilter("Territory eq '" + searchTerm + "'");

        return queryBuilder.sendRequests(doesFilterAlreadyHaveAllResults(filterTypes.Non_Utility_Lighting));
    }

    function getRepNonUtility(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Rep_Non_Utility_Lighting.url, 250, searchedRegionInfo, isFollowupRequest)
            .withTerritorySearch(searchedRegionInfo.searchTerm);
            //.withRegionSearch()
            //.withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    function getCanadaAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Canada.url, 250, searchedRegionInfo, isFollowupRequest);
        var searchTerm = getCurrentSearchTerm();

        if (searchTerm) {
            switch (selectedSearchType) {
                case SEARCH_TYPES.ZIP_CODE:
                    var zipPrefix = searchTerm.trim().substring(0, 3);
                    queryBuilder = queryBuilder.withTerritorySearch(zipPrefix);
                    break;
                case SEARCH_TYPES.CITY_STATE:
                    var postalCode;
                    for (var i in ZipCityCanadaArray) {
                        if (ZipCityCanadaArray[i].city === searchTerm.city && ZipCityCanadaArray[i].province === searchTerm.state) {
                            postalCode = ZipCityCanadaArray[i].postal.substring(0,3);
                            break;
                        }
                    }

                    if(postalCode)
                        queryBuilder = queryBuilder.withTerritorySearch(postalCode);
                    else
                        queryBuilder = queryBuilder.withCityStateSearch(searchTerm.city, searchTerm.state);
                    break;
                case SEARCH_TYPES.AGENCY_NAME:
                    queryBuilder = queryBuilder.withBusinessSearch(searchTerm);
                    break;
                case SEARCH_TYPES.AGENT_ID:
                    queryBuilder = queryBuilder.withAgentSearch(searchTerm);
                    break;
            }
        }

        return queryBuilder.sendRequests();
    }

    function getMexicoAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Mexico.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    function getInternationalAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.International.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        if (!queryBuilder.hasSpatialFilter()) {
            queryBuilder = queryBuilder.withAgentSearch(searchedRegionInfo.searchTerm);
        }
        return queryBuilder.sendRequests();
    }

    function getDGLogikAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.DGLogik.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    // shows hlp utility
    function getHlpUtility(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Utility_Lighting.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();

        var searchTerm = getCurrentSearchTerm();
        if (isPostalCode(searchTerm))
            queryBuilder = queryBuilder.addWildcardFilter("Territory eq '" + searchTerm + "'");

        return queryBuilder.sendRequests(doesFilterAlreadyHaveAllResults(filterTypes.Utility_Lighting));
    }

    function getRepUtility(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Rep_Utility_Lighting.url, 250, searchedRegionInfo, isFollowupRequest)
            .withTerritorySearch(searchedRegionInfo.searchTerm);
            //.withRegionSearch()
            //.withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    // geolocate user browser location
    function geoLocate() {
        var etimeout = 0;
        if (navigator.geolocation) {
            etimeout = setTimeout(onError, 10000);
            navigator.geolocation.getCurrentPosition(onSuccess, onError, { timeout: 5000 });
        } else {
            initMapAndSearch({ lat: initLat, lng: initLng }, options.defaultZoom);
            console.log("Geolocation is not supported by this browser.");
        }

        function onSuccess(position) {
            clearTimeout(etimeout);
            showPosition(position);
        }

        function onError(positionError) {
            clearTimeout(etimeout);
            initMapAndSearch({ lat: initLat, lng: initLng }, options.defaultZoom);
            console.log(positionError);
        }
    }

    // helper function used by geolocate to point current position on the map
    function showPosition(position) {
        var userLat = position.coords.latitude;
        var userLng = position.coords.longitude;
        userLatLong.lat = userLat;
        userLatLong.lng = userLng;

        var center = { lat: userLat, lng: userLng };

        initMapAndSearch(center, options.geoZoom);

        //load pins
        loadPinsNearby(userLat, userLng, options.distance);
    }

    // initializing item list bindings
    function initItemListHandlers(filterTypes) {
        $('.items-list', $(scope)).on('click', 'li', function () {
            //open marker
            var id = $(this).data('id').toString();
            $('.items-list li', $(scope)).removeClass('active');
            $(this).addClass('active');

            for (var i = 0; i < markers.length; i++) {
                if (markers[i].title === id) {
                    google.maps.event.trigger(markers[i], 'click');
                    map.setCenter(markers[i].getPosition());
                    break;
                }
            }
        });
    }

    function verifySearchInputType() {
        if (!filterTypes.US_Agents.isSelected && !filterTypes.Canada.isSelected
            && !filterTypes.AgentDistributors.isSelected && !filterTypes.Showrooms.isSelected)
            return { isValid: true };

        var searchTerm = getCurrentSearchTerm();
        if (searchTerm === '')
            return { isValid: true };

        if (((filterTypes.AgentDistributors.isSelected && selectedSearchCountry == SEARCH_COUNTRY.AMERICA) || filterTypes.Showrooms.isSelected)
            && (selectedSearchType === SEARCH_TYPES.ZIP_CODE || selectedSearchType === SEARCH_TYPES.CITY_STATE)) {
            var searchRadius = getSelectedSearchRadius();
            if (searchRadius === 0)
                return { isValid: false, isRadiusEmpty: true};
        }
        
        switch (selectedSearchType) {
            case SEARCH_TYPES.ZIP_CODE:
                if (filterTypes.US_Agents.isSelected && previousInput === searchTerm) {
                    var searchRadius = getSelectedSearchRadius();
                    if (searchRadius === 0)
                        return { isValid: false, isRadiusEmpty: true };
                }
                if (filterTypes.Canada.isSelected)
                    return { isValid: isCaPostalCode(searchTerm), isRadiusEmpty: false };
                else
                    return { isValid: isPostalCode(searchTerm) || isCaPostalCode(searchTerm), isRadiusEmpty: false };
            case SEARCH_TYPES.CITY_STATE:
            case SEARCH_TYPES.AGENCY_NAME:
                return { isValid: true };
            case SEARCH_TYPES.AGENT_ID:
                if (filterTypes.Canada.isSelected)
                    return { isValid: searchTerm.match(/^\d\d\d$/gi), isRadiusEmpty: false };
                else
                    return { isValid: searchTerm.match(/^(a)?\d{3,5}$/gi), isRadiusEmpty: false };
            default:
                return { isValid: false, isRadiusEmpty: false };
        }
    }

    // function used for retrieveing place from textbox upon pressing 'enter' key
    function getPlaceFromTextboxValue(text) {
        deleteMarkers();
        resetSidebar();

        var searchValidity = verifySearchInputType();
        if (!searchValidity.isValid) {
            if (searchValidity.isRadiusEmpty)
                showInvalidRadiusText();
            else
                showIncorrectFormatText();
        }
        else if (service && text && text.length) {
            service.textSearch({
                query: text ,
                 types: "locality"
            }, function (results, status) {
                freeTextSearchCallback(results, status, text);
            });
        }
        else if (!text || !text.length) {
            loadAllJsonDataToView(getSearchedRegionInfo(null, null));
        }
    }

    function getDetailsCallback(results, status, searchTerm) {
        try {
            mostRecentlyFoundGooglePlacesResponse = results;
            loadAllJsonDataToView(getSearchedRegionInfo(results, searchTerm));
        } catch (err) {
            mostRecentlyFoundGooglePlacesResponse = null;
            console.log(err);
        }
    }

    function freeTextSearchCallback(results, status, searchTerm) {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
            if (results && results.length > 0) {
                var result = results[0];

                service.getDetails({
                    placeId: results[0].place_id
                }, function (getDetailsResults, status) {
                    getDetailsCallback(getDetailsResults, status, searchTerm);
                });
            }
            else {
                mostRecentlyFoundGooglePlacesResponse = null;
            }
        }
        else {
            mostRecentlyFoundGooglePlacesResponse = null;
            loadAllJsonDataToView(getSearchedRegionInfo(null, searchTerm));
        }
    }

    function isSearchRegionTypeRelevant(relevantTypes, regionType) {
        return relevantTypes.some(function (supportedRegionType) {
            return supportedRegionType === regionType;
        });
    }

    function getAddressComponentWeight(addressComponent, relevantTypes) {
        var weight = 0;
        var powerOfTen = 1;
        for (var i = relevantTypes.length - 1; i >= 0; i--) {
            if (addressComponent.types.find(function (addressComponentType) {
                return addressComponentType === relevantTypes[i];
            })) {
                weight += powerOfTen;
            }
            powerOfTen = powerOfTen * 10;
        }

        return weight;
    }

    function getGooglePlaceRegionTypeInList(googlePlacesResponse, relevantTypes) {
        if (!googlePlacesResponse || !googlePlacesResponse.address_components) {
            return null;
        }

        var relevantPortions = googlePlacesResponse.address_components.filter(function (addressComponent) {
            return addressComponent.types.some(function (element) {
                return isSearchRegionTypeRelevant(relevantTypes, element);
            });
        });

        var relevantAddressPortionsSorted = relevantPortions.sort(function (element1, element2) {
            return getAddressComponentWeight(element2, relevantTypes) - getAddressComponentWeight(element1, relevantTypes);
        });

        return relevantAddressPortionsSorted && relevantAddressPortionsSorted.length ? relevantAddressPortionsSorted[0] : null;
    }

    function transformPlace(googlePlace, regionType, isMostSpecificSearchRegion) {
        return {
            regionCode: googlePlace.short_name,
            regionName: googlePlace.long_name,
            regionType: regionType,
            isMostSpecificSearchRegion: isMostSpecificSearchRegion
        };
    }

    function getCountry(googlePlacesResponse) {
        var country = getGooglePlaceRegionTypeInList(googlePlacesResponse, ['country']);
        return country ? transformPlace(country, 'country') : null;
    }

    function getState(googlePlacesResponse) {
        var state = getGooglePlaceRegionTypeInList(googlePlacesResponse, ['administrative_area_level_1']);
        return state ? transformPlace(state, 'administrative_area_level_1') : null;
    }

    function isPostalCode(searchTerm) {
        var usPostalCodeRegex = /^\d{5}(?:[-\s]\d{4})?$/;
        return usPostalCodeRegex.test(searchTerm);
    }

    function isCaPostalCode(searchTerm) {
        var canadaPostalCodeRegex = /^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i;
        return canadaPostalCodeRegex.test(searchTerm);
    }

    function getSearchedRegionInfo(googlePlacesResponse, searchTerm) {
        var isSearchTermAPostalCode = isPostalCode(searchTerm) || isCaPostalCode(searchTerm);
        var supportedSearchRegionTypesInOrder = isSearchTermAPostalCode ?
            ['postal_code', 'locality', 'administrative_area_level_1', 'country'] :
            ['locality', 'postal_code', 'administrative_area_level_1', 'country'];
        var mostSpecificSearchRegion = getGooglePlaceRegionTypeInList(googlePlacesResponse, supportedSearchRegionTypesInOrder);
        var mostSpecificSearchRegionType = mostSpecificSearchRegion ? mostSpecificSearchRegion.types.find(function (searchRegionType) {
            return isSearchRegionTypeRelevant(supportedSearchRegionTypesInOrder, searchRegionType);
        }) : null;

        var isCountry = mostSpecificSearchRegionType === 'country';
        // Google Places may return zip codes even if they were not what the user was searching for
        var isPostalRegion = isSearchTermAPostalCode;
        var isStateProvince = mostSpecificSearchRegionType === 'administrative_area_level_1';
        var isCity = mostSpecificSearchRegionType === 'locality';

        var region = mostSpecificSearchRegion ?
            transformPlace(mostSpecificSearchRegion, mostSpecificSearchRegionType, true) :
            null;

        return {
            regionType: mostSpecificSearchRegionType,
            region: region,
            latitude: googlePlacesResponse ? googlePlacesResponse.geometry.location.lat() : null,
            longitude: googlePlacesResponse ? googlePlacesResponse.geometry.location.lng() : null,
            googlePlacesData: googlePlacesResponse,
            isCountry: isCountry,
            isPostalRegion: isPostalRegion,
            isStateProvince: isStateProvince,
            isCity: isCity,
            searchTerm: encodeURIComponent(searchTerm),
            getCountry: function () { return getCountry(googlePlacesResponse); },
            getState: function () { return getState(googlePlacesResponse); },
            loadAll: !googlePlacesResponse && (!searchTerm || !searchTerm.length)
        };
    }

    var clicksWithinLast5Seconds = 0;
    function triggerSendingSelectedFiltersToGoogleAnalytics() {
        clicksWithinLast5Seconds++;
        setTimeout(sendSelectedFiltersToGoogleAnalyticsIfDoneFiltering, 5000);
    }

    // Send an event to Google Analytics if the user hasn't selected filters in the last 5 seconds
    function sendSelectedFiltersToGoogleAnalyticsIfDoneFiltering() {
        if (clicksWithinLast5Seconds > 0) {
            clicksWithinLast5Seconds--;
        }

        if (clicksWithinLast5Seconds > 0) {
            return;
        }

        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Filters Selected: '.concat(
                'Page: "' + window.location.href + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"',
                ' . Search Term: "' + getSearchTermAsString() + '"'),
            Label: 'How To Buy Filters Selected'
        });
    }

    function getCurrentSearchTerm() {
        var searchInput;

        if (filterTypes.US_Agents.isSelected || filterTypes.Canada.isSelected
            || filterTypes.AgentDistributors.isSelected || filterTypes.Showrooms.isSelected) {
            switch (selectedSearchType) {
                case SEARCH_TYPES.ZIP_CODE:
                    if (filterTypes.Canada.isSelected)
                        searchInput = $(".how-to-buy-2__search #postal-code-searchbox .form-control");
                    else
                        searchInput = $(".how-to-buy-2__search #zip-code-searchbox .form-control");
                    break;
                case SEARCH_TYPES.AGENCY_NAME:
                    searchInput = $(".how-to-buy-2__search #agency-name-searchbox .form-control");
                    break;
                case SEARCH_TYPES.AGENT_ID:
                    searchInput = $(".how-to-buy-2__search #agent-id-searchbox .form-control");
                    break;
                case SEARCH_TYPES.CITY_STATE:
                    var searchInputs;
                    if (filterTypes.Canada.isSelected || ((filterTypes.AgentDistributors.isSelected || filterTypes.Showrooms.isSelected) && selectedSearchCountry == SEARCH_COUNTRY.CANADA))
                        searchInputs = $(".how-to-buy-2__search #city-province-searchbox .form-control");
                    else
                        searchInputs = $(".how-to-buy-2__search #city-state-searchbox .form-control");
                    if (searchInputs && searchInputs.length == 2) {
                        cityInput = $(searchInputs[0]);
                        stateInput = $(searchInputs[1]);
                        if (cityInput.val() && stateInput.val())
                            return { city: cityInput.val(), state: stateInput.val() };
                        else
                            return '';
                    } else
                        return '';
            }
        } else
            searchInput = $(".how-to-buy-2__search #generic-searchbox .form-control");

        if (searchInput && searchInput.val()) {
            return searchInput.val();
        }
        else {
            return '';
        }
    }

    function  getSelectedSearchRadius(){
        var radiusBox = $("#how-to-buy-2__search-input-radius");
        if (radiusBox && radiusBox.val())
            return radiusBox.val();
        else
            return 0;
    }

    function getSelectedFilters() {
        var selectedCheckboxFilter = $(".how-to-buy-2__filters :checkbox:checked");
        var selectedRadioFilter = $(".how-to-buy-2__filters :radio:checked");
        var loadedFilters = [];
        $.each(selectedCheckboxFilter, function (index, filter) {
            loadedFilters.push(filter.value);
        });
        $.each(selectedRadioFilter, function (index, filter) {
            loadedFilters.push(filter.value);
        });
        return loadedFilters;
    }

    // initilaize map and bindings based on location source type
    function initMapAndSearch(defaultMapCenter, defaultZoom) {

        var mapContainer = $('.map-container', $(scope)).get(0);

        map = new google.maps.Map(mapContainer, {
            zoom: defaultZoom,
            center: defaultMapCenter
        });

        google.maps.event.addDomListener(window, 'resize', function () {
            //  map.fitBounds(path_bounds);
            map.setCenter(defaultMapCenter);

        });

        service = new google.maps.places.PlacesService(map);

        //if the search is map related (non-agent id based), we will initialize searchbox listeners
        // Create the search box

        //By Agent IDs
        $('.how-to-buy-2__search .form-control', $(scope)).bind("enterKey", function (e) {
            handleSearchInputSubmission();
        });

        //for click
        $('#map-search-button', $(scope)).bind("click", function (e) {
            handleSearchInputSubmission();
        });

        $('.how-to-buy-2__search .form-control', $(scope)).keyup(function (e) {
            if (e.keyCode === 13) {
                $(this).trigger("enterKey");
            }
        });

        $('#search-type-zip', $(scope)).bind("click", function (e) {
            hideAllSearchboxes();
            $("#zip-code-searchbox").show();
            $("#map-search-button").show();
            selectedSearchType = SEARCH_TYPES.ZIP_CODE;
            selectedSearchCountry = SEARCH_COUNTRY.AMERICA;
            $("#dropdownSearchTypeButton").text("Zip Code Search");

            if (filterTypes.AgentDistributors.isSelected || filterTypes.Showrooms.isSelected )
                $("#how-to-buy-2__search-input-radius").show();
        });

        $('#search-type-postal', $(scope)).bind("click", function (e) {
            hideAllSearchboxes();
            $("#postal-code-searchbox").show();
            $("#map-search-button").show();
            selectedSearchType = SEARCH_TYPES.ZIP_CODE;
            selectedSearchCountry = SEARCH_COUNTRY.AMERICA;
            $("#dropdownSearchTypeButton").text("Postal Code Search");
        });

        $('#search-type-city-state', $(scope)).bind("click", function (e) {
            hideAllSearchboxes();
            $("#city-state-searchbox").show();
            $("#map-search-button").show();
            selectedSearchType = SEARCH_TYPES.CITY_STATE;
            selectedSearchCountry = SEARCH_COUNTRY.AMERICA;
            $("#dropdownSearchTypeButton").text("City/State Search");

            if (filterTypes.AgentDistributors.isSelected || filterTypes.Showrooms.isSelected)
                $("#how-to-buy-2__search-input-radius").show();
        });

        $('#search-type-city-province', $(scope)).bind("click", function (e) {
            hideAllSearchboxes();
            $("#city-province-searchbox").show();
            $("#map-search-button").show();
            selectedSearchType = SEARCH_TYPES.CITY_STATE;
            selectedSearchCountry = SEARCH_COUNTRY.CANADA;
            $("#dropdownSearchTypeButton").text("City/Province Search");

            if (filterTypes.AgentDistributors.isSelected || filterTypes.Showrooms.isSelected)
                $("#how-to-buy-2__search-input-radius").show();
        });

        $('#search-type-agency-name', $(scope)).bind("click", function (e) {
            hideAllSearchboxes();
            $("#agency-name-searchbox").show();
            $("#map-search-button").show();
            selectedSearchType = SEARCH_TYPES.AGENCY_NAME;
            selectedSearchCountry = SEARCH_COUNTRY.AMERICA;
            $("#dropdownSearchTypeButton").text("Business Name Search");
        });

        $('#search-type-agent-id', $(scope)).bind("click", function (e) {
            hideAllSearchboxes();
            $("#agent-id-searchbox").show();
            $("#map-search-button").show();
            selectedSearchType = SEARCH_TYPES.AGENT_ID;
            selectedSearchCountry = SEARCH_COUNTRY.AMERICA;
            $("#dropdownSearchTypeButton").text("Agent ID Search");
        });

        initItemListHandlers(filterTypes);

    }

    function getData(url) {
        var deferred = jQuery.Deferred();

        if (!url) {
            return deferred.reject();
        }

        jQuery.get(url)
            .done(function (responseData) {
                deferred.resolve(responseData);
            })
            .fail(function () {
                deferred.reject();
            });

        return deferred;
    }
}
;
var app = app || {};
app.specregistration = app.specregistration || {};


function initSpecMap() {
    var args = app.specregistration.data;
    var initLat = 35.8669864;
    var initLng = -78.8548692;
    var map;
    var markers = [];
    var activeInfowindow = null;
    var service;
    var userLatLong = {};
    var agentsById = [];
    var mostRecentlyFoundGooglePlacesResponse = null;
    var ZipCityArray = new Array();


    var options = {
        initChecked: args.initChecked, key: args.key, defaultZoom: args.defaultZoom, distance: args.distance
    };

    var isFilterEnabledByDefault = function (filterClass) {
        var filterClassLowered = filterClass ? filterClass.toLowerCase() : "";
        return args.DefaultEnabledFilters && args.DefaultEnabledFilters.length && args.DefaultEnabledFilters.some(function (element) {
            return element && element.toLowerCase() === filterClassLowered;
        });
    };

    var filterTypes = {
        US_Agents: {
            isSelected: isFilterEnabledByDefault('us-agents'),
            name: 'US Agents',
            url: args.USAgentBingServiceEndpoint,
            class: 'us-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAADnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIytbQhFDAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        }/*,
        Canada: {
            isSelected: isFilterEnabledByDefault('canada-agents'),
            name: 'Canada Agents',
            url: args.CanadaBingServiceEndpoint,
            class: 'canada-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAYAAAAe2bNZAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAVmSURBVFhHnZhrbBRVFMfPzOy2hW5TlErbbcFqFRYsBUrtKoUKbenDYGtFbbLdYPtFgyYawPgBjcZXQkp8oGg0Jo2oiX5oQq0JWiWibUI0gqlWi3yASFvQIKWBPvY5ez3nzkx3uzszO8Mvmczrzp3/nHPuOWdXYIyBXUY+/4JN/PEnXPl7DILXpiEwOweLclyQm3cz5N+2ApaW3g5lPp+gDreMLTE/dR9kw729EBkbBweLgRSLqXfiCIIAs5IDlt1dAd6H26F0l9+yKMti+vx+dv77E5Apy+A0EMHnEpR7AhPheoYT7mxrg5bDhy0JsiTmg5ZWNn36F8gNR9UrhKjuU4VpREQRgg4JVjc2wv09PWkFaTMa0tvuY3OnfoXFXEfi8Bhaw/xDyII54QiMDnwHXz3zdNqvNhUzdKCbnTs5BK5ICCcmNTGI4ffRRlhzsYiujcFIXz9M9Hxs+oCpm15cW8aWTF4FVzTMY4Cg0WT+kCSBZ9MmKKjcCHluN0yOT8Do4CD8NzKMVkTh6nhCxvEBHF9QVQW+vqOG7jIUc/rV19jxDz+C7GgIMvDLCJo0iu+I3JIPO57bByv9u1ImPv7Uk+y3vi8hK5oU6BjYk5mLoO3A6+DpSH2OMHTT8I+DaN4oSAlaowKuEGcmPLp3r64Qov699wVaQQGnxFcYDRJxr1nq0oVxvtdDV8yZzz5ll8+eQXNHFuSSsFMET3MTFHc+pitEg5Zyzh2rYA7zTRStGUPrkwfoZRcvTCiDdNAVI+IEemDkwJotm9Uzcyq3bYMgipFV2UxUDqampvheD/23JgRfMmR6K+TfWszji6nDRXQ3ZYKZqWvKBR1038pAVo/iWFvGca7+exkc6OHkVCSiq40wvENfRPlEE0FBKFm0ChEMhNWj+CtozuzsHPUsFV0xng6/IC52oYUc874mSaLM4PcTP/DzdPz87TG+AAQsqDJ/WiHfXagepWJomQ3bG2AaC50sOOYTXpYcgXMDAzDa3W3qs6O7d7PQ+BhPDZRrcJHzJU64iwrUo1QMxbgxqypvJMdjHcIjSutLgyE4duhd+HrPHl1B3zzxODvf3w/ZEZk/o200mKGb84qK8Egf03LwVl0dk8/+BS4sdrQaNCgTh0RM757VULr5XmDOLGCBWTiFBTH6z0XIiqB7EuKLykdAEmFNU5Np9TYVc/LgG2zonbfhJrSGEVrRTBRLzPc3SAjzDfU2nS+/AkVdxgkzbT/zZmUlc05cwkwsY3dnPlYPEns9IxOKa2vB98kRQyGEYcxobH2wFWawzsTUVWUXEYNfxppW0dCoXjEmrWWIl8rXstwrk9jXJHZ6C6F5krOz0jqI2Dp4TVsHjbSWIWra23n/YoZemaAqT9X7vtYW9Yo5lsQUlZSoR6nwLK3jQroSlgRYUrYOg7YrrVUIS2IoI9+FVXjGiUkQTU8zaxsvgLFUV9MVah/W125VLljAkhiiorYOAg7sT9D09CLaqE/RRMXBbhBzbkhygmtFCVTve3bhbRMsi6GGqvieagg54nPzXIL7hXbBph3dM4fVubq5Wb1mDctiCG/LDoigZZJJXpFhjKFoQSGsf2G/ZasQtsR4/D7BXb4O5hxOnuIJvQCO4HLe8tBO9cw6tsQQdY/shFmnA5Ogck4Ne2LTTlMyQYJly5er59axLaa4s0vIXrkKXaHkHS1mKH7IWtMZEpTX13Ir8gE2sC2GqGqqR1coYuiNtFHcxDCegg5czjU1/J5dLJUDPQ55vUzE30Dxv0aUfx0K0SodR8wLohE3ZBmipqWVB7L2U4QgN21s2K6e2eeGxWx4fr9Q0tjA//JQYkUE7wPNPFurQ2wC8D/fT+lbfdMtXQAAAABJRU5ErkJggg=='
        }*/
    };

    var scope = ('#how-to-buy-container');

    var urlString = options.data;
    var bingKey = options.key;
    var initCheckedBoolean = /^true$/i.test(options.initChecked);

    // if geolocate is enabled
    if (initCheckedBoolean) {
        geoLocate();
    } else {
        initMapAndSearch({ lat: initLat, lng: initLng }, options.defaultZoom);
    }


    //load city zip code map
    function loadCityZipArray() {
        getData('/assets/json/zip-cities-json.txt').then(function (data) {
            ZipCityArray = eval(data);
        });
    }
    loadCityZipArray();

    function isEmpty(obj) {
        return Object.keys(obj).length === 0;
    }

    // created functions
    function createDirectionLink(address) {
        var encodeUrl = encodeURI(address);
        if (isEmpty(userLatLong)) {
            return "https://www.google.com/maps/dir/?api=1&destination=" + encodeUrl;
        }
        return "https://www.google.com/maps/dir/?api=1&origin=" + userLatLong.lat + "," + userLatLong.lng + "&destination=" + encodeUrl;
    }

    // builds infowindows, attaches event listeners, adds markers and init sidebar 
    function buildStoreInfoContent(result, markerZIndex, filterType, loadAll) {
        var hasDodgeCodes = result.DodgeCodes !== undefined && filterType !== undefined && filterType.name === "US Agents";

        if (hasDodgeCodes) {
            var dodgeCodes = result.DodgeCodes.split(';');
        }

        if (!hasDodgeCodes || (dodgeCodes.length > 1 && !dodgeCodes.includes("0"))) {
            var infoContent;
            var id = (Math.floor(Math.random() * (1000 - 1 + 1) + 1)).toString(),
                business = result.Business,
                address1 = result.AddressLine1,
                address2 = result.AddressLine2,
                city = result.Locality,
                state = result.AdminDistrict,
                zip = result.PostalCode,
                country = result.CountryRegion ? result.CountryRegion : '',
                salesId = result.SalesId,
                salesPhone = result.Phone,
                salesWeb = result.Web,
                salesAgentName = result.AgentName;
            var infoLinks;
            var concatAddress = $.grep([address1, address2], Boolean).join(", ");
            var cityStateZip = city + ', ' + state + ' ' + zip + ' ' + country;
            var selectedFilter = filterType;

            infoContent = "<li class='gm-style " + selectedFilter.class + "'" + "data-id='" + id + ">'";
            infoContent += "<div class='place-name'>" + business + "</div>";
            if (typeof city === 'undefined' || city == "") {
                cityStateZip = "";
            }
            infoContent += "<div class='address'>" + concatAddress + ", " + cityStateZip + "</div>";


            var listContent = "<li data-id='" + id + "' class='" + selectedFilter.class + "'>";
            listContent += "<a href='#' onclick='return false;' class='list-business-name'>" + business + "</a>";
            listContent += "<p>" + concatAddress + "</p>";
            if (cityStateZip !== "") {
                listContent += "<p>" + cityStateZip + "</p>";
            }

            if ((selectedFilter.name === "US Agents" || selectedFilter.name === "International Agents") && typeof salesId !== 'undefined') {
                listContent += "<p>Agent #: " + salesId + "</p>";
                infoContent += "<div class='address'>Agent #: " + salesId + "</div>";
            }

            if (salesWeb !== "" && typeof salesWeb !== 'undefined') {
                if (salesWeb.indexOf("@") > -1) {
                    listContent += "<p><a href='mailto:" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='mailto:" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";
                } else if (salesWeb.indexOf("http") > -1) {
                    listContent += "<p><a href='" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";

                } else {
                    listContent += "<p><a href='http://" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='http://" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";

                }
            }

            if (salesPhone !== "" && typeof salesPhone !== 'undefined') {
                listContent += "<p>" + salesPhone + "</p>";
                infoContent += "<div class='address'>" + salesPhone + "</div>";
            }

            if (salesAgentName !== "" && typeof salesAgentName !== 'undefined') {
                listContent += "<p> Agent: " + salesAgentName + "</p>";
                infoContent += "<div class='address'> Agent: " + salesAgentName + "</div>";
            }

            listContent += "</li>";
            infoContent += "</li></div></div>";
            var address = concatAddress + ", " + cityStateZip;
            infoLinks = "<div class='navigate'>";
            infoLinks += "<a target='_blank' href='" + createDirectionLink(address) + "' class='navigate-link'>";
            infoLinks += "<div class='navigate-tex'>  Get Direction </div></a></div>";

            var info = new google.maps.InfoWindow({
                content: infoContent + infoLinks,
                maxWidth: 400
            });

            addMarker(result, info, id, selectedFilter, markerZIndex);
            if (!loadAll)
                appendItemListMarkup(listContent);
        }
    }

    //checks abbrevs to state
    function abbrState(input, to) {

        var states = stateList;

        if (to == 'abbr') {
            input = input.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });
            for (i = 0; i < states.length; i++) {
                if (states[i][0] == input) {
                    return (states[i][1]);
                }
            }
        } else if (to == 'name') {
            input = input.toUpperCase();
            for (i = 0; i < states.length; i++) {
                if (states[i][1] == input) {
                    return (states[i][0]);
                }
            }
        }
    }

    // closes active info window
    function closeActiveInfowindows() {
        if (activeInfowindow != null) {
            activeInfowindow.close();
        }
    }

    // Adds a marker to the map and push to the array.
    function addMarker(result, info, id, selectedFilter, markerZIndex) {
        var marker = new google.maps.Marker({
            position: { lat: result.Latitude, lng: result.Longitude },
            map: map,
            animation: google.maps.Animation.DROP,
            title: id,
            icon: selectedFilter.icon,
            category: selectedFilter.class,
            zIndex: markerZIndex ? markerZIndex : undefined
        });
        marker.addListener('click', function () {
            closeActiveInfowindows();
            highlightListing(marker, info);
            info.open(map, marker);
            activeInfowindow = info;

            sendMarkerClickEventToGoogleAnalytics(marker, result.Business);
        });
        map.addListener('click', function () {
            info.close();
        });
        markers.push(marker);
    }

    // Sets the map on all markers in the array.
    function setMapOnAll(mapValue) {
        for (var i = 0; i < markers.length; i++) {
            markers[i].setMap(mapValue);
        }
    }

    // Removes the markers from the map, but keeps them in the array.
    function clearMarkers() {
        setMapOnAll(null);
    }

    // Shows any markers currently in the array.
    function showMarkers() {
        setMapOnAll(map);

        if (markers.length > 1) {
            var bounds = new google.maps.LatLngBounds();
            markers.forEach(function (marker) {
                bounds.extend(new google.maps.LatLng(marker.position.lat(), marker.position.lng()));
            });
            map.fitBounds(bounds);

        } else if (markers.length === 1) {
            zoomHere(markers[0]);
        }
    }

    // Deletes all markers in the array by removing references to them.
    function deleteMarkers() {
        clearMarkers();
        markers = [];
    }

    // Zoom '15' for selected marker
    function zoomHere(marker) {
        map.setZoom(15);
        map.panTo(marker.position);
    }

    // Clear items sidebar
    function resetSidebar() {
        $('.items-list', $(scope)).empty();
    }

    // append list items markup
    function appendItemListMarkup(listing) {
        hideSpinner();
        $('.items-list', $(scope)).append(listing);
    }

    // helper method used for marker click bind event
    function highlightListing(marker) {
        var thisId = marker.title;
        $('.items-list li', $(scope)).each(function () {
            if ($(this).attr('data-id') === thisId) {
                $('.items-list li', $(scope)).removeClass('active');
                $(this).addClass('active');
            }
        });
    }

    function getUrlPiecesFromDataFolderString(string) {
        if (string.indexOf(",") !== -1) {
            return string.split(",");
        }
        else {
            return [string];
        }
    }

    // shows pins nearby passed lat and lng
    function loadPinsNearby(lat, lng, distance) {
        distance = distance !== "" ? distance : 100;
        var urlPieces = getUrlPiecesFromDataFolderString(urlString);
        for (x in urlPieces) {
            var urlPiece = urlPieces[x];
            var baseUrl = "https://spatial.virtualearth.net/REST/v1/data/" + urlPiece + "?";
            var filter = "spatialFilter=nearby(" + lat + "," + lng + "," + distance + ")";
            var options = "&$top=250&$format=json&jsonp=?";
            var key = "&key=" + bingKey;

            var url = baseUrl + filter + options + key;
            loadPinsFromUrl(url);
        }
    }

    // loads pins by calling getJSON function for passed url
    function loadPinsFromUrl(url, filterFunc, filterArgs) {
        hideResultMessages();
        $.getJSON(url, function (data) {
            $.each(data["d"].results, function (key, value) {

                //filter pins and check if the search type belongs 
                if (typeof (filterFunc) === 'function') {
                    if (!filterFunc.call(this, value, filterArgs, filterArgs2))
                        return true;
                }
                buildStoreInfoContent(value[0]);
            });

            if (markers.length > 0) {
                hideResultMessages();
                showMarkers();
            } else {
                resetSidebar();
                showNoResultsText();
            }
        });
    }

    function showSpinner() {
        $('.how-to-buy-2__list__addresses', $(scope)).html('<i class="fa fa-spinner fa-spin"></i>');
    }

    function hideSpinner() {
        $('.how-to-buy-2__list__addresses .fa-spinner', $(scope)).remove();
    }


    function getCityStateFromSearch() {
        var searchTerm = getSearchTerm().toUpperCase();
        var states = stateList;
        if (!states) {
            return null;
        }
        var state = states.find(function (o) { return searchTerm.includes(o[0].toUpperCase()); });
        if (state == null) {
            var words = searchTerm.split(' ');
            var stateabbr = words.find(function (element) {
                return element.length == 2;
            });
            if (!stateabbr) {
                return null;
            }
            state = states.find(function (o) { return stateabbr.includes(o[1].toUpperCase()); });
        }
        if (state == null) {
            return null;
        }
        //ZipCityArray
        var cityLong = ZipCityArray.find(function (o) { return o.state.toUpperCase() == state[1].toUpperCase() && searchTerm.includes(o.primary_city.toUpperCase()); });


        //var adminLong = abbrState(data.AdminDistrict, 'name').toUpperCase();
        //if (searchTerm.includes(data.Locality.toUpperCase())
        //    && (searchTerm.includes(data.AdminDistrict.toUpperCase()) || searchTerm.includes(adminLong))) {
            //return [city, state];
        //}
        return cityLong;
    }

    function getCitiesFromSearch() {
        var searchTerm = getSearchTerm().toUpperCase();

        //ZipCityArray
        var stateArr = [];

        var cityLong = ZipCityArray.filter(function (o) {
            if (searchTerm.includes(o.primary_city.toUpperCase()) && !stateArr.includes(o.state)) {
                stateArr.push(o.state);
                return searchTerm.includes(o.primary_city.toUpperCase());
            }
            return false;
        });


        //var adminLong = abbrState(data.AdminDistrict, 'name').toUpperCase();
        //if (searchTerm.includes(data.Locality.toUpperCase())
        //    && (searchTerm.includes(data.AdminDistrict.toUpperCase()) || searchTerm.includes(adminLong))) {
        //return [city, state];
        //}
        return cityLong;
    }

    function displayFilterType(checkBoxfilterArr, filterType, searchedRegionInfo, markerZIndex) {
        var hasAnyFilteredResults = false;
        var hasAnyCityFilteredResults = false;
        var citySearchBox = document.getElementById("cityCheck").checked;
        var searchTerm = getSearchTerm().toUpperCase();
        
        
        var isFilterTypeSelected = checkBoxfilterArr.find(function (element) {
            return element == filterType.class;
        });
        if (isFilterTypeSelected !== undefined && citySearchBox) {
            var uniqueArr = [];
            $.each(filterType.data,
                function (index, data) {
                    var adminLong = abbrState(data.AdminDistrict, 'name').toUpperCase();
                    if (searchTerm.includes(data.Locality.toUpperCase())
                        && (searchTerm.includes(data.AdminDistrict.toUpperCase()) || searchTerm.includes(adminLong))) {
                        hasAnyCityFilteredResults = true;
                    }
                });
        }
        if (isFilterTypeSelected !== undefined) {
            var uniqueArr = [];
            $.each(filterType.data,
                function (index, data) {
                    var matchingItems = $.grep(uniqueArr, function (item) {
                        return item.Business === data.Business && item.AddressLine1 === data.AddressLine1
                            && item.AddressLine2 === data.AddressLine2 && item.AddressLine3 === data.AddressLine3
                            && item.Web === data.Web;
                    });
                    if (matchingItems.length === 0) {
                        buildStoreInfoContent(data, markerZIndex, filterType, searchedRegionInfo.loadAll);
                        hasAnyFilteredResults = true;
                        uniqueArr.push(data);
                    }
                });
        }
        return [hasAnyFilteredResults, hasAnyCityFilteredResults];
    }

    function getSearchTerm() {
        var searchInput = $('#how-to-buy-2__search-input');
        if (searchInput && searchInput.val()) {
            return searchInput.val();
        }
        else {
            return '';
        }
    }

    function getSelectedFiltersAsString() {
        var selectedFilterTypes = $(".how-to-buy-2__filters :checkbox:checked").map(function (index, element) {
            return element.value;
        }).toArray();
        return selectedFilterTypes.join(', ');
    }

    function sendNoResultsDataToGoogleAnalytics() {
        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Search - No Results Found - '.concat(
                'Page: "' + window.location.href + '"',
                ' . Search Term: "' + getSearchTerm() + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"'),
            Label: 'How To Buy Search - No Results Found'
        });
    }

    function sendMarkerClickEventToGoogleAnalytics(marker, businessName) {
        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Map Click - '.concat(
                'Page: "' + window.location.href + '"',
                ' Business: "' + businessName + '"',
                ' . Search Term: "' + getSearchTerm() + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"'),
            Label: 'How To Buy Map Click'
        });
    }

    function clearStoredFilterData() {
        Object.values(filterTypes).forEach(function (filterValue) {
            filterValue.allFilterData = [];
            filterValue.wasRadialSearchPerformed = false;
        });
    }

    function loadSearchByRegionDataToView(checkBoxfilterArr, searchedRegionInfo) {
        var generateMapEntry = function (requestFunc, filterToPopulate, optionalFilterFunc) {
            return {
                requestFunc: requestFunc,
                filter: filterToPopulate,
                optionalFilterFunc: optionalFilterFunc
            };
        };

        clearStoredFilterData();

        var getUsAgentData = function (isFollowupRequest) { return getUSAgents(searchedRegionInfo, isFollowupRequest); };
        //var getCanadaData = function (isFollowupRequest) { return getCanadaAgents(searchedRegionInfo, isFollowupRequest); };

        var internationalDataFilterFunc = function (data) {
            if (agentsById.length > 0) {
                var index = data.d.results.map(function (e) { return e.Id; }).indexOf(agentsById[0].Id);
                if (index !== -1) {
                    data.d.results.splice(index, 1);
                }
            }

            filterTypes.International.data = data.d.results;
        };

        var requestDataMap = [
            generateMapEntry(getUsAgentData, filterTypes.US_Agents)
            //generateMapEntry(getCanadaData, filterTypes.Canada),
        ].filter(function (requestData) {
            // only send new requests when the filter is selected and the search term has changed since the last request
            return requestData.filter.isSelected && requestData.filter.hasResultsForSearchTerm !== searchedRegionInfo.searchTerm;
        });      


        var updateFilterDataFromResponse = function (responseData, filter, isFollowupRequestData) {
            if (responseData && responseData.d && responseData.d.results && responseData.d.results.length) {
                var citySearchBox = document.getElementById("cityCheck").checked;
                var cityState = getCityStateFromSearch();
                var citiesOnly = getCitiesFromSearch();

                if (citySearchBox && !cityState && citiesOnly && citiesOnly.length > 0) {
                    var cityZips = citiesOnly.map(function (a) { return a.zip; });
                    responseData.d.results = responseData.d.results.filter(function (element) {
                        var allTerritoryZipCodes = "";
                        if (element["Territory1"]) {
                            for (var i = 1; i < 21; i++) {
                                if (element["Territory" + i]) {
                                    allTerritoryZipCodes = allTerritoryZipCodes.concat(element["Territory" + i]);
                                }
                            }
                        }
                        console.log(allTerritoryZipCodes);
                        return cityZips.find(function (element) {
                            return allTerritoryZipCodes.includes(element);
                        });
                    });                    
                }

                if (filter.optionalFilterFunc) {
                    filter.optionalFilterFunc(responseData);
                }
                else {
                    filter.allFilterData = filter.allFilterData.concat(responseData.d.results);
                }

                if (isFollowupRequestData) {
                    filter.wasRadialSearchPerformed = true;
                }
            }
            //if (document.getElementById("cityCheck").checked) {
            //    var cityState = getCityStateFromSearch();
            //    if (cityState) {

            //    }
            //}
        };

        var storeResultsForInMemoryFilter = function (responseData, filter) {
            if (responseData && responseData.d && responseData.d.results && responseData.d.results.length) {
                filter.allResultsForDataSource = responseData.d.results;
            }
        };

        var filterResultsInMemory = function (results, regionSearchInfo) {
            var searchTerm = regionSearchInfo.searchTerm;
            if (!searchTerm || !searchTerm.length || !regionSearchInfo.isPostalRegion) {
                return [];
            }

            function getZipCodesForResult(searchResult) {
                var allTerritoryZipCodes = [];

                if (searchResult["Territory1"]) {
                    for (var i = 1; i < 21; i++) {
                        if (searchResult["Territory" + i]) {
                            allTerritoryZipCodes = allTerritoryZipCodes.concat(searchResult["Territory" + i].split(';'));
                        }
                    }
                }

                return allTerritoryZipCodes;
            }


            searchTerm = searchTerm.trim();
            return results.filter(function (result) {
                return getZipCodesForResult(result).includes(searchTerm.trim());
            });
        };

        var collapseFilterResponseData = function (filter, regionSearchInfo) {
            var serverResponseData = filter.allFilterData;
            var inMemorySearchHits = filter.allResultsForDataSource ? filterResultsInMemory(filter.allResultsForDataSource, regionSearchInfo) : [];

            var dataPointsToRender = inMemorySearchHits;
            filter.hasTerritoryMatch = inMemorySearchHits && inMemorySearchHits.length > 0;
            if (!inMemorySearchHits || !inMemorySearchHits.length) {
                dataPointsToRender = dataPointsToRender.concat(serverResponseData);
            }
            filter.hasResultsForSearchTerm = regionSearchInfo.searchTerm;
            // get uniques by id
            return dataPointsToRender.map(function (filterDataItem) {
                return {
                    id: filterDataItem.Id,
                    filterData: filterDataItem
                };
            }).filter(function (value, index, self) {
                return self.findIndex(function (element) {
                    return element.id === value.id;
                }) === index;
            }).map(function (item) {
                return item.filterData;
            });
        };

        var promisesForAllFilters = [];

        requestDataMap.forEach(function (element) {
            var executedRequestData = element.requestFunc();
            executedRequestData = executedRequestData && Array.isArray(executedRequestData) ? executedRequestData : [executedRequestData];

            var requestSuccessHandler = function (responseData, requestItem) {
                var processResultsAsFilteredByServer = !requestItem.isClientFilterRequest;
                var processResultsAsClientFilter = requestItem.isClientFilterRequest || requestItem.isBlankQuery;
                if (processResultsAsFilteredByServer) {
                    updateFilterDataFromResponse(responseData, element.filter);
                }
                if (processResultsAsClientFilter) {
                    storeResultsForInMemoryFilter(responseData, element.filter);
                }
            };

            var failureHandler = function (responseData, failedFilterClass) {
                console.log('Request for ' + failedFilterClass + ' failed.');
            };

            var createDeferredPromiseForRequest = function (request) {
                return request ? $.Deferred() : null;
            };

            var primaryRequestsWithDeferred = executedRequestData.map(function (requestItem) {
                return {
                    requestItem: requestItem,
                    deferredPromise: createDeferredPromiseForRequest(requestItem.request)
                };
            });

            primaryRequestsWithDeferred.forEach(function (requestWithDeferredPromise) {
                requestWithDeferredPromise.requestItem.request.done(function (responseData) {
                    requestSuccessHandler(responseData, requestWithDeferredPromise.requestItem);
                    requestWithDeferredPromise.deferredPromise.resolve();
                }).fail(function (failureData) {
                    failureHandler(failureData, element.filter.class);
                    requestWithDeferredPromise.deferredPromise.resolve();
                });
            });

            var deferredPromises = primaryRequestsWithDeferred.map(function (req) {
                return req.deferredPromise;
            });

            // aggregate results when the requests for this particular filter are finished
            var promiseForThisFilter = $.when.apply($, deferredPromises);
            promisesForAllFilters.push(promiseForThisFilter);
            promiseForThisFilter.done(function () {
                // attempt to run a wider search if there were no results for the user's search

                if (element.filter.allFilterData.length === 0) {
                    var followupRequestData = element.requestFunc(true);
                    followupRequestData = followupRequestData && Array.isArray(followupRequestData) ? followupRequestData : [followupRequestData];

                    var followupRequestsWithDeferred = followupRequestData.map(function (requestItem) {
                        return {
                            requestItem: requestItem,
                            deferredPromise: createDeferredPromiseForRequest(requestItem.request)
                        };
                    });

                    followupRequestsWithDeferred.forEach(function (followupRequestWithDeferred) {
                        followupRequestWithDeferred.requestItem.request.done(function (followupResponseData) {
                            updateFilterDataFromResponse(followupResponseData, element.filter, true);
                            followupRequestWithDeferred.deferredPromise.resolve();
                        }).fail(function (failureData) {
                            failureHandler(failureData, element.filter.class);
                            followupRequestWithDeferred.deferredPromise.resolve();
                        });
                    });

                    var followupDeferredPromises = followupRequestsWithDeferred.map(function (requestWithDeferredPromise) {
                        return requestWithDeferredPromise.deferredPromise;
                    });

                    var followupPromise = $.when.apply($, followupDeferredPromises);
                    followupPromise.done(function () {
                        element.filter.data = collapseFilterResponseData(element.filter, searchedRegionInfo);
                    });

                    element.followupPromise = followupPromise;
                }
                else {
                    element.filter.data = collapseFilterResponseData(element.filter, searchedRegionInfo);
                }
            });
        });

        // decide what to display when ALL of the requests are finished and results are processed
        $.when.apply($, promisesForAllFilters).done(
            function () {

                var followupPromises = requestDataMap.filter(function (requestMapEntry) {
                    return requestMapEntry.followupPromise;
                }).map(function (requestMapEntry) {
                    return requestMapEntry.followupPromise;
                });

                if (followupPromises && followupPromises.length) {
                    $.when.apply($, followupPromises).done(
                        function () {
                            processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo);
                        });
                } else {
                    processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo);
                }
            }
        );
    }


    function wasRadialSearchPerformed(filterTypes) {
        return Object.values(filterTypes).some(function (filter) {
            return filter && filter.data && filter.data.length && filter.wasRadialSearchPerformed;
        });
    };

    function processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo) {
        deleteMarkers();
        if (checkBoxfilterArr.length == 0) {
            hideSpinner();

            showNoResultsText();
        }

        var usResults = displayFilterType(checkBoxfilterArr, filterTypes.US_Agents, searchedRegionInfo, 990);
        //var canadaResults = displayFilterType(checkBoxfilterArr, filterTypes.Canada, searchedRegionInfo, 960);

        var hasAnyFilteredResults = usResults[0]; // || canadaResults
        var hasAnyFilteredCityResults = usResults[1];

        hideSpinner();
        var searchTerm = getSearchTerm();
        var hasAnyResults = hasAnyFilteredResults || $(".how-to-buy-2__list__addresses li").length > 0;
        var citySearch = document.getElementById("cityCheck").checked;
        var isZip = isPostalCode(searchTerm);
        if (isZip && filterTypes.US_Agents.isSelected && searchTerm && searchTerm != "") {
            showUSAgentExactMatchMessage();        
        }
        else if (hasAnyResults && citySearch && filterTypes.US_Agents.isSelected && searchTerm && searchTerm != "") {
            showUSAgentExactCityMatchMessage();
        }
        else if (filterTypes.US_Agents.isSelected && filterTypes.US_Agents.hasTerritoryMatch) {
            showUSAgentTerritoryMatchMessage();
        }
        else if (hasAnyResults && wasRadialSearchPerformed(filterTypes)) {
            if (filterTypes.US_Agents.isSelected && searchedRegionInfo.isPostalRegion) {
                showUSAgentRadialSearchMessage();
            }
            else {
                showRadialSearchMessage();
            }
            //} else if (!searchedRegionInfo.isPostalRegion && !hasAnyResults) {
            //    showSearchTips();
        } else if (!hasAnyResults) {
            showNoResultsText();
        }
        else if (hasAnyResults && getSearchTerm()) {
            showRadialSearchMessage();
        }

        if (!hasAnyFilteredResults) {
            sendNoResultsDataToGoogleAnalytics();
        }

        showMarkers();
    }

    function showSearchTips() {
        hideResultMessages()
        $('.no-results-found-search-tips', $(scope)).show();
    }

    function showNoResultsText() {
        hideResultMessages()
        $('.no-agents-found', $(scope)).show();
    }

    function showRadialSearchMessage() {
        hideResultMessages()
        $('.zip-no-agents-found', $(scope)).show();
    }

    function showUSAgentRadialSearchMessage() {
        hideResultMessages()
        $('.zip-no-agents-found', $(scope)).show();
    }

    function showUSAgentTerritoryMatchMessage() {
        hideResultMessages()
        $('.zip-no-exact-match', $(scope)).show();
    }
    function showUSAgentExactCityMatchMessage() {
        hideResultMessages()
        $('.city-exact-match', $(scope)).show();
    }

    function showUSAgentExactMatchMessage() {
        hideResultMessages()
        $('.zip-exact-match', $(scope)).show();
    }
    function showSearchZipMessage() {
        hideResultMessages()
        $('.search-zip-text', $(scope)).show();
    }


    function hideResultMessages() {
        $('.how-to-buy-search-result-indicator', $(scope)).hide();
    }

    var stateList =
        [
            ['Arizona', 'AZ'],
            ['Alabama', 'AL'],
            ['Alaska', 'AK'],
            ['Arkansas', 'AR'],
            ['California', 'CA'],
            ['Colorado', 'CO'],
            ['Connecticut', 'CT'],
            ['Delaware', 'DE'],
            ['Florida', 'FL'],
            ['Georgia', 'GA'],
            ['Hawaii', 'HI'],
            ['Idaho', 'ID'],
            ['Illinois', 'IL'],
            ['Indiana', 'IN'],
            ['Iowa', 'IA'],
            ['Kansas', 'KS'],
            ['Kentucky', 'KY'],
            ['Louisiana', 'LA'],
            ['Maine', 'ME'],
            ['Maryland', 'MD'],
            ['Massachusetts', 'MA'],
            ['Michigan', 'MI'],
            ['Minnesota', 'MN'],
            ['Mississippi', 'MS'],
            ['Missouri', 'MO'],
            ['Montana', 'MT'],
            ['Nebraska', 'NE'],
            ['Nevada', 'NV'],
            ['New Hampshire', 'NH'],
            ['New Jersey', 'NJ'],
            ['New Mexico', 'NM'],
            ['New York', 'NY'],
            ['North Carolina', 'NC'],
            ['North Dakota', 'ND'],
            ['Ohio', 'OH'],
            ['Oklahoma', 'OK'],
            ['Oregon', 'OR'],
            ['Pennsylvania', 'PA'],
            ['Rhode Island', 'RI'],
            ['South Carolina', 'SC'],
            ['South Dakota', 'SD'],
            ['Tennessee', 'TN'],
            ['Texas', 'TX'],
            ['Utah', 'UT'],
            ['Vermont', 'VT'],
            ['Virginia', 'VA'],
            ['Washington', 'WA'],
            ['West Virginia', 'WV'],
            ['Wisconsin', 'WI'],
            ['Wyoming', 'WY'],
            ['Alberta', 'AB'],
            ['British Columbia', 'BC'],
            ['Manitoba', 'MB'],
            ['New Brunswick', 'NB'],
            ['Newfoundland', 'NF'],
            ['Northwest Territory', 'NT'],
            ['Nova Scotia', 'NS'],
            ['Nunavut', 'NU'],
            ['Ontario', 'ON'],
            ['Prince Edward Island', 'PE'],
            ['Quebec', 'QC'],
            ['Saskatchewan', 'SK'],
            ['Yukon', 'YT']
        ];

    function getStateBoundingBoxes() {
        return {
            // xmin, ymin, xmax, ymax 
            al: [-88.473227, 30.223334, -84.88908, 35.008028],
            ak: [-179.148909, 51.214183, 179.77847, 71.365162],
            as: [-171.089874, -14.548699, -168.1433, -11.046934],
            az: [-114.81651, 31.332177, -109.045223, 37.00426],
            ar: [-94.617919, 33.004106, -89.644395, 36.4996],
            ca: [-124.409591, 32.534156, -114.131211, 42.009518],
            co: [-109.060253, 36.992426, -102.041524, 41.003444],
            mp: [144.886331, 14.110472, 146.064818, 20.553802],
            ct: [-73.727775, 40.980144, -71.786994, 42.050587],
            de: [-75.788658, 38.451013, -75.048939, 39.839007],
            dc: [-77.119759, 38.791645, -76.909395, 38.99511],
            fl: [-87.634938, 24.523096, -80.031362, 31.000888],
            ga: [-85.605165, 30.357851, -80.839729, 35.000659],
            gu: [144.618068, 13.234189, 144.956712, 13.654383],
            hi: [-178.334698, 18.910361, -154.806773, 28.402123],
            id: [-117.243027, 41.988057, -111.043564, 49.001146],
            il: [-91.513079, 36.970298, -87.494756, 42.508481],
            in: [-88.09776, 37.771742, -84.784579, 41.760592],
            ia: [-96.639704, 40.375501, -90.140061, 43.501196],
            ks: [-102.051744, 36.993016, -94.588413, 40.003162],
            ky: [-89.571509, 36.497129, -81.964971, 39.147458],
            la: [-94.043147, 28.928609, -88.817017, 33.019457],
            me: [-71.083924, 42.977764, -66.949895, 47.459686],
            md: [-79.487651, 37.911717, -75.048939, 39.723043],
            ma: [-73.508142, 41.237964, -69.928393, 42.886589],
            mi: [-90.418136, 41.696118, -82.413474, 48.2388],
            mn: [-97.239209, 43.499356, -89.491739, 49.384358],
            ms: [-91.655009, 30.173943, -88.097888, 34.996052],
            mo: [-95.774704, 35.995683, -89.098843, 40.61364],
            mt: [-116.050003, 44.358221, -104.039138, 49.00139],
            ne: [-104.053514, 39.999998, -95.30829, 43.001708],
            nv: [-120.005746, 35.001857, -114.039648, 42.002207],
            nh: [-72.557247, 42.69699, -70.610621, 45.305476],
            nj: [-75.559614, 38.928519, -73.893979, 41.357423],
            nm: [-109.050173, 31.332301, -103.001964, 37.000232],
            ny: [-79.762152, 40.496103, -71.856214, 45.01585],
            nc: [-84.321869, 33.842316, -75.460621, 36.588117],
            nd: [-104.0489, 45.935054, -96.554507, 49.000574],
            oh: [-84.820159, 38.403202, -80.518693, 41.977523],
            ok: [-103.002565, 33.615833, -94.430662, 37.002206],
            or: [-124.566244, 41.991794, -116.463504, 46.292035],
            pa: [-80.519891, 39.7198, -74.689516, 42.26986],
            pr: [-67.945404, 17.88328, -65.220703, 18.515683],
            ri: [-71.862772, 41.146339, -71.12057, 42.018798],
            sc: [-83.35391, 32.0346, -78.54203, 35.215402],
            sd: [-104.057698, 42.479635, -96.436589, 45.94545],
            tn: [-90.310298, 34.982972, -81.6469, 36.678118],
            tx: [-106.645646, 25.837377, -93.508292, 36.500704],
            vi: [-65.085452, 17.673976, -64.564907, 18.412655],
            ut: [-114.052962, 36.997968, -109.041058, 42.001567],
            vt: [-73.43774, 42.726853, -71.464555, 45.016659],
            va: [-83.675395, 36.540738, -75.242266, 39.466012],
            wa: [-124.763068, 45.543541, -116.915989, 49.002494],
            wv: [-82.644739, 37.201483, -77.719519, 40.638801],
            wi: [-92.888114, 42.491983, -86.805415, 47.080621],
            wy: [-111.056888, 40.994746, -104.05216, 45.005904],
            on: [-95.15, 41.68, -74.32, 56.86],
            qc: [-79.77, 44.99, -57.11, 62.58],
            ns: [-66.4471, 43.2718, -59.6188, 47.2351],
            nb: [-69.0535, 44.5561, -63.6147, 48.0897],
            mb: [-102.01, 49.0, -88.99, 60.0],
            bc: [-139.05, 48.22, -114.05, 60.0],
            pe: [-64.41, 45.95, -61.97, 47.06],
            sk: [-110.01, 49.0, -101.36, 60.0],
            ab: [-120.0, 49.0, -110.0, 60.0],
            nl: [-67.82, 46.6, -52.61, 60.38]
        };
    }

    function getCountryBoundingBoxes() {
        return {

            aw: [12.1702998, -70.2809842, 12.8102998, -69.6409842],
            af: [29.3772, 60.5176034, 38.4910682, 74.889862],
            ao: [-18.038945, 11.4609793, -4.3880634, 24.0878856],
            ai: [18.0615454, -63.6391992, 18.7951194, -62.7125449],
            //ALA: [59.4541578, 19.0832098, 60.87665, 21.3456556],
            al: [11.081041, -72.6598913, 11.408791, -72.4039128],
            ad: [42.4288238, 1.4135781, 42.6559357, 1.7863837],
            //ANT: [12.1544542, -68.940593, 12.1547472, -68.9403518],
            ae: [22.6444, 51.4980, 26.2822, 56.3834],
            ar: [-55.1850761, -73.5600329, -21.781168, -53.6374515],
            am: [4.3951997, -75.7854388, 4.5895768, -75.6325211],
            as: [-14.7608358, -171.2951296, -10.8449746, -167.9322899],
            aq: [-85.0511287, -180.0, -60.0, 180.0],
            tf: [-50.2187169, 39.4138676, -11.3139928, 77.8494974],
            ag: [16.7573901, -62.5536517, 17.929, -61.447857],
            au: [-55.3228175, 72.2460938, -9.0882278, 168.2249543],
            at: [46.3722761, 9.5307487, 49.0205305, 17.160776],
            az: [38.3929551, 44.7633701, 41.9502947, 51.0090302],
            bi: [-4.4693155, 29.0007401, -2.3096796, 30.8498462],
            be: [49.4969821, 2.3889137, 51.5516667, 6.408097],
            bj: [6.1730586, 5.4621058, 6.4930586, 5.7821058],
            bf: [9.4104718, -5.5132416, 15.084, 2.4089717],
            bd: [20.3756582, 88.0075306, 26.6382534, 92.6804979],
            bg: [41.2353929, 22.3571459, 44.2167064, 28.8875409],
            bh: [35.1878012, 72.5273968, 35.2278012, 72.5673968],
            bs: [20.7059846, -80.7001941, 27.4734551, -72.4477521],
            ba: [42.5553114, 15.7287433, 45.2764135, 19.6237311],
            bl: [17.670931, -63.06639, 18.1375569, -62.5844019],
            by: [51.2575982, 23.1783344, 56.17218, 32.7627809],
            bz: [15.8857286, -89.2262083, 18.496001, -87.3098494],
            bm: [32.0469651, -65.1232222, 32.5913693, -64.4109842],
            bo: [-22.8982742, -69.6450073, -9.6689438, -57.453],
            br: [-33.8689056, -73.9830625, 5.2842873, -28.6341164],
            bb: [12.845, -59.8562115, 13.535, -59.2147175],
            bn: [4.002508, 114.0758734, 5.1011857, 115.3635623],
            bt: [26.702016, 88.7464724, 28.246987, 92.1252321],
            bv: [-54.654, 2.9345531, -54.187, 3.7791099],
            bw: [-26.9059669, 19.9986474, -17.778137, 29.375304],
            cf: [25.217277, 55.1742999, 25.2194356, 55.1762608],
            ca: [41.6765556, -141.00275, 83.3362128, -52.3231981],
            cc: [-12.4055983, 96.612524, -11.6213132, 97.1357343],
            ch: [45.817995, 5.9559113, 47.8084648, 10.4922941],
            cl: [-56.725, -109.6795789, -17.4983998, -66.0753474],
            cn: [25.0671341, -99.4612273, 25.9161824, -98.421576],
            ci: [4.1621205, -8.601725, 10.740197, -2.493031],
            cm: [1.6546659, 8.3822176, 13.083333, 16.1921476],
            cd: [-4.2726671, 15.2829578, -4.2723703, 15.283136],
            cg: [-5.149089, 11.0048205, 3.713056, 18.643611],
            ck: [-22.15807, -166.0856468, -8.7168792, -157.1089329],
            co: [-4.2316872, -82.1243666, 16.0571269, -66.8511907],
            km: [-12.621, 43.025305, -11.165, 44.7451922],
            cv: [14.8031546, -25.3609478, 17.2053108, -22.6673416],
            cr: [5.3329698, -87.2722647, 11.2195684, -82.5060208],
            cu: [19.6275294, -85.1679702, 23.4816972, -73.9190004],
            cx: [-10.5698515, 105.5336422, -10.4123553, 105.7130159],
            ky: [19.0620619, -81.6313748, 19.9573759, -79.5110954],
            cy: [27.4823018, 25.6451285, 42.4823018, 40.6451285],
            cz: [48.5518083, 12.0905901, 51.0557036, 18.859216],
            de: [47.2701114, 5.8663153, 55.099161, 15.0419319],
            dj: [10.9149547, 41.7713139, 12.7923081, 43.6579046],
            dm: [15.0074207, -61.6869184, 15.7872222, -61.0329895],
            dk: [54.4516667, 7.7153255, 57.9524297, 15.5530641],
            do: [17.2701708, -72.0574706, 21.303433, -68.1101463],
            dz: [18.968147, -8.668908, 37.2962055, 11.997337],
            ec: [-5.0159314, -92.2072392, 1.8835964, -75.192504],
            eg: [22.0, 24.6499112, 31.8330854, 37.1153517],
            er: [25.2197993, 55.1720522, 25.2220008, 55.1736716],
            eh: [24.1597324, -13.7867848, 24.1997324, -13.7467848],
            es: [27.4335426, -18.3936845, 43.9933088, 4.5918885],
            ee: [57.5092997, 21.3826069, 59.9383754, 28.2100175],
            et: [3.397448, 32.9975838, 14.8940537, 47.9823797],
            fi: [59.4541578, 19.0832098, 70.0922939, 31.5867071],
            fj: [-21.9434274, -180.0, -12.2613866, 180.0],
            fk: [-53.1186766, -61.7726772, -50.7973007, -57.3662367],
            fr: [41.2632185, -5.4534286, 51.268318, 9.8678344],
            fo: [61.3915553, -7.6882939, 62.3942991, -6.2565525],
            fm: [0.827, 137.2234512, 10.291, 163.2364054],
            ga: [-4.1012261, 8.5002246, 2.3182171, 14.539444],
            gb: [25.2223186, 55.1579517, 25.2241651, 55.1606916],
            ge: [30.355757, -85.6051201, 35.0013544, -80.7514321],
            gg: [49.4155331, -2.6751703, 49.5090776, -2.501814],
            gh: [4.5392525, -3.260786, 11.1748562, 1.2732942],
            gi: [36.100807, -5.3941295, 36.180807, -5.3141295],
            gn: [38.1240893, -77.4591124, 38.1640893, -77.4191124],
            gp: [15.8320085, -61.809764, 16.5144664, -61.0003663],
            gm: [13.061, -17.0288254, 13.8253137, -13.797778],
            gw: [10.6514215, -16.894523, 12.6862384, -13.6348777],
            gq: [-1.6732196, 5.4172943, 3.989, 11.3598628],
            gr: [34.7006096, 19.2477876, 41.7488862, 29.7296986],
            gd: [11.786, -62.0065868, 12.5966532, -61.1732143],
            gl: [43.0015105, -70.907562, 43.0770931, -70.805801],
            gt: [13.6345804, -92.3105242, 17.8165947, -88.1755849],
            gf: [2.112222, -54.60278, 5.7507111, -51.6346139],
            gu: [13.182335, 144.563426, 13.706179, 145.009167],
            gy: [1.1710017, -61.414905, 8.6038842, -56.4689543],
            hk: [22.1193278, 114.0028131, 22.4393278, 114.3228131],
            hm: [-53.394741, 72.2460938, -52.7030677, 74.1988754],
            hn: [12.9808485, -89.3568207, 17.619526, -82.1729621],
            hr: [42.1765993, 13.2104814, 46.555029, 19.4470842],
            ht: [21.7470269, -78.1147805, 21.7870269, -78.0747805],
            hu: [45.737128, 16.1138867, 48.585257, 22.8977094],
            id: [-11.2085669, 94.7717124, 6.2744496, 141.0194444],
            im: [54.0539576, -4.7946845, 54.4178705, -4.3076853],
            in: [6.5546079, 68.1113787, 35.6745457, 97.395561],
            io: [-7.6454079, 71.036504, -5.037066, 72.7020157],
            ie: [51.222, -11.0133788, 55.636, -5.6582363],
            ir: [24.8465103, 44.0318908, 39.7816502, 63.3332704],
            iq: [29.0585661, 38.7936719, 37.380932, 48.8412702],
            is: [51.3863696, 0.5475318, 51.3868275, 0.5479162],
            il: [29.4533796, 34.2674994, 33.3356317, 35.8950234],
            it: [35.2889616, 6.6272658, 47.0921462, 18.7844746],
            jm: [16.5899443, -78.5782366, 18.7256394, -75.7541143],
            je: [49.1625179, -2.254512, 49.2621288, -2.0104193],
            jo: [10.5378127, 122.4078085, 10.6910595, 122.6356296],
            jp: [20.2145811, 122.7141754, 45.7112046, 154.205541],
            kz: [40.5686476, 46.4932179, 55.4421701, 87.3156316],
            ke: [-4.8995204, 33.9098987, 4.62, 41.899578],
            kg: [39.1728437, 69.2649523, 43.2667971, 80.2295793],
            kh: [9.4752639, 102.3338282, 14.6904224, 107.6276788],
            ki: [-7.0516717, -179.1645388, 7.9483283, -164.1645388],
            kn: [16.895, -63.051129, 17.6158146, -62.3303519],
            kr: [37.52806, 126.89575, 37.52816, 126.89585],
            kw: [-12.0494672, -72.8801102, -12.0094672, -72.8401102],
            la: [13.9096752, 100.0843247, 22.5086717, 107.6349989],
            lb: [40.3199193, -76.4508668, 40.355802, -76.391965],
            lr: [4.1555907, -11.6080764, 8.5519861, -7.367323],
            ly: [19.5008138, 9.391081, 33.3545898, 25.3770629],
            lc: [13.508, -61.2853867, 14.2725, -60.6669363],
            li: [47.0484291, 9.4716736, 47.270581, 9.6357143],
            lk: [25.2287738, 55.1813071, 25.2303051, 55.1828523],
            ls: [-30.6772773, 27.0114632, -28.570615, 29.4557099],
            lt: [53.8967893, 20.653783, 56.4504213, 26.8355198],
            lu: [49.4969821, 4.9684415, 50.430377, 6.0344254],
            lv: [55.6746505, 20.6715407, 58.0855688, 28.2414904],
            mo: [25.2349583, 55.1803834, 25.2368385, 55.1821684],
            mf: [17.8963535, -63.3605643, 18.1902778, -62.7644063],
            ma: [21.3365321, -17.2551456, 36.0505269, -0.998429],
            mc: [43.7247599, 7.4090279, 43.7519311, 7.4398704],
            md: [46.6744934, 29.7521496, 46.6745934, 29.7522496],
            mg: [-25.6071002, 43.2202072, -11.9519693, 50.4862553],
            mv: [25.2252959, 55.1823199, 25.2263769, 55.1837469],
            mx: [19.2726009, -99.2933416, 19.5926009, -98.9733416],
            mh: [-0.5481258, 163.4985095, 14.4518742, 178.4985095],
            mk: [40.8536596, 20.4529023, 42.3735359, 23.034051],
            ml: [10.147811, -12.2402835, 25.001084, 4.2673828],
            mt: [35.6029696, 13.9324226, 36.2852706, 14.8267966],
            mm: [9.4399432, 92.1719423, 28.547835, 101.1700796],
            me: [-29.8446455, -51.662, -29.5743342, -51.3498193],
            mn: [41.5800276, 87.73762, 52.1496, 119.931949],
            mp: [14.036565, 144.813338, 20.616556, 146.154418],
            mz: [19.038889, -96.274167, 19.078889, -96.234167],
            mr: [25.2143602, 55.1665334, 25.2163939, 55.1690669],
            ms: [16.475, -62.450667, 17.0152978, -61.9353818],
            mq: [14.3948596, -61.2290815, 14.8787029, -60.8095833],
            mu: [-20.725, 56.3825151, -10.138, 63.7151319],
            mw: [-17.1296031, 32.6703616, -9.3683261, 35.9185731],
            my: [-5.1076241, 105.3471939, 9.8923759, 120.3471939],
            yt: [-13.0210119, 45.0183298, -12.6365902, 45.2999917],
            na: [-28.96945, 11.5280384, -16.9634855, 25.2617671],
            nc: [33.0351363, -92.6876556, 33.0751363, -92.6476556],
            ne: [11.693756, 0.1689653, 23.517178, 15.996667],
            nf: [-29.333, 167.6873878, -28.796, 168.2249543],
            ng: [4.0690959, 2.676932, 13.885645, 14.678014],
            ni: [10.7076565, -87.901532, 15.0331183, -82.6227023],
            nu: [-19.0840514, -169.9383436, -19.0739661, -169.9129672],
            nl: [11.825, -52.35, 53.7253321, 7.2274985],
            no: [57.7590052, 4.0875274, 71.3848787, 31.7614911],
            np: [26.3477581, 80.0586226, 30.446945, 88.2015257],
            nr: [-0.5541334, 166.9091794, -0.5025906, 166.9589235],
            nz: [-52.8213687, -179.059153, -29.0303303, 179.3643594],
            om: [25.2268538, 55.1759911, 25.2291352, 55.1773672],
            pk: [23.5393916, 60.872855, 37.084107, 77.1203914],
            pa: [35.246906, -119.0767707, 35.286906, -119.0367707],
            pn: [-25.1306736, -130.8049862, -23.8655769, -124.717534],
            pe: [41.309511, -89.164781, 41.38197, -89.105652],
            ph: [4.2158064, 114.0952145, 21.3217806, 126.8072562],
            pw: [42.5481153, 2.9351868, 42.5844284, 2.9840518],
            pg: [-13.1816069, 136.7489081, 1.8183931, 151.7489081],
            pl: [49.0020468, 14.1229707, 55.0336963, 24.145783],
            pr: [17.9268695, -67.271492, 18.5159789, -65.5897525],
            kp: [37.5867855, 124.0913902, 43.0089642, 130.924647],
            pt: [29.8288021, -31.5575303, 42.1543112, -6.1891593],
            py: [-27.6063935, -62.6442036, -19.2876472, -54.258],
            ps: [31.2201289, 34.0689732, 32.5521479, 35.5739235],
            pf: [-28.0990232, -154.9360599, -7.6592173, -134.244799],
            qa: [25.2271767, 55.1726803, 25.2289841, 55.1741485],
            re: [-21.3897308, 55.2164268, -20.8717136, 55.8366924],
            ro: [43.618682, 20.2619773, 48.2653964, 30.0454257],
            ru: [41.1850968, 19.6389, 82.0586232, 180],
            rw: [-2.8389804, 28.8617546, -1.0474083, 30.8990738],
            sa: [14.4840316, 121.0177023, 14.4846897, 121.0265441],
            sd: [10.88, 6.48, 10.92, 6.52],
            sn: [12.2372838, -17.7862419, 16.6919712, -11.3458996],
            sg: [1.1304753, 103.6920359, 1.4504753, 104.0120359],
            gs: [-59.684, -42.354739, -53.3500755, -25.8468303],
            sh: [-16.23, -5.9973424, -15.704, -5.4234153],
            sj: [70.6260825, -9.6848146, 81.028076, 34.6891253],
            sb: [-13.2424298, 155.3190556, -4.81085, 170.3964667],
            sl: [6.755, -13.5003389, 9.999973, -10.271683],
            sv: [12.976046, -90.1790975, 14.4510488, -87.6351394],
            sm: [43.8937002, 12.4033246, 43.992093, 12.5160665],
            so: [-13.200556, 15.246667, -13.160556, 15.286667],
            pm: [46.5507173, -56.6972961, 47.365, -55.9033333],
            rs: [42.2322435, 18.8142875, 46.1900524, 23.006309],
            st: [-0.2135137, 6.260642, 1.9257601, 7.6704783],
            sr: [1.8312802, -58.070833, 6.225, -53.8433358],
            sk: [47.7314286, 16.8331891, 49.6138162, 22.56571],
            si: [45.4214242, 13.3754696, 46.8766816, 16.5967702],
            se: [55.1331192, 10.5930952, 69.0599699, 24.1776819],
            sz: [25.2156672, 55.1807318, 25.217255, 55.18286],
            sc: [25.2237725, 55.1816849, 25.2250726, 55.184065],
            sy: [27.1401861, 31.5494106, 42.1401861, 46.5494106],
            tc: [20.9553418, -72.6799046, 22.1630989, -70.8643591],
            td: [7.44107, 13.47348, 23.4975, 24.0],
            tg: [5.926547, -0.1439746, 11.1395102, 1.8087605],
            th: [5.612851, 97.3438072, 20.4648337, 105.636812],
            tj: [36.6711153, 67.3332775, 41.0450935, 75.1539563],
            tk: [-9.6442499, -172.7213673, -8.3328631, -170.9797586],
            tm: [35.129093, 52.335076, 42.7975571, 66.6895177],
            tl: [-6.3294157, 106.9549541, -6.3284839, 106.9551755],
            to: [-24.1034499, -179.3866055, -15.3655722, -173.5295458],
            tt: [9.8732106, -62.083056, 11.5628372, -60.2895848],
            tn: [30.230236, 7.5219807, 37.7612052, 11.8801133],
            tr: [35.8076804, 25.6212891, 42.297, 44.8176638],
            tv: [-10.9939389, -180.0, -5.4369611, 180.0],
            tw: [50.8832129, 6.0296969, 50.8833129, 6.0297969],
            tz: [-6.8127308, 39.2895223, -6.812538, 39.2897105],
            ug: [-1.4823179, 29.573433, 4.2340766, 35.000308],
            ua: [44.184598, 22.137059, 52.3791473, 40.2275801],
            um: [6.1779744, -162.6816297, 6.6514388, -162.1339885],
            uy: [-35.7824481, -58.4948438, -30.0853962, -53.0755833],
            us: [24.9493, -125.0011, 49.5904, -66.9326],
            usa: [24.9493, -125.0011, 49.5904, -66.9326],
            uz: [37.1821164, 55.9977865, 45.590118, 73.1397362],
            va: [41.9002044, 12.4457442, 41.9073912, 12.4583653],
            vc: [12.5166548, -61.6657471, 13.583, -60.9094146],
            ve: [0.647529, -73.3529632, 15.9158431, -59.5427079],
            vg: [17.623468, -65.159094, 18.464984, -64.512674],
            vi: [17.623468, -65.159094, 18.464984, -64.512674],
            vn: [8.1790665, 102.14441, 23.393395, 114.3337595],
            vu: [-20.4627425, 166.3355255, -12.8713777, 170.449982],
            wf: [-14.5630748, -178.3873749, -12.9827961, -175.9190391],
            ws: [40.7987372, -124.2064518, 40.8387372, -124.1664518],
            ye: [11.9084802, 41.60825, 19.0, 54.7389375],
            za: [-47.1788335, 16.3335213, -22.1250301, 38.2898954],
            zm: [-18.0765945, 21.9993509, -8.2712822, 33.701111],
            zw: [-22.4241096, 25.2373, -15.6097033, 33.0683413]
        };
    }

    // loads pins by calling getJSON function for passed url
    function loadAllJsonDataToView(searchedRegionInfo) {
        searchedRegionInfo = searchedRegionInfo ? searchedRegionInfo : getSearchedRegionInfo(null, getCurrentSearchTerm());

        agentsById = [];
        hideResultMessages();
        showSpinner();

        loadSearchByRegionDataToView(getSelectedFilters(), searchedRegionInfo);
    }

    // shows pins nearby passed lat and lng
    function getNearbyCategory(lat, lng, distance) {
        //var dist = jQuery("#proximity").val();

        //distance = dist !== "" ? dist : distance;
        distance = distance !== "" ? distance : 100;
        var urlPieces = getUrlPiecesFromDataFolderString(urlString);
        urlPieces.forEach(function (item, index) {
            var urlPiece = urlPieces[item];
            var baseUrl = "https://spatial.virtualearth.net/REST/v1/data/" + urlPiece + "?";
            var filter = "spatialFilter=nearby(" + lat + "," + lng + "," + distance + ")";
            var options = "&$top=250&$format=json&jsonp=?";
            var key = "&key=" + bingKey;

            var url = baseUrl + filter + options + key;
            loadPinsFromUrl(url);
        });
    }

    function getAllJsonData(filterTypes) {
        $.each(filterTypes, function (element, value) {

            $.getJSON(createEndPointUrl(filterTypes[element].url), function (data) {
                if (data.d.results !== undefined) {
                    return filterTypes[element].data = data.d.results;
                }
                filterTypes[element].data = "";
            });
        });
    }

    function createEndPointUrl(dataUrl) {
        var baseUrl = dataUrl + "?";
        //this statemnt does not filter anything but we have to specify something because that argument is required
        var filter = "$filter=AdminDistrict ne 'unknown'";
        var options = "&$format=json&jsonp=?";
        var key = "&key=" + bingKey;
        var totalCount = "&$top=250";
        var url = baseUrl + filter + options + key + totalCount;
        return url;
    }

    function doesFilterAlreadyHaveAllResults(filter) {
        return !filter.allResultsForDataSource || !filter.allResultsForDataSource.length;
    }

    // shows agent by id
    function getUSAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.US_Agents.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        if (!queryBuilder.hasSpatialFilter()) {
            queryBuilder = queryBuilder.withAgentSearch(searchedRegionInfo.searchTerm);
        }

        var citySearchBox = document.getElementById("cityCheck").checked;
        var cityState = getCityStateFromSearch();
        var citiesOnly = getCitiesFromSearch();

        if (citySearchBox && !cityState && citiesOnly && citiesOnly.length > 0) {
            //citiesOnly.forEach(function (city) {
            //    queryBuilder = queryBuilder.withOrRadialSearch(city.population_center_latitude, city.population_center_longitude);
            //});
            queryBuilder = new bingQueryBuilder(filterTypes.US_Agents.url, 250, searchedRegionInfo, isFollowupRequest).withCountrySearch(searchedRegionInfo.getCountry());

        }


        return queryBuilder.sendRequests(doesFilterAlreadyHaveAllResults(filterTypes.US_Agents));
    }

    function bundleRequestWithFilteringIntent(request, isClientFilterable, isBlankQuery) {
        return {
            request: request,
            isClientFilterRequest: isClientFilterable,
            isBlankQuery: isBlankQuery
        };
    }

    function getDistributors(searchedRegionInfo, isFollowupRequest) {

        var queryBuilder = new bingQueryBuilder(filterTypes.AgentDistributors.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch().withBusinessSearch();
        var pendingRequests = queryBuilder.sendRequests();

        if (searchedRegionInfo.searchTerm && searchedRegionInfo.searchTerm.length && !isFollowupRequest) {
            // pendingRequests.push(bundleRequestWithFilteringIntent(getDistributorsByBusinessName(searchedRegionInfo.searchTerm)));
            pendingRequests.push(bundleRequestWithFilteringIntent(getDistributorsByAgentName(searchedRegionInfo.searchTerm)));
            pendingRequests.push(bundleRequestWithFilteringIntent(getDistributorsByAgentNum(searchedRegionInfo.searchTerm)));
        }

        return pendingRequests;
    }

    function getDistributorsByBusinessName(input) {
        if (!input) {
            return false;
        }
        var pountInd = input.indexOf('#');
        if (pountInd > 0) {
            input = input.slice(0, pountInd);
        }

        var baseUrl = filterTypes.AgentDistributors.url + "?";
        var filter = "$filter=StartsWith(Business,'" + input + "') eq true";
        var options = "&$format=json&jsonp=?";
        var key = "&key=" + bingKey;
        var totalCount = "&$top=250";

        var url = baseUrl + filter + options + key + totalCount;
        return $.getJSON(url);
    }

    function getDistributorsByAgentName(input) {
        if (!input) {
            return false;
        }
        var pountInd = input.indexOf(' ');
        if (pountInd > 0) {
            input = input.slice(0, pountInd);
        }

        var baseUrl = filterTypes.AgentDistributors.url + "?";
        var filter = "$filter=StartsWith(AgentName,'" + input.toUpperCase() + "') eq true";
        var options = "&$format=json&jsonp=?";
        var key = "&key=" + bingKey;
        var totalCount = "&$top=250";

        var url = baseUrl + filter + options + key + totalCount;
        return $.getJSON(url);
    }

    function getDistributorsByAgentNum(input) {
        if (!input) {
            return false;
        }

        var pountInd = input.indexOf('#');
        var numberRegex = /^\d+\s/gi;
        var aPlusRegex = /^[a]\d+\s/gi;
        var aPlusNoSpaceRegex = /^[a]\d+/gi;
        if (pountInd > 0) {
            input = input.slice(0, pountInd);
        }
        else if (input.match(numberRegex)) {
            var sliceInd = input.indexOf(" ");
            input = input.slice(0, sliceInd);
        }
        else if (input.match(aPlusRegex)) {
            var sliceInd = input.indexOf(" ");
            input = input.slice(1, sliceInd);
        }
        else if (input.match(aPlusNoSpaceRegex)) {
            input = input.slice(1);
        }
        var baseUrl = filterTypes.AgentDistributors.url + "?";
        //$filter=SalesId Eq 'A" + id + "'";
        var filter = "$filter=AgentNum Eq '" + input + "'";
        var options = "&$format=json&jsonp=?";
        var key = "&key=" + bingKey;
        var totalCount = "&$top=250";

        var url = baseUrl + filter + options + key + totalCount;
        return $.getJSON(url);
    }

    function bingQueryBuilder(baseUrl, topXLocations, regionSearchInfo, isFollowupRequest, unsupportedSearchFields) {
        var self = this;
        this.baseUrl = baseUrl;
        this.topXLocations = topXLocations;
        this.filterClause = null;
        this.spatialFilterClause = null;
        this.additionalRequests = [];
        this.regionSearchInfo = regionSearchInfo;
        this.isFollowupRequest = isFollowupRequest;
        this.unsupportedSearchFields = unsupportedSearchFields ? unsupportedSearchFields : [];
        var combineFilterClauses = function (newFilterClause, oldFilterClause, joinWith) {
            if (!oldFilterClause) {
                return newFilterClause;
            } else {
                return {
                    joinWith: joinWith,
                    clause1: newFilterClause,
                    clause2: oldFilterClause
                };
            }
        };

        var addFilterClause = function (newFilterClause, joinWith) {
            var clonedBuilder = self.clone();
            clonedBuilder.filterClause = combineFilterClauses(newFilterClause, clonedBuilder.filterClause, joinWith);
            return clonedBuilder;
        };

        var addSpatialFilterClause = function (newSpatialFilterClause, joinWith) {
            var clonedBuilder = self.clone();
            clonedBuilder.spatialFilterClause = combineFilterClauses(newSpatialFilterClause, clonedBuilder.spatialFilterClause, joinWith);
            return clonedBuilder;
        };

        this.hasSpatialFilter = function () {
            return this.spatialFilterClause && this.spatialFilterClause.length > 0;
        };

        this.hasFilter = function () {
            return this.filterClause && this.filterClause.length > 0;
        };

        this.addAndFilter = function (filterClause) {
            return addFilterClause(filterClause, "and");
        };

        // bing does not support and/or when executing a wildcard (starts/endswith) search - execute an additional request and combine results afterwards.
        this.addWildcardFilter = function (filterClause) {
            var newAdditionalQuery = new bingQueryBuilder(this.baseUrl, this.topXLocations);
            this.additionalRequests.push(newAdditionalQuery.addAndFilter(filterClause));
            return this;
        };

        this.addOrFilter = function (filterClause) {
            return addFilterClause(filterClause, "or");
        };

        this.addSpatialFilter = function (spatialFilter) {
            return addSpatialFilterClause(spatialFilter, "and");
        };

        this.clone = function () {
            var newQueryBuilder = new bingQueryBuilder(this.baseUrl, this.topXLocations, this.regionSearchInfo, this.isFollowupRequest, this.unsupportedSearchFields);
            newQueryBuilder.filterClause = this.filterClause;
            newQueryBuilder.spatialFilterClause = this.spatialFilterClause;
            newQueryBuilder.additionalRequests = this.additionalRequests.slice(0);
            return newQueryBuilder;
        };

        this.withValidAdminDistrict = function () {
            return this.clone().addAndFilter("AdminDistrict ne 'unknown'");
        };

        this.withRadialSearch = function (latitude, longitude, radiusInKilometers) {
            if (!radiusInKilometers) {
                // 50 miles
                radiusInKilometers = 120.5;
            }
            if (latitude && longitude) {
                var spatialFilter = "nearby(" + latitude + "," + longitude + "," + radiusInKilometers + ")";
                return this.addSpatialFilter(spatialFilter);
            }
            else {
                return this;
            }
        };

        this.withOrRadialSearch = function (latitude, longitude, radiusInKilometers) {
            if (!radiusInKilometers) {
                // 50 miles
                radiusInKilometers = 80.5;
            }
            if (latitude && longitude) {
                var spatialFilter = "nearby(" + latitude + "," + longitude + "," + radiusInKilometers + ")";
                return this.addOrFilter(spatialFilter);
            }
            else {
                return this;
            }
        };

        var regionFilterEnum = {
            EQUALS: 'eq',
            STARTSWITH: 'StartsWith'
        };

        function filterAgainstRegion(fieldName, region, searchTerm, filterOperator) {
            var regionNames = [region.regionCode, region.regionName, searchTerm];
            var distinctRegionNames = regionNames.filter(function (item, pos) {
                // get unique items that are 'truthy'
                return item && regionNames.indexOf(item) === pos;
            }).map(function (uniqueValue) {
                // to encode an apostrophe for bing requests, replace 1 apostrophe with 2 apostrophes
                return uniqueValue.replaceAll("'", "''");
            });

            var getFilterPiece = function (fieldName, regionName, operator) {
                if (operator === regionFilterEnum.STARTSWITH) {
                    return "StartsWith(" + fieldName.trim() + ",'" + regionName.trim() + "') eq true";
                }
                else {
                    return fieldName.trim() + " eq '" + regionName.trim() + "'";
                }
            };

            var regionFilter = distinctRegionNames.map(function (regionName) {
                return getFilterPiece(fieldName, regionName, filterOperator);
            }).join(' or ');

            regionFilter = distinctRegionNames.length > 1 ? '(' + regionFilter + ')' : regionFilter;
            return regionFilter;
        }

        this.withStateSearch = function (region, country, searchTerm) {
            var stateSearchQuery = this.addAndFilter(filterAgainstRegion('AdminDistrict', region, searchTerm));
            return stateSearchQuery.withCountrySearch(country);
        };

        this.withCitySearch = function (region, state, country, searchTerm) {
            var cityQuery = this.addAndFilter(filterAgainstRegion('Locality', region, searchTerm));
            return cityQuery.withStateSearch(state, country);
        };

        this.withPostalSearch = function (region, state, country, searchTerm) {
            var postalQueryExact = this.addAndFilter(filterAgainstRegion('PostalCode', region, searchTerm)).withStateSearch(state, country);
            var postalQueryWithStartsWith = postalQueryExact.addWildcardFilter(filterAgainstRegion('PostalCode', region, searchTerm, regionFilterEnum.STARTSWITH));
            return postalQueryWithStartsWith;
        };

        this.withBusinessSearch = function () {
            if (this.regionSearchInfo && this.regionSearchInfo.searchTerm && this.regionSearchInfo.searchTerm.length) {
                return this.addWildcardFilter("StartsWith(Business,'" + this.regionSearchInfo.searchTerm.trim() + "') eq true");
            }
            else {
                return this;
            }
        };

        this.withCountrySearch = function (country, searchTerm) {
            if (country && !this.unsupportedSearchFields.includes('CountryRegion')) {
                // google places gives responses with 'US' as country code - bing returns 'USA'
                country.regionCode = country.regionCode === 'US' ? 'USA' : country.regionCode;
                return this.addAndFilter(filterAgainstRegion('CountryRegion', country, searchTerm));
            }
            else if (country && country.regionCode && country.isMostSpecificSearchRegion && this.unsupportedSearchFields.includes('CountryRegion')) {
                var countryBoundingBox = getBoundingBoxForCountry(country.regionCode);
                if (countryBoundingBox && countryBoundingBox.length) {
                    var boundingBoxFilter = "bbox(" + countryBoundingBox.join(',') + ")";
                    return this.addSpatialFilter(boundingBoxFilter);
                }
                else {
                    return this;
                }
            }
            else {
                return this;
            }
        };

        this.withAgentSearch = function (agentNumber) {
            if (!agentNumber) {
                return this;
            }

            var regex = /^(a)?\d{3,5}/gi;
            if (!agentNumber.match(regex)) {
                return this;
            }

            var cleanedAgentNumber = agentNumber ? agentNumber.toLowerCase().trim() : '';
            if (cleanedAgentNumber.startsWith('a')) {
                cleanedAgentNumber = cleanedAgentNumber.substring(1, cleanedAgentNumber.length);
            }

            cleanedAgentNumber = ('A' + cleanedAgentNumber).toUpperCase();
            return this.addOrFilter("SalesId eq '" + cleanedAgentNumber + "'");
        };

        this.withRegionSearch = function () {
            var searchedRegionInfo = this.regionSearchInfo;
            var isFollowupRequest = this.isFollowupRequest;
            var citySearchBox = document.getElementById("cityCheck").checked;
            if (citySearchBox) { //&& isFollowupRequest) {
                var cityState = getCityStateFromSearch();
                if (cityState) {
                    return this.withRadialSearch(cityState.population_center_latitude, cityState.population_center_longitude);
                }
            }           

            if (searchedRegionInfo.isPostalRegion && searchedRegionInfo.latitude && searchedRegionInfo.longitude) {
                if (isFollowupRequest) {
                    return this.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude);
                }
                else {
                    return this.withPostalSearch(searchedRegionInfo.region, searchedRegionInfo.getState(), searchedRegionInfo.getCountry(), searchedRegionInfo.searchTerm);
                }
            }
            else if (searchedRegionInfo.isCity) {
                if (isFollowupRequest) {
                    return this.withRadialSearch(searchedRegionInfo.latitude, searchedRegionInfo.longitude);
                }
                else {
                    return this.withCitySearch(searchedRegionInfo.region, searchedRegionInfo.getState(), searchedRegionInfo.getCountry(), searchedRegionInfo.searchTerm);
                }
            }
            else if (searchedRegionInfo.isStateProvince) {
                return this.withStateSearch(searchedRegionInfo.region, searchedRegionInfo.getCountry(), searchedRegionInfo.searchTerm);
            }
            else if (searchedRegionInfo.isCountry) {
                return this.withCountrySearch(searchedRegionInfo.region, searchedRegionInfo.searchTerm);
            }
            else {
                return this;
            }
        };

        var generateFilterExpression = function (filterClause) {
            if (!filterClause) {
                return '';
            } else if (typeof filterClause === 'string') {
                return filterClause;
            } else if (typeof filterClause === 'object' && filterClause.joinWith === 'or' || filterClause.joinWith === 'and') {
                var leftSide = generateFilterExpression(filterClause.clause1).trim();
                var rightSide = generateFilterExpression(filterClause.clause2).trim();
                var combinedFilters = [leftSide, rightSide].filter(function (element) {
                    return element && element.length > 0;
                }).join(' ' + filterClause.joinWith.trim() + ' ');
                return filterClause.joinWith === 'or' ? '(' + combinedFilters + ')' : combinedFilters;
            } else {
                return '';
            }
        };

        //todo: maybe add search by agent id / number

        this.buildQuery = function () {
            var baseUrl = this.baseUrl + "?";
            var filterExpression = generateFilterExpression(this.filterClause);
            filterExpression = filterExpression && filterExpression.length ? "$filter=" + filterExpression : "";
            var spatialFilterExpression = generateFilterExpression(this.spatialFilterClause);
            spatialFilterExpression = spatialFilterExpression && spatialFilterExpression.length ? "&spatialFilter=" + spatialFilterExpression : "";
            var options = "&$format=json&jsonp=?";
            var key = "&key=" + bingKey;
            var totalCount = "&$top=" + this.topXLocations;
            if (!filterExpression && !spatialFilterExpression) {
                // there needs to be a filter expression for bing to return any results
                filterExpression = '$filter=true eq true';
            }
            var finalQuery = baseUrl + filterExpression + spatialFilterExpression + options + key + totalCount;
            return finalQuery;
        };

        this.isBlankQuery = function () {
            return !generateFilterExpression(this.filterClause) && !generateFilterExpression(this.spatialFilterClause);
        };

        function allowRequest(isFollowupRequest, searchedRegionInfo) {
            return !isFollowupRequest || (searchedRegionInfo.isPostalRegion || searchedRegionInfo.isCity);
        }

        this.sendRequests = function (gatherResultsForInMemoryFilter) {
            if (!this.baseUrl || !allowRequest(this.isFollowupRequest, this.regionSearchInfo)) {
                return [];
            }

            var isMainQueryBlank = this.isBlankQuery();
            var queryData = [];
            queryData.push({
                query: this.buildQuery(),
                isBlankQuery: isMainQueryBlank
            });

            if (this.additionalRequests && this.additionalRequests.length) {
                queryData = queryData.concat(this.additionalRequests.map(function (additionalRequest) {
                    return {
                        query: additionalRequest.buildQuery(),
                        isBlankQuery: false
                    };
                }));
            }

            var requestData = queryData.map(function (queryDataItem) {
                return bundleRequestWithFilteringIntent($.getJSON(queryDataItem.query), false, queryDataItem.isBlankQuery);
            });

            if (gatherResultsForInMemoryFilter && !isMainQueryBlank) {
                var blankQuery = new bingQueryBuilder(this.baseUrl, this.topXLocations, this.regionSearchInfo, false);
                var allResultsRequests = blankQuery.sendRequests();
                allResultsRequests.forEach(function (req) {
                    req.isClientFilterRequest = true;
                });
                requestData = requestData.concat(allResultsRequests);
            }

            return requestData;
        };
    }

    function getShowroomsByRegion(searchedRegionInfo, isFollowupRequest) {
        // CountryRegion data is missing in this data set - do not filter by it
        var queryBuilder = new bingQueryBuilder(filterTypes.Showrooms.url, 250, searchedRegionInfo, isFollowupRequest, ['CountryRegion'])
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    function getBoundingBoxForCountry(searchedCountryCode) {
        if (!searchedCountryCode) {
            return false;
        }

        var countryBoundingBoxes = getCountryBoundingBoxes();
        var matchingCountryCode = Object.keys(countryBoundingBoxes).find(function (countryCode) {
            return countryCode.toLowerCase() === searchedCountryCode.toLowerCase();
        });

        if (matchingCountryCode) {
            var boundingBox = countryBoundingBoxes[matchingCountryCode];
            return boundingBox;
        }
        else {
            return false;
        }
    }

    function getBoundingBoxForState(searchedStateCode) {
        if (!searchedStateCode) {
            return false;
        }

        var stateBoundingBoxes = getStateBoundingBoxes();
        var matchingStateCode = Object.keys(stateBoundingBoxes).find(function (stateCode) {
            return stateCode === searchedStateCode;
        });

        if (matchingStateCode) {
            var boundingBox = stateBoundingBoxes[matchingStateCode];
            // convert from xMin, yMin, xMax, yMax --> (southLatitude,westLongitude,northLatitude,eastLongitude)
            return [boundingBox[1], boundingBox[0], boundingBox[3], boundingBox[2]];
        }
        else {
            return false;
        }
    }

    function getCanadaAgents(searchedRegionInfo, isFollowupRequest) {
        var queryBuilder = new bingQueryBuilder(filterTypes.Canada.url, 250, searchedRegionInfo, isFollowupRequest)
            .withRegionSearch()
            .withBusinessSearch();
        return queryBuilder.sendRequests();
    }

    // if web address has no 'http' segment, add it to returned string value
    function addHttp(url) {
        if (!/^(f|ht)tps?:\/\//i.test(url)) {
            url = "http://" + url;
        }
        return url;
    }

    function geoLocate() {
        var etimeout = 0;
        if (navigator.geolocation) {
            etimeout = setTimeout(onError, 10000);
            navigator.geolocation.getCurrentPosition(onSuccess, onError, { timeout: 5000 });
        } else {
            initMapAndSearch({ lat: initLat, lng: initLng }, options.defaultZoom);
            console.log("Geolocation is not supported by this browser.");
        }

        function onSuccess(position) {
            clearTimeout(etimeout);
            showPosition(position);
        }

        function onError(positionError) {
            clearTimeout(etimeout);
            initMapAndSearch({ lat: initLat, lng: initLng }, options.defaultZoom);
            console.log(positionError);
        }
    }

    // helper function used by geolocate to point current position on the map
    function showPosition(position) {
        var userLat = position.coords.latitude;
        var userLng = position.coords.longitude;
        userLatLong.lat = userLat;
        userLatLong.lng = userLng;

        var center = { lat: userLat, lng: userLng };

        initMapAndSearch(center, options.geoZoom);

        //load pins
        loadPinsNearby(userLat, userLng, options.distance);
    }

    // initializing item list bindings
    function initItemListHandlers(filterTypes) {
        $('.items-list', $(scope)).on('click', 'li', function () {
            //open marker
            var id = $(this).data('id').toString();
            $('.items-list li', $(scope)).removeClass('active');
            $(this).addClass('active');

            for (var i = 0; i < markers.length; i++) {
                if (markers[i].title === id) {
                    google.maps.event.trigger(markers[i], 'click');
                    map.setCenter(markers[i].getPosition());
                    break;
                }
            }
        });
    }

    // function used for retrieveing place from textbox upon pressing 'enter' key
    function getPlaceFromTextboxValue(text) {
        deleteMarkers();
        resetSidebar();

        if (service && text && text.length) {
            service.textSearch({
                query: text //,
                // types: options
            }, function (results, status) {
                freeTextSearchCallback(results, status, text);
            });
        }
        else if (!text || !text.length) {
            loadAllJsonDataToView(getSearchedRegionInfo(null, null));
        }
    }

    function getDetailsCallback(results, status, searchTerm) {
        try {
            mostRecentlyFoundGooglePlacesResponse = results;
            loadAllJsonDataToView(getSearchedRegionInfo(results, searchTerm));
        } catch (err) {
            mostRecentlyFoundGooglePlacesResponse = null;
            console.log(err);
        }
    }

    function freeTextSearchCallback(results, status, searchTerm) {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
            if (results && results.length > 0) {
                var result = results[0];

                service.getDetails({
                    placeId: results[0].place_id
                }, function (getDetailsResults, status) {
                    getDetailsCallback(getDetailsResults, status, searchTerm);
                });
            }
            else {
                mostRecentlyFoundGooglePlacesResponse = null;
            }
        }
        else {
            mostRecentlyFoundGooglePlacesResponse = null;
            loadAllJsonDataToView(getSearchedRegionInfo(null, searchTerm));
        }
    }

    function isSearchRegionTypeRelevant(relevantTypes, regionType) {
        return relevantTypes.some(function (supportedRegionType) {
            return supportedRegionType === regionType;
        });
    }

    function getAddressComponentWeight(addressComponent, relevantTypes) {
        var weight = 0;
        var powerOfTen = 1;
        for (var i = relevantTypes.length - 1; i >= 0; i--) {
            if (addressComponent.types.find(function (addressComponentType) {
                return addressComponentType === relevantTypes[i];
            })) {
                weight += powerOfTen;
            }
            powerOfTen = powerOfTen * 10;
        }

        return weight;
    }

    function getGooglePlaceRegionTypeInList(googlePlacesResponse, relevantTypes) {
        if (!googlePlacesResponse || !googlePlacesResponse.address_components) {
            return null;
        }

        var relevantPortions = googlePlacesResponse.address_components.filter(function (addressComponent) {
            return addressComponent.types.some(function (element) {
                return isSearchRegionTypeRelevant(relevantTypes, element);
            });
        });

        var relevantAddressPortionsSorted = relevantPortions.sort(function (element1, element2) {
            return getAddressComponentWeight(element2, relevantTypes) - getAddressComponentWeight(element1, relevantTypes);
        });

        return relevantAddressPortionsSorted && relevantAddressPortionsSorted.length ? relevantAddressPortionsSorted[0] : null;
    }

    function transformPlace(googlePlace, regionType, isMostSpecificSearchRegion) {
        return {
            regionCode: googlePlace.short_name,
            regionName: googlePlace.long_name,
            regionType: regionType,
            isMostSpecificSearchRegion: isMostSpecificSearchRegion
        };
    }

    function getCountry(googlePlacesResponse) {
        var country = getGooglePlaceRegionTypeInList(googlePlacesResponse, ['country']);
        return country ? transformPlace(country, 'country') : null;
    }

    function getState(googlePlacesResponse) {
        var state = getGooglePlaceRegionTypeInList(googlePlacesResponse, ['administrative_area_level_1']);
        return state ? transformPlace(state, 'administrative_area_level_1') : null;
    }

    function isPostalCode(searchTerm) {
        var usPostalCodeRegex = /^\d{5}(?:[-\s]\d{4})?$/;
        var canadaPostalCodeRegex = /^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i;
        return usPostalCodeRegex.test(searchTerm) || canadaPostalCodeRegex.test(searchTerm);
    }

    function getSearchedRegionInfo(googlePlacesResponse, searchTerm) {
        var isSearchTermAPostalCode = isPostalCode(searchTerm);
        var supportedSearchRegionTypesInOrder = isSearchTermAPostalCode ?
            ['postal_code', 'locality', 'administrative_area_level_1', 'country'] :
            ['locality', 'postal_code', 'administrative_area_level_1', 'country'];
        var mostSpecificSearchRegion = getGooglePlaceRegionTypeInList(googlePlacesResponse, supportedSearchRegionTypesInOrder);
        var mostSpecificSearchRegionType = mostSpecificSearchRegion ? mostSpecificSearchRegion.types.find(function (searchRegionType) {
            return isSearchRegionTypeRelevant(supportedSearchRegionTypesInOrder, searchRegionType);
        }) : null;

        var isCountry = mostSpecificSearchRegionType === 'country';
        // Google Places may return zip codes even if they were not what the user was searching for
        var isPostalRegion = mostSpecificSearchRegionType === 'postal_code' && isSearchTermAPostalCode;
        var isStateProvince = mostSpecificSearchRegionType === 'administrative_area_level_1';
        var isCity = mostSpecificSearchRegionType === 'locality';

        var region = mostSpecificSearchRegion ?
            transformPlace(mostSpecificSearchRegion, mostSpecificSearchRegionType, true) :
            null;

        return {
            regionType: mostSpecificSearchRegionType,
            region: region,
            latitude: googlePlacesResponse ? googlePlacesResponse.geometry.location.lat() : null,
            longitude: googlePlacesResponse ? googlePlacesResponse.geometry.location.lng() : null,
            googlePlacesData: googlePlacesResponse,
            isCountry: isCountry,
            isPostalRegion: isPostalRegion,
            isStateProvince: isStateProvince,
            isCity: isCity,
            searchTerm: encodeURIComponent(searchTerm),
            getCountry: function () { return getCountry(googlePlacesResponse); },
            getState: function () { return getState(googlePlacesResponse); },
            loadAll: !googlePlacesResponse && (!searchTerm || !searchTerm.length)
        };
    }

    var clicksWithinLast5Seconds = 0;
    function triggerSendingSelectedFiltersToGoogleAnalytics() {
        clicksWithinLast5Seconds++;
        setTimeout(sendSelectedFiltersToGoogleAnalyticsIfDoneFiltering, 5000);
    }

    // Send an event to Google Analytics if the user hasn't selected filters in the last 5 seconds
    function sendSelectedFiltersToGoogleAnalyticsIfDoneFiltering() {
        if (clicksWithinLast5Seconds > 0) {
            clicksWithinLast5Seconds--;
        }

        if (clicksWithinLast5Seconds > 0) {
            return;
        }

        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Filters Selected: '.concat(
                'Page: "' + window.location.href + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"',
                ' . Search Term: "' + getSearchTerm() + '"'),
            Label: 'How To Buy Filters Selected'
        });
    }

    function getCurrentSearchTerm() {
        return $('#how-to-buy-2__search-input').val();
    }

    function getSelectedFilters() {
        var selectedCheckboxFilter = $(".how-to-buy-2__filters :checkbox:checked");
        var loadedFilters = [];
        $.each(selectedCheckboxFilter, function (index, filter) {
            loadedFilters.push(filter.value);
        });
        return loadedFilters;
    }

    // initilaize map and bindings based on location source type
    function initMapAndSearch(defaultMapCenter, defaultZoom) {

        var mapContainer = $('.map-container', $(scope)).get(0);

        map = new google.maps.Map(mapContainer, {
            zoom: defaultZoom,
            center: defaultMapCenter
        });

        google.maps.event.addDomListener(window, 'resize', function () {
            //  map.fitBounds(path_bounds);
            map.setCenter(defaultMapCenter);

        });

        service = new google.maps.places.PlacesService(map);

        //if the search is map related (non-agent id based), we will initialize searchbox listeners
        // Create the search box

        function handleSearchInputSubmission() {
            var text = getCurrentSearchTerm();
            var isValidSearch = true;
            //make sure a city is searched
            if (text && text != "" && !isPostalCode(text) && !document.getElementById("cityCheck").checked) {
                showSearchZipMessage();
                isValidSearch = false
            }

            if (isValidSearch) {
                getPlaceFromTextboxValue(text);
            }
        }

        //By Agent IDs
        $('#how-to-buy-2__search-input', $(scope)).bind("enterKey", function (e) {
            handleSearchInputSubmission();
        });

        //for click
        $('#map-search-button', $(scope)).bind("click", function (e) {
            handleSearchInputSubmission();
        });

        $('#how-to-buy-2__search-input', $(scope)).keyup(function (e) {
            if (e.keyCode === 13) {
                $(this).trigger("enterKey");
            }
        });

        initItemListHandlers(filterTypes);

        loadSearchByRegionDataToView(getSelectedFilters(), getSearchedRegionInfo(mostRecentlyFoundGooglePlacesResponse, null));

        var setFilterSelectedStatus = function (modifiedCheckbox) {
            var matchingFilter = Object.values(filterTypes).find(function (filter) {
                return modifiedCheckbox && filter.class === modifiedCheckbox.value;
            });
            if (matchingFilter) {
                matchingFilter.isSelected = modifiedCheckbox.checked;
            }
        };

        $(".how-to-buy-2__filters :checkbox").click(function () {
            setFilterSelectedStatus(this);
            triggerSendingSelectedFiltersToGoogleAnalytics();
            hideResultMessages();
            var bounds = new google.maps.LatLngBounds();
            loadSearchByRegionDataToView(getSelectedFilters(), getSearchedRegionInfo(mostRecentlyFoundGooglePlacesResponse, getCurrentSearchTerm()));
            if ($(".how-to-buy-2__filters :checkbox:checked").length == 0) {
                $(".how-to-buy-2__list__addresses> li").hide();

                for (var i = 0; i < markers.length; i++) {
                    markers[i].setVisible(false);
                }
                bounds.extend({ lat: initLat, lng: initLng });
            }
            if ($(".how-to-buy-2__filters :checkbox:checked").length > 0) {

                $(".how-to-buy-2__list__addresses> li").hide();
                for (var i = 0; i < markers.length; i++) {
                    markers[i].setVisible(false);
                }

                $(".how-to-buy-2__filters :checkbox:checked").each(function () {
                    $(".how-to-buy-2__list__addresses ." + $(this).val()).show();
                    for (var i = 0; i < markers.length; i++) {
                        if (markers[i].category === $(this).val()) {
                            markers[i].setVisible(true);
                            bounds.extend(markers[i].getPosition());
                        }
                    }
                });
                showMarkers();
                map.fitBounds(bounds);
            }
        });
    }

    function getData(url) {
        var deferred = jQuery.Deferred();

        if (!url) {
            return deferred.reject();
        }

        var response = jQuery.get(url)
            .done(function (responseData) {
                deferred.resolve(responseData);
            })
            .fail(function () {
                deferred.reject();
            });

        return deferred;
    }
}
;
var app = app || {};
app.sqlspecregistration = app.sqlspecregistration || {};

function initSpecSQLMap() {
    var args = app.sqlspecregistration.data;
    var initLat = 35.8669864;
    var initLng = -78.8548692;
    var map;
    var markers = [];
    var activeInfowindow = null;
    var service;
    var userLatLong = {};
    var mostRecentlyFoundGooglePlacesResponse = null;
    var ZipCityArray = new Array();


    var options = {
        key: args.key, defaultZoom: args.defaultZoom, distance: args.distance
    };

    var isFilterEnabledByDefault = function (filterClass) {
        var filterClassLowered = filterClass ? filterClass.toLowerCase() : "";
        return args.DefaultEnabledFilters && args.DefaultEnabledFilters.length && args.DefaultEnabledFilters.some(function (element) {
            return element && element.toLowerCase() === filterClassLowered;
        });
    };

    $.ajaxSetup({
        scriptCharset: "utf-8",
        contentType: "application/json; charset=utf-8"
    });

    var filterTypes = {
        US_Agents: {
            isSelected: isFilterEnabledByDefault('us-agents'),
            name: 'US Agents',
            url: args.USAgentBingServiceEndpoint,
            class: 'us-agents',
            icon: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAMAAAApB0NrAAABC1BMVEUAAADnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIyvnIytbQhFDAAAAWHRSTlMAAQIDBAUGBwgJCgwNDxATFBUYGh4iJigpKy4xNjg5OjxDRkdOVFZXWFlbXWNkZ3F1d3t/gIiJkZKUl5ueqqutsLK0ucHHyM7P0dPZ2tzi5Obo7e/x9fv9H2++QwAAARxJREFUGBl9wQlDAVEYBdA7lmSphFYttGulPaW0qBQl6/3/v6T5BuO9MeMc6BJbx/nDTBSefHst9lVX4S7xy5FyEC7SXapqMYxJ0aEWgMNUk04lOBRoeUz5EFyr07IEzTQtp7D4XyjeoclQFDEQbFBEoLqjiGEoS7EOVYWmD9jCFDmoWjTdYoSiANUfTUXYDIozqN5o+oYtSrEP1TlFHEO7FCtQLVKUMRBp09TzQ2X8UFwbEOFPikvotmn52oyF5nIdWmah87Xp9ACnIzol4TTVpe4V4/LULWNclJoq3NxQtQE381Q0DLh64sgO3C3Q1vHDQ4VDJ/CS5kAvBE919l3AW5Z9M/Dma1LcY5IDiiQmCbRIljBZ/Ll5FYDuHxoTjmFV67GMAAAAAElFTkSuQmCC'
        }
    };

    var scope = ('#how-to-buy-container');

    initMapAndSearch({ lat: initLat, lng: initLng }, options.defaultZoom);

    //load city zip code map
    function loadCityZipArray() {
        getData('/assets/json/xs-zip-cities-json.txt').then(function (data) {
            ZipCityArray = eval(data);
        });
    }
    loadCityZipArray();

    function isEmpty(obj) {
        return Object.keys(obj).length === 0;
    }

    // created functions
    function createDirectionLink(address) {
        var encodeUrl = encodeURI(address);
        if (isEmpty(userLatLong)) {
            return "https://www.google.com/maps/dir/?api=1&destination=" + encodeUrl;
        }
        return "https://www.google.com/maps/dir/?api=1&origin=" + userLatLong.lat + "," + userLatLong.lng + "&destination=" + encodeUrl;
    }

    // builds infowindows, attaches event listeners, adds markers and init sidebar 
    function buildStoreInfoContent(result, markerZIndex, filterType, loadAll) {
        var hasDodgeCodes = result.DodgeCodes !== undefined && filterType !== undefined && filterType.name === "US Agents";

        if (hasDodgeCodes) {
            var dodgeCodes = result.DodgeCodes.split(';');
        }

        if (!hasDodgeCodes || (dodgeCodes.length > 1 && !dodgeCodes.includes("0"))) {
            var infoContent;
            var id = (Math.floor(Math.random() * (1000 - 1 + 1) + 1)).toString(),
                business = result.Business,
                address1 = result.AddressLine1,
                address2 = result.AddressLine2,
                city = result.Locality,
                state = result.AdminDistrict,
                zip = result.PostalCode,
                country = result.CountryRegion ? result.CountryRegion : '',
                salesId = result.SalesId,
                salesPhone = result.Phone,
                salesWeb = result.Web,
                salesAgentName = result.AgentName;
            var infoLinks;
            var concatAddress = $.grep([address1, address2], Boolean).join(", ");
            var cityStateZip = city + ', ' + state + ' ' + zip + ' ' + country;
            var selectedFilter = filterType;

            infoContent = "<li class='gm-style " + selectedFilter.class + "'" + "data-id='" + id + ">'";
            infoContent += "<div class='place-name'>" + business + "</div>";
            if (typeof city === 'undefined' || city == "") {
                cityStateZip = "";
            }
            infoContent += "<div class='address'>" + concatAddress + ", " + cityStateZip + "</div>";


            var listContent = "<li data-id='" + id + "' class='" + selectedFilter.class + "'>";
            listContent += "<a href='#' onclick='return false;' class='list-business-name'>" + business + "</a>";
            listContent += "<p>" + concatAddress + "</p>";
            if (cityStateZip !== "") {
                listContent += "<p>" + cityStateZip + "</p>";
            }

            if ((selectedFilter.name === "US Agents" || selectedFilter.name === "International Agents") && typeof salesId !== 'undefined') {
                listContent += "<p>Agent #: " + salesId + "</p>";
                infoContent += "<div class='address'>Agent #: " + salesId + "</div>";
            }

            if (salesWeb !== "" && typeof salesWeb !== 'undefined') {
                if (salesWeb.indexOf("@") > -1) {
                    listContent += "<p><a href='mailto:" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='mailto:" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";
                } else if (salesWeb.indexOf("http") > -1) {
                    listContent += "<p><a href='" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";

                } else {
                    listContent += "<p><a href='http://" + salesWeb + "' class='email'>" + salesWeb + "</a></p>";
                    infoContent += "<div class='address'><a href='http://" + salesWeb + "' class='email'>" + salesWeb + "</a></div>";

                }
            }

            if (salesPhone !== "" && typeof salesPhone !== 'undefined') {
                listContent += "<p>" + salesPhone + "</p>";
                infoContent += "<div class='address'>" + salesPhone + "</div>";
            }

            if (salesAgentName !== "" && typeof salesAgentName !== 'undefined') {
                listContent += "<p> Agent: " + salesAgentName + "</p>";
                infoContent += "<div class='address'> Agent: " + salesAgentName + "</div>";
            }

            listContent += "</li>";
            infoContent += "</li></div></div>";
            var address = concatAddress + ", " + cityStateZip;
            infoLinks = "<div class='navigate'>";
            infoLinks += "<a target='_blank' href='" + createDirectionLink(address) + "' class='navigate-link'>";
            infoLinks += "<div class='navigate-tex'>  Get Direction </div></a></div>";

            var info = new google.maps.InfoWindow({
                content: infoContent + infoLinks,
                maxWidth: 400
            });

            addMarker(result, info, id, selectedFilter, markerZIndex);
            if (!loadAll)
                appendItemListMarkup(listContent);
        }
    }

    //checks abbrevs to state
    function abbrState(input, to) {

        var states = stateList;

        if (to == 'abbr') {
            input = input.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });
            for (i = 0; i < states.length; i++) {
                if (states[i][0] == input) {
                    return (states[i][1]);
                }
            }
        } else if (to == 'name') {
            input = input.toUpperCase();
            for (i = 0; i < states.length; i++) {
                if (states[i][1] == input) {
                    return (states[i][0]);
                }
            }
        }
    }

    // closes active info window
    function closeActiveInfowindows() {
        if (activeInfowindow != null) {
            activeInfowindow.close();
        }
    }

    // Adds a marker to the map and push to the array.
    function addMarker(result, info, id, selectedFilter, markerZIndex) {
        var marker = new google.maps.Marker({
            position: { lat: parseFloat(result.Latitude), lng: parseFloat(result.Longitude) },
            map: map,
            animation: google.maps.Animation.DROP,
            title: id,
            icon: selectedFilter.icon,
            category: selectedFilter.class,
            zIndex: markerZIndex ? markerZIndex : undefined
        });
        marker.addListener('click', function () {
            closeActiveInfowindows();
            highlightListing(marker, info);
            info.open(map, marker);
            activeInfowindow = info;

            sendMarkerClickEventToGoogleAnalytics(marker, result.Business);
        });
        map.addListener('click', function () {
            info.close();
        });
        markers.push(marker);
    }

    // Sets the map on all markers in the array.
    function setMapOnAll(mapValue) {
        for (var i = 0; i < markers.length; i++) {
            markers[i].setMap(mapValue);
        }
    }

    // Removes the markers from the map, but keeps them in the array.
    function clearMarkers() {
        setMapOnAll(null);
    }

    // Shows any markers currently in the array.
    function showMarkers() {
        setMapOnAll(map);

        if (markers.length > 1) {
            var bounds = new google.maps.LatLngBounds();
            markers.forEach(function (marker) {
                bounds.extend(new google.maps.LatLng(marker.position.lat(), marker.position.lng()));
            });
            map.fitBounds(bounds);

        } else if (markers.length === 1) {
            zoomHere(markers[0]);
        }
    }

    // Deletes all markers in the array by removing references to them.
    function deleteMarkers() {
        clearMarkers();
        markers = [];
    }

    // Zoom '15' for selected marker
    function zoomHere(marker) {
        map.setZoom(15);
        map.panTo(marker.position);
    }

    // Clear items sidebar
    function resetSidebar() {
        $('.items-list', $(scope)).empty();
    }

    // append list items markup
    function appendItemListMarkup(listing) {
        hideSpinner();
        $('.items-list', $(scope)).append(listing);
    }

    // helper method used for marker click bind event
    function highlightListing(marker) {
        var thisId = marker.title;
        $('.items-list li', $(scope)).each(function () {
            if ($(this).attr('data-id') === thisId) {
                $('.items-list li', $(scope)).removeClass('active');
                $(this).addClass('active');
            }
        });
    }

    function showSpinner() {
        $('.how-to-buy-2__list__addresses', $(scope)).html('<i class="fa fa-spinner fa-spin"></i>');
    }

    function hideSpinner() {
        $('.how-to-buy-2__list__addresses .fa-spinner', $(scope)).remove();
    }

    function getCitiesFromSearch(searchedRegionInfo) {
        if (!searchedRegionInfo)
            return [];

        var searchCity = searchedRegionInfo.region ? searchedRegionInfo.region.regionName.toUpperCase() : null;
        var searchState = searchedRegionInfo.getState() ? searchedRegionInfo.getState().regionCode : null;

        if (!searchCity || !searchState)
            return [];

        var cityLong = ZipCityArray.filter(function (o) {
            return (searchCity === o.primary_city.toUpperCase() && searchState === o.state);
        });
        
        return cityLong;
    }

    function displayFilterType(checkBoxfilterArr, filterType, searchedRegionInfo, markerZIndex) {
        var hasAnyFilteredResults = false;
        var hasAnyCityFilteredResults = false;
        var citySearchBox = document.getElementById("cityCheck").checked;
        var searchTerm = getSearchTerm().toUpperCase();
        
        
        var isFilterTypeSelected = checkBoxfilterArr.find(function (element) {
            return element == filterType.class;
        });
        if (isFilterTypeSelected !== undefined && citySearchBox) {
            var uniqueArr = [];
            $.each(filterType.data,
                function (index, data) {
                    var adminLong = abbrState(data.AdminDistrict, 'name').toUpperCase();
                    if (searchTerm.includes(data.Locality.toUpperCase())
                        && (searchTerm.includes(data.AdminDistrict.toUpperCase()) || searchTerm.includes(adminLong))) {
                        hasAnyCityFilteredResults = true;
                    }
                });
        }
        if (isFilterTypeSelected !== undefined) {
            var uniqueArr = [];
            $.each(filterType.data,
                function (index, data) {
                    var matchingItems = $.grep(uniqueArr, function (item) {
                        return item.Business === data.Business && item.AddressLine1 === data.AddressLine1
                            && item.AddressLine2 === data.AddressLine2 && item.AddressLine3 === data.AddressLine3
                            && item.Web === data.Web;
                    });
                    if (matchingItems.length === 0) {
                        buildStoreInfoContent(data, markerZIndex, filterType, searchedRegionInfo.loadAll);
                        hasAnyFilteredResults = true;
                        uniqueArr.push(data);
                    }
                });
        }
        return [hasAnyFilteredResults, hasAnyCityFilteredResults];
    }

    function getSearchTerm() {
        var searchInput = $('#how-to-buy-2__search-input');
        if (searchInput && searchInput.val()) {
            return searchInput.val();
        }
        else {
            return '';
        }
    }

    function getSelectedFiltersAsString() {
        var selectedFilterTypes = $(".how-to-buy-2__filters :checkbox:checked").map(function (index, element) {
            return element.value;
        }).toArray();
        return selectedFilterTypes.join(', ');
    }

    function sendNoResultsDataToGoogleAnalytics() {
        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Search - No Results Found - '.concat(
                'Page: "' + window.location.href + '"',
                ' . Search Term: "' + getSearchTerm() + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"'),
            Label: 'How To Buy Search - No Results Found'
        });
    }

    function sendMarkerClickEventToGoogleAnalytics(marker, businessName) {
        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Map Click - '.concat(
                'Page: "' + window.location.href + '"',
                ' Business: "' + businessName + '"',
                ' . Search Term: "' + getSearchTerm() + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"'),
            Label: 'How To Buy Map Click'
        });
    }

    function clearStoredFilterData() {
        Object.values(filterTypes).forEach(function (filterValue) {
            filterValue.allFilterData = [];
        });
    }

    function loadSearchByRegionDataToView(checkBoxfilterArr, searchedRegionInfo) {
        var generateMapEntry = function (requestFunc, filterToPopulate) {
            return {
                requestFunc: requestFunc,
                filter: filterToPopulate,
            };
        };

        clearStoredFilterData();

        var getUsAgentData = function () { return getUSAgents(searchedRegionInfo); };

        var requestDataMap = [
            generateMapEntry(getUsAgentData, filterTypes.US_Agents)
        ].filter(function (requestData) {
            // only send new requests when the filter is selected and the search term has changed since the last request
            return requestData.filter.isSelected && requestData.filter.hasResultsForSearchTerm !== searchedRegionInfo.searchTerm;
        });      


        var updateFilterDataFromResponse = function (responseData, filter) {
            if (responseData && responseData.length) {
                var citySearchBox = document.getElementById("cityCheck").checked;
                var citiesOnly = getCitiesFromSearch(searchedRegionInfo);

                if (citySearchBox && citiesOnly && citiesOnly.length > 0) {
                    var cityZips = citiesOnly.map(function (a) { return a.zip; });
                    responseData = responseData.filter(function (element) {
                        var allTerritoryZipCodes = "";
                        if (element["Territory1"]) {
                            for (var i = 1; i < 21; i++) {
                                if (element["Territory" + i]) {
                                    allTerritoryZipCodes = allTerritoryZipCodes.concat(element["Territory" + i]);
                                }
                            }
                        }
                        return cityZips.find(function (element) {
                            return allTerritoryZipCodes.includes(element);
                        });
                    });
                } else if (citySearchBox && getSearchTerm().length > 0)
                    responseData = [];

                filter.allFilterData = filter.allFilterData.concat(responseData);
            }
        };

        var storeResultsForInMemoryFilter = function (responseData, filter) {
            if (responseData && responseData.length) {
                filter.allResultsForDataSource = responseData;
            }
        };

        var collapseFilterResponseData = function (filter, regionSearchInfo) {
            var serverResponseData = filter.allFilterData;
            
            filter.hasResultsForSearchTerm = regionSearchInfo.searchTerm;
            filter.hasTerritoryMatch = filter.allFilterData.length > 0;
            // get uniques by id
            return serverResponseData.map(function (filterDataItem) {
                return {
                    id: filterDataItem.Id,
                    filterData: filterDataItem
                };
            }).filter(function (value, index, self) {
                return self.findIndex(function (element) {
                    return element.id === value.id;
                }) === index;
            }).map(function (item) {
                return item.filterData;
            });
        };

        var promisesForAllFilters = [];

        requestDataMap.forEach(function (element) {
            var executedRequestData = element.requestFunc();
            executedRequestData = executedRequestData && Array.isArray(executedRequestData) ? executedRequestData : [executedRequestData];

            var requestSuccessHandler = function (responseData, requestItem) {
                var processResultsAsFilteredByServer = !requestItem.isClientFilterRequest;
                var processResultsAsClientFilter = requestItem.isClientFilterRequest || requestItem.isBlankQuery;
                if (processResultsAsFilteredByServer) {
                    updateFilterDataFromResponse(responseData, element.filter);
                }
                if (processResultsAsClientFilter) {
                    storeResultsForInMemoryFilter(responseData, element.filter);
                }
            };

            var failureHandler = function (responseData, failedFilterClass) {
                console.log('Request for ' + failedFilterClass + ' failed.');
            };

            var createDeferredPromiseForRequest = function (request) {
                return request ? $.Deferred() : null;
            };

            var primaryRequestsWithDeferred = executedRequestData.map(function (requestItem) {
                return {
                    requestItem: requestItem,
                    deferredPromise: createDeferredPromiseForRequest(requestItem.request)
                };
            });

            primaryRequestsWithDeferred.forEach(function (requestWithDeferredPromise) {
                requestWithDeferredPromise.requestItem.request.done(function (responseData) {
                    requestSuccessHandler(responseData, requestWithDeferredPromise.requestItem);
                    requestWithDeferredPromise.deferredPromise.resolve();
                }).fail(function (failureData) {
                    failureHandler(failureData, element.filter.class);
                    requestWithDeferredPromise.deferredPromise.resolve();
                });
            });

            var deferredPromises = primaryRequestsWithDeferred.map(function (req) {
                return req.deferredPromise;
            });

            // aggregate results when the requests for this particular filter are finished
            var promiseForThisFilter = $.when.apply($, deferredPromises);
            promisesForAllFilters.push(promiseForThisFilter);
            promiseForThisFilter.done(function () {
                element.filter.data = collapseFilterResponseData(element.filter, searchedRegionInfo);
            });
        });

        // decide what to display when ALL of the requests are finished and results are processed
        $.when.apply($, promisesForAllFilters).done( function () {
            processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo);
        });
    }

    function processReturnedFilterData(checkBoxfilterArr, searchedRegionInfo) {
        deleteMarkers();
        if (checkBoxfilterArr.length == 0) {
            hideSpinner();

            showNoResultsText();
        }

        var usResults = displayFilterType(checkBoxfilterArr, filterTypes.US_Agents, searchedRegionInfo, 990);

        var hasAnyFilteredResults = usResults[0];

        hideSpinner();
        var searchTerm = getSearchTerm();
        var hasAnyResults = hasAnyFilteredResults || $(".how-to-buy-2__list__addresses li").length > 0;
        var citySearch = document.getElementById("cityCheck").checked;
        var isZip = isPostalCode(searchTerm);
        if (isZip && filterTypes.US_Agents.isSelected && searchTerm && searchTerm != "") {
            showUSAgentExactMatchMessage();        
        }
        else if (hasAnyResults && citySearch && filterTypes.US_Agents.isSelected && searchTerm && searchTerm != "") {
            showUSAgentExactCityMatchMessage();
        }
        /*else if (filterTypes.US_Agents.isSelected && filterTypes.US_Agents.hasTerritoryMatch) {
            showUSAgentTerritoryMatchMessage();
        }*/
        else if (!hasAnyResults) {
            showNoResultsText();
        }

        if (!hasAnyFilteredResults) {
            sendNoResultsDataToGoogleAnalytics();
        }

        showMarkers();
    }

    function showNoResultsText() {
        hideResultMessages()
        $('.no-agents-found', $(scope)).show();
    }

    function showUSAgentTerritoryMatchMessage() {
        hideResultMessages()
        $('.zip-no-exact-match', $(scope)).show();
    }
    function showUSAgentExactCityMatchMessage() {
        hideResultMessages()
        $('.city-exact-match', $(scope)).show();
    }

    function showUSAgentExactMatchMessage() {
        hideResultMessages()
        $('.zip-exact-match', $(scope)).show();
    }
    function showSearchZipMessage() {
        hideResultMessages()
        $('.search-zip-text', $(scope)).show();
    }


    function hideResultMessages() {
        $('.how-to-buy-search-result-indicator', $(scope)).hide();
    }

    var stateList =
        [
            ['Arizona', 'AZ'],
            ['Alabama', 'AL'],
            ['Alaska', 'AK'],
            ['Arkansas', 'AR'],
            ['California', 'CA'],
            ['Colorado', 'CO'],
            ['Connecticut', 'CT'],
            ['Delaware', 'DE'],
            ['Florida', 'FL'],
            ['Georgia', 'GA'],
            ['Hawaii', 'HI'],
            ['Idaho', 'ID'],
            ['Illinois', 'IL'],
            ['Indiana', 'IN'],
            ['Iowa', 'IA'],
            ['Kansas', 'KS'],
            ['Kentucky', 'KY'],
            ['Louisiana', 'LA'],
            ['Maine', 'ME'],
            ['Maryland', 'MD'],
            ['Massachusetts', 'MA'],
            ['Michigan', 'MI'],
            ['Minnesota', 'MN'],
            ['Mississippi', 'MS'],
            ['Missouri', 'MO'],
            ['Montana', 'MT'],
            ['Nebraska', 'NE'],
            ['Nevada', 'NV'],
            ['New Hampshire', 'NH'],
            ['New Jersey', 'NJ'],
            ['New Mexico', 'NM'],
            ['New York', 'NY'],
            ['North Carolina', 'NC'],
            ['North Dakota', 'ND'],
            ['Ohio', 'OH'],
            ['Oklahoma', 'OK'],
            ['Oregon', 'OR'],
            ['Pennsylvania', 'PA'],
            ['Rhode Island', 'RI'],
            ['South Carolina', 'SC'],
            ['South Dakota', 'SD'],
            ['Tennessee', 'TN'],
            ['Texas', 'TX'],
            ['Utah', 'UT'],
            ['Vermont', 'VT'],
            ['Virginia', 'VA'],
            ['Washington', 'WA'],
            ['West Virginia', 'WV'],
            ['Wisconsin', 'WI'],
            ['Wyoming', 'WY'],
            ['Alberta', 'AB'],
            ['British Columbia', 'BC'],
            ['Manitoba', 'MB'],
            ['New Brunswick', 'NB'],
            ['Newfoundland', 'NF'],
            ['Northwest Territory', 'NT'],
            ['Nova Scotia', 'NS'],
            ['Nunavut', 'NU'],
            ['Ontario', 'ON'],
            ['Prince Edward Island', 'PE'],
            ['Quebec', 'QC'],
            ['Saskatchewan', 'SK'],
            ['Yukon', 'YT']
        ];

    // loads pins by calling getJSON function for passed url
    function loadAllJsonDataToView(searchedRegionInfo) {
        searchedRegionInfo = searchedRegionInfo ? searchedRegionInfo : getSearchedRegionInfo(null, getCurrentSearchTerm());

        agentsById = [];
        hideResultMessages();
        showSpinner();

        loadSearchByRegionDataToView(getSelectedFilters(), searchedRegionInfo);
    }

    function doesFilterAlreadyHaveAllResults(filter) {
        return !filter.allResultsForDataSource || !filter.allResultsForDataSource.length;
    }

    // shows agent by id
    function getUSAgents(searchedRegionInfo) {
        var queryBuilder = new bingQueryBuilder(filterTypes.US_Agents.url, 250, searchedRegionInfo);
        var citySearchBox = document.getElementById("cityCheck").checked;

        if (isPostalCode(getCurrentSearchTerm()) && !citySearchBox)
            queryBuilder = queryBuilder.withPostalSearch(getCurrentSearchTerm());

        return queryBuilder.sendRequests(doesFilterAlreadyHaveAllResults(filterTypes.US_Agents));
    }

    function bundleRequestWithFilteringIntent(request, isClientFilterable, isBlankQuery) {
        return {
            request: request,
            isClientFilterRequest: isClientFilterable,
            isBlankQuery: isBlankQuery
        };
    }

    function bingQueryBuilder(baseUrl, topXLocations, regionSearchInfo, unsupportedSearchFields) {
        var self = this;
        this.baseUrl = baseUrl;
        this.topXLocations = topXLocations;
        this.filterClause = null;
        this.additionalRequests = [];
        this.regionSearchInfo = regionSearchInfo;
        this.unsupportedSearchFields = unsupportedSearchFields ? unsupportedSearchFields : [];
        var combineFilterClauses = function (newFilterClause, oldFilterClause, joinWith) {
            if (!oldFilterClause) {
                return newFilterClause;
            } else {
                return {
                    joinWith: joinWith,
                    clause1: newFilterClause,
                    clause2: oldFilterClause
                };
            }
        };

        var addFilterClause = function (newFilterClause, joinWith) {
            var clonedBuilder = self.clone();
            clonedBuilder.filterClause = combineFilterClauses(newFilterClause, clonedBuilder.filterClause, joinWith);
            return clonedBuilder;
        };

        this.hasFilter = function () {
            return this.filterClause && this.filterClause.length > 0;
        };

        this.addAndFilter = function (filterClause) {
            return addFilterClause(filterClause, "and");
        };

        // bing does not support and/or when executing a wildcard (starts/endswith) search - execute an additional request and combine results afterwards.
        this.addWildcardFilter = function (filterClause) {
            var newAdditionalQuery = new bingQueryBuilder(this.baseUrl, this.topXLocations);
            this.additionalRequests.push(newAdditionalQuery.addAndFilter(filterClause));
            return this;
        };

        this.addOrFilter = function (filterClause) {
            return addFilterClause(filterClause, "or");
        };

        this.clone = function () {
            var newQueryBuilder = new bingQueryBuilder(this.baseUrl, this.topXLocations, this.regionSearchInfo, this.unsupportedSearchFields);
            newQueryBuilder.filterClause = this.filterClause;
            newQueryBuilder.additionalRequests = this.additionalRequests.slice(0);
            return newQueryBuilder;
        };

        this.withValidAdminDistrict = function () {
            return this.clone().addAndFilter("AdminDistrict ne 'unknown'");
        };

        this.withPostalSearch = function (zipCode) {
            return this.addAndFilter("(Territory eq '" + zipCode + "')");
        };

        var generateFilterExpression = function (filterClause) {
            if (!filterClause) {
                return '';
            } else if (typeof filterClause === 'string') {
                return filterClause;
            } else if (typeof filterClause === 'object' && filterClause.joinWith === 'or' || filterClause.joinWith === 'and') {
                var leftSide = generateFilterExpression(filterClause.clause1).trim();
                var rightSide = generateFilterExpression(filterClause.clause2).trim();
                var combinedFilters = [leftSide, rightSide].filter(function (element) {
                    return element && element.length > 0;
                }).join(' ' + filterClause.joinWith.trim() + ' ');
                return filterClause.joinWith === 'or' ? '(' + combinedFilters + ')' : combinedFilters;
            } else {
                return '';
            }
        };
        
        //todo: maybe add search by agent id / number

        this.buildQuery = function () {
            var baseUrl = this.baseUrl + "?";
            var filterExpression = generateFilterExpression(this.filterClause);
            filterExpression = filterExpression && filterExpression.length ? "filter=" + filterExpression : "";
            var totalCount = "&$top=" + this.topXLocations;
            if (!filterExpression) {
                // there needs to be a filter expression for bing to return any results
                filterExpression = 'filter=true eq true';
            }
            var finalQuery = baseUrl + filterExpression  + totalCount;
            return finalQuery;
        };

        this.isBlankQuery = function () {
            return !generateFilterExpression(this.filterClause);
        };

        this.sendRequests = function (gatherResultsForInMemoryFilter) {
            if (!this.baseUrl) {
                return [];
            }

            var isMainQueryBlank = this.isBlankQuery();
            var queryData = [];
            queryData.push({
                query: this.buildQuery(),
                isBlankQuery: isMainQueryBlank
            });

            if (this.additionalRequests && this.additionalRequests.length) {
                queryData = queryData.concat(this.additionalRequests.map(function (additionalRequest) {
                    return {
                        query: additionalRequest.buildQuery(),
                        isBlankQuery: false
                    };
                }));
            }

            var requestData = queryData.map(function (queryDataItem) {
                return bundleRequestWithFilteringIntent($.ajax({ url: queryDataItem.query, dataType: "text json", type: "GET" }), false, queryDataItem.isBlankQuery);
            });

            if (gatherResultsForInMemoryFilter && !isMainQueryBlank) {
                var blankQuery = new bingQueryBuilder(this.baseUrl, this.topXLocations, this.regionSearchInfo, false);
                var allResultsRequests = blankQuery.sendRequests();
                allResultsRequests.forEach(function (req) {
                    req.isClientFilterRequest = true;
                });
                requestData = requestData.concat(allResultsRequests);
            }

            return requestData;
        };
    }

    // initializing item list bindings
    function initItemListHandlers(filterTypes) {
        $('.items-list', $(scope)).on('click', 'li', function () {
            //open marker
            var id = $(this).data('id').toString();
            $('.items-list li', $(scope)).removeClass('active');
            $(this).addClass('active');

            for (var i = 0; i < markers.length; i++) {
                if (markers[i].title === id) {
                    google.maps.event.trigger(markers[i], 'click');
                    map.setCenter(markers[i].getPosition());
                    break;
                }
            }
        });
    }

    // function used for retrieveing place from textbox upon pressing 'enter' key
    function getPlaceFromTextboxValue(text) {
        deleteMarkers();
        resetSidebar();

        if (service && text && text.length) {
            service.textSearch({
                query: text //,
                // types: options
            }, function (results, status) {
                freeTextSearchCallback(results, status, text);
            });
        }
        else if (!text || !text.length) {
            loadAllJsonDataToView(getSearchedRegionInfo(null, null));
        }
    }

    function getDetailsCallback(results, status, searchTerm) {
        try {
            mostRecentlyFoundGooglePlacesResponse = results;
            loadAllJsonDataToView(getSearchedRegionInfo(results, searchTerm));
        } catch (err) {
            mostRecentlyFoundGooglePlacesResponse = null;
            console.log(err);
        }
    }

    function freeTextSearchCallback(results, status, searchTerm) {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
            if (results && results.length > 0) {
                var result = results[0];

                service.getDetails({
                    placeId: results[0].place_id
                }, function (getDetailsResults, status) {
                    getDetailsCallback(getDetailsResults, status, searchTerm);
                });
            }
            else {
                mostRecentlyFoundGooglePlacesResponse = null;
            }
        }
        else {
            mostRecentlyFoundGooglePlacesResponse = null;
            loadAllJsonDataToView(getSearchedRegionInfo(null, searchTerm));
        }
    }

    function isSearchRegionTypeRelevant(relevantTypes, regionType) {
        return relevantTypes.some(function (supportedRegionType) {
            return supportedRegionType === regionType;
        });
    }

    function getAddressComponentWeight(addressComponent, relevantTypes) {
        var weight = 0;
        var powerOfTen = 1;
        for (var i = relevantTypes.length - 1; i >= 0; i--) {
            if (addressComponent.types.find(function (addressComponentType) {
                return addressComponentType === relevantTypes[i];
            })) {
                weight += powerOfTen;
            }
            powerOfTen = powerOfTen * 10;
        }

        return weight;
    }

    function getGooglePlaceRegionTypeInList(googlePlacesResponse, relevantTypes) {
        if (!googlePlacesResponse || !googlePlacesResponse.address_components) {
            return null;
        }

        var relevantPortions = googlePlacesResponse.address_components.filter(function (addressComponent) {
            return addressComponent.types.some(function (element) {
                return isSearchRegionTypeRelevant(relevantTypes, element);
            });
        });

        var relevantAddressPortionsSorted = relevantPortions.sort(function (element1, element2) {
            return getAddressComponentWeight(element2, relevantTypes) - getAddressComponentWeight(element1, relevantTypes);
        });

        return relevantAddressPortionsSorted && relevantAddressPortionsSorted.length ? relevantAddressPortionsSorted[0] : null;
    }

    function transformPlace(googlePlace, regionType, isMostSpecificSearchRegion) {
        return {
            regionCode: googlePlace.short_name,
            regionName: googlePlace.long_name,
            regionType: regionType,
            isMostSpecificSearchRegion: isMostSpecificSearchRegion
        };
    }

    function getCountry(googlePlacesResponse) {
        var country = getGooglePlaceRegionTypeInList(googlePlacesResponse, ['country']);
        return country ? transformPlace(country, 'country') : null;
    }

    function getState(googlePlacesResponse) {
        var state = getGooglePlaceRegionTypeInList(googlePlacesResponse, ['administrative_area_level_1']);
        return state ? transformPlace(state, 'administrative_area_level_1') : null;
    }

    function isPostalCode(searchTerm) {
        var usPostalCodeRegex = /^\d{5}(?:[-\s]\d{4})?$/;
        return usPostalCodeRegex.test(searchTerm);
    }

    function getSearchedRegionInfo(googlePlacesResponse, searchTerm) {
        var isSearchTermAPostalCode = isPostalCode(searchTerm);
        var supportedSearchRegionTypesInOrder = isSearchTermAPostalCode ?
            ['postal_code', 'locality', 'administrative_area_level_1', 'country'] :
            ['locality', 'postal_code', 'administrative_area_level_1', 'country'];
        var mostSpecificSearchRegion = getGooglePlaceRegionTypeInList(googlePlacesResponse, supportedSearchRegionTypesInOrder);
        var mostSpecificSearchRegionType = mostSpecificSearchRegion ? mostSpecificSearchRegion.types.find(function (searchRegionType) {
            return isSearchRegionTypeRelevant(supportedSearchRegionTypesInOrder, searchRegionType);
        }) : null;

        var isCountry = mostSpecificSearchRegionType === 'country';
        // Google Places may return zip codes even if they were not what the user was searching for
        var isPostalRegion = mostSpecificSearchRegionType === 'postal_code' && isSearchTermAPostalCode;
        var isStateProvince = mostSpecificSearchRegionType === 'administrative_area_level_1';
        var isCity = mostSpecificSearchRegionType === 'locality';

        var region = mostSpecificSearchRegion ?
            transformPlace(mostSpecificSearchRegion, mostSpecificSearchRegionType, true) :
            null;

        return {
            regionType: mostSpecificSearchRegionType,
            region: region,
            latitude: googlePlacesResponse ? googlePlacesResponse.geometry.location.lat() : null,
            longitude: googlePlacesResponse ? googlePlacesResponse.geometry.location.lng() : null,
            googlePlacesData: googlePlacesResponse,
            isCountry: isCountry,
            isPostalRegion: isPostalRegion,
            isStateProvince: isStateProvince,
            isCity: isCity,
            searchTerm: encodeURIComponent(searchTerm),
            getCountry: function () { return getCountry(googlePlacesResponse); },
            getState: function () { return getState(googlePlacesResponse); },
            loadAll: !googlePlacesResponse && (!searchTerm || !searchTerm.length)
        };
    }

    var clicksWithinLast5Seconds = 0;
    function triggerSendingSelectedFiltersToGoogleAnalytics() {
        clicksWithinLast5Seconds++;
        setTimeout(sendSelectedFiltersToGoogleAnalyticsIfDoneFiltering, 5000);
    }

    // Send an event to Google Analytics if the user hasn't selected filters in the last 5 seconds
    function sendSelectedFiltersToGoogleAnalyticsIfDoneFiltering() {
        if (clicksWithinLast5Seconds > 0) {
            clicksWithinLast5Seconds--;
        }

        if (clicksWithinLast5Seconds > 0) {
            return;
        }

        app.sendEventToGoogleAnalytics({
            Category: 'How To Buy',
            Action: 'How To Buy Filters Selected: '.concat(
                'Page: "' + window.location.href + '"',
                ' . Selected filters: "' + getSelectedFiltersAsString() + '"',
                ' . Search Term: "' + getSearchTerm() + '"'),
            Label: 'How To Buy Filters Selected'
        });
    }

    function getCurrentSearchTerm() {
        return $('#how-to-buy-2__search-input').val();
    }

    function getSelectedFilters() {
        var selectedCheckboxFilter = $(".how-to-buy-2__filters :checkbox:checked");
        var loadedFilters = [];
        $.each(selectedCheckboxFilter, function (index, filter) {
            loadedFilters.push(filter.value);
        });
        return loadedFilters;
    }

    // initilaize map and bindings based on location source type
    function initMapAndSearch(defaultMapCenter, defaultZoom) {

        var mapContainer = $('.map-container', $(scope)).get(0);

        map = new google.maps.Map(mapContainer, {
            zoom: defaultZoom,
            center: defaultMapCenter
        });

        google.maps.event.addDomListener(window, 'resize', function () {
            //  map.fitBounds(path_bounds);
            map.setCenter(defaultMapCenter);

        });

        service = new google.maps.places.PlacesService(map);

        //if the search is map related (non-agent id based), we will initialize searchbox listeners
        // Create the search box

        function handleSearchInputSubmission() {
            var text = getCurrentSearchTerm();
            var isValidSearch = true;
            //make sure a city is searched
            if (text && text != "" && !isPostalCode(text) && !document.getElementById("cityCheck").checked) {
                deleteMarkers();
                $(".how-to-buy-2__list__addresses> li").hide();
                showSearchZipMessage();
                isValidSearch = false
            }

            if (isValidSearch) {
                getPlaceFromTextboxValue(text);
            }
        }

        //By Agent IDs
        $('#how-to-buy-2__search-input', $(scope)).bind("enterKey", function (e) {
            handleSearchInputSubmission();
        });

        //for click
        $('#map-search-button', $(scope)).bind("click", function (e) {
            handleSearchInputSubmission();
        });

        $('#how-to-buy-2__search-input', $(scope)).keyup(function (e) {
            if (e.keyCode === 13) {
                $(this).trigger("enterKey");
            }
        });

        initItemListHandlers(filterTypes);

        loadSearchByRegionDataToView(getSelectedFilters(), getSearchedRegionInfo(mostRecentlyFoundGooglePlacesResponse, null));

        var setFilterSelectedStatus = function (modifiedCheckbox) {
            var matchingFilter = Object.values(filterTypes).find(function (filter) {
                return modifiedCheckbox && filter.class === modifiedCheckbox.value;
            });
            if (matchingFilter) {
                matchingFilter.isSelected = modifiedCheckbox.checked;
            }
        };

        $(".how-to-buy-2__filters :checkbox").click(function () {
            setFilterSelectedStatus(this);
            triggerSendingSelectedFiltersToGoogleAnalytics();
            hideResultMessages();
            var bounds = new google.maps.LatLngBounds();
            loadSearchByRegionDataToView(getSelectedFilters(), getSearchedRegionInfo(mostRecentlyFoundGooglePlacesResponse, getCurrentSearchTerm()));
            if ($(".how-to-buy-2__filters :checkbox:checked").length == 0) {
                $(".how-to-buy-2__list__addresses> li").hide();

                for (var i = 0; i < markers.length; i++) {
                    markers[i].setVisible(false);
                }
                bounds.extend({ lat: initLat, lng: initLng });
            }
            if ($(".how-to-buy-2__filters :checkbox:checked").length > 0) {

                $(".how-to-buy-2__list__addresses> li").hide();
                for (var i = 0; i < markers.length; i++) {
                    markers[i].setVisible(false);
                }

                $(".how-to-buy-2__filters :checkbox:checked").each(function () {
                    $(".how-to-buy-2__list__addresses ." + $(this).val()).show();
                    for (var i = 0; i < markers.length; i++) {
                        if (markers[i].category === $(this).val()) {
                            markers[i].setVisible(true);
                            bounds.extend(markers[i].getPosition());
                        }
                    }
                });
                showMarkers();
                map.fitBounds(bounds);
            }
        });
    }

    function getData(url) {
        var deferred = jQuery.Deferred();

        if (!url) {
            return deferred.reject();
        }

        jQuery.get(url)
            .done(function (responseData) {
                deferred.resolve(responseData);
            })
            .fail(function () {
                deferred.reject();
            });

        return deferred;
    }
}
;
var app = app || {};
app.shareurl = app.shareurl || {};

app.shareurl = {
    init: function() {
        $('body').on('click',
            function(e) {
                if (e.target.closest('.share')) {
                    return;
                }
                $('.share').removeClass('share--open');
            });
    },
    socialClick: function(e) {
        e.preventDefault();
        var queryParam = "";
        var isDefaultShare = $(this).attr("data-defaultShare");
        var src = $(this).attr("href");
        var linkType = $(this).attr("data-linktype");

        if (isDefaultShare) {
            var title = $("meta[property='og:title']").attr("content") || 'Acuity Brands';
            var description = $("meta[property='og:title']").attr("description") ||
                'World’s leading providers of innovative lighting systems.';
            var src = $(this).attr("href");
            if (linkType.toLowerCase() == "twitter") {
                queryParam = '&text=' + description;
            }
            if (linkType.toLowerCase() == "linkedin") {
                queryParam = '&title=' + title + "&summary=" + description;
            }
            src = (src + queryParam);
            //for length issue: 
            var url = src.substring(0, 140);
            var win = window.open((url), '_blank');
            win.focus();
        } else {
            var win = window.open((src), '_blank');
            win.focus();
        }
    }
};
;
var app = app || {};
app.featuredProducts = app.featuredProducts || {};

app.featuredProducts = {
    init: function () {
        app.featuredProducts.resizeComponents();
        app.featuredProducts.setupClickHandlers();
    },
    setupClickHandlers: function (componentSelector) {
        $('.featured-products .featured-products__button, .base-product-list .featured-products__button').each(function (index, element) {
            var showMoreButton = $(element);
            var componentToDisplay = showMoreButton.data('displayComponent');
            var showLessButton = $(componentToDisplay + ' .load-less');
            showMoreButton.click(function () {
                app.featuredProducts.showMore(componentToDisplay);
                showMoreButton.hide();
                showLessButton.show();
            });
            showLessButton.click(function () {
                app.featuredProducts.showLess(componentToDisplay);
                showLessButton.hide();
                showMoreButton.show();
                var componentRoot = showLessButton.closest('.tabs__sections__current-section');
                $('html, body').animate({
                    'scrollTop': $(componentRoot).offset().top-200
                },20);
            });
        });
    },
    showMore: function (componentSelector) {
        $(componentSelector + ' .featured-products__product.hide-item').each(function (index, element) {
            element.classList.remove("d-none");
            $(element).show();
        });
        app.featuredProducts.resizeComponents(componentSelector);
    },
    showLess: function (componentSelector) {
        $(componentSelector + ' .featured-products__product.hide-item').each(function (index, element) {
            element.classList.add("d-none");
            $(element).hide();
        });
        app.featuredProducts.resizeComponents(componentSelector);
    },
    resizeComponents: function (componentSelector) {
        var selector = '.featured-products';
        if (componentSelector) {
            selector = componentSelector;
        }

        $(selector).each(function (index, featuredProductComponent) {
            /* ########## IMAGE ########## */
            var featuredProductImages = $(featuredProductComponent).find('.featured-products__image');
            featuredProductImages.css('height', 'auto');
            var tallestSRImage = -1;
            featuredProductImages.each(function () {
                tallestSRImage = tallestSRImage > $(this).innerHeight() ? tallestSRImage : $(this).innerHeight();
            });
            featuredProductImages.css('height', tallestSRImage);

            /* ########## INFO ########## */
            var featuredProductInfo = $(featuredProductComponent).find('.featured-products__info');
            featuredProductInfo.css('height', 'auto');
            var tallestSRInfo = -1;
            featuredProductInfo.each(function () {
                tallestSRInfo = tallestSRInfo > $(this).innerHeight() ? tallestSRInfo : $(this).innerHeight();
            });
            featuredProductInfo.css('height', tallestSRInfo);
        });
    }
};

$(window).on("load resize click.tabs__nav", function () {
    app.featuredProducts.init();
});;
(function () {
    function WhoToCallController($scope, $attrs) {
        $scope.regions = null;
        $scope.data = null;
        $scope.dataSourceId = $attrs.dataSourceId;
        $scope.agenciesNames = [];
        $scope.departmentsNames = [];
        $scope.agenciesObjects = [];
        $scope.departmentsObjects = [];
        $scope.regionsNames = [];
        $scope.selectedRegion = null;
        $scope.selectedDepartment = null;
        $scope.selectedAgency = null;

        $scope.update = function () {
            var a = 1;
        };

        $scope.getAgenciesToDisplay = function (agencies) {
            if ($scope.selectedAgency === null) {
                return agencies;
            }
            var result = [];
            angular.forEach(agencies, function (agency, index) {
                if ($scope.selectedAgency.Code === agency.Code) {
                    result.push(agency);
                }
            });
            return result;
        };

        $scope.toggleAgencyShowAllContacts = function (agency) {
            agency.showAllContacts = !agency.showAllContacts;
        };

        $scope.getDepartmentsToDisplay = function () {
            if ($scope.selectedDepartment !== null && $scope.selectedDepartment.Name !== null) {
                var results = [];
                angular.forEach($scope.departmentsObjects, function (department, indexthree) {
                    if (department.Name === $scope.selectedDepartment.Name) {
                        results.push(department);
                    }
                });
                return results;
            }
            return $scope.departmentsObjects;
        };

        $scope.getUniqueArray = function (array) {
            var result = [];
            for (var x = 0; x < array.length; x++) {
                if (result.indexOf(array[x]) === -1)
                    result.push(array[x]);
            }
            return result;
        };

        $scope.setAgenciesInFilters = function () {
            $scope.agenciesNames = [];
            $scope.agenciesObjects = [];
            //regions
            angular.forEach($scope.regions, function (region, index) {
                //departments
                if ($scope.selectedRegion === null || region.Name === $scope.selectedRegion.Name) {
                    angular.forEach(region.Departments, function (department, indexTwo) {
                        //agencies
                        if ($scope.selectedDepartment === null || department.Name === $scope.selectedDepartment.Name) {
                            angular.forEach(department.Agencies, function (agency, indexThree) {
                                if ($scope.selectedAgency === null || agency.Name === $scope.selectedAgency.Name) {
                                    if (!$scope.agenciesNames.includes(agency.Name)) {
                                        $scope.agenciesNames.push(agency.Name);
                                        $scope.agenciesObjects.push(agency);
                                    }
                                }
                            });
                        }
                    });
                }
            });
        };

        $scope.setDepartmentsInFilters = function () {
            $scope.departmentsNames = [];
            $scope.departmentsObjects = [];
            //regions
            angular.forEach($scope.regions, function (region, index) {
                //departments
                if ($scope.selectedRegion === null || region.Name === $scope.selectedRegion.Name) {
                    angular.forEach(region.Departments, function (department, indexTwo) {
                        if ($scope.selectedDepartment === null || department.Name === $scope.selectedDepartment.Name) {
                            if (!$scope.departmentsNames.includes(department.Name)) {
                                $scope.departmentsNames.push(department.Name);
                                $scope.departmentsObjects.push(department);
                            }
                        }
                    });
                }
            });
        };


        $scope.displayOddContact = function (agencyLength, index) {
            return agencyLength > index * 2 + 1;
        };

        $scope.setupWhoToCallData = function (data) {
            $scope.$apply(function () {
                $scope.regions = data;

                //$scope.setDepartmentsInFilters();
                //$scope.setAgenciesInFilters();
            });
        };

        $scope.resetAgency = function () {
            $scope.selectedAgency = null;
            $scope.resetDepartment();
            $scope.setAgenciesInFilters();


        };

        $scope.resetDepartment = function () {
            $scope.selectedDepartment = null;
            $scope.setDepartmentsInFilters();

        };

        function fetchWhoToCallData() {
            if ($scope.dataSourceId && !$scope.regions) {
                $.post(
                    '/api/whotocall/getdata',
                    {
                        dataSourceId: $scope.dataSourceId
                    },
                    function (data) {
                        if (data && data.Success && data.Value) {
                            var parsedRegions = JSON.parse(data.Value);
                            if (parsedRegions && parsedRegions.length) {
                                $scope.setupWhoToCallData(parsedRegions);
                            }
                            else {
                                console.log('Who To Call Error: Unable to parse region data.');
                            }
                        }
                        else {
                            var responseErr = 'Who To Call Error: Unable to retrieve who to call data.';
                            if (data && data.Error) {
                                responseErr = 'Who To Call Error:' + data.Error;
                            }
                            console.log(responseErr);
                        }
                    },
                    'json'
                );
            }
        }

        if ($scope.directChildInitializers) {
            $scope.directChildInitializers.push(fetchWhoToCallData);
        }
        else {
            fetchWhoToCallData();
        }
    }

    var whoToCallModule = angular.module('whoToCall', []);
    whoToCallModule.controller('WhoToCallController', ['$scope', '$attrs', WhoToCallController]);
    angular.module('acuityApp').requires.push('whoToCall');
})();;
var app = app || {};
app.warranty = app.warranty || {};

app.warranty = {
    registration: {
        init: function () {
            $.validator.addMethod("proofofpurchaserequired", function (value, element) {
                console.log('proofofpurchaserequired validation: ' + element.name);

                //debugger;
                if (value == "") {
                    if ($("#" + element.id).parent().siblings(".file-upload-button").first().val() == "") {
                        return false;
                    }
                    return true;
                }
                else {
                    return true;
                }
            });
            $.validator.addMethod("filesizetoolarge", function (value, element) {
                console.log('filesizetoolarge validation: ' + element.name);

                if (value) {
                    var maxSize = parseInt($('.warranty-registration-form').attr('data-file-size'));
                    var selectedSize = parseInt($(element).attr('data-selectedfilesize'));

                    if (selectedSize > maxSize) {
                        return false;
                    }
                }

                return true;
            });
            
            app.warranty.registration.AddProofOfPurchaseValidation();

            $(".file-upload-button").change(function (e) {
                app.warranty.registration.onFileSelected(e);
            });

        },
        onBegin: function () {
            $("#warranty-registration-errors").html("");
            $('#warranty-form-submit-button, .warranty-reset-button').prop('disabled', true);
            $('#loadingIcon').show();
        },
        onSuccess: function (data) {
            if (data && data.Value && data.Value.SuccessMessage) {
                $("#warranty-registration-success-message").html(data.Value.SuccessMessage);
                $(".warranty-registration-form").hide();
            }
            else {
                var responseErr = 'Warranty Registration Error: Unable to process submitted form data.';
                if (data && data.Error) {
                    responseErr = data.Error;
                }
                $("#warranty-registration-errors").html(responseErr);
                $('#warranty-form-submit-button, .warranty-reset-button').prop('disabled', false);
                $('#loadingIcon').hide();
            }
            window.scrollTo(0, 0);
        },
        onFailure: function (xhr, status, error) {
            $("#warranty-registration-errors").html("There was an error while processing the warranty registration form.");
            $('#warranty-form-submit-button, .warranty-reset-button').prop('disabled', false);
            $('#loadingIcon').hide();
        },
        AddProofOfPurchaseValidation: function () {

            //var i = app.warranty.registration.elementCount - 1;
            //debugger;
            $("input.product-date-code").each(function () {
                console.log('Adding: ProductDateCode ' + $(this).attr('name'));
                $(this).rules("add", {
                    proofofpurchaserequired: true,
                    messages: {
                        proofofpurchaserequired: $(this).attr("data-val-proofofpurchaserequired")
                    }
                });
            });

            $("input.file-upload-button").each(function () {
                console.log('Adding: ProofOfPurchaseImage ' + $(this).attr('name'));
                $(this).rules("add", {
                    filesizetoolarge: true,
                    messages: {
                        filesizetoolarge: $(this).attr("data-val-filesizetoolarge")
                    }
                });
            });
        },
        elementCount: 1,
        onFileSelected: function (e) {
            var indx = $(e.currentTarget).attr("data-index");

            $(e.currentTarget).attr('data-selectedfilesize', e.currentTarget.files[0].size);

            var fileName = $(e.currentTarget).val().split('\\')[$(e.currentTarget).val().split('\\').length - 1];
            $(e.currentTarget).siblings(".uploaded-receipt-text").text(fileName);


            //VALIDATION HERE
            var maxSize = parseInt($('.warranty-registration-form').attr('data-file-size'));
            if (maxSize > e.currentTarget.files[0].size) {
                var element = document.getElementById('ProofOfPurchaseImage_' + indx + '-error');
                element.parentNode.removeChild(element);
            }
            


        }
        
    },
    lookup: {
        viewFullSizeImage: function (element) {
            var image = new Image();
            image.src = $(element).attr("src");

            var w = window.open("");
            w.document.write(image.outerHTML);
        }
    }
}

$(document).ready(function () {
    app.warranty.registration.init();
})

//Create the parent div for the row of elements and add the textboxes and delete button to the row.
function getInputRow(indexNum) {
    var clonedDiv = $(".warranty-product-row").first().clone();

    $(clonedDiv).find("div div:nth-child(1) .form-group input").prop("id", "ModelNumber_" + indexNum).val("");
    $(clonedDiv).find("div div:nth-child(1) .form-group input").prop("name", "RegisteredProducts[" + indexNum + "].ModelNumber").removeAttr("aria-describedby aria-invalid");
    $(clonedDiv).find("div div:nth-child(1) .form-group label").prop("for", "ModelNumber_" + indexNum);
    $(clonedDiv).find("div div:nth-child(1) .form-group span").html("").removeClass("field-validation-error").addClass("field-validation-valid")
        .attr("data-valmsg-for", "RegisteredProducts[" + indexNum + "].ModelNumber");

    $(clonedDiv).find("div div:nth-child(2) .form-group input").prop("id", "Quantity_" + indexNum).val("");
    $(clonedDiv).find("div div:nth-child(2) .form-group input").prop("name", "RegisteredProducts[" + indexNum + "].Quantity").removeAttr("aria-describedby aria-invalid");
    $(clonedDiv).find("div div:nth-child(2) .form-group label").prop("for", "Quantity_" + indexNum);
    $(clonedDiv).find("div div:nth-child(2) .form-group span").html("").removeClass("field-validation-error").addClass("field-validation-valid")
        .attr("data-valmsg-for", "RegisteredProducts[" + indexNum + "].Quantity");

    $(clonedDiv).find("div div:nth-child(3) .form-group input").prop("id", "PurchaseDate_" + indexNum).val("");
    $(clonedDiv).find("div div:nth-child(3) .form-group input").prop("name", "RegisteredProducts[" + indexNum + "].PurchaseDate").removeAttr("aria-describedby aria-invalid");
    $(clonedDiv).find("div div:nth-child(3) .form-group label").prop("for", "PurchaseDate_" + indexNum);
    $(clonedDiv).find("div div:nth-child(3) .form-group span").html("").removeClass("field-validation-error").addClass("field-validation-valid")
        .attr("data-valmsg-for", "RegisteredProducts[" + indexNum + "].PurchaseDate");

    $(clonedDiv).find("div div:nth-child(5) .upload-receipt button.upload-receipt-button")
        .click(function (e) {
            e.preventDefault();
            $(this).siblings(".file-upload-button").click();
        });

    $(clonedDiv).find("div div:nth-child(5) .upload-receipt .file-upload-button").prop("name", "RegisteredProducts[" + indexNum + "].ProofOfPurchaseImage");
    $(clonedDiv).find(".file-upload-button").attr("data-index", indexNum);

    $(clonedDiv).find("div div:nth-child(5) .upload-receipt input.file-upload-button").val("").change(function (e) {
        app.warranty.registration.onFileSelected(e);
    });
    $(clonedDiv).find("div div:nth-child(5) .upload-receipt span.uploaded-receipt-text").text("");
    $(clonedDiv).find("input.product-date-code").prop("id", "ProductDateCode_" + indexNum).val("");
    $(clonedDiv).find("input.product-date-code").prop("name", "RegisteredProducts[" + indexNum + "].ProductDateCode");

    $(clonedDiv).find("input.file-upload-button").prop("id", "ProofOfPurchaseImage_" + indexNum).val("");
    $(clonedDiv).find("input.file-upload-button").prop("name", "RegisteredProducts[" + indexNum + "].ProofOfPurchaseImage");

    $(clonedDiv).find("div div:nth-child(5) .form-group label").prop("for", "ProductDateCode_" + indexNum);
    $(clonedDiv).find("span.val-msg-productCode").html("").removeClass("field-validation-error").addClass("field-validation-valid")
        .attr("data-valmsg-for", "RegisteredProducts[" + indexNum + "].ProductDateCode");
    $(clonedDiv).find("span.val-msg-proofImg").html("").removeClass("field-validation-error").addClass("field-validation-valid")
        .attr("data-valmsg-for", "RegisteredProducts[" + indexNum + "].ProofOfPurchaseImage");

    var removeImage = document.createElement("img");
    $(removeImage).addClass("warranty-remove-row").attr("src", "/Assets/img/compare-remove.png").attr("alt", "Remove Product").attr("data-row", indexNum);

    //when a remove button is clicked, update properties of rows after this one to keep everything in sync
    $(removeImage).click(function () {
        var counter = parseInt($(this).data("row"));
        $(this).parent().nextAll(".warranty-product-row").each(function () {
            $(this).children(".warranty-remove-row").attr("data-row", counter);
            $(this).find("div div:nth-child(1) .form-group input").prop("id", "ModelNumber_" + counter);
            $(this).find("div div:nth-child(1) .form-group input").prop("name", "RegisteredProducts[" + counter + "].ModelNumber");
            $(this).find("div div:nth-child(1) .form-group label").prop("for", "ModelNumber_" + counter);
            $(this).find("div div:nth-child(1) .form-group span").attr("data-valmsg-for", "RegisteredProducts[" + counter + "].ModelNumber");

            $(this).find("div div:nth-child(2) .form-group input").prop("id", "Quantity_" + counter);
            $(this).find("div div:nth-child(2) .form-group input").prop("name", "RegisteredProducts[" + counter + "].Quantity");
            $(this).find("div div:nth-child(2) .form-group label").prop("for", "Quantity_" + counter);
            $(this).find("div div:nth-child(2) .form-group span").attr("data-valmsg-for", "RegisteredProducts[" + counter + "].Quantity");

            $(this).find("div div:nth-child(3) .form-group input").prop("id", "PurchaseDate_" + counter).val("");
            $(this).find("div div:nth-child(3) .form-group input").prop("name", "RegisteredProducts[" + counter + "].PurchaseDate");
            $(this).find("div div:nth-child(3) .form-group label").prop("for", "PurchaseDate_" + counter);
            $(this).find("div div:nth-child(3) .form-group span").attr("data-valmsg-for", "RegisteredProducts[" + counter + "].PurchaseDate");

            $(this).find("div div:nth-child(5) .upload-receipt .file-upload-button").prop("name", "RegisteredProducts[" + counter + "].ProofOfPurchaseImage");

            $(this).find("div div:nth-child(5) .form-group input").prop("id", "ProductDateCode_" + counter).val("");
            $(this).find("div div:nth-child(5) .form-group input").prop("name", "RegisteredProducts[" + counter + "].ProductDateCode");
            $(this).find("div div:nth-child(5) .form-group label").prop("for", "ProductDateCode_" + counter);
            $(this).find("div div:nth-child(5) > span").attr("data-valmsg-for", "RegisteredProducts[" + counter + "].ProductDateCode");

            counter++;
        });
        $(this).parent().remove();
        app.warranty.registration.elementCount--;
    });
    $(clonedDiv).prepend(removeImage);

    return clonedDiv;
}

$('button.warranty-registration__spacing').click(function (e) {
    e.preventDefault();
    var parentDiv = $("#warrantyProductRows");
    var elem = getInputRow(app.warranty.registration.elementCount);
    parentDiv.append(elem);

    //Remove and reapply page validation so the dynamically created elements will be registered for validation
    $("form.warranty-registration-form").removeData("validator").removeData("unobtrusiveValidation");
    $.validator.unobtrusive.parse("form.warranty-registration-form");

    app.warranty.registration.elementCount++;
    app.warranty.registration.AddProofOfPurchaseValidation();
});

$(".upload-receipt-button").click(function (e) {
    e.preventDefault();
    $(this).siblings(".file-upload-button").click();
});

$(".warranty-reset-button").click(function () {
    $(".warranty-remove-row").click();
    $("span.uploaded-receipt-text").text("");
    $(".field-validation-error").html("");
    $(".warranty-registration-form").trigger("reset");
    $("#EndUser").trigger("change");
});

$("#EndUser").change(function (e) {
    if ($(this).val() == "Other") {
        $("#OtherEndUser").show();
    }
    else {
        $("#OtherEndUser").val("").hide();
    }
});

(function () {
    function WarrantyController($scope, $http, pagerService) {
        $scope.users = [];
        $scope.pagedUserResults = [];
        $scope.resultsPerPage = 10;
        $scope.pager = {};
        $scope.setPage = setPage;

        $scope.searchClicked = function (event) {
            event.preventDefault();
            var searchCriteria = $('.warranty-lookup #searchForm').serializeArray();
            var queryString = $.param(searchCriteria);
            getUsers(queryString);
        }

        function getUsers(queryString) {
            $('.searchBtn, page-link').prop('disabled', true);
            $('#usersTableContainer').fadeTo(0, .5);
            $("#usersTableContainer table caption").removeClass("text-danger").hide();
            $('#loadingIcon').show();

            $http.get("/api/warranty/getuserresults?" + queryString)
                .then(function (response) {
                    $scope.users = response.data.Users;
                    $scope.resultsPerPage = response.data.ResultsPerPage;

                    $("#usersTableContainer table caption").show();
                    setPage(1, true);
                },
                    function (response) {
                        $("#usersTableContainer table caption").text(response.data.FailureMessage).addClass("text-danger").show();
                    })
                .finally(function () {
                    $('.searchBtn, page-link').prop('disabled', false);
                    $('#usersTableContainer').fadeTo(0, 1);
                    $('#loadingIcon').hide();
                });
        }

        function setPage(page, init) {

            if (!init) {
                if (page < 1 || page > $scope.pager.totalPages) {
                    return;
                }
            }

            $scope.pager = pagerService.GetPager($scope.users.length, page, $scope.resultsPerPage);

            // get current page of items
            $scope.pagedUserResults = $scope.users.slice($scope.pager.startIndex, $scope.pager.endIndex + 1);
        }
    }

    var warrantyModule = angular.module('warranty', []);
    warrantyModule.factory('pagerService', app.angularshared.PagerService);
    warrantyModule.controller('WarrantyController', ['$scope', '$http', 'pagerService', WarrantyController]);
    angular.module('acuityApp').requires.push('warranty');
})();;
var app = app || {};
app.imageList = app.imageList || {};

app.imageList = {
    onClick: function (obj) {
        var linkurl = obj.parentNode.attributes.href.value;
        if (linkurl === "") {
            $('body').addClass('image-list-modal-open');
            var imageSelected = obj.attributes.src.value;
            $('.image-list-modal__image').attr('src', imageSelected);
        }
    }
};

$(window).on("load", function () {
    $('.image-list-cmpnt img').click(function () {
        app.imageList.onClick(this);
    });
});;
(function () {
    function UserProfileController($scope, $http) {
        $scope.profile = { displayName: "", givenName: "", surname: "", streetAddress: "", city: "", state: "", postalCode: "", country: "", department: "", jobTitle: "", mobilePhone: "" };

        $scope.init = function (displayName, givenName, surname, streetAddress, city, state, postalCode, country, department, jobTitle, mobilePhone) {
            $scope.profile.displayName = displayName;
            $scope.profile.firstName = givenName;
            $scope.profile.lastName = surname;
            $scope.profile.state = state;
            $scope.profile.city = city;
            $scope.profile.streetAddress = streetAddress;
            $scope.profile.postalCode = postalCode;
            $scope.profile.country = country;
            $scope.profile.department = department;
            $scope.profile.jobTitle = jobTitle;
            $scope.profile.mobilePhone = mobilePhone;


            $scope.submitted = false;

        };

        $scope.save = function ($event) {

            $("#user-profile-success").hide();
            $("#user-profile-errors").hide();
            $scope.submitted = true;
            if (userProfileForm.checkValidity() && !$scope.showLoader) {
                $("#loadingIcon").show();
                $scope.profile.givenName = $scope.profile.firstName;
                $scope.profile.surname = $scope.profile.lastName;

                $.post("/api/account/updateprofile", $scope.profile, function (data) {
                    $("#loadingIcon").hide();
                    if (data.result) {
                        $("#user-profile-success").show();
                    } else {
                        $("#user-profile-errors").show();
                    }
                });
            }



        };

    }


    var module = angular.module('userprofile', []);
    module.controller('UserProfileController', ['$scope', '$http', UserProfileController]);
    angular.module('acuityApp').requires.push('userprofile');
})();;
/// Crazy Egg
setTimeout(function () {
    var a = document.createElement("script");
    var b = document.getElementsByTagName("script")[0];
    a.src = document.location.protocol + "//script.crazyegg.com/pages/scripts/0017/2959.js?" + Math.floor(new Date().getTime() / 3600000);
    a.async = true; a.type = "text/javascript"; b.parentNode.insertBefore(a, b)
}, 1);
/// Crazy Egg
/// Pardot analytics 
piAId = '457272';
piCId = '66379';
piHostname = 'pi.pardot.com';

(function () {
    function async_load() {
        var s = document.createElement('script'); s.type = 'text/javascript';
        s.src = ('https:' === document.location.protocol ? 'https://pi' : 'http://cdn') + '.pardot.com/pd.js';
        var c = document.getElementsByTagName('script')[0]; c.parentNode.insertBefore(s, c);
    }
    if (window.attachEvent) { window.attachEvent('onload', async_load); }
    else { window.addEventListener('load', async_load, false); }
})();
/// Pardot analytics 
;
var app = app || {};
app.persona = app.persona || {};

(function () {
    function PersonaController($scope, $http) {

        $scope.getPersonasErrorMessage = '';
        $scope.setPersonaErrorMessage = '';
        $scope.errorMessage = '';
        $scope.setPersonaRequestPending = false;
        $scope.sentRequestForPersona = '';
        $scope.returnUrl = '';

        $scope.init = function (getPersonasErrorMessage, setPersonaErrorMessage, currentErrorMessage, returnUrl) {
            $scope.getPersonasErrorMessage = getPersonasErrorMessage;
            $scope.setPersonaErrorMessage = setPersonaErrorMessage;
            $scope.errorMessage = currentErrorMessage;
            $scope.returnUrl = returnUrl;
        };

        var setPersonaErrorHandler = function (data) {
            $scope.errorMessage = $scope.setPersonaErrorMessage;
            $scope.setPersonaRequestPending = false;
        };

        var setPersonaSuccessHandler = function (data) {
            $scope.errorMessage = '';

            if (data && data.Value) {
                window.location.href = data.Value;
            }
        };

        $scope.selectPersona = function (personaName) {
            $scope.setPersonaRequestPending = true;
            $scope.sentRequestForPersona = personaName;

            $http(
                {
                    url: '/api/personas/setpersona',
                    method: 'POST',
                    data: {
                        personaName: personaName,
                        returnUrl: $scope.returnUrl
                    },
                    dataType: 'json'
                })
                .then(function (response) {
                    var serverData = response && response.data ? response.data : null;
                    if (serverData && serverData.Success) {
                        setPersonaSuccessHandler(serverData);
                    } else {
                        setPersonaErrorHandler(response);
                    }
                }, function (response) {
                    setPersonaErrorHandler(response);
                });
        };
    }

    var personaModule = angular.module('persona', []);
    personaModule.controller('PersonaController', ['$scope', '$http', PersonaController]);
    angular.module('acuityApp').requires.push('persona');

})();
;
var app = app || {};
app.photometrydownloads = app.photometrydownloads || {};

app.photometrydownloads = {
    init: function() {
    }
};

$(window).on('load', function () {
    app.photometrydownloads.init();
});

(function () {
    function PhotometryDownloadController($scope) {
        $scope.productTypeArray = [];
        $scope.photometrySeriesArray = [];
        $scope.productPages = {};
        $scope.photometryList = {};
        $scope.errorMessage = '';
        $scope.pendingRequests = [];

        $scope.initdata = function (brandAcronym, maxResultCount, errorMessage, errorOnLoad) {
            $scope.brandAcronym = brandAcronym;
            $scope.maxResultCount = maxResultCount;
            $scope.errorMessage = errorMessage;
            if (errorOnLoad) {
                $scope.displayErrorMessage();
            }
        };

        $scope.displayErrorMessage = function (errMsg) {
            var messageToDisplay = $scope.errorMessage;
            if (errMsg) {
                messageToDisplay = errMsg;
            }

            if (messageToDisplay) {
                $.notify({
                    message: messageToDisplay
                }, {
                    type: 'danger'
                });
            }
        };

        $scope.isProductsFetched = function (productType) {
            if ($scope.productTypeArray.indexOf(productType) !== -1) {
                return true;
            }
            return false;
        };

        $scope.isPhotometryListFetched = function (seriesId) {
            if ($scope.photometrySeriesArray.indexOf(seriesId) !== -1) {
                return true;
            }
            return false;
        };

        $scope.isRequestPending = function (key) {
            return $scope.pendingRequests.indexOf(key) !== -1;
        };

        $scope.addPendingRequest = function (key) {
            // $scope.$apply(function () {
                $scope.pendingRequests.push(key);
            // });
        };

        $scope.removePendingRequest = function (key) {
            $scope.$apply(function () {
                $scope.pendingRequests = $scope.pendingRequests.filter(function (requestName) {
                    return requestName !== key;
                });
            });
        };

        $scope.getBrandWebPages = function (productGroup, productType) {
            if (!$scope.isProductsFetched(productType)) {
                $scope.addPendingRequest(productGroup + productType);
                var data = { productGroup: productGroup, productType: productType, brandAcronym:  $scope.brandAcronym };
                var response = $.post('/api/photometrydownloads/getbrandwebpages', data);
                response.done(function (result) {
                    if (result && result.Success) {
                        $scope.productTypeArray.push(productType);
                        $scope.$apply(function () {
                            var filteredProductTypes = result.Value.filter(function (product) {
                                return product.PhotometryCount > 0;
                            });
                            $scope.productPages[productType] = filteredProductTypes;
                        });
                    }
                    else {
                        $scope.displayErrorMessage();
                    }
                    $scope.removePendingRequest(productGroup + productType);
                });
            }
        }; 

        $scope.getPhotometryList = function (product) {
            var seriesId = product.SeriesID;
            if (!$scope.isPhotometryListFetched(seriesId)) {
                product.ajaxRequestPending = true;
                var data = {seriesId: seriesId, photometryListMaxResultCount: $scope.maxResultCount };
                var response = $.post('/api/photometrydownloads/getphotometryList', data);
                response.done(function (result) {
                    if (result && result.Success) {
                        $scope.photometrySeriesArray.push(seriesId);
                        $scope.$apply(function () {
                            $scope.photometryList[seriesId] = result.Value;
                        });
                    }
                    else {
                        $scope.displayErrorMessage();
                    }
                    $scope.$apply(function () {
                        product.ajaxRequestPending = false;
                    });
                });
            }
        };
    }

    var photometryDownloadsModule = angular.module('photometryDownloads', []);
    photometryDownloadsModule.controller('photometryDownloadController', ['$scope', '$attrs', '$timeout', PhotometryDownloadController]);
    angular.module('acuityApp').requires.push('photometryDownloads');

})();
;
var app = app || {};
app.quickview = app.quickview || {};

app.quickview = {
    init: function () {
        $(".altered-gutters .hide-item").hide();

        app.quickview.handleSearchQuickViewClick();

        $(".altered-gutters .load-more button").click(function () {
            $(".altered-gutters .load-more").hide();
            $(".altered-gutters .hide-item").show();
        });

        $('.quick-view').click(function () {
            var result = $(this).closest('.item__search-results');
            var productId = $(this).data("productid");
            result.find('iframe').attr('src', '/products/detail/' + productId + '?qv=1' + app.quickview.getVersionParameter(this));
            result.addClass('modal-open');
            $("body").css("height", "100vh");
            $("body").css("overflow-y", "hidden");
        });

        // need to handle this at a higher level, since the close-qv-modal button
        // may be created after the click handlers are created
        $('body').on('click', '.close-qv-modal', function () {
            var result = $(this).closest('.item__search-results');
            result.removeClass('modal-open');

            closeQuickViewV2(this);
        });

        var closeQuickViewV2 = function(btn) {
            $(btn).closest('.search-results-grid').removeClass('search-results-grid--quick-view-open');
            $('body').removeClass('quick-view-open');
            $("body").css("height", "auto");
            $("body").css("overflow-y", "auto");
        };
    },
    handleSearchQuickViewClick: function () {
        if (Coveo && $('.CoveoSearchInterface.ablSearch.search-results').length > 0) {
            Coveo.$('.CoveoSearchInterface.ablSearch.search-results').on('newResultsDisplayed', function (e, args) {
                $(this).find('.quick-view').click(function () {
                    var result = $(this).closest('.item__search-results');
                    var productId = $(this).data("productid");
                    if (result && result.length > 0 && productId) {
                        result.find('iframe').attr('src', '/products/detail/' + productId + '?qv=1' + app.quickview.getVersionParameter(this));
                    }
                });
            });
        }
    },
    getVersionParameter: function(element) {
        var isV2SearchForm = element.closest(".CoveoSearchInterface.v2-search");
        return isV2SearchForm ? "&v=2" : "";
    }
};

// This snippet is necessary on non-coveo pages
$(window).on("load", function () {
    app.quickview.init();
});;
var app = app || {};
app.userProfileList = app.userProfileList || {};

app.userProfileList = {
    name: 'favorites',
    init: function () {
        var isanon = document.getElementById("isAnonymous").value;

        if (isanon.toLowerCase() === 'true') {
            sessionStorage.removeItem(app.userProfileList.name);
        }
        else {
            getList()
                .then(function (result) {
                    if (isanon.toLowerCase() !== 'true') {
                        $('.profile-list').each(function () {
                            this.model = createModel(this);
                            if (result.indexOf(this.model.value) > -1) {
                                setButtonToDelete(this);
                            }
                        });
                    }
                });
        }

        $('.profile-list').unbind('click').click(function () {
            app.userProfileList.onClick(this);
        });
    },
    onClick: function (obj) {
        obj.model = createModel(obj);

        var isanon = document.getElementById("isAnonymous").value;
        if (isanon.toLowerCase() === 'true') {
            var redirUrl = window.location.pathname;
            if (window.location.hash) {
                redirUrl = redirUrl.concat(window.location.hash);
            }
            else if (window.location.qstring) {
                redirUrl = redirUrl.concat(window.location.qstring);
            }
            var loginUrl = "/login?returnUrl=" + redirUrl;
            window.location.href = loginUrl;
        }
        else if (obj.model.isAddButton || obj.model.isDeleteButton) {
            toggleButton(obj);
            updateList(obj);
        }
    }
};

function getList(obj) {
    var listUrl = getListUrl();
    return $.ajax({
        type: "Get",
        url: listUrl,
        context: obj,
        success: function (result) {
            return result;
        },
        error: function (error) {
            return error;
        }
    });
}

function getListUrl() {
    var protocol = location.protocol;
    var slashes = protocol.concat("//");
    var host = slashes.concat(window.location.hostname);
    return host.concat('/api/favorites');
}

// This snippet is necessary on non-coveo pages
$(window).on("load", function () {
    app.userProfileList.init();
});

function createModel(obj) {
    var datatype = $(obj).data('type');
    var action = $(obj).data('action');
    var value = $(obj).data('value');
    var isAddButton = action === 'add';
    var isDeleteButton = action === 'delete';

    listUrl = getListUrl();

    if (listUrl && action && value) {
        actionUrl = listUrl + '/' + action + '/' + value;
    }

    return {
        datatype: datatype,
        listUrl: listUrl,
        actionUrl: actionUrl,
        action: action,
        value: value,
        isAddButton: isAddButton,
        isDeleteButton: isDeleteButton

    };
}

function updateList(obj) {
    if (obj.model.actionUrl) {
        requestType = obj.model.isAddButton ? 'Put' : 'Delete';

        $.ajax({
            type: requestType,
            url: obj.model.actionUrl,
            context: obj,
            success: function (result) {
                if (result.IsSuccessful) {
                    sessionStorage.setItem(app.userProfileList.name, result.FavoriteProductIds);
                    if ($('.profile-list.favorites__delete').length > 0) {
                        window.location.reload(true);
                    }
                }
                return result.FavoriteProductIds;
            },
            error: function (error) {
                return error;
            }
        });
    }
}

// Change the data value and update the images css classes
function toggleButton(obj) {
    // change the data attributes
    if (obj.model.isAddButton) {
        setButtonToDelete(obj);
    }
    else if (obj.model.isDeleteButton) {
        setButtonToAdd(obj);
    }
}

function setButtonToDelete(obj) {
    // The two lines below serve two different purposes; DO NOT REMOVE EITHER
    $(obj).data('action', 'delete');
    obj.setAttribute('data-action', 'delete');
    $(obj).removeClass('add');
    $(obj).addClass('delete');
}

function setButtonToAdd(obj) {
    // The two lines below serve two different purposes; DO NOT REMOVE EITHER
    $(obj).data('action', 'add');
    obj.setAttribute('data-action', 'add');
    $(obj).removeClass('delete');
    $(obj).addClass('add');
};
var app = app || {};
app.video = app.video || {};

app.video = {
    onVideoOpen: function (e, id) {
        console.log("Inside onVideoOpen method");
        console.log("videoId: " + id);
        e.preventDefault();
        $("#" + id + " .video-overlay").hide();
        $("#" + id + " .video-player").show();
    }
}
;
var app = app || {};

(function () {

    function DocumentFilteringController($scope, $timeout) {
        $scope.componentId = '';
        $scope.datasourceId = '';
        $scope.documentItems = [];
        $scope.visibleDocumentItems = [];
        $scope.filterCategories = [];
        $scope.displayedDocumentRange;
        $scope.selectedPdfDownloads = [];
        $scope.selectedVslDownloads = [];
        $scope.pdfDocumentCount = 0;
        $scope.vslDocumentCount = 0;
        $scope.selectDownloadAllPdfsChecked = false;
        $scope.selectDownloadAllVslsChecked = false;
        $scope.searchString = '';
        $scope.documentsPerWindow = 10;
        $scope.currentPage = 0;
        $scope.paginationWindows = [0];
        $scope.downloadStartedMessage = '';
        $scope.paginationPlaceholderText = '';
        $scope.paginationText = '';
        $scope.filterDropdownPlaceholderText = '';
        $scope.visibleFilters = [];

        $scope.init = function (componentId, datasourceId, documentsPerWindow, downloadStartedMessage, paginationPlaceholderText, filterDropdownPlaceholderText) {
            $scope.componentId = componentId;
            $scope.datasourceId = datasourceId;
            $scope.downloadStartedMessage = downloadStartedMessage;
            $scope.paginationPlaceholderText = paginationPlaceholderText;
            $scope.filterDropdownPlaceholderText = filterDropdownPlaceholderText;

            $scope.visibleDocumentItems = $scope.documentItems = $('#' + componentId + ' .document-item').toArray().map(function (document) {
                return {
                    column1Text: document.dataset.colOneText,
                    column2Text: document.dataset.colTwoText,
                    column3Text: document.dataset.colThreeText,
                    description: document.dataset.description,
                    pdfPath: document.dataset.pdfPath,
                    vslPath: document.dataset.vslPath,
                    pdfLink: document.dataset.pdfLink ? app.updateQueryString(document.dataset.pdfLink, 'attachment', 'true') : '',
                    vslLink: document.dataset.vslLink ? app.updateQueryString(document.dataset.vslLink, 'attachment', 'true') : '',
                    filters: document.dataset.filters.split(",")
                };
            });
            $scope.filterCategories = $('#' + componentId + ' .document-filter-category').toArray().map(function (filterCategory) {
                return {
                    categoryId: filterCategory.dataset.categoryId,
                    categoryLabel: filterCategory.dataset.categoryLabel,
                    displayedCategoryLabel: filterCategory.dataset.categoryLabel,
                    categoryFilters: $(filterCategory).find('.document-filter').toArray().map(function (filterValue) {
                        return {
                            filterId: filterValue.dataset.filterId,
                            filterValue: filterValue.dataset.filterValue,
                            selected: false
                        };
                    })
                };
            });
            $scope.initializeFilterLabels();

            $scope.documentsPerWindow = app.isExperienceEditing() ? $scope.documentItems.length : documentsPerWindow;

            $scope.pdfDocumentCount = $scope.documentItems.filter(function (document) {
                return document.pdfPath;
            }).length;
            $scope.vslDocumentCount = $scope.documentItems.filter(function (document) {
                return document.vslPath;
            }).length;

            $scope.paginationText = $scope.getPaginationText();
            $scope.paginationWindows = $scope.getPaginationWindows();

            var arrayOfVisibleFilters = $scope.visibleDocumentItems
                .map(function (documentItem) {
                    return documentItem.filters;
                });

            var flattennedArrayOfVisibleFilters = [].concat.apply([], arrayOfVisibleFilters);

            $scope.visibleFilters = flattennedArrayOfVisibleFilters
                .filter(function (v, i, a) {
                    return a.indexOf(v) === i;
                });

            //console.log($scope.visibleFilters);

            $(".document-filter-modal").on('click', function (e) {
                $(".document-filter-modal").removeClass("show");
                e.stopPropagation();
            });
        };

        $scope.DownloadPdfCheckboxChanged = function (document) {
            if (document.pdfDownloadChecked) {
                $scope.selectedPdfDownloads.push(document);
                if ($scope.selectedPdfDownloads.length === $scope.pdfDocumentCount) {
                    $scope.selectDownloadAllPdfsChecked = true;
                }
            } else {
                var index = $scope.selectedPdfDownloads.indexOf(document);
                if (index >= 0) {
                    $scope.selectedPdfDownloads.splice(index, 1);
                }
                if ($scope.selectedPdfDownloads.length !== $scope.pdfDocumentCount) {
                    $scope.selectDownloadAllPdfsChecked = false;
                }
            }
        };

        $scope.SelectDownloadAllPdfsChanged = function () {
            $scope.documentItems.forEach(function (document) {
                if (document.pdfPath) {
                    document.pdfDownloadChecked = $scope.selectDownloadAllPdfsChecked;
                }
            });
            $scope.selectedPdfDownloads = $scope.selectDownloadAllPdfsChecked ? $scope.documentItems : [];
        };

        $scope.DownloadVslCheckboxChanged = function (document) {
            if (document.vslDownloadChecked) {
                $scope.selectedVslDownloads.push(document);
                if ($scope.selectedVslDownloads === $scope.vslDocumentCount) {
                    $scope.selectDownloadAllVslsChecked = true;
                }
            } else {
                var index = $scope.selectedVslDownloads.indexOf(document);
                if (index >= 0) {
                    $scope.selectedVslDownloads.splice(index, 1);
                }
                if ($scope.selectedVslDownloads !== $scope.vslDocumentCount) {
                    $scope.selectDownloadAllVslsChecked = false;
                }
            }
        };

        $scope.SelectDownloadAllVslsChanged = function () {
            $scope.documentItems.forEach(function (document) {
                if (document.vslPath) {
                    document.vslDownloadChecked = $scope.selectDownloadAllVslsChecked;
                }
            });
            $scope.selectedVslDownloads = $scope.selectDownloadAllVslsChecked ? $scope.documentItems : [];
        };

        $scope.createDownload = function () {

            var getDocumentPaths = function (documentPathsAccumulator, currentDocument) {
                if (currentDocument.pdfDownloadChecked) {
                    documentPathsAccumulator.push(currentDocument.pdfPath);
                }
                if (currentDocument.vslDownloadChecked) {
                    documentPathsAccumulator.push(currentDocument.vslPath);
                }

                return documentPathsAccumulator;
            };
            var documentPaths = $scope.documentItems.reduce(getDocumentPaths, []);

            $.ajax({
                url: "/api/documents/multidocdownload",
                data: { paths: documentPaths, componentId: $scope.datasourceId },
                type: "POST",
                dataType: 'json',
                xhrFields: {
                    withCredentials: true
                }
            });

            // Wait 10 seconds and check the server - may not need to wait a full minute
            setTimeout(app.pollDocDownload, 15000, false);

            $.notify({
                message: $scope.downloadStartedMessage
            },
                {
                    newest_on_top: true
                });
        };

        $scope.ComputeVisibleDocuments = function () {
            var categoriesToFilterOn = $scope.filterCategories.filter(function (category) {
                return category.categoryFilters.some(function (filter) {
                    return filter.selected;
                });
            }).map(function (category) {
                return {
                    categoryFilters: category.categoryFilters.filter(function (categoryFilter) {
                        return categoryFilter.selected;
                    })
                };
            });

            var searchTermMatches = function (document, searchTerm) {
                //escape regex reserved characters in user input
                var input = searchTerm.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');

                //convert % wildcard character to its regex equivalent
                input = input.replace(/%/g, ".+?");

                var inputRegex = new RegExp(input, "i");

                return inputRegex.test(document.column1Text) || inputRegex.test(document.column2Text) || inputRegex.test(document.column3Text) || inputRegex.test(document.description);
            };

            $scope.visibleDocumentItems = $scope.documentItems.filter(function (documentItem) {
                return searchTermMatches(documentItem, $scope.searchString) && categoriesToFilterOn.every(function (category) {
                    return category.categoryFilters.some(function (categoryFilter) {
                        return documentItem.filters.includes(categoryFilter.filterId);
                    });
                });
            });

            var arrayOfVisibleFilters = $scope.visibleDocumentItems
                .map(function (documentItem) {
                    return documentItem.filters;
                });

            var flattennedArrayOfVisibleFilters = [].concat.apply([], arrayOfVisibleFilters);

            $scope.visibleFilters = flattennedArrayOfVisibleFilters
                .filter(function (v, i, a) {
                    return a.indexOf(v) === i;
                });

        };

        $scope.getPaginationWindows = function () {
            return Array(Math.ceil($scope.visibleDocumentItems.length / $scope.documentsPerWindow)).fill(0).map(function (element, index) {
                return index;
            });
        };

        $scope.IsDocumentVisible = function (document) {
            var index = $scope.visibleDocumentItems.indexOf(document);
            return index >= $scope.currentPage * $scope.documentsPerWindow && index < ($scope.currentPage + 1) * $scope.documentsPerWindow;
        };

        $scope.IsFilterVisible = function (filterId) {
            if ($scope.visibleFilters.includes(filterId)) {
                return true;
            }
            else {
                return false;
            }
        };

        $scope.IsFilterCategoryVisible = function (filterCategoryIndex) {
            var categoryFilters = $scope.filterCategories[filterCategoryIndex].categoryFilters.map(function (categoryFilter) {
                return categoryFilter.filterId;
            });

            return $scope.visibleFilters.some(function (visibleFilter) {
                return categoryFilters.includes(visibleFilter);
            });
        };

        $scope.$watch('searchString', function (tmpStr) {
            $timeout(function () {
                // if searchStr is still the same..
                // go ahead and retrieve the data
                if (tmpStr === $scope.searchString) {
                    $scope.ComputeVisibleDocuments();
                }
            }, 500);
        });

        $scope.getPaginationText = function () {
            var lowerBound = Math.min(($scope.currentPage * $scope.documentsPerWindow) + 1, $scope.visibleDocumentItems.length);
            var upperBound = Math.min((($scope.currentPage + 1) * $scope.documentsPerWindow), $scope.visibleDocumentItems.length);

            return $scope.paginationPlaceholderText.replace("{displayedRange}", "<span>" + lowerBound + "-" + upperBound + "</span>")
                .replace("{totalDocuments}", "<span>" + ($scope.visibleDocumentItems.length) + "</span>");
        };

        $scope.clearFilters = function ($event) {
            $event.preventDefault();
  
            $scope.filterCategories.forEach(function (categoy, index) {
                categoy.categoryFilters.forEach(function (filter, j) {
                    filter.selected = false;
                });
            });
            $scope.ComputeVisibleDocuments();
        };

        $scope.updatePaginationWindow = function (delta) {
            var newPosition = $scope.currentPage + delta;
            if (newPosition >= 0 && newPosition <= ($scope.paginationWindows.length - 1)) {
                $scope.currentPage = newPosition;
            }
        };

        $scope.setCurrentPage = function (pageNumber) {
            $scope.currentPage = pageNumber;
            $scope.paginationText = $scope.getPaginationText();
        };

        $scope.$watchGroup(['visibleDocumentItems', 'paginationWindow'], function () {
            $scope.paginationText = $scope.getPaginationText();
            $scope.paginationWindows = $scope.getPaginationWindows();
        });

        $scope.initializeFilterLabels = function () {
            $scope.filterCategories.forEach(function (category, index) {
                $scope.$watch('filterCategories[' + index + '].categoryFilters', function (categoryFilters) {
                    var newCategoryLabel = category.categoryLabel;
                    var selectedFilters = categoryFilters.filter(function (categoryFilter) {
                        return categoryFilter.selected;
                    });

                    if (selectedFilters.length === 1) {
                        newCategoryLabel = selectedFilters[0].filterValue;
                    }
                    else if (selectedFilters.length >= 2) {
                        newCategoryLabel = $scope.filterDropdownPlaceholderText.replace("{selectedFilterCount}", selectedFilters.length);
                    }
                    category.displayedCategoryLabel = newCategoryLabel;

                }, true);
            });
        };

        $scope.$watch('visibleDocumentItems', function (visibleDocuments) {
            if ($scope.currentPage * $scope.documentsPerWindow >= visibleDocuments.length) {
                $scope.currentPage = 0;
            }
        });
    }

    var documentFilteringModule = angular.module('documentFiltering', ['ngSanitize']);
    documentFilteringModule.controller('DocumentFilteringController', ["$scope", '$timeout', DocumentFilteringController]);
    angular.module('acuityApp').requires.push('documentFiltering');
})();;
(function () {
    function HeadingController($scope) {

        $scope.displayHeading = true;

        $(window).on("load scroll", function () {
            var element = $("#heading-" + $scope.$id);
            if (this.scrollY + this.innerHeight > element.offset().top && this.scrollY + 80 < element.offset().top) {
                element.addClass($scope.animation + " animated");
            } else {
                element.removeClass($scope.animation + " animated");
            }
        });

        $scope.init = function (prerequisiteElementId) {
            if (prerequisiteElementId && (typeof prerequisiteElementId === 'string' || prerequisiteElementId instanceof String)) {
                var idWithHashTag = prerequisiteElementId.startsWith('#') ? prerequisiteElementId : '#' + prerequisiteElementId;
                var matchingElements = $(idWithHashTag);
                if (matchingElements && matchingElements.length > 0) {
                    prerequisiteElementDisplayHandler(matchingElements[0]);
                }
            }
        };

        var prerequisiteElementDisplayHandler = function (prerequisiteElement) {
            var displayHeadingIfPrerequisiteElementIsVisible = function () {
                if ($(prerequisiteElement).is(':visible')) {
                    $scope.displayHeading = true;
                } else {
                    $scope.displayHeading = false;
                }
            };
            displayHeadingIfPrerequisiteElementIsVisible();

            var observer = new MutationObserver(function (mutations) {
                $scope.$apply(function () {
                    displayHeadingIfPrerequisiteElementIsVisible();
                });
            });
            observer.observe(prerequisiteElement, {
                attributes: true
            });
        };
        
    }

    var headingModule = angular.module('heading', []);
    headingModule.controller('HeadingController', ['$scope', HeadingController]);
    angular.module('acuityApp').requires.push('heading');
})();;
var app = app || {};

(function () {

    function GalleryFilteringController($scope, $timeout) {
        $scope.componentId = '';
        $scope.photoCollections = {};
        $scope.filterCategories = [];
        $scope.documentsPerWindow = 12;
        $scope.filterDropdownPlaceholderText = '';
        $scope.pageUrlWithoutGalleryQueryParameters = window.location.href;

        $scope.init = function (componentId, documentsPerWindow, filterDropdownPlaceholderText,
            applicationGalleryClass, projectGalleryClass, videoGalleryClass, photoItemClass) {

            $scope.componentId = componentId;
            var componentIdSelectorPortion = '#' + componentId;

            $scope.filterDropdownPlaceholderText = filterDropdownPlaceholderText;
            $scope.documentsPerWindow = documentsPerWindow;

            // using data-src attribute breaks due to some angularjs conflict
            app.photogallery.lazyLoadImages(componentIdSelectorPortion, 'imageSrc', true);

            var createPhotoItem = function (photoItem) {
                return {
                    itemName: photoItem.dataset.itemName,
                    itemId: photoItem.dataset.itemId,
                    applicableFilters: JSON.parse(photoItem.dataset.applicableFilters)
                };
            };

            var showSectionWithLightGallery = function (galleryDomElement) {
                return galleryDomElement && galleryDomElement.hasAttribute("data-enable-light-gallery")
                    && galleryDomElement.getAttribute("data-enable-light-gallery").toLowerCase() === "true";
            };

            var getGallerySection = function (gallerySelectorClass) {
                var sectionRootElementJquery = $(componentIdSelectorPortion + ' .' + gallerySelectorClass);
                var sectionRootElement = sectionRootElementJquery[0];
                var sectionItems = sectionRootElementJquery.find(' .' + photoItemClass).toArray().map(createPhotoItem);
                var showAsLightGallery = showSectionWithLightGallery(sectionRootElement);
                return {
                    selectorClass: gallerySelectorClass,
                    rootElement: sectionRootElement,
                    itemData: sectionItems,
                    showAsLightGallery: showAsLightGallery,
                    numberOfPhotosToDisplay: showAsLightGallery ?
                        getNumberOfPhotosToDisplayForGallerySection($scope.documentsPerWindow, sectionRootElement, sectionItems.length) :
                        $scope.documentsPerWindow
                };
            };

            var appPhotoSection = getGallerySection(applicationGalleryClass);
            var projectPhotoSection = getGallerySection(projectGalleryClass);
            var videoSection = getGallerySection(videoGalleryClass);

            var gallerySections = [appPhotoSection, projectPhotoSection, videoSection];

            $scope.photoCollections = {};

            gallerySections.forEach(function (gallerySection) {
                $scope.photoCollections[gallerySection.selectorClass] = {
                    collectionName: gallerySection.selectorClass,
                    photoData: gallerySection.itemData,
                    visiblePhotoData: gallerySection.itemData,
                    initialNumberOfDisplayedPhotos: documentsPerWindow,
                    numberOfPhotosToDisplay: gallerySection.numberOfPhotosToDisplay,
                    displayAsLightGallery: gallerySection.showAsLightGallery
                };
            });

            Object.values($scope.photoCollections).forEach(function (photoCollection) {
                var gallerySelector = componentIdSelectorPortion + ' .' + photoCollection.collectionName;
                setupIsotopeGrid(gallerySelector);

                var displayAsLightGalleryIfNecessary = function (photos, destroyOldLightGallery) {
                    if (photos.displayAsLightGallery) {
                        $timeout(function () {
                            setupLightGallery(gallerySelector, destroyOldLightGallery);
                        });
                    }
                };
                
                $scope.$watchCollection(function () {
                    return photoCollection.visiblePhotoData;
                }, function (oldVal, newVal, arg3) {
                    $timeout(function () {
                        setupIsotopeGrid(gallerySelector);
                        displayAsLightGalleryIfNecessary(photoCollection, oldVal !== newVal);
                    });
                }, true);
            });

            $scope.filterCategories = $('#' + componentId + ' .document-filter-category').toArray().map(function (filterCategory) {
                return {
                    filterName: filterCategory.dataset.filterName,
                    categoryLabel: filterCategory.dataset.categoryLabel,
                    displayedCategoryLabel: filterCategory.dataset.categoryLabel,
                    categoryFilters: $(filterCategory).find('.document-filter').toArray().map(function (filterValue) {
                        return {
                            filterId: filterValue.dataset.filterId,
                            filterValue: filterValue.dataset.filterValue,
                            selected: shouldOptionBeSelectedBasedOnQueryParams(filterCategory.dataset.filterName, filterValue.dataset.filterValue)
                        };
                    })
                };
            });

            var pageUrlWithoutGalleryParams = $scope.pageUrlWithoutGalleryQueryParameters;
            $scope.filterCategories.forEach(function (filterCategory) {
                pageUrlWithoutGalleryParams = app.updateQueryString(pageUrlWithoutGalleryParams, filterCategory.filterName);
            });
            $scope.pageUrlWithoutGalleryQueryParameters = app.updateQueryString(pageUrlWithoutGalleryParams, 'gallery-to-init');

            initializeGallery();
            
            $scope.documentsPerWindow = documentsPerWindow;

            // Removing this event handler allows the filter dropdowns to hide upon selection
            //$(".document-filter-modal").on('click', function (e) {
            //    e.stopPropagation();
            //});
        };

        var urlSearchParams;

        var galleryToInit;

        var isGalleryQueryStringForThisGallery = function (urlSearchParams) {
            var getGalleryToInit = function (urlSearchParams) {
                var gallery = urlSearchParams.get('gallery-to-init');
                if (gallery) {
                    return decodeURIComponent(gallery);
                }
                else {
                    return null;
                }
            };

            galleryToInit = galleryToInit || getGalleryToInit(urlSearchParams);

            return galleryToInit && galleryToInit === $scope.componentId;
        };

        // this comparison should be case insensitive to support casing variations in shared URLs
        var shouldOptionBeSelectedBasedOnQueryParams = function (filterName, filterValue) {
            urlSearchParams = urlSearchParams || new URLSearchParams(window.location.search ? window.location.search.toLowerCase() : "");
            
            if (!isGalleryQueryStringForThisGallery(urlSearchParams)) {
                return false;
            }

            var matchingQueryParam = urlSearchParams.get(encodeURIComponent(filterName.toLowerCase()));
            return matchingQueryParam && matchingQueryParam === filterValue.toLowerCase();
        };

        // If the current URL is a light gallery link with a hash string, we need to display enough photos to allow the light gallery to display
        // the gallery at the slide requested in the URL.
        var getNumberOfPhotosToDisplayForGallerySection = function (numberOfPhotosPerPage, sectionRootElement, numberOfPhotosInCollection) {
            if (sectionRootElement && window.location.hash) {
                var urlParams = new URLSearchParams(window.location.hash.replace('#', ''));
                var galleryId = sectionRootElement.id;
                var galleryToOpen = urlParams.get('lg');
                if (galleryId && galleryToOpen === galleryId) {
                    var slideParameter = urlParams.get('slide');
                    var isNumeric = function (str) {
                        if (typeof str != "string") {
                            return false;
                        }
                        else {
                            return !isNaN(str) && !isNaN(parseFloat(str));
                        }
                    };
                    if (isNumeric(slideParameter)) {
                        var slideParamAsInt = parseInt(slideParameter);
                        if (slideParamAsInt >= 0 && numberOfPhotosPerPage >= 1) {
                            // slideParamAsInt is 0 indexed
                            slideParamAsInt = slideParamAsInt + 1;
                            var nextPageCountMultiple = numberOfPhotosPerPage * (Math.floor((slideParamAsInt - 1) / numberOfPhotosPerPage) + 1);
                            return nextPageCountMultiple <= numberOfPhotosInCollection ? nextPageCountMultiple : numberOfPhotosInCollection;
                        }
                    }
                }
            }

            return numberOfPhotosPerPage;
        };

        var initializeGallery = function () {
            updateGallery();
        };

        $scope.handleFilterSelection = function (filterCategoryIndex, filterCategoryValueIndex, dropdownIdToToggle) {
            unsetAnyChangedFilters(filterCategoryIndex, filterCategoryValueIndex);
            updateGalleryAndQueryParams();

            if (dropdownIdToToggle) {
                $(dropdownIdToToggle).collapse('hide');
            }
        };

        var updateGalleryAndQueryParams = function () {
            updateQueryParams();
            updateGallery();
        };

        var getSelectedFiltersForQueryParamGeneration = function () {
            return $scope.filterCategories.filter(function (filterCategory) {
                return filterCategory.categoryFilters.some(function (filterOption) {
                    return filterOption.selected;
                });
            }).map(function (filterCategory) {
                return {
                    filterName: filterCategory.filterName,
                    filterValues: filterCategory.categoryFilters.filter(function (filterOption) {
                        return filterOption.selected;
                    })
                };
            });
        };

        var updateQueryParams = function () {
            var intendedNewUrl = getNewUrlWithQueryString(getSelectedFiltersForQueryParamGeneration());
            if (history && history.replaceState) {
                history.replaceState(null, '', intendedNewUrl);
            }
        };

        var getNewUrlWithQueryString = function (selectedFilters) {
            var queryParamPieces = selectedFilters.map(function (filter) {
                return filter.filterValues.map(function (filterValue) {
                    return {
                        name: filter.filterName,
                        value: filterValue.filterValue
                    };
                });
            }).flat();

            if (queryParamPieces.length > 0) {
                queryParamPieces.unshift({
                    name: 'gallery-to-init',
                    value: $scope.componentId
                });
            }

            var newUrlWithQueryString = $scope.pageUrlWithoutGalleryQueryParameters;
            queryParamPieces.forEach(function (queryParamToAdd) {
                newUrlWithQueryString = app.updateQueryString(newUrlWithQueryString, encodeURIComponent(queryParamToAdd.name), encodeURIComponent(queryParamToAdd.value));
            });

            return newUrlWithQueryString;
        };

        var unsetAnyChangedFilters = function (filterCategoryIndex, filterCategoryValueIndex) {
            var modifiedFilterCategory = $scope.filterCategories[filterCategoryIndex];
            var modifiedFilterCategoryOption = modifiedFilterCategory.categoryFilters[filterCategoryValueIndex];
            var filterOptionsToDisable = modifiedFilterCategory.categoryFilters.filter(function (filterOption) {
                return filterOption.selected && filterOption.filterValue !== modifiedFilterCategoryOption.filterValue;
            });

            filterOptionsToDisable.forEach(function (optionToDisable) {
                optionToDisable.selected = false;
            });
        };
        
        var setupIsotopeGrid = function (gridSelector) {
            // Disabled isotope grid for this component to allow bootstrap positioning to work correctly
            //$(gridSelector).isotope({
            //    itemSelector: '.photo-gallery__photo-item',
            //    layoutMode: 'fitRows',
            //    transitionDuration: 0
            //});
        };

        var setupLightGallery = function (lightGallerySelector, destroyOldGalleryData) {
            $(lightGallerySelector).each(function (index, element) {
                var jqueryElement = $(element);
                if (destroyOldGalleryData && jqueryElement.data('lightGallery')) {
                    jqueryElement.data('lightGallery').destroy(true);
                }
                jqueryElement.lightGallery({
                    thumbnail: true,
                    animatedThumb: false,
                    showThumbByDefault: false,
                    selector: '.gallery-launcher.visible-photo',
                    subHtmlSelectorRelative: false,
                    share: false,
                    galleryId: element.id,
                    iframeMaxWidth: '45%',
                    exThumbImage: 'data-exthumbimage'
                });
            });
        };
        
        $scope.isDocumentVisible = function (collectionName, index) {
            var photoItem = $scope.photoCollections[collectionName].photoData[index];
            return $scope.photoCollections[collectionName].visiblePhotoData.indexOf(photoItem) !== -1;
        };

        $scope.wouldFilterCategoryDisplayResults = function (filterCategoryIndex) {
            var filterCategory = $scope.filterCategories[filterCategoryIndex];
            var filterCategoryOptions = filterCategory.categoryFilters.map(function (categoryFilterOption) {
                return categoryFilterOption.filterValue;
            });

            return wouldFilterOptionsDisplayResults(filterCategory.filterName, filterCategoryOptions);
        };

        $scope.wouldFilterOptionDisplayResults = function (filterCategoryIndex, filterOptionIndex) {
            var filterCategory = $scope.filterCategories[filterCategoryIndex];
            var relevantCategoryOption = filterCategory.categoryFilters[filterOptionIndex];

            return wouldFilterOptionsDisplayResults(filterCategory.filterName, [relevantCategoryOption.filterValue]);
        };

        var wouldFilterOptionsDisplayResults = function (filterCategoryName, filterCategoryValues) {
            return Object.values($scope.photoCollections).some(function (collection) {
                return collection.validPhotosForSelectedFilters.some(function (visiblePhotoItem) {
                    return arePotentialFiltersValidForItem(visiblePhotoItem, filterCategoryName, filterCategoryValues);
                });
            });
        };
        
        var updateGallery = function () {
            Object.values($scope.photoCollections).forEach(function (photoCollection) {
                photoCollection.validPhotosForSelectedFilters = calculateVisibleDocuments(photoCollection);
                photoCollection.visiblePhotoData = photoCollection.validPhotosForSelectedFilters.slice(0, Math.min(photoCollection.validPhotosForSelectedFilters.length, photoCollection.numberOfPhotosToDisplay));
            });
        };

        $scope.loadMore = function (collectionName) {
            var collectionToLoad = $scope.photoCollections[collectionName];
            collectionToLoad.numberOfPhotosToDisplay += collectionToLoad.initialNumberOfDisplayedPhotos;
            collectionToLoad.visiblePhotoData = collectionToLoad.validPhotosForSelectedFilters.slice(0,
                Math.min(collectionToLoad.validPhotosForSelectedFilters.length, collectionToLoad.numberOfPhotosToDisplay));
        };

        $scope.showLoadMore = function (collectionName) {
            var collectionToLoad = $scope.photoCollections[collectionName];
            return collectionToLoad.numberOfPhotosToDisplay < collectionToLoad.validPhotosForSelectedFilters.length;
        };

        var calculateVisibleDocuments = function (collection) {
            return collection.photoData.filter(function (item) {
                return isPhotoItemVisible(item);
            });
        };

        var isPhotoItemVisible = function (item) {
            return areSelectedFiltersValidForItem(item);
        };

        var arePotentialFiltersValidForItem = function (item, potentialFilterCategory, potentialFilterValues) {
            return item.applicableFilters.some(function (filterCategoryForItem) {
                return filterCategoryForItem.FilterName === potentialFilterCategory && potentialFilterValues.some(function (filterCategoryOptionForItem) {
                    return filterCategoryForItem.ApplicableValues.some(function (itemFilterOptionValue) {
                        return filterCategoryOptionForItem === itemFilterOptionValue;
                    });
                });
            });
        };

        var areSelectedFiltersValidForItem = function (item) {
            var filters = $scope.filterCategories;

            return filters.every(function (filter) {
                return isFilterValidForItem(filter, item);
            });
        };
        
        var isFilterValidForItem = function (filterCategory, item) {
            var isFilterOptionSelectedForItem = function (filterCategoryName, filterOptionValue, item) {
                return item.applicableFilters.some(function (filterCategoryForItem) {
                    return filterCategoryForItem.FilterName === filterCategoryName && filterCategoryForItem.ApplicableValues.some(function (filterCategoryOptionForItem) {
                        return filterCategoryOptionForItem === filterOptionValue.filterValue;
                    });
                });
            };

            var selectedFilters = filterCategory.categoryFilters.filter(function (filterOption) {
                return filterOption.selected;
            });
            
            return selectedFilters.length === 0 || selectedFilters.some(function (filter) {
                return isFilterOptionSelectedForItem(filterCategory.filterName, filter, item);
            });
        };

        $scope.clearFilters = function ($event) {
            $event.preventDefault();

            $scope.filterCategories.forEach(function (categoy, index) {
                categoy.categoryFilters.forEach(function (filter, j) {
                    filter.selected = false;
                });
            });

            updateGalleryAndQueryParams();
        };

        $scope.getDisplayedCategoryLabel = function (category) {
            var newCategoryLabel = category.categoryLabel;
            var selectedFilters = category.categoryFilters.filter(function (categoryFilter) {
                return categoryFilter.selected;
            });

            if (selectedFilters.length === 1) {
                newCategoryLabel = selectedFilters[0].filterValue;
            }
            else if (selectedFilters.length >= 2) {
                newCategoryLabel = $scope.filterDropdownPlaceholderText.replace("{selectedFilterCount}", selectedFilters.length);
            }
            return newCategoryLabel;
        };
    }

    var filteredPhotoGalleryModule = angular.module('filteredPhotoGalleryModule', ['ngSanitize']);
    filteredPhotoGalleryModule.controller('GalleryFilteringController', ["$scope", '$timeout', GalleryFilteringController]);
    angular.module('acuityApp').requires.push('filteredPhotoGalleryModule');
})();;
var app = app || {};

function RepDistributorSelector(scope, requestData) {

    var $scope = scope;
    var requestDataFunc = requestData && requestData instanceof Function ? requestData : null;

    var repSelector = {
        allowEmptySelection: false,
        allowUserToClickApplyUnnecessarily: false,
        enableButton: true,
        domElementSelector: '',
        selections: [],
        filteredSelections: [],
        searchTerm: '',
        activeSelection: null,
        dataWasRequestedFor: null,
        canClearSelection: function () { return canClearSelection($scope.repSelector) },
        setActiveSelection: function (selectedRep) { setActiveSelection($scope.repSelector, selectedRep, recomputeFilteredRepSelections) },
        isDataCurrentForActiveSelection: true,
        recordDataAsCurrentFor: function (selectedRep) { recordDataAsCurrentFor($scope.repSelector, selectedRep) },
        clearSelection: function () { clearSelectionFor($scope.repSelector, $scope.repSelector.allowEmptySelection, true) },
        applySelection: function () { $scope.applySelections(true, $scope.repSelector.hidePopup, $scope.repSelector.isDataCurrentForActiveSelection) },
        hidePopup: function () {
            $($scope.repSelector.domElementSelector).modal("hide");
        },
        getElementDropdownText: function (element) {
            return element ?
                [element.Key, element.Value].filter(function (elementDetail) { return !!elementDetail; }).join(' ') :
                '';
        },
        getNonSelectedOptions: function () { return $scope.repSelector.selections.filter(function (rep) { return !rep.isSelected; }); }
    };

    var distributorSelector = {
        allowEmptySelection: false,
        allowUserToClickApplyUnnecessarily: false,
        enableButton: true,
        domElementSelector: '',
        selections: [],
        filteredSelections: [],
        searchTerm: '',
        activeSelection: null,
        dataWasRequestedFor: null,
        canClearSelection: function () { return canClearSelection($scope.distributorSelector) },
        setActiveSelection: function (selectedDist) { setActiveSelection($scope.distributorSelector, selectedDist, recomputeFilteredDistributorSelections) },
        isDataCurrentForActiveSelection: true,
        recordDataAsCurrentFor: function (selectedDist) { recordDataAsCurrentFor($scope.distributorSelector, selectedDist) },
        clearSelection: function () { clearSelectionFor($scope.distributorSelector, $scope.distributorSelector.allowEmptySelection, false) },
        applySelection: function () { $scope.applySelections(false, $scope.distributorSelector.hidePopup, $scope.distributorSelector.isDataCurrentForActiveSelection) },
        hidePopup: function () {
            $($scope.distributorSelector.domElementSelector).modal("hide");
        },
        getElementDropdownText: function (element) {
            return element ?
                [element.Value, element.Location, element.Key].filter(function (elementDetail) { return !!elementDetail; }).join('<br />') :
                '';
        },
        getNonSelectedOptions: function () { return $scope.distributorSelector.selections.filter(function (distributor) { return !distributor.isSelected; }); }
    };

    var canClearSelection = function (selectionObject) {
        return selectionObject && selectionObject.selections && selectionObject.selections.length && selectionObject.selections.length > 0
            && ((selectionObject.allowEmptySelection && selectionObject.activeSelection != null)
                || (!selectionObject.allowEmptySelection && selectionObject.activeSelection != selectionObject.selections[0])
                || (selectionObject.activeSelection != selectionObject.dataWasRequestedFor));
    };

    var setActiveSelection = function (selectionObject, selectedOption, callback) {

        var selectedElement = selectedOption ?
            selectionObject.selections.find(function (element) {
                return element.Key === selectedOption.Key
            }) :
            null;
        if (selectionObject.activeSelection != null) {
            selectionObject.activeSelection.isSelected = false;
        }

        if (selectedElement) {
            selectedElement.isSelected = true;
        }

        selectionObject.activeSelection = selectedElement;
        selectionObject.isDataCurrentForActiveSelection = calculateIsViewDataApplicableForCurrentSelection(selectionObject);

        if (callback && callback instanceof Function) {
            callback();
        }
    };

    var recordDataAsCurrentFor = function (selectionObject, dataWasRequestedFor) {
        selectionObject.dataWasRequestedFor = dataWasRequestedFor;
        selectionObject.isDataCurrentForActiveSelection = calculateIsViewDataApplicableForCurrentSelection(selectionObject);
    };

    var clearSelectionFor = function (selectionObject, allowEmptySelection, resetDistributorCustomerList) {
        var newSelection = allowEmptySelection ?
            null :
            (selectionObject.selections.length > 0 ? selectionObject.selections[0] : null);

        selectionObject.setActiveSelection(newSelection);
        if (!selectionObject.isDataCurrentForActiveSelection) {
            var distributorCustomerToRequestFor = resetDistributorCustomerList ? null : $scope.distributorSelector.activeSelection;
            if (requestDataFunc) {
                requestDataFunc($scope.repSelector.activeSelection, distributorCustomerToRequestFor);
            }
        }
        selectionObject.allowUserToClickApplyUnnecessarily = true;
    }

    var applySelections = function (resetDistributorCustomerList, hidePopupCallback, doesDataAlreadyMatchCurrentSelection) {
        $scope.repSelector.allowUserToClickApplyUnnecessarily = false;
        $scope.distributorSelector.allowUserToClickApplyUnnecessarily = false;
        if (doesDataAlreadyMatchCurrentSelection) {
            hidePopupCallback();
        }
        else {
            var distributorCustomerToRequestFor = resetDistributorCustomerList ? null : $scope.distributorSelector.activeSelection;
            requestDataFunc($scope.repSelector.activeSelection, distributorCustomerToRequestFor, hidePopupCallback);
        }
    };

    var calculateIsViewDataApplicableForCurrentSelection = function (selectionObject) {
        var activeSelectionId = selectionObject.activeSelection ? selectionObject.activeSelection.Key : null;
        var previouslyRequestedSelectorKey = selectionObject.dataWasRequestedFor != null ? selectionObject.dataWasRequestedFor.Key : null;
        return previouslyRequestedSelectorKey === activeSelectionId;
    };

    var recomputeFilteredRepSelections = function () {
        $scope.repSelector.filteredSelections = getNonSelectedReps();
        clearSelectorSearch($scope.repSelector);
        $scope.repSelector.applySelection();
    };

    var recomputeFilteredDistributorSelections = function () {
        $scope.distributorSelector.filteredSelections = getNonSelectedDistributors();
        clearSelectorSearch($scope.distributorSelector);
        $scope.distributorSelector.applySelection();
    };

    var getNonSelectedReps = function () {
        return $scope.repSelector.selections.filter(function (rep) { return !rep.isSelected; });
    };

    var getNonSelectedDistributors = function () {
        return $scope.distributorSelector.selections.filter(function (dist) { return !dist.isSelected; });
    };

    var clearSelectorSearch = function (selector) {
        selector.searchTerm = "";
        $(".rep-search").val('');
    }

    var getArraywithoutElementAtIndex = function (arr, index) {
        return arr.filter(function (value, arrIndex) {
            return index !== arrIndex;
        });
    };

    var initializeSelectionList = function (selectionList, listOfOptions, forceASelection, dataWasReturnedFor) {
        var dataWasReturnedForOption = dataWasReturnedFor && listOfOptions.find(function (option) {
            return option.Key === dataWasReturnedFor;
        });
        var selectAnOption = forceASelection || dataWasReturnedForOption;

        var optionToSelect = null;
        if (selectAnOption && dataWasReturnedForOption) {
            optionToSelect = dataWasReturnedForOption;
        }
        else if (forceASelection) {
            optionToSelect = listOfOptions != null && listOfOptions.length && listOfOptions.length > 0 ?
                listOfOptions[0] :
                null;
        }

        var optionToSelectIndex = optionToSelect ?
            listOfOptions.indexOf(optionToSelect) :
            -1;

        selectionList.selections = listOfOptions && listOfOptions.length ? listOfOptions : [];
        selectionList.activeSelection = optionToSelect ? optionToSelect : null;

        selectionList.filteredSelections = optionToSelectIndex >= 0 ?
            getArraywithoutElementAtIndex(listOfOptions, optionToSelectIndex) :
            listOfOptions;

        if (selectionList.activeSelection) {
            selectionList.activeSelection.isSelected = true;
        }
    };

    var calculateWhoDataWasReturnedFor = function (requestedDataFor, serverIndicatesResponseIsFor, selectorObject) {
        var matchingElementForServerIndication = serverIndicatesResponseIsFor && selectorObject.selections.find(function (element) {
            return element.Key === serverIndicatesResponseIsFor;
        });
        if (matchingElementForServerIndication) {
            return matchingElementForServerIndication;
        }
        else {
            return requestedDataFor ? requestedDataFor : selectorObject.activeSelection;
        }
    };

    return {
        repSelector: repSelector,
        distributorSelector: distributorSelector,
        functions: {
            applySelections: applySelections,
            initializeSelectionList: initializeSelectionList,
            calculateWhoDataWasReturnedFor: calculateWhoDataWasReturnedFor
        }
    };
};
var app = app || {};
app.repDistributorSelector = app.repDistributorSelector || {};

function HeaderRepDistributorSelectorController($scope, $rootScope, $http, $timeout) {
    app.repDistributorSelector.hasHeaderSelector = true;

    var requestAdditionalLogging = getQueryStringParameterByName('logMore');
    var mimicUser = getQueryStringParameterByName('mimicUser');

    var requestDataWrapper = function (selectedRep, selectedCustomer, successCallback) {
        requestData(successCallback, selectedRep, selectedCustomer, false);
    };

    var repAndDistributorSelector = RepDistributorSelector($scope, requestDataWrapper);

    $scope.repSelector = repAndDistributorSelector.repSelector;
    $scope.distributorSelector = repAndDistributorSelector.distributorSelector;
    $scope.applySelections = repAndDistributorSelector.functions.applySelections;
    $scope.displaySelectors = false;

    var useStockedProductsSelectorInstead = false;

    var callbackErrorFunc = function () {
        $scope.showError = true;
        $scope.isRequestPending = false;
        console.error("Failed to load rep/distributor selections");
    };

    $scope.init = function (repModalDOMSelector, distributorModalDOMSelector, displaySelectors) {
        $scope.repSelector.domElementSelector = repModalDOMSelector;
        $scope.distributorSelector.domElementSelector = distributorModalDOMSelector;
        $scope.displaySelectors = displaySelectors === true || displaySelectors === 'true';
    };

    $scope.$on('rep-distributor-selector', function (event, arg) {
        if (arg && arg.isSelectionEvent && arg.repDistributorSelector) {
            useStockedProductsSelectorInstead = true;
            overwriteWithStockedProductsData(arg.repDistributorSelector);
            $scope.repSelector.domElementSelector = arg.repDistributorSelector.repSelector.domElementSelector;
            $scope.distributorSelector.domElementSelector = arg.repDistributorSelector.distributorSelector.domElementSelector;
        }
    });

    $timeout(function () {
        if (!useStockedProductsSelectorInstead) {
            requestData(null, null, null, true);
        }
    });

    var overwriteWithStockedProductsData = function (selectionLists) {
        repAndDistributorSelector.functions.initializeSelectionList($scope.repSelector, selectionLists.repSelector.selections,
            selectionLists.repSelector.allowEmptySelection, selectionLists.repSelector.dataWasRequestedFor);
        repAndDistributorSelector.functions.initializeSelectionList($scope.distributorSelector, selectionLists.distributorSelector.selections,
            selectionLists.distributorSelector.allowEmptySelection, selectionLists.distributorSelector.dataWasRequestedFor);

        $scope.repSelector.recordDataAsCurrentFor(selectionLists.repSelector.dataWasRequestedFor);
        $scope.distributorSelector.recordDataAsCurrentFor(selectionLists.distributorSelector.dataWasRequestedFor);
    };

    var requestData = function (successCallback, selectedRep, selectedCustomer, isFirstRequest) {
        var successHandlerWrapper = function (response) { successHandler(response, successCallback, selectedRep, selectedCustomer); }
        $scope.isRequestPending = true;
        $http(
            {
                url: '/api/products/getrepsanddistributors',
                method: 'POST',
                data: {
                    RepNumber: selectedRep ? selectedRep.Key : null,
                    CustomerNumber: selectedCustomer ? selectedCustomer.Key : null,
                    AdditionalLogging: requestAdditionalLogging,
                    MimicUser: mimicUser,
                    IsInitializationRequest: isFirstRequest
                },
                dataType: 'json'
            })
            .then(successHandlerWrapper, callbackErrorFunc);
    };

    var recordActiveSelectionState = function (rep, customer) {
        $scope.repSelector.recordDataAsCurrentFor(rep);
        $scope.distributorSelector.recordDataAsCurrentFor(customer);
    };

    var successHandler = function (response, successCallback, requestedDataForRep, requestedDataForCustomer) {

        var responseData = response && response.data ? response.data : null;
        $scope.isRequestPending = false;

        if (response && response.status === 200 && responseData && responseData.Value) {

            $scope.repSelector.enableButton = responseData.Value.AllowAgentToggling;
            $scope.distributorSelector.allowEmptySelection = !responseData.Value.ForceSelectADistributor;
            $scope.displaySelectors = responseData.Value.DisplaySelectors;

            // if we didn't request data for a specific rep, initialize the rep collection from the response
            if (responseData.Value.RepSelector) {
                repAndDistributorSelector.functions.initializeSelectionList($scope.repSelector, responseData.Value.RepSelector.Selections, !$scope.repSelector.allowEmptySelection, responseData.Value.DataIsForRep);
            }

            // if we requested data for a specific rep, we need to reinitialize the customer selector for that repAgent
            if (responseData.Value.DistributorSelector) {
                repAndDistributorSelector.functions.initializeSelectionList($scope.distributorSelector, responseData.Value.DistributorSelector.Selections, !$scope.distributorSelector.allowEmptySelection, responseData.Value.DataIsForCustomer);
            }

            var calculateWhoDataWasReturnedFor = repAndDistributorSelector.functions.calculateWhoDataWasReturnedFor;
            var dataWasReturnedForRep = calculateWhoDataWasReturnedFor(requestedDataForRep, responseData.Value.DataIsForRep, $scope.repSelector);
            var dataWasReturnedForCustomer = calculateWhoDataWasReturnedFor(requestedDataForCustomer, responseData.Value.DataIsForCustomer, $scope.distributorSelector);
            recordActiveSelectionState(dataWasReturnedForRep, dataWasReturnedForCustomer);

            if (successCallback && successCallback instanceof Function) {
                successCallback();
            }
        } else {
            console.error(response.data.Error);
        }
    };

    $scope.$watch('repSelector.searchTerm', function (tmpStr) {
        $timeout(function () {
            // if searchStr is still the same..
            // go ahead and retrieve the data
            if (tmpStr === $scope.repSelector.searchTerm) {
                $scope.repSelector.filteredSelections = app.stockedproducts.wildcardSearchFilter($scope.repSelector.getNonSelectedOptions(), ['Key', 'Value'], $scope.repSelector.searchTerm, null);
            }
        }, 500);
    });

    $scope.$watch('distributorSelector.searchTerm', function (tmpStr) {
        $timeout(function () {
            // if searchStr is still the same..
            // go ahead and retrieve the data
            if (tmpStr === $scope.distributorSelector.searchTerm) {
                $scope.distributorSelector.filteredSelections = app.stockedproducts.wildcardSearchFilter($scope.distributorSelector.getNonSelectedOptions(), ['Key', 'Value'], $scope.distributorSelector.searchTerm, null);
            }
        }, 500);
    });
};

var headerrepdistributorselectormodule = angular.module('headerrepdistributorselectormodule', []);
headerrepdistributorselectormodule.controller('HeaderRepDistributorSelectorController', ['$scope', '$rootScope', '$http', '$timeout', HeaderRepDistributorSelectorController]);
angular.module('acuityApp').requires.push('headerrepdistributorselectormodule');;
var app = app || {};
app.stockedproducts = app.stockedproducts || {};
app.stockedproducts.wildcardSearchFilter = WildcardSearchFilter;
app.repDistributorSelector = app.repDistributorSelector || {};

var skuScrollThreshold;
var skuScrollLimit;
var skuScrolled = false;

function StockedProductsController($scope, $rootScope, $http, $timeout, pagerService) {
    app.repDistributorSelector.hasStockedProductsSelector = true;

    $scope.isRequestPending = false;
    $scope.displayComponent = false;
    $scope.showViewAll = true;
    $scope.hasNoResults = false;
    $scope.showError = false;
    $scope.showPricing = false;
    $scope.stockedProducts = [];
    $scope.filteredStockedProducts = [];
    $scope.productId = null;
    $scope.pageData = [];
    $scope.itemsPerPage = 10;
    $scope.page = 1;
    $scope.totalPages = 1;
    $scope.inventoryTypes = [];
    $scope.searchCriteria = {
        searchQuery: "",
        inventoryType: ""
    };

    // popup details
    $scope.SHORT_DESCRIPTION = "Loading";
    $scope.LONG_DESCRIPTION = "Loading";
    $scope.CICODE = "Loading";
    $scope.PALLET_QUANTITY = "Loading";
    $scope.WEIGHT = "Loading";
    $scope.UPC = "Loading";
    $scope.PALLET_DIMENSION = "Loading";

    $scope.isViewDataApplicableForCurrentSelections = true;
    $scope.productId = null;

    $rootScope.$broadcast('rep-distributor-selector', {
        initializedFromStockedProducts: true
    });

    var requestAdditionalLogging = getQueryStringParameterByName('logMore');
    var mimicUser = getQueryStringParameterByName('mimicUser');
    var displayXNumberOfDistributorQuotes = 6;

    var requestDataWrapper = function (selectedRep, selectedCustomer, successCallback) {
        requestData($scope.productId, successCallback, selectedRep, selectedCustomer, false);
    };

    var repAndDistributorSelector = RepDistributorSelector($scope, requestDataWrapper);

    $scope.repSelector = repAndDistributorSelector.repSelector;
    $scope.distributorSelector = repAndDistributorSelector.distributorSelector;

    $("[id='Product Accordion V2']").hide();

    $scope.init = function (itemsPerPage, productId, repModalDOMSelector, distributorModalDOMSelector) {
        requestData(productId, null, null, null, true);
        $scope.itemsPerPage = typeof itemsPerPage === 'number' && itemsPerPage >= 1 ? itemsPerPage : 10;
        $scope.productId = productId;
        $scope.repSelector.domElementSelector = repModalDOMSelector;
        $scope.distributorSelector.domElementSelector = distributorModalDOMSelector;
    };

    var requestData = function (productId, successCallback, selectedRep, selectedCustomer, isFirstRequest) {
        var successHandlerWrapper = function (response) { successHandler(response, successCallback, selectedRep, selectedCustomer); }
        $scope.isRequestPending = true;
        $http(
            {
                url: '/api/products/getstockedproducts',
                method: 'POST',
                data: {
                    ProductId: productId,
                    RepNumber: selectedRep ? selectedRep.Key : null,
                    CustomerNumber: selectedCustomer ? selectedCustomer.Key : null,
                    AdditionalLogging: requestAdditionalLogging,
                    MimicUser: mimicUser,
                    IsInitializationRequest: isFirstRequest
                },
                dataType: 'json'
            })
            .then(successHandlerWrapper, callbackErrorFunc);
    };

    var successHandler = function (response, successCallback, requestedDataForRep, requestedDataForCustomer) {

        var responseData = response && response.data ? response.data : null;
        $scope.isRequestPending = false;
        if (response && response.status === 200 && responseData && responseData.Value) {
            var stockedProductsSuccess = responseData.Value && responseData.Value.StockedProducts && responseData.Value.StockedProducts.Success
                && responseData.Value.StockedProducts.Data && responseData.Value.StockedProducts.Data.length;
            var stockedProducts = stockedProductsSuccess ? responseData.Value.StockedProducts.Data : [];

            if (!responseData.Value.HideComponentEntirely && stockedProducts.length > 0) {
                $("[id='Product Accordion V2']").show();
            }

            $scope.showPricing = responseData.Value.ShowPricing;
            $scope.repSelector.enableButton = responseData.Value.AllowAgentToggling;
            $scope.distributorSelector.allowEmptySelection = !responseData.Value.ForceSelectADistributor;

            stockedProducts.forEach(function (sku) {
                initializeSku(sku);
            });

            $scope.filteredStockedProducts = $scope.stockedProducts = stockedProducts;

            // if we didn't request data for a specific rep, initialize the rep collection from the response
            if (responseData.Value.RepSelector) {
                repAndDistributorSelector.functions.initializeSelectionList($scope.repSelector, responseData.Value.RepSelector.Selections, !$scope.repSelector.allowEmptySelection, responseData.Value.DataIsForRep);
            }

            // if we requested data for a specific rep, we need to reinitialize the customer selector for that repAgent
            if (responseData.Value.DistributorSelector) {
                repAndDistributorSelector.functions.initializeSelectionList($scope.distributorSelector, responseData.Value.DistributorSelector.Selections, !$scope.distributorSelector.allowEmptySelection, responseData.Value.DataIsForCustomer);
            }

            var dataWasReturnedForRep = repAndDistributorSelector.functions.calculateWhoDataWasReturnedFor(requestedDataForRep,
                responseData.Value.DataIsForRep, $scope.repSelector);
            var dataWasReturnedForCustomer = repAndDistributorSelector.functions.calculateWhoDataWasReturnedFor(requestedDataForCustomer,
                responseData.Value.DataIsForCustomer, $scope.distributorSelector);
            recordActiveSelectionState(dataWasReturnedForRep, dataWasReturnedForCustomer);

            recalculateVisibleStockedProducts();
            $scope.displayComponent = true;
            alternateSectionBackgroundColors();

            if (successCallback && successCallback instanceof Function) {
                successCallback();
            }

            $rootScope.$broadcast('rep-distributor-selector', {
                initializedFromStockedProducts: true,
                isSelectionEvent: true,
                repDistributorSelector: repAndDistributorSelector
            });
        } else {
            $scope.hasNoResults = true;
            console.error(response.data.Error);
        }
    };

    $scope.clearFilters = function ($event) {
        $scope.searchCriteria.searchQuery = "";
        $scope.searchCriteria.inventoryType = "";
        $event.preventDefault();
    }

    $scope.getButtonHoverTextForElement = function (selectedAgentOrCustomer) {
        var locationWithNewline = selectedAgentOrCustomer && selectedAgentOrCustomer.Location ? '\r\n' + selectedAgentOrCustomer.Location : "";
        return selectedAgentOrCustomer != null ?
            [selectedAgentOrCustomer.Key, selectedAgentOrCustomer.Value, locationWithNewline]
                .filter(function (element) { return !!element }).join(' ') :
            "";
    };

    var callbackErrorFunc = function () {
        $scope.showError = true;
        $scope.isRequestPending = false;
        console.error("Failed to load SKU data");
    };

    $scope.SkuViewAll = function () {
        $scope.showViewAll = false;
        $scope.pageData = $scope.filteredStockedProducts;
    };
    $scope.SkuViewLess = function () {
        $scope.showViewAll = true;
        loadPage($scope.page);
        anchorToTop();
    };

    $scope.getMinimumDisplayedIndex = function () {
        if (!$scope.showViewAll) {
            return 1;
        }
        return $scope.pager ? $scope.pager.startIndex + 1 : 0;
    };

    $scope.getMaximumDisplayedIndex = function () {
        if (!$scope.showViewAll) {
            return $scope.filteredStockedProducts.length;
        }
        return $scope.pager ? $scope.pager.endIndex + 1 : 0;
    };

    function loadPage(pagejump) {
        $scope.pager = pagerService.GetPager($scope.filteredStockedProducts.length, pagejump, $scope.itemsPerPage);
        $scope.pageData = $scope.filteredStockedProducts.slice($scope.pager.startIndex, $scope.pager.endIndex + 1);
        $scope.page = $scope.pager.currentPage;
        $scope.totalPages = $scope.pager.totalPages;
        if (!$scope.showViewAll) {
            $scope.pageData = $scope.filteredStockedProducts;
        }
    }

    function anchorToTop() {
        window.scrollTo({ top: $("#stocked-products").offset().top - 100 });
    }

    $scope.skipto = function (pagejump) {
        if (pagejump > 0 && pagejump <= $scope.pager.totalPages) {
            loadPage(pagejump);
            anchorToTop();
        }
    };

    $scope.popupOpen = function (sku) {
        $scope.popupSku = sku;
        var popup = document.getElementById("details-popup");
        popup.style.visibility = 'visible';
        popup.style.opacity = '1';

        var shadeList = document.getElementsByClassName("shade");
        var shade = shadeList[0];
        shade.style.visibility = 'visible';
        shade.style.opacity = '1';
        shade.style.zIndex = '1000';

        if (sku.details == null) {
            sku.detailsRequestPending = true;
            requestDetails(sku, $scope.repSelector.dataWasRequestedFor, $scope.distributorSelector.dataWasRequestedFor);
        }
    }

    $scope.popupClose = function () {
        var popup = document.getElementById("details-popup");
        popup.style.visibility = 'hidden';
        popup.style.opacity = '0';

        var shadeList = document.getElementsByClassName("shade");
        var shade = shadeList[0];
        shade.style.visibility = 'hidden';
        shade.style.opacity = '0';
        shade.style.zIndex = '499';
    }

    var distributorFieldsToSearch = ['LABEL', 'UNIT_PRICE', 'GOOD_THRU'];

    var initializeSku = function (sku) {

        sku.Description = sku.Description.replaceAll(",", ", ");
        sku.hasStandingQuotes = false;
        sku.hideStandingQuotesSection = false;
        sku.noQuotesMessage = '';
        sku.noQuotesHoverText = '';

        sku.standingQuotesForCurrentSelections = {
            displayStandingQuoteSearch: false,
            searchTerm: '',
            displayMore: false,
            standingQuoteData: null,
            visibleQuotes: [],
            hasMoreQuotes: false,
            isPrimaryQuoteList: true,
        };

        sku.allStandingQuotesForRep = {
            displayStandingQuoteSearch: false,
            searchTerm: '',
            displayMore: false,
            standingQuoteData: null,
            visibleQuotes: [],
            hasMoreQuotes: false,
            isPrimaryQuoteList: false,
        };
    }

    $scope.clearStandingQuoteSearch = function (element, sku) {
        element.searchTerm = "";
        $scope.initializeStandingQuotes(sku, true);
    }

    $scope.initializeStandingQuotes = function (sku, resetViewMore) {
        if (sku.standingQuotesForCurrentSelections.standingQuoteData == null) {
            sku.standingQuotesForCurrentSelections.standingQuoteData = sku.details && sku.details.STANDING_QUOTES ?
                sku.details.STANDING_QUOTES :
                [];
        }
        initializeVisibleStandingQuotes(sku, resetViewMore, sku.standingQuotesForCurrentSelections, true);
    }

    $scope.clearStandingQuoteSearchForRep = function (element, sku) {
        element.searchTerm = "";
        $scope.initializeAllStandingQuotesForRep(sku, true);
    }

    $scope.initializeAllStandingQuotesForRep = function (sku, resetViewMore) {
        if (sku.allStandingQuotesForRep.standingQuoteData == null) {
            sku.allStandingQuotesForRep.standingQuoteData = sku.details && sku.details.ALL_STANDING_QUOTES ?
                sku.details.ALL_STANDING_QUOTES :
                [];
        }
        initializeVisibleStandingQuotes(sku, resetViewMore, sku.allStandingQuotesForRep);
    }

    var initializeVisibleStandingQuotes = function (sku, resetViewMore, whichStandingQuoteList) {
        var standingQuoteData = whichStandingQuoteList && whichStandingQuoteList.standingQuoteData && whichStandingQuoteList
            ? whichStandingQuoteList.standingQuoteData :
            [];
        var allQuotes = standingQuoteData && standingQuoteData.StandingQuotes && standingQuoteData.StandingQuotes.length
            ? standingQuoteData.StandingQuotes :
            [];

        whichStandingQuoteList.displayStandingQuoteSearch = allQuotes.length > 1;

        var filteredQuotes = WildcardSearchFilter(allQuotes, distributorFieldsToSearch, whichStandingQuoteList.searchTerm, null);
        var firstFilteredQuotes = filteredQuotes.length > displayXNumberOfDistributorQuotes && !whichStandingQuoteList.displayMore ?
            filteredQuotes.slice(0, displayXNumberOfDistributorQuotes) :
            filteredQuotes;

        whichStandingQuoteList.displayMore = (resetViewMore || whichStandingQuoteList.displayMore == null) ?
            false :
            whichStandingQuoteList.displayMore;

        whichStandingQuoteList.hasStandingQuotes = allQuotes.length > 0;
        whichStandingQuoteList.visibleQuotes = firstFilteredQuotes;
        whichStandingQuoteList.hasMoreQuotes = firstFilteredQuotes.length < filteredQuotes.length;

        if (whichStandingQuoteList.isPrimaryQuoteList) {
            sku.hideStandingQuotesSection = standingQuoteData && standingQuoteData.HideStandingQuotesSection;
            sku.noQuotesMessage = standingQuoteData && standingQuoteData.NoQuotesMessage ?
                standingQuoteData.NoQuotesMessage :
                "";
            sku.noQuotesHoverText = standingQuoteData && standingQuoteData.NoQuotesHoverText ?
                standingQuoteData.NoQuotesHoverText :
                "";
        }
    };

    $scope.viewMoreDistributorQuotes = function (sku, whichStandingQuoteList) {
        whichStandingQuoteList.displayMore = true;
        initializeVisibleStandingQuotes(sku, false, whichStandingQuoteList);
    };

    $scope.viewLessDistributorQuotes = function (sku, whichStandingQuoteList) {
        whichStandingQuoteList.displayMore = false;
        initializeVisibleStandingQuotes(sku, false, whichStandingQuoteList);
    };

    $scope.toggleShowAllStandingQuotes = function (sku) {
        if (sku.showAllStandingQuotes === undefined) {
            sku.showAllStandingQuotes = true;
        }
        else {
            sku.showAllStandingQuotes = !sku.showAllStandingQuotes;
        }
        $scope.initializeStandingQuotes(sku, true, sku.showAllStandingQuotes);
    };

    $scope.locationsOpen = function (sku) {
        sku.showLocationDropdown = !sku.showLocationDropdown;

        if (sku.showLocationDropdown && sku.details == null) {
            sku.detailsRequestPending = true;
            requestDetails(sku, $scope.repSelector.dataWasRequestedFor, $scope.distributorSelector.dataWasRequestedFor);
        }
    }
    $scope.transitOpen = function (sku) {
        sku.showInTransitDropdown = !sku.showInTransitDropdown;
    }


    var recordActiveSelectionState = function (rep, customer) {
        $scope.repSelector.recordDataAsCurrentFor(rep);
        $scope.distributorSelector.recordDataAsCurrentFor(customer);
    };

    $scope.applySelections = repAndDistributorSelector.functions.applySelections;

    var requestDetails = function (sku, repAgent, customerDistributor) {
        $http(
            {
                url: '/api/products/getstockeddetails',
                method: 'POST',
                data: {
                    SkuDescription: sku.Title,
                    InventoryId: sku.InventoryId,
                    Division: sku.Division,
                    RepNumber: repAgent ? repAgent.Key : null,
                    CustomerNumber: customerDistributor ? customerDistributor.Key : null,
                    AdditionalLogging: requestAdditionalLogging,
                    MimicUser: mimicUser
                },
                dataType: 'json'
            })
            .then(function (response) {
                sku.detailsRequestPending = false;
                sku.detailsShowError = false;

                var responseData = response && response.data ? response.data : null;

                if (response && response.status === 200 && responseData && responseData.Success && responseData.Value) {
                    var details = responseData.Value;

                    if (details.INVENTORY_ID === "0" || details.INVENTORY_ID === 0)
                        sku.detailsShowError = true;
                    else {
                        sku.altLocationsHaveInventory = false;
                        details.ALTERNATE_LOCATIONS.forEach(function (loc) {
                            loc.altLocationsHaveInTransit = false;
                            loc.showInTransitDropdown = false;
                            if (loc.QUANTITY > 0) {
                                sku.altLocationsHaveInventory = true;
                            }
                            if (loc.TRANSIT_DETAILS && loc.TRANSIT_DETAILS.length > 0) {
                                loc.altLocationsHaveInTransit = true;
                            }
                        });
                        details.LONG_DESCRIPTION = details.LONG_DESCRIPTION.replaceAll(",", ", ");
                        sku.details = details;
                        $scope.initializeStandingQuotes(sku);
                        $scope.initializeAllStandingQuotesForRep(sku);
                    }
                } else {
                    sku.hasNoDetailsResults = true;
                    sku.isUserRestricted = responseData.Value.IsUserRestricted;
                    sku.isUserLoggedIn = responseData.Value.IsUserLoggedIn;
                }
            }, function () {
                sku.detailsRequestPending = false;
                sku.detailsShowError = true;
            });
    };

    var itemFieldsToSearch = ["Title", "Description"];

    var recalculateVisibleStockedProducts = function () {
        $scope.filteredStockedProducts = WildcardSearchFilter($scope.stockedProducts, itemFieldsToSearch, $scope.searchCriteria.searchQuery, $scope.searchCriteria.inventoryType);
        loadPage(1);
    }

    $scope.$watch('searchCriteria.searchQuery', function (newValue, oldValue, scope) {
        if (newValue !== oldValue) {
            recalculateVisibleStockedProducts();
        }
    });

    $scope.$watch('searchCriteria.inventoryType', function (newValue, oldValue, scope) {
        if (newValue !== oldValue) {
            recalculateVisibleStockedProducts();
        }
    });

    $scope.$watch('repSelector.searchTerm', function (tmpStr) {
        $timeout(function () {
            // if searchStr is still the same..
            // go ahead and retrieve the data
            if (tmpStr === $scope.repSelector.searchTerm) {
                $scope.repSelector.filteredSelections = WildcardSearchFilter($scope.repSelector.getNonSelectedOptions(), ['Key', 'Value'], $scope.repSelector.searchTerm, null);
            }
        }, 500);
    });

    $scope.$watch('distributorSelector.searchTerm', function (tmpStr) {
        $timeout(function () {
            // if searchStr is still the same..
            // go ahead and retrieve the data
            if (tmpStr === $scope.distributorSelector.searchTerm) {
                $scope.distributorSelector.filteredSelections = WildcardSearchFilter($scope.distributorSelector.getNonSelectedOptions(), ['Key', 'Value'], $scope.distributorSelector.searchTerm, null);
            }
        }, 500);
    });

    $(window).scroll(function () {
        var headerHeight = 70.8;
        skuScrollThreshold = $(".stocked-products-list").offset().top - $("header").height();
        skuScrollLimit = skuScrollThreshold + $(".stocked-products-list").height() - 200 - (skuScrolled ? 0 : headerHeight);

        try {
            var headerfacetClass = "sku-scrolled";
            var scrollAmount = $(window).scrollTop();

            if (scrollAmount >= skuScrollThreshold && scrollAmount <= skuScrollLimit) {
                $('body').addClass(headerfacetClass);
                skuScrolled = true;
            } else {
                $('body').removeClass(headerfacetClass);
                skuScrolled = false;
            }
            resizeFilterHeader();
        } catch (error) {
        }
    });

    $(window).resize(resizeFilterHeader);

    function resizeFilterHeader() {
        var filterBar = $("body.sku-scrolled .stocked-products-list__filters");
        if (filterBar[0])
            filterBar.css("width", ($(".stocked-products-list__results").width() + 40) + "px");
        else
            $(".stocked-products-list__filters").css("width", "");
    }

}

function WildcardSearchFilter(items, itemFieldsToInspect, freeTextQuery, inventoryType) {
    //first, filter results based on what is typed into the search box
    var textboxFiltered = [];
    itemFieldsToInspect = itemFieldsToInspect || [];

    if (freeTextQuery === "" || freeTextQuery == null) {
        textboxFiltered = items;
    }
    else {
        //escape regex reserved characters in user input
        var input = freeTextQuery.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');

        //convert % wildcard character to its regex equivalent
        input = input.replace(/%/g, ".+?");

        var inputRegex = new RegExp(input, "i");

        for (var wildCardItemCounter = 0; wildCardItemCounter < items.length; wildCardItemCounter++) {
            var item = items[wildCardItemCounter];
            var filterFunction = function (fieldName) {
                return item[fieldName] && inputRegex.test(item[fieldName]);
            };

            if (itemFieldsToInspect.some(filterFunction)) {
                textboxFiltered.push(item);
            }
        }
    }

    // clone array to prevent modifying array while iterating
    var fullyFiltered = inventoryType ? [] : textboxFiltered.map(function (item) { return item });
    //second, filter results based on search filters selected in the dropdowns
    for (var i = 0; i < textboxFiltered.length; i++) {
        var filteredItem = textboxFiltered[i];
        if (!inventoryType || filteredItem.InventoryTypes.includes(inventoryType)) {
            if (!fullyFiltered.includes(filteredItem)) {
                fullyFiltered.push(filteredItem);
            }
        }
    }

    return fullyFiltered;
}

var stockedProductsModule = angular.module('stockedproductsmodule', []);
stockedProductsModule.factory('pagerService', app.angularshared.PagerService);
stockedProductsModule.controller('StockedProductsController', ['$scope', '$rootScope', '$http', '$timeout', 'pagerService', StockedProductsController]);
angular.module('acuityApp').requires.push('stockedproductsmodule');
;
var app = app || {};
app.cookiedisclosure = app.cookiedisclosure || {};
app.cookieLifetime = app.cookieLifetime || 30;

app.cookiedisclosure = {
    init: function () {
        var container = $("#cookie-disclosure");
        var isDisclosureAccepted = app.getCookie("accepted_cookies") === 'true';

        if (!isDisclosureAccepted)
            container.show();

        $("#cookie-disclosure-agree").click(function(e) {
            app.setCookie("accepted_cookies", true, app.cookieLifetime);
            container.hide();
        });
    }
};

$(document).ready(function () {
    app.cookiedisclosure.init();
});;
