vendor: 1,515 bytes, line 1
1!function(e){var t=!0;e.flexslider=function(a,n){var i=e(a);i.vars=e.extend({},e.flexslider.defaults,n);var s,r=i.vars.namespace,o=window.navigator&&window.navigator.msPointerEnabled&&window.MSGesture,l=("ontouchstart"in window||o||window.DocumentTouch&&document instanceof DocumentTouch)&&i.vars.touch,c="click touchend MSPointerUp keyup",d="",u="vertical"===i.vars.direction,v=i.vars.reverse,p=i.vars.itemWidth>0,m="fade"===i.vars.animation,f=""!==i.vars.asNavFor,g={};e.data(a,"flexslider",i),g={init:function(){i.animating=!1,i.currentSlide=parseInt(i.vars.startAt?i.vars.startAt:0,10),isNaN(i.currentSlide)&&(i.currentSlide=0),i.animatingTo=i.currentSlide,i.atEnd=0===i.currentSlide||i.currentSlide===i.last,i.containerSelector=i.vars.selector.substr(0,i.vars.selector.search(" ")),i.slides=e(i.vars.selector,i),i.container=e(i.containerSelector,i),i.count=i.slides.length,i.syncExists=e(i.vars.sync).length>0,"slide"===i.vars.animation&&(i.vars.animation="swing"),i.prop=u?"top":"marginLeft",i.args={},i.manualPause=!1,i.stopped=!1,i.started=!1,i.startTimeout=null,i.transitions=!i.vars.video&&!m&&i.vars.useCSS&&function(){var e=document.createElement("div"),t=["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"];for(var a in t)if(void 0!==e.style[t[a]])return i.pfx=t[a].replace("Perspective","").toLowerCase(),i.prop="-"+i.pfx+"-transform",!0;return!1}(),i.ensureAnimationEnd="",""!==i.vars.controlsContainer&&(i.controlsContainer=e(i.vars.controlsContainer).length>
10&&e(i.vars.controlsContainer)),""!==i.vars.manualControls&&(i.manualControls=e(i.vars.manualControls).length>0&&e(i.vars.manualControls)),""!==i.vars.customDirectionNav&&(i.customDirectionNav=2===e(i.vars.customDirectionNav).length&&e(i.vars.customDirectionNav)),i.vars.randomize&&(i.slides.sort(function(){return Math.round(Math.random())-.5}),i.container.empty().append(i.slides)),i.doMath(),i.setup("init"),i.vars.controlNav&&g.controlNav.setup(),i.vars.directionNav&&g.directionNav.setup(),i.vars.keyboard&&(1===e(i.containerSelector).length||i.vars.multipleKeyboard)&&e(document).bind("keyup",function(e){var t=e.keyCode;if(!i.animating&&(39===t||37===t)){var a=39===t?i.getTarget("next"):37===t&&i.getTarget("prev");i.flexAnimate(a,i.vars.pauseOnAction)}}),i.vars.mousewheel&&i.bind("mousewheel",function(e,t,a,n){e.preventDefault();var s=t<0?i.getTarget("next"):i.getTarget("prev");i.flexAnimate(s,i.vars.pauseOnAction)}),i.vars.pausePlay&&g.pausePlay.setup(),i.vars.slideshow&&i.vars.pauseInvisible&&g.pauseInvisible.init(),i.vars.slideshow&&(i.vars.pauseOnHover&&i.hover(function(){i.manualPlay||i.manualPause||i.pause()},function(){i.manualPause||i.manualPlay||i.stopped||i.play()}),i.vars.pauseInvisible&&g.pauseInvisible.isHidden()||(i.vars.initDelay>0?i.startTimeout=setTimeout(i.play,i.vars.initDelay):i.play())),f&&g.asNav.setup(),l&&i.vars.touch&&g.touch(),(!m||m&&i.vars.smoothHeight)&&e(window).bind("resize orientationchange focus",g.resize),i.find("img").attr("draggable","false"),setTimeout(function(){i.vars.start(i)},200)},asNav:{setup:function(){i.asNav=!0,i.animatingTo=Math.floor(i.currentSlide/i.move),i.currentItem=i.currentSlide,i.slides.removeClass(r+"active-slide").eq(i.currentItem).addClass(r+"active-slide"),o?(a._slider=i,i.slides.each(function(){this._gesture=new MSGesture,this._gesture.target=this,this.addEventListener("MSPointerDown",function(e){e.preventDefault(),e.currentTarget._gesture&&e.currentTarget._gesture.addPointer(e.pointerId)},!1),this.addEventListener("MSGestureTap",function(t){t.preventDefault();var a=e(this),n=a.index();e(i.vars.asNavFor).data("flexslider").animating||a.hasClass("active")||(i.direction=i.currentItem<n?"next":"prev",i.flexAnimate(n,i.vars.pauseOnAction,!1,!0,!0))})})):i.slides.on(c,function(t){t.preventDefault();var a=e(this),n=a.index();a.offset().left-e(i).scrollLeft()<=0&&a.hasClass(r+"active-slide")?i.flexAnimate(i.getTarget("prev"),!0):e(i.vars.asNavFor).data("flexslider").animating||a.hasClass(r+"active-slide")||(i.direction=i.currentItem<n?"next":"prev",i.flexAnimate(n,i.vars.pauseOnAction,!1,!0,!0))})}},controlNav:{setup:function(){i.manualControls?g.controlNav.setupManual():g.controlNav.setupPaging()},setupPaging:function(){var t,a,n="thumbnails"===i.vars.controlNav?"control-thumbs":"control-paging",s=1;if(i.controlNavScaffold=e('<ol class="'+r+"control-nav "+r+n+'"></ol>'),i.pagingCount>1)for(var o=0;o<i.pagingCount;o++){if(void 0===(a=i.slides.eq(o)).attr("data-thumb-alt")&&a.attr("data-thumb-alt",""),altText=""!==a.attr("data-thumb-alt")?altText=' alt="'+a.attr("data-thumb-alt")+'"':"",t="thumbnails"===i.vars.controlNav?'<img src="'+a.attr("data-thumb")+'"'+altText+"/>":'<a href="#">'+s+"</a>","thumbnails"===i.vars.controlNav&&!0===i.vars.thumbCaptions){var l=a.attr("data-thumbcaption");""!==l&&void 0!==l&&(t+='<span class="'+r+'caption">'+l+"</span>")}i.controlNavScaffold.append("<li>"+t+"</li>"),s++}i.controlsContainer?e(i.controlsContainer).append(i.controlNavScaffold):i.append(i.controlNavScaffold),g.controlNav.set(),g.controlNav.active(),i.controlNavScaffold.delegate("a, img",c,function(t){if(t.preventDefault(),""===d||d===t.type){var a=e(this),n=i.controlNav.index(a);a.hasClass(r+"active")||(i.direction=n>i.currentSlide?"next":"prev",i.flexAnimate(n,i.vars.pauseOnAction))}""===d&&(d=t.type),g.setToClearWatchedEvent()})},setupManual:function(){i.controlNav=i.manualControls,g.controlNav.active(),i.controlNav.bind(c,function(t){if(t.preventDefault(),""===d||d===t.type){var a=e(this),n=i.controlNav.index(a);a.hasClass(r+"active")||(n>i.currentSlide?i.direction="next":i.direction="prev",i.flexAnimate(n,i.vars.pauseOnAction))}""===d&&(d=t.type),g.setToClearWatchedEvent()})}
vendor: 12,486 bytes, line 1
1,set:function(){var t="thumbnails"===i.vars.controlNav?"img":"a";i.controlNav=e("."+r+"control-nav li "+t,i.controlsContainer?i.controlsContainer:i)},active:function(){i.controlNav.removeClass(r+"active").eq(i.animatingTo).addClass(r+"active")},update:function(t,a){i.pagingCount>1&&"add"===t?i.controlNavScaffold.append(e('<li><a href="#">'+i.count+"</a></li>")):1===i.pagingCount?i.controlNavScaffold.find("li").remove():i.controlNav.eq(a).closest("li").remove(),g.controlNav.set(),i.pagingCount>1&&i.pagingCount!==i.controlNav.length?i.update(a,t):g.controlNav.active()}},directionNav:{setup:function(){var t=e('<ul class="'+r+'direction-nav"><li class="'+r+'nav-prev"><a class="'+r+'prev" href="#">'+i.vars.prevText+'</a></li><li class="'+r+'nav-next"><a class="'+r+'next" href="#">'+i.vars.nextText+"</a></li></ul>");i.customDirectionNav?i.directionNav=i.customDirectionNav:i.controlsContainer?(e(i.controlsContainer).append(t),i.directionNav=e("."+r+"direction-nav li a",i.controlsContainer)):(i.append(t),i.directionNav=e("."+r+"direction-nav li a",i)),g.directionNav.update(),i.directionNav.bind(c,function(t){var a;t.preventDefault(),""!==d&&d!==t.type||(a=e(this).hasClass(r+"next")?i.getTarget("next"):i.getTarget("prev"),i.flexAnimate(a,i.vars.pauseOnAction)),""===d&&(d=t.type),g.setToClearWatchedEvent()})},update:function(){var e=r+"disabled";1===i.pagingCount?i.directionNav.addClass(e).attr("tabindex","-1"):i.vars.animationLoop?i.directionNav.removeClass(e).removeAttr("tabindex"):0===i.animatingTo?i.directionNav.removeClass(e).filter("."+r+"prev").addClass(e).attr("tabindex","-1"):i.animatingTo===i.last?i.directionNav.removeClass(e).filter("."+r+"next").addClass(e).attr("tabindex","-1"):i.directionNav.removeClass(e).removeAttr("tabindex")}},pausePlay:{setup:function(){var t=e('<div class="'+r+'pauseplay"><a href="#"></a></div>');i.controlsContainer?(i.controlsContainer.append(t),i.pausePlay=e("."+r+"pauseplay a",i.controlsContainer)):(i.append(t),i.pausePlay=e("."+r+"pauseplay a",i)),g.pausePlay.update(i.vars.slideshow?r+"pause":r+"play"),i.pausePlay.bind(c,function(t){t.preventDefault(),""!==d&&d!==t.type||(e(this).hasClass(r+"pause")?(i.manualPause=!0,i.manualPlay=!1,i.pause()):(i.manualPause=!1,i.manualPlay=!0,i.play())),""===d&&(d=t.type),g.setToClearWatchedEvent()})},update:function(e){"play"===e?i.pausePlay.removeClass(r+"pause").addClass(r+"play").html(i.vars.playText):i.pausePlay.removeClass(r+"play").addClass(r+"pause").html(i.vars.pauseText)}},touch:function(){var e,t,n,s,r,l,c,d,f,g=!1,h=0,S=0,x=0;if(o){a.style.msTouchAction="none",a._gesture=new MSGesture,a._gesture.target=a,a.addEventListener("MSPointerDown",function(e){e.stopPropagation(),i.animating?e.preventDefault():(i.pause(),a._gesture.addPointer(e.pointerId),x=0,s=u?i.h:i.w,l=Number(new Date),n=p&&v&&i.animatingTo===i.last?0:p&&v?i.limit-(i.itemW+i.vars.itemMargin)*i.move*i.animatingTo:p&&i.currentSlide===i.last?i.limit:p?(i.itemW+i.vars.itemMargin)*i.move*i.currentSlide:v?(i.last-i.currentSlide+i.cloneOffset)*s:(i.currentSlide+i.cloneOffset)*s)},!1),a._slider=i,a.addEventListener("MSGestureChange",function(e){e.stopPropagation();var t=e.target._slider;if(!t)return;var i=-e.translationX,o=-e.translationY;if(r=x+=u?o:i,g=u?Math.abs(x)<Math.abs(-i):Math.abs(x)<Math.abs(-o),e.detail===e.MSGESTURE_FLAG_INERTIA)return void setImmediate(function(){a._gesture.stop()});(!g||Number(new Date)-l>500)&&(e.preventDefault(),!m&&t.transitions&&(t.vars.animationLoop||(r=x/(0===t.currentSlide&&x<0||t.currentSlide===t.last&&x>0?Math.abs(x)/s+2:1)),t.setProps(n+r,"setTouch")))},!1),a.addEventListener("MSGestureEnd",function(a){a.stopPropagation();var i=a.target._slider;if(!i)return;if(i.animatingTo===i.currentSlide&&!g&&null!==r){var o=v?-r:r,c=o>0?i.getTarget("next"):i.getTarget("prev");i.canAdvance(c)&&(Number(new Date)-l<550&&Math.abs(o)>50||Math.abs(o)>s/2)?i.flexAnimate(c,i.vars.pauseOnAction):m||i.flexAnimate(i.currentSlide,i.vars.pauseOnAction,!0)}e=null,t=null,r=null,n=null,x=0},!1)}else c=function(r){i.animating?r.preventDefault():(window.navigator.msPointerEnabled||1===r.touches.length)&&(i.pause(),s=u?i.h:i.w,l=Number(new Date),h=r.touches[0].pageX,S=r.touches[0].pageY,n=p&&v&&i.animatingTo===i.last?0:p&&v?i.limit-(i.itemW+i.vars.itemMargin)*i.move*i.animatingTo:p&&i.currentSlide===i.last?i.limit:p?(i.itemW+i.vars.itemMargin)*i.move*i.currentSlide:v?(i.last-i.currentSlide+i.cloneOffset)*s:(i.currentSlide+i.cloneOffset)*s,e=u?S:h,t=u?h:S,a.addEventListener("touchmove",d,!1),a.addEventListener("touchend",f,!1))},d=function(a){h=a.touches[0].pageX,S=a.touches[0].pageY,r=u?e-S:e-h;(!(g=u?Math.abs(r)<Math.abs(h-t):Math.abs(r)<Math.abs(S-t))||Number(new Date)-l>500)&&(a.preventDefault(),!m&&i.transitions&&(i.vars.animationLoop||(r/=0===i.currentSlide&&r<0||i.currentSlide===i.last&&r>0?Math.abs(r)/s+2:1),i.setProps(n+r,"setTouch")))},f=function(o){if(a.removeEventListener("touchmove",d,!1),i.animatingTo===i.currentSlide&&!g&&null!==r){var c=v?-r:r,u=c>0?i.getTarget("next"):i.getTarget("prev");i.canAdvance(u)&&(Number(new Date)-l<550&&Math.abs(c)>50||Math.abs(c)>s/2)?i.flexAnimate(u,i.vars.pauseOnAction):m||i.flexAnimate(i.currentSlide,i.vars.pauseOnAction,!0)}a.removeEventListener("touchend",f,!1),e=null,t=null,r=null,n=null},a.addEventListener("touchstart",c,!1)},resize:function(){!i.animating&&i.is(":visible")&&(p||i.doMath(),m?g.smoothHeight():p?(i.slides.width(i.computedW),i.update(i.pagingCount),i.setProps()):u?(i.viewport.height(i.h),i.setProps(i.h,"setTotal")):(i.vars.smoothHeight&&g.smoothHeight(),i.newSlides.width(i.computedW),i.setProps(i.computedW,"setTotal")))},smoothHeight:function(e){if(!u||m){var t=m?i:i.viewport;e?t.animate({height:i.slides.eq(i.animatingTo).height()},e):t.height(i.slides.eq(i.animatingTo).height())}},sync:function(t){var a=e(i.vars.sync).data("flexslider"),n=i.animatingTo;switch(t){case"animate":a.flexAnimate(n,i.vars.pauseOnAction,!1,!0);break;case"play":a.playing||a.asNav||a.play();break;case"pause":a.pause()}},uniqueID:function(t){return t.filter("[id]").add(t.find("[id]")).each(function(){var t=e(this);t.attr("id",t.attr("id")+"_clone")}),t},pauseInvisible:{visProp:null,init:function(){var e=g.pauseInvisible.getHiddenProp();if(e){var t=e.replace(/[H|h]idden/,"")+"visibilitychange";document.addEventListener(t,function(){g.pauseInvisible.isHidden()?i.startTimeout?clearTimeout(i.startTimeout):i.pause():i.started?i.play():i.vars.initDelay>0?setTimeout(i.play,i.vars.initDelay):i.play()})}},isHidden:function(){var e=g.pauseInvisible.getHiddenProp();return!!e&&document[e]},getHiddenProp:function(){var e=["webkit","moz","ms","o"];if("hidden"in document)return"hidden";for(var t=0;t<e.length;t++)if(e[t]+"Hidden"in document)return e[t]+"Hidden";return null}},setToClearWatchedEvent:function(){clearTimeout(s),s=setTimeout(function(){d=""},3e3)}},i.flexAnimate=function(t,a,n,s,o){if(i.vars.animationLoop||t===i.currentSlide||(i.direction=t>i.currentSlide?"next":"prev"),f&&1===i.pagingCount&&(i.direction=i.currentItem<t?"next":"prev"),!i.animating&&(i.canAdvance(t,o)||n)&&i.is(":visible")){if(f&&s){var c=e(i.vars.asNavFor).data("flexslider");if(i.atEnd=0===t||t===i.count-1,c.flexAnimate(t,!0,!1,!0,o),i.direction=i.currentItem<t?"next":"prev",c.direction=i.direction,Math.ceil((t+1)/i.visible)-1===i.currentSlide||0===t)return i.currentItem=t,i.slides.removeClass(r+"active-slide").eq(t).addClass(r+"active-slide"),!1;i.currentItem=t,i.slides.removeClass(r+"active-slide").eq(t).addClass(r+"active-slide"),t=Math.floor(t/i.visible)}if(i.animating=!0,i.animatingTo=t,a&&i.pause(),i.vars.before(i),i.syncExists&&!o&&g.sync("animate"),i.vars.controlNav&&g.controlNav.active(),p||i.slides.removeClass(r+"active-slide").eq(t).addClass(r+"active-slide"),i.atEnd=0===t||t===i.last,i.vars.directionNav&&g.directionNav.update(),t===i.last&&(i.vars.end(i),i.vars.animationLoop||i.pause()),m)l?(i.slides.eq(i.currentSlide).css({opacity:0,zIndex:1}),i.slides.eq(t).css({opacity:1,zIndex:2}),i.wrapup(x)):(i.slides.eq(i.currentSlide).css({zIndex:1}).animate({opacity:0},i.vars.animationSpeed,i.vars.easing),i.slides.eq(t).css({zIndex:2}).animate({opacity:1},i.vars.animationSpeed,i.vars.easing,i.wrapup));else{var d,h,S,x=u?i.slides.filter(":first").height():i.computedW;p?(d=i.vars.itemMargin,h=(S=(i.itemW+d)*i.move*i.animatingTo)>i.limit&&1!==i.visible?i.limit:S):h=0===i.currentSlide&&t===i.count-1&&i.vars.animationLoop&&"next"!==i.direction?v?(i.count+i.cloneOffset)*x:0:i.currentSlide===i.last&&0===t&&i.vars.animationLoop&&"prev"!==i.direction?v?0:(i.count+1)*x:v?(i.count-1-t+i.cloneOffset)*x:(t+i.cloneOffset)*x,i.setProps(h,"",i.vars.animationSpeed),i.transitions?(i.vars.animationLoop&&i.atEnd||(i.animating=!1,i.currentSlide=i.animatingTo),i.container.unbind("webkitTransitionEnd transitionend"),i.container.bind("webkitTransitionEnd transitionend",function(){clearTimeout(i.ensureAnimationEnd),i.wrapup(x)}),clearTimeout(i.ensureAnimationEnd),i.ensureAnimationEnd=setTimeout(function(){i.wrapup(x)},i.vars.animationSpeed+100)):i.container.animate(i.args,i.vars.animationSpeed,i.vars.easing,function(){i.wrapup(x)})}i.vars.smoothHeight&&g.smoothHeight(i.vars.animationSpeed)}},i.wrapup=function(e){m||p||(0===i.currentSlide&&i.animatingTo===i.last&&i.vars.animationLoop?i.setProps(e,"jumpEnd"):i.currentSlide===i.last&&0===i.animatingTo&&i.vars.animationLoop&&i.setProps(e,"jumpStart")),i.animating=!1,i.currentSlide=i.animatingTo,i.vars.after(i)},i.animateSlides=function(){!i.animating&&t&&i.flexAnimate(i.getTarget("next"))},i.pause=function(){clearInterval(i.animatedSlides),i.animatedSlides=null,i.playing=!1,i.vars.pausePlay&&g.pausePlay.update("play"),i.syncExists&&g.sync("pause")},i.play=function(){i.playing&&clearInterval(i.animatedSlides),i.animatedSlides=i.animatedSlides||setInterval(i.animateSlides,i.vars.slideshowSpeed),i.started=i.playing=!0,i.vars.pausePlay&&g.pausePlay.update("pause"),i.syncExists&&g.sync("play")},i.stop=function(){i.pause(),i.stopped=!0},i.canAdvance=function(e,t){var a=f?i.pagingCount-1:i.last;return!!t||(!(!f||i.currentItem!==i.count-1||0!==e||"prev"!==i.direction)||(!f||0!==i.currentItem||e!==i.pagingCount-1||"next"===i.direction)&&(!(e===i.currentSlide&&!f)&&(!!i.vars.animationLoop||(!i.atEnd||0!==i.currentSlide||e!==a||"next"===i.direction)&&(!i.atEnd||i.currentSlide!==a||0!==e||"next"!==i.direction))))},i.getTarget=function(e){return i.direction=e,"next"===e?i.currentSlide===i.last?0:i.currentSlide+1:0===i.currentSlide?i.last:i.currentSlide-1},i.setProps=function(e,t,a){var n,s=(n=e||(i.itemW+i.vars.itemMargin)*i.move*i.animatingTo,-1*function(){if(p)return"setTouch"===t?e:v&&i.animatingTo===i.last?0:v?i.limit-(i.itemW+i.vars.itemMargin)*i.move*i.animatingTo:i.animatingTo===i.last?i.limit:n;switch(t){case"setTotal":return v?(i.count-1-i.currentSlide+i.cloneOffset)*e:(i.currentSlide+i.cloneOffset)*e;case"setTouch":return e;case"jumpEnd":return v?e:i.count*e;case"jumpStart":return v?i.count*e:e;default:return e}}()+"px");i.transitions&&(s=u?"translate3d(0,"+s+",0)":"translate3d("+s+",0,0)",a=void 0!==a?a/1e3+"s":"0s",i.container.css("-"+i.pfx+"-transition-duration",a),i.container.css("transition-duration",a)),i.args[i.prop]=s,(i.transitions||void 0===a)&&i.container.css(i.args),i.container.css("transform",s)},i.setup=function(t){var a,n;m?(i.slides.css({width:"100%",float:"left",marginRight:"-100%",position:"relative"}),"init"===t&&(l?i.slides.css({opacity:0,display:"block",webkitTransition:"opacity "+i.vars.animationSpeed/1e3+"s ease",zIndex:1}).eq(i.currentSlide).css({opacity:1,zIndex:2}):0==i.vars.fadeFirstSlide?i.slides.css({opacity:0,display:"block",zIndex:1}).eq(i.currentSlide).css({zIndex:2}).css({opacity:1}):i.slides.css({opacity:0,display:"block",zIndex:1}).eq(i.currentSlide).css({zIndex:2}).animate({opacity:1},i.vars.animationSpeed,i.vars.easing)),i.vars.smoothHeight&&g.smoothHeight()):("init"===t&&(i.viewport=e('<div class="'+r+'viewport"></div>').css({overflow:"hidden",position:"relative"}).appendTo(i).append(i.container),i.cloneCount=0,i.cloneOffset=0,v&&(n=e.makeArray(i.slides).reverse(),i.slides=e(n),i.container.empty().append(i.slides))),i.vars.animationLoop&&!p&&(i.cloneCount=2,i.cloneOffset=1,"init"!==t&&i.container.find(".clone").remove(),i.container.append(g.uniqueID(i.slides.first().clone().addClass("clone")).attr("aria-hidden","true")).prepend(g.uniqueID(i.slides.last().clone().addClass("clone")).attr("aria-hidden","true"))),i.newSlides=e(i.vars.selector,i),a=v?i.c
1ount-1-i.currentSlide+i.cloneOffset:i.currentSlide+i.cloneOffset,u&&!p?(i.container.height(200*(i.count+i.cloneCount)+"%").css("position","absolute").width("100%"),setTimeout(function(){i.newSlides.css({display:"block"}),i.doMath(),i.viewport.height(i.h),i.setProps(a*i.h,"init")},"init"===t?100:0)):(i.container.width(200*(i.count+i.cloneCount)+"%"),i.setProps(a*i.computedW,"init"),setTimeout(function(){i.doMath(),i.newSlides.css({width:i.computedW,marginRight:i.computedM,float:"left",display:"block"}),i.vars.smoothHeight&&g.smoothHeight()},"init"===t?100:0)));p||i.slides.removeClass(r+"active-slide").eq(i.currentSlide).addClass(r+"active-slide"),i.vars.init(i)},i.doMath=function(){var e=i.slides.first(),t=i.vars.itemMargin,a=i.vars.minItems,n=i.vars.maxItems;i.w=void 0===i.viewport?i.width():i.viewport.width(),i.h=e.height(),i.boxPadding=e.outerWidth()-e.width(),p?(i.itemT=i.vars.itemWidth+t,i.itemM=t,i.minW=a?a*i.itemT:i.w,i.maxW=n?n*i.itemT-t:i.w,i.itemW=i.minW>i.w?(i.w-t*(a-1))/a:i.maxW<i.w?(i.w-t*(n-1))/n:i.vars.itemWidth>i.w?i.w:i.vars.itemWidth,i.visible=Math.floor(i.w/i.itemW),i.move=i.vars.move>0&&i.vars.move<i.visible?i.vars.move:i.visible,i.pagingCount=Math.ceil((i.count-i.visible)/i.move+1),i.last=i.pagingCount-1,i.limit=1===i.pagingCount?0:i.vars.itemWidth>i.w?i.itemW*(i.count-1)+t*(i.count-1):(i.itemW+t)*i.count-i.w-t):(i.itemW=i.w,i.itemM=t,i.pagingCount=i.count,i.last=i.count-1),i.computedW=i.itemW-i.boxPadding,i.computedM=i.itemM},i.update=function(e,t){i.doMath(),p||(e<i.currentSlide?i.currentSlide+=1:e<=i.currentSlide&&0!==e&&(i.currentSlide-=1),i.animatingTo=i.currentSlide),i.vars.controlNav&&!i.manualControls&&("add"===t&&!p||i.pagingCount>i.controlNav.length?g.controlNav.update("add"):("remove"===t&&!p||i.pagingCount<i.controlNav.length)&&(p&&i.currentSlide>i.last&&(i.currentSlide-=1,i.animatingTo-=1),g.controlNav.update("remove",i.last))),i.vars.directionNav&&g.directionNav.update()},i.addSlide=function(t,a){var n=e(t);i.count+=1,i.last=i.count-1,u&&v?void 0!==a?i.slides.eq(i.count-a).after(n):i.container.prepend(n):void 0!==a?i.slides.eq(a).before(n):i.container.append(n),i.update(a,"add"),i.slides=e(i.vars.selector+":not(.clone)",i),i.setup(),i.vars.added(i)},i.removeSlide=function(t){var a=isNaN(t)?i.slides.index(e(t)):t;i.count-=1,i.last=i.count-1,isNaN(t)?e(t,i.slides).remove():u&&v?i.slides.eq(i.last).remove():i.slides.eq(t).remove(),i.doMath(),i.update(a,"remove"),i.slides=e(i.vars.selector+":not(.clone)",i),i.setup(),i.vars.removed(i)},g.init()},e(window).blur(function(e){t=!1}).focus(function(e){t=!0}),e.flexslider.defaults={namespace:"flex-",selector:".slides > li",animation:"fade",easing:"swing",direction:"horizontal",reverse:!1,animationLoop:!0,smoothHeight:!1,startAt:0,slideshow:!0,slideshowSpeed:7e3,animationSpeed:600,initDelay:0,randomize:!1,fadeFirstSlide:!0,thumbCaptions:!1,pauseOnAction:!0,pauseOnHover:!1,pauseInvisible:!0,useCSS:!0,touch:!0,video:!1,controlNav:!0,directionNav:!0,prevText:"Previous",nextText:"Next",keyboard:!0,multipleKeyboard:!1,mousewheel:!1,pausePlay:!1,pauseText:"Pause",playText:"Play",controlsContainer:"",manualControls:"",customDirectionNav:"",sync:"",asNavFor:"",itemWidth:0,itemMargin:0,minItems:1,maxItems:0,move:0,allowOneSlide:!0,start:function(){},before:function(){},after:function(){},end:function(){},added:function(){},removed:function(){},init:function(){}},e.fn.flexslider=function(t){if(void 0===t&&(t={}),"object"==typeof t)return this.each(function(){var a=e(this),n=t.selector?t.selector:".slides > li",i=a.find(n);1===i.length&&!0===t.allowOneSlide||0===i.length?(i.fadeIn(400),t.start&&t.start(a)):void 0===a.data("flexslider")&&new e.flexslider(this,t)});var a=e(this).data("flexslider");switch(t){case"play":a.play();break;case"pause":a.pause();break;case"stop":a.stop();break;case"next":a.flexAnimate(a.getTarget("next"),!0);break;case"prev":case"previous":a.flexAnimate(a.getTarget("prev"),!0);break;default:"number"==typeof t&&a.flexAnimate(t,!0)}}}(jQuery); 2; 3!function(a){"use strict";var b=function(){var b=a(".dd-fullwidth");b.closest('div[class^="col-"]').css("position","static");var c=Math.floor((a("body").width()-a(".dd-ve-container").first().width())/2);b.each(function(){a(this).css("margin","0 -"+c+"px"),a(this).find(".dd-hero-box, .dd-image-box").length||a(this).css("padding","0 "+c+"px")})};a(".dd-boxed-container").length||a(window).on("load",b).on("resize",b),a(".dd-tabs .tab-select").change(function(){var b=a(this).closest(".dd-tabs");a(".nav a",b).eq(a("option:selected",this).index()).tab("show")});var c=a(".dd-hero-fixed");c.length&&(a(window).height()>a(".dd-hero-inner",c).height()?c.height(a(window).height()):c.height(a(".dd-hero-inner",c).height()));var d=a(".dd-image-box.dd-image-lightbox");if(d.length){var e={other:[]},f={other:0};d.each(function(){var b={src:a(this).data("original-image"),w:a(this).data("image-width"),h:a(this).data("image-height")};a("a",this).attr("title")&&(b.title=a("a",this).attr("title")),b.el=this;var c=a(this).data("gallery-id");c?(void 0===e[c]&&(e[c]=[],f[c]=0),e[c].push(b)):e.other.push(b)});var g={index:0,history:!1,mainClass:"pswp--minimal--dark",barsSize:{top:0,bottom:0},fullscreenEl:!1,shareEl:!1,bgOpacity:.85,tapToClose:!0,tapToToggleControls:!1};d.each(function(){var b=a(this).data("gallery-id")||"other";a("a",this).data("image-index",f[b]).on("click",function(c){c.preventDefault(),g.index=a(this).data("image-index"),g.getThumbBoundsFn=function(c){var d=a("img",e[b][c].el)[0],f=window.pageYOffset||document.documentElement.scrollTop,g=d.getBoundingClientRect();return{x:g.left,y:g.top+f,w:g.width,h:g.height}},new PhotoSwipe(a(".pswp")[0],PhotoSwipeUI_Default,e[b],g).init()}),f[b]++})}}(jQuery); 4//# sourceMappingURL=scripts.min.js.map 5;
vendor: 8,327 bytes, lines 5-261
5 6(function (global, factory) { 7 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 8 typeof define === 'function' && define.amd ? define(factory) : 9 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory()); 10})(this, (function () { 'use strict'; 11 12 /** 13 * -------------------------------------------------------------------------- 14 * Bootstrap dom/data.js 15 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 16 * -------------------------------------------------------------------------- 17 */ 18 19 /** 20 * Constants 21 */ 22 23 const elementMap = new Map(); 24 const Data = { 25 set(element, key, instance) { 26 if (!elementMap.has(element)) { 27 elementMap.set(element, new Map()); 28 } 29 const instanceMap = elementMap.get(element); 30 31 // make it clear we only want one instance per element 32 // can be removed later when multiple key/instances are fine to be used 33 if (!instanceMap.has(key) && instanceMap.size !== 0) { 34 // eslint-disable-next-line no-console 35 console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`); 36 return; 37 } 38 instanceMap.set(key, instance); 39 }, 40 get(element, key) { 41 if (elementMap.has(element)) { 42 return elementMap.get(element).get(key) || null; 43 } 44 return null; 45 }, 46 remove(element, key) { 47 if (!elementMap.has(element)) { 48 return; 49 } 50 const instanceMap = elementMap.get(element); 51 instanceMap.delete(key); 52 53 // free up element references if there are no instances left for an element 54 if (instanceMap.size === 0) { 55 elementMap.delete(element); 56 } 57 } 58 }; 59 60 /** 61 * -------------------------------------------------------------------------- 62 * Bootstrap util/index.js 63 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 64 * -------------------------------------------------------------------------- 65 */ 66 67 const MAX_UID = 1000000; 68 const MILLISECONDS_MULTIPLIER = 1000; 69 const TRANSITION_END = 'transitionend'; 70 71 /** 72 * Properly escape IDs selectors to handle weird IDs 73 * @param {string} selector 74 * @returns {string} 75 */ 76 const parseSelector = selector => { 77 if (selector && window.CSS && window.CSS.escape) { 78 // document.querySelector needs escaping to handle IDs (html5+) containing for instance / 79 selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`); 80 } 81 return selector; 82 }; 83 84 // Shout-out Angus Croll (https://goo.gl/pxwQGp) 85 const toType = object => { 86 if (object === null || object === undefined) { 87 return `${object}`; 88 } 89 return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase(); 90 }; 91 92 /** 93 * Public Util API 94 */ 95 96 const getUID = prefix => { 97 do { 98 prefix += Math.floor(Math.random() * MAX_UID); 99 } while (document.getElementById(prefix)); 100 return prefix; 101 }; 102 const getTransitionDurationFromElement = element => { 103 if (!element) { 104 return 0; 105 } 106 107 // Get transition-duration of the element 108 let { 109 transitionDuration, 110 transitionDelay 111 } = window.getComputedStyle(element); 112 const floatTransitionDuration = Number.parseFloat(transitionDuration); 113 const floatTransitionDelay = Number.parseFloat(transitionDelay); 114 115 // Return 0 if element or transition duration is not found 116 if (!floatTransitionDuration && !floatTransitionDelay) { 117 return 0; 118 } 119 120 // If multiple durations are defined, take the first 121 transitionDuration = transitionDuration.split(',')[0]; 122 transitionDelay = transitionDelay.split(',')[0]; 123 return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; 124 }; 125 const triggerTransitionEnd = element => { 126 element.dispatchEvent(new Event(TRANSITION_END)); 127 }; 128 const isElement$1 = object => { 129 if (!object || typeof object !== 'object') { 130 return false; 131 } 132 if (typeof object.jquery !== 'undefined') { 133 object = object[0]; 134 } 135 return typeof object.nodeType !== 'undefined'; 136 }; 137 const getElement = object => { 138 // it's a jQuery object or a node element 139 if (isElement$1(object)) { 140 return object.jquery ? object[0] : object; 141 } 142 if (typeof object === 'string' && object.length > 0) { 143 return document.querySelector(parseSelector(object)); 144 } 145 return null; 146 }; 147 const isVisible = element => { 148 if (!isElement$1(element) || element.getClientRects().length === 0) { 149 return false; 150 } 151 const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'; 152 // Handle `details` element as its content may falsie appear visible when it is closed 153 const closedDetails = element.closest('details:not([open])'); 154 if (!closedDetails) { 155 return elementIsVisible; 156 } 157 if (closedDetails !== element) { 158 const summary = element.closest('summary'); 159 if (summary && summary.parentNode !== closedDetails) { 160 return false; 161 } 162 if (summary === null) { 163 return false; 164 } 165 } 166 return elementIsVisible; 167 }; 168 const isDisabled = element => { 169 if (!element || element.nodeType !== Node.ELEMENT_NODE) { 170 return true; 171 } 172 if (element.classList.contains('disabled')) { 173 return true; 174 } 175 if (typeof element.disabled !== 'undefined') { 176 return element.disabled; 177 } 178 return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'; 179 }; 180 const findShadowRoot = element => { 181 if (!document.documentElement.attachShadow) { 182 return null; 183 } 184 185 // Can find the shadow root otherwise it'll return the document 186 if (typeof element.getRootNode === 'function') { 187 const root = element.getRootNode(); 188 return root instanceof ShadowRoot ? root : null; 189 } 190 if (element instanceof ShadowRoot) { 191 return element; 192 } 193 194 // when we don't find a shadow root 195 if (!element.parentNode) { 196 return null; 197 } 198 return findShadowRoot(element.parentNode); 199 }; 200 const noop = () => {}; 201 202 /** 203 * Trick to restart an element's animation 204 * 205 * @param {HTMLElement} element 206 * @return void 207 * 208 * @see https://www.harrytheo.com/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation 209 */ 210 const reflow = element => { 211 element.offsetHeight; // eslint-disable-line no-unused-expressions 212 }; 213 const getjQuery = () => { 214 if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) { 215 return window.jQuery; 216 } 217 return null; 218 }; 219 const DOMContentLoadedCallbacks = []; 220 const onDOMContentLoaded = callback => { 221 if (document.readyState === 'loading') { 222 // add listener on the first call when the document is in loading state 223 if (!DOMContentLoadedCallbacks.length) { 224 document.addEventListener('DOMContentLoaded', () => { 225 for (const callback of DOMContentLoadedCallbacks) { 226 callback(); 227 } 228 }); 229 } 230 DOMContentLoadedCallbacks.push(callback); 231 } else { 232 callback(); 233 } 234 }; 235 const isRTL = () => document.documentElement.dir === 'rtl'; 236 const defineJQueryPlugin = plugin => { 237 onDOMContentLoaded(() => { 238 const $ = getjQuery(); 239 /* istanbul ignore if */ 240 if ($) { 241 const name = plugin.NAME; 242 const JQUERY_NO_CONFLICT = $.fn[name]; 243 $.fn[name] = plugin.jQueryInterface; 244 $.fn[name].Constructor = plugin; 245 $.fn[name].noConflict = () => { 246 $.fn[name] = JQUERY_NO_CONFLICT; 247 return plugin.jQueryInterface; 248 }; 249 } 250 }); 251 }; 252 const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => { 253 return typeof possibleCallback === 'function' ? possibleCallback.call(...args) : defaultValue; 254 }; 255 const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => { 256 if (!waitForTransition) { 257 execute(callback); 258 return; 259 } 260 const durationPadding = 5; 261 const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
vendor: 9,815 bytes, lines 262-513
262 let called = false; 263 const handler = ({ 264 target 265 }) => { 266 if (target !== transitionElement) { 267 return; 268 } 269 called = true; 270 transitionElement.removeEventListener(TRANSITION_END, handler); 271 execute(callback); 272 }; 273 transitionElement.addEventListener(TRANSITION_END, handler); 274 setTimeout(() => { 275 if (!called) { 276 triggerTransitionEnd(transitionElement); 277 } 278 }, emulatedDuration); 279 }; 280 281 /** 282 * Return the previous/next element of a list. 283 * 284 * @param {array} list The list of elements 285 * @param activeElement The active element 286 * @param shouldGetNext Choose to get next or previous element 287 * @param isCycleAllowed 288 * @return {Element|elem} The proper element 289 */ 290 const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => { 291 const listLength = list.length; 292 let index = list.indexOf(activeElement); 293 294 // if the element does not exist in the list return an element 295 // depending on the direction and if cycle is allowed 296 if (index === -1) { 297 return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]; 298 } 299 index += shouldGetNext ? 1 : -1; 300 if (isCycleAllowed) { 301 index = (index + listLength) % listLength; 302 } 303 return list[Math.max(0, Math.min(index, listLength - 1))]; 304 }; 305 306 /** 307 * -------------------------------------------------------------------------- 308 * Bootstrap dom/event-handler.js 309 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 310 * -------------------------------------------------------------------------- 311 */ 312 313 314 /** 315 * Constants 316 */ 317 318 const namespaceRegex = /[^.]*(?=\..*)\.|.*/; 319 const stripNameRegex = /\..*/; 320 const stripUidRegex = /::\d+$/; 321 const eventRegistry = {}; // Events storage 322 let uidEvent = 1; 323 const customEvents = { 324 mouseenter: 'mouseover', 325 mouseleave: 'mouseout' 326 }; 327 const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']); 328 329 /** 330 * Private methods 331 */ 332 333 function makeEventUid(element, uid) { 334 return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++; 335 } 336 function getElementEvents(element) { 337 const uid = makeEventUid(element); 338 element.uidEvent = uid; 339 eventRegistry[uid] = eventRegistry[uid] || {}; 340 return eventRegistry[uid]; 341 } 342 function bootstrapHandler(element, fn) { 343 return function handler(event) { 344 hydrateObj(event, { 345 delegateTarget: element 346 }); 347 if (handler.oneOff) { 348 EventHandler.off(element, event.type, fn); 349 } 350 return fn.apply(element, [event]); 351 }; 352 } 353 function bootstrapDelegationHandler(element, selector, fn) { 354 return function handler(event) { 355 const domElements = element.querySelectorAll(selector); 356 for (let { 357 target 358 } = event; target && target !== this; target = target.parentNode) { 359 for (const domElement of domElements) { 360 if (domElement !== target) { 361 continue; 362 } 363 hydrateObj(event, { 364 delegateTarget: target 365 }); 366 if (handler.oneOff) { 367 EventHandler.off(element, event.type, selector, fn); 368 } 369 return fn.apply(target, [event]); 370 } 371 } 372 }; 373 } 374 function findHandler(events, callable, delegationSelector = null) { 375 return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector); 376 } 377 function normalizeParameters(originalTypeEvent, handler, delegationFunction) { 378 const isDelegated = typeof handler === 'string'; 379 // TODO: tooltip passes `false` instead of selector, so we need to check 380 const callable = isDelegated ? delegationFunction : handler || delegationFunction; 381 let typeEvent = getTypeEvent(originalTypeEvent); 382 if (!nativeEvents.has(typeEvent)) { 383 typeEvent = originalTypeEvent; 384 } 385 return [isDelegated, callable, typeEvent]; 386 } 387 function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) { 388 if (typeof originalTypeEvent !== 'string' || !element) { 389 return; 390 } 391 let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); 392 393 // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position 394 // this prevents the handler from being dispatched the same way as mouseover or mouseout does 395 if (originalTypeEvent in customEvents) { 396 const wrapFunction = fn => { 397 return function (event) { 398 if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) { 399 return fn.call(this, event); 400 } 401 }; 402 }; 403 callable = wrapFunction(callable); 404 } 405 const events = getElementEvents(element); 406 const handlers = events[typeEvent] || (events[typeEvent] = {}); 407 const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null); 408 if (previousFunction) { 409 previousFunction.oneOff = previousFunction.oneOff && oneOff; 410 return; 411 } 412 const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, '')); 413 const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable); 414 fn.delegationSelector = isDelegated ? handler : null; 415 fn.callable = callable; 416 fn.oneOff = oneOff; 417 fn.uidEvent = uid; 418 handlers[uid] = fn; 419 element.addEventListener(typeEvent, fn, isDelegated); 420 } 421 function removeHandler(element, events, typeEvent, handler, delegationSelector) { 422 const fn = findHandler(events[typeEvent], handler, delegationSelector); 423 if (!fn) { 424 return; 425 } 426 element.removeEventListener(typeEvent, fn, Boolean(delegationSelector)); 427 delete events[typeEvent][fn.uidEvent]; 428 } 429 function removeNamespacedHandlers(element, events, typeEvent, namespace) { 430 const storeElementEvent = events[typeEvent] || {}; 431 for (const [handlerKey, event] of Object.entries(storeElementEvent)) { 432 if (handlerKey.includes(namespace)) { 433 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); 434 } 435 } 436 } 437 function getTypeEvent(event) { 438 // allow to get the native events from namespaced events ('click.bs.button' --> 'click') 439 event = event.replace(stripNameRegex, ''); 440 return customEvents[event] || event; 441 } 442 const EventHandler = { 443 on(element, event, handler, delegationFunction) { 444 addHandler(element, event, handler, delegationFunction, false); 445 }, 446 one(element, event, handler, delegationFunction) { 447 addHandler(element, event, handler, delegationFunction, true); 448 }, 449 off(element, originalTypeEvent, handler, delegationFunction) { 450 if (typeof originalTypeEvent !== 'string' || !element) { 451 return; 452 } 453 const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); 454 const inNamespace = typeEvent !== originalTypeEvent; 455 const events = getElementEvents(element); 456 const storeElementEvent = events[typeEvent] || {}; 457 const isNamespace = originalTypeEvent.startsWith('.'); 458 if (typeof callable !== 'undefined') { 459 // Simplest case: handler is passed, remove that listener ONLY. 460 if (!Object.keys(storeElementEvent).length) { 461 return; 462 } 463 removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null); 464 return; 465 } 466 if (isNamespace) { 467 for (const elementEvent of Object.keys(events)) { 468 removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)); 469 } 470 } 471 for (const [keyHandlers, event] of Object.entries(storeElementEvent)) { 472 const handlerKey = keyHandlers.replace(stripUidRegex, ''); 473 if (!inNamespace || originalTypeEvent.includes(handlerKey)) { 474 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); 475 } 476 } 477 }, 478 trigger(element, event, args) { 479 if (typeof event !== 'string' || !element) { 480 return null; 481 } 482 const $ = getjQuery(); 483 const typeEvent = getTypeEvent(event); 484 const inNamespace = event !== typeEvent; 485 let jQueryEvent = null; 486 let bubbles = true; 487 let nativeDispatch = true; 488 let defaultPrevented = false; 489 if (inNamespace && $) { 490 jQueryEvent = $.Event(event, args); 491 $(element).trigger(jQueryEvent); 492 bubbles = !jQueryEvent.isPropagationStopped(); 493 nativeDispatch = !jQueryEvent.isImmediatePropagationStopped(); 494 defaultPrevented = jQueryEvent.isDefaultPrevented(); 495 } 496 const evt = hydrateObj(new Event(event, { 497 bubbles, 498 cancelable: true 499 }), args); 500 if (defaultPrevented) { 501 evt.preventDefault(); 502 } 503 if (nativeDispatch) { 504 element.dispatchEvent(evt); 505 } 506 if (evt.defaultPrevented && jQueryEvent) { 507 jQueryEvent.preventDefault(); 508 } 509 return evt; 510 } 511 }; 512 function hydrateObj(obj, meta = {}) { 513 for (const [key, value] of Object.entries(meta)) {
vendor: 4,589 bytes, lines 514-671
514 try { 515 obj[key] = value; 516 } catch (_unused) { 517 Object.defineProperty(obj, key, { 518 configurable: true, 519 get() { 520 return value; 521 } 522 }); 523 } 524 } 525 return obj; 526 } 527 528 /** 529 * -------------------------------------------------------------------------- 530 * Bootstrap dom/manipulator.js 531 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 532 * -------------------------------------------------------------------------- 533 */ 534 535 function normalizeData(value) { 536 if (value === 'true') { 537 return true; 538 } 539 if (value === 'false') { 540 return false; 541 } 542 if (value === Number(value).toString()) { 543 return Number(value); 544 } 545 if (value === '' || value === 'null') { 546 return null; 547 } 548 if (typeof value !== 'string') { 549 return value; 550 } 551 try { 552 return JSON.parse(decodeURIComponent(value)); 553 } catch (_unused) { 554 return value; 555 } 556 } 557 function normalizeDataKey(key) { 558 return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`); 559 } 560 const Manipulator = { 561 setDataAttribute(element, key, value) { 562 element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value); 563 }, 564 removeDataAttribute(element, key) { 565 element.removeAttribute(`data-bs-${normalizeDataKey(key)}`); 566 }, 567 getDataAttributes(element) { 568 if (!element) { 569 return {}; 570 } 571 const attributes = {}; 572 const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig')); 573 for (const key of bsKeys) { 574 let pureKey = key.replace(/^bs/, ''); 575 pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1); 576 attributes[pureKey] = normalizeData(element.dataset[key]); 577 } 578 return attributes; 579 }, 580 getDataAttribute(element, key) { 581 return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)); 582 } 583 }; 584 585 /** 586 * -------------------------------------------------------------------------- 587 * Bootstrap util/config.js 588 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 589 * -------------------------------------------------------------------------- 590 */ 591 592 593 /** 594 * Class definition 595 */ 596 597 class Config { 598 // Getters 599 static get Default() { 600 return {}; 601 } 602 static get DefaultType() { 603 return {}; 604 } 605 static get NAME() { 606 throw new Error('You have to implement the static method "NAME", for each component!'); 607 } 608 _getConfig(config) { 609 config = this._mergeConfigObj(config); 610 config = this._configAfterMerge(config); 611 this._typeCheckConfig(config); 612 return config; 613 } 614 _configAfterMerge(config) { 615 return config; 616 } 617 _mergeConfigObj(config, element) { 618 const jsonConfig = isElement$1(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse 619 620 return { 621 ...this.constructor.Default, 622 ...(typeof jsonConfig === 'object' ? jsonConfig : {}), 623 ...(isElement$1(element) ? Manipulator.getDataAttributes(element) : {}), 624 ...(typeof config === 'object' ? config : {}) 625 }; 626 } 627 _typeCheckConfig(config, configTypes = this.constructor.DefaultType) { 628 for (const [property, expectedTypes] of Object.entries(configTypes)) { 629 const value = config[property]; 630 const valueType = isElement$1(value) ? 'element' : toType(value); 631 if (!new RegExp(expectedTypes).test(valueType)) { 632 throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`); 633 } 634 } 635 } 636 } 637 638 /** 639 * -------------------------------------------------------------------------- 640 * Bootstrap base-component.js 641 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 642 * -------------------------------------------------------------------------- 643 */ 644 645 646 /** 647 * Constants 648 */ 649 650 const VERSION = '5.3.8'; 651 652 /** 653 * Class definition 654 */ 655 656 class BaseComponent extends Config { 657 constructor(element, config) { 658 super(); 659 element = getElement(element); 660 if (!element) { 661 return; 662 } 663 this._element = element; 664 this._config = this._getConfig(config); 665 Data.set(this._element, this.constructor.DATA_KEY, this); 666 } 667 668 // Public 669 dispose() { 670 Data.remove(this._element, this.constructor.DATA_KEY); 671 EventHandler.off(this._element, this.constructor.EVENT_KEY);
vendor: 29,739 bytes, lines 672-1601
672 for (const propertyName of Object.getOwnPropertyNames(this)) { 673 this[propertyName] = null; 674 } 675 } 676 677 // Private 678 _queueCallback(callback, element, isAnimated = true) { 679 executeAfterTransition(callback, element, isAnimated); 680 } 681 _getConfig(config) { 682 config = this._mergeConfigObj(config, this._element); 683 config = this._configAfterMerge(config); 684 this._typeCheckConfig(config); 685 return config; 686 } 687 688 // Static 689 static getInstance(element) { 690 return Data.get(getElement(element), this.DATA_KEY); 691 } 692 static getOrCreateInstance(element, config = {}) { 693 return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null); 694 } 695 static get VERSION() { 696 return VERSION; 697 } 698 static get DATA_KEY() { 699 return `bs.${this.NAME}`; 700 } 701 static get EVENT_KEY() { 702 return `.${this.DATA_KEY}`; 703 } 704 static eventName(name) { 705 return `${name}${this.EVENT_KEY}`; 706 } 707 } 708 709 /** 710 * -------------------------------------------------------------------------- 711 * Bootstrap dom/selector-engine.js 712 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 713 * -------------------------------------------------------------------------- 714 */ 715 716 const getSelector = element => { 717 let selector = element.getAttribute('data-bs-target'); 718 if (!selector || selector === '#') { 719 let hrefAttribute = element.getAttribute('href'); 720 721 // The only valid content that could double as a selector are IDs or classes, 722 // so everything starting with `#` or `.`. If a "real" URL is used as the selector, 723 // `document.querySelector` will rightfully complain it is invalid. 724 // See https://github.com/twbs/bootstrap/issues/32273 725 if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) { 726 return null; 727 } 728 729 // Just in case some CMS puts out a full URL with the anchor appended 730 if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) { 731 hrefAttribute = `#${hrefAttribute.split('#')[1]}`; 732 } 733 selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null; 734 } 735 return selector ? selector.split(',').map(sel => parseSelector(sel)).join(',') : null; 736 }; 737 const SelectorEngine = { 738 find(selector, element = document.documentElement) { 739 return [].concat(...Element.prototype.querySelectorAll.call(element, selector)); 740 }, 741 findOne(selector, element = document.documentElement) { 742 return Element.prototype.querySelector.call(element, selector); 743 }, 744 children(element, selector) { 745 return [].concat(...element.children).filter(child => child.matches(selector)); 746 }, 747 parents(element, selector) { 748 const parents = []; 749 let ancestor = element.parentNode.closest(selector); 750 while (ancestor) { 751 parents.push(ancestor); 752 ancestor = ancestor.parentNode.closest(selector); 753 } 754 return parents; 755 }, 756 prev(element, selector) { 757 let previous = element.previousElementSibling; 758 while (previous) { 759 if (previous.matches(selector)) { 760 return [previous]; 761 } 762 previous = previous.previousElementSibling; 763 } 764 return []; 765 }, 766 // TODO: this is now unused; remove later along with prev() 767 next(element, selector) { 768 let next = element.nextElementSibling; 769 while (next) { 770 if (next.matches(selector)) { 771 return [next]; 772 } 773 next = next.nextElementSibling; 774 } 775 return []; 776 }, 777 focusableChildren(element) { 778 const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(','); 779 return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el)); 780 }, 781 getSelectorFromElement(element) { 782 const selector = getSelector(element); 783 if (selector) { 784 return SelectorEngine.findOne(selector) ? selector : null; 785 } 786 return null; 787 }, 788 getElementFromSelector(element) { 789 const selector = getSelector(element); 790 return selector ? SelectorEngine.findOne(selector) : null; 791 }, 792 getMultipleElementsFromSelector(element) { 793 const selector = getSelector(element); 794 return selector ? SelectorEngine.find(selector) : []; 795 } 796 }; 797 798 /** 799 * -------------------------------------------------------------------------- 800 * Bootstrap util/component-functions.js 801 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 802 * -------------------------------------------------------------------------- 803 */ 804 805 const enableDismissTrigger = (component, method = 'hide') => { 806 const clickEvent = `click.dismiss${component.EVENT_KEY}`; 807 const name = component.NAME; 808 EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) { 809 if (['A', 'AREA'].includes(this.tagName)) { 810 event.preventDefault(); 811 } 812 if (isDisabled(this)) { 813 return; 814 } 815 const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`); 816 const instance = component.getOrCreateInstance(target); 817 818 // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method 819 instance[method](); 820 }); 821 }; 822 823 /** 824 * -------------------------------------------------------------------------- 825 * Bootstrap alert.js 826 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 827 * -------------------------------------------------------------------------- 828 */ 829 830 831 /** 832 * Constants 833 */ 834 835 const NAME$f = 'alert'; 836 const DATA_KEY$a = 'bs.alert'; 837 const EVENT_KEY$b = `.${DATA_KEY$a}`; 838 const EVENT_CLOSE = `close${EVENT_KEY$b}`; 839 const EVENT_CLOSED = `closed${EVENT_KEY$b}`; 840 const CLASS_NAME_FADE$5 = 'fade'; 841 const CLASS_NAME_SHOW$8 = 'show'; 842 843 /** 844 * Class definition 845 */ 846 847 class Alert extends BaseComponent { 848 // Getters 849 static get NAME() { 850 return NAME$f; 851 } 852 853 // Public 854 close() { 855 const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE); 856 if (closeEvent.defaultPrevented) { 857 return; 858 } 859 this._element.classList.remove(CLASS_NAME_SHOW$8); 860 const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5); 861 this._queueCallback(() => this._destroyElement(), this._element, isAnimated); 862 } 863 864 // Private 865 _destroyElement() { 866 this._element.remove(); 867 EventHandler.trigger(this._element, EVENT_CLOSED); 868 this.dispose(); 869 } 870 871 // Static 872 static jQueryInterface(config) { 873 return this.each(function () { 874 const data = Alert.getOrCreateInstance(this); 875 if (typeof config !== 'string') { 876 return; 877 } 878 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 879 throw new TypeError(`No method named "${config}"`); 880 } 881 data[config](this); 882 }); 883 } 884 } 885 886 /** 887 * Data API implementation 888 */ 889 890 enableDismissTrigger(Alert, 'close'); 891 892 /** 893 * jQuery 894 */ 895 896 defineJQueryPlugin(Alert); 897 898 /** 899 * -------------------------------------------------------------------------- 900 * Bootstrap button.js 901 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 902 * -------------------------------------------------------------------------- 903 */ 904 905 906 /** 907 * Constants 908 */ 909 910 const NAME$e = 'button'; 911 const DATA_KEY$9 = 'bs.button'; 912 const EVENT_KEY$a = `.${DATA_KEY$9}`; 913 const DATA_API_KEY$6 = '.data-api'; 914 const CLASS_NAME_ACTIVE$3 = 'active'; 915 const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle="button"]'; 916 const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`; 917 918 /** 919 * Class definition 920 */ 921 922 class Button extends BaseComponent { 923 // Getters 924 static get NAME() { 925 return NAME$e; 926 } 927 928 // Public 929 toggle() { 930 // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method 931 this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3)); 932 } 933 934 // Static 935 static jQueryInterface(config) { 936 return this.each(function () { 937 const data = Button.getOrCreateInstance(this); 938 if (config === 'toggle') { 939 data[config](); 940 } 941 }); 942 } 943 } 944 945 /** 946 * Data API implementation 947 */ 948 949 EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => { 950 event.preventDefault(); 951 const button = event.target.closest(SELECTOR_DATA_TOGGLE$5); 952 const data = Button.getOrCreateInstance(button); 953 data.toggle(); 954 }); 955 956 /** 957 * jQuery 958 */ 959 960 defineJQueryPlugin(Button); 961 962 /** 963 * -------------------------------------------------------------------------- 964 * Bootstrap util/swipe.js 965 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 966 * -------------------------------------------------------------------------- 967 */ 968 969 970 /** 971 * Constants 972 */ 973 974 const NAME$d = 'swipe'; 975 const EVENT_KEY$9 = '.bs.swipe'; 976 const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`; 977 const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`; 978 const EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`; 979 const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`; 980 const EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`; 981 const POINTER_TYPE_TOUCH = 'touch'; 982 const POINTER_TYPE_PEN = 'pen'; 983 const CLASS_NAME_POINTER_EVENT = 'pointer-event'; 984 const SWIPE_THRESHOLD = 40; 985 const Default$c = { 986 endCallback: null, 987 leftCallback: null, 988 rightCallback: null 989 }; 990 const DefaultType$c = { 991 endCallback: '(function|null)', 992 leftCallback: '(function|null)', 993 rightCallback: '(function|null)' 994 }; 995 996 /** 997 * Class definition 998 */ 999 1000 class Swipe extends Config { 1001 constructor(element, config) { 1002 super(); 1003 this._element = element; 1004 if (!element || !Swipe.isSupported()) { 1005 return; 1006 } 1007 this._config = this._getConfig(config); 1008 this._deltaX = 0; 1009 this._supportPointerEvents = Boolean(window.PointerEvent); 1010 this._initEvents(); 1011 } 1012 1013 // Getters 1014 static get Default() { 1015 return Default$c; 1016 } 1017 static get DefaultType() { 1018 return DefaultType$c; 1019 } 1020 static get NAME() { 1021 return NAME$d; 1022 } 1023 1024 // Public 1025 dispose() { 1026 EventHandler.off(this._element, EVENT_KEY$9); 1027 } 1028 1029 // Private 1030 _start(event) { 1031 if (!this._supportPointerEvents) { 1032 this._deltaX = event.touches[0].clientX; 1033 return; 1034 } 1035 if (this._eventIsPointerPenTouch(event)) { 1036 this._deltaX = event.clientX; 1037 } 1038 } 1039 _end(event) { 1040 if (this._eventIsPointerPenTouch(event)) { 1041 this._deltaX = event.clientX - this._deltaX; 1042 } 1043 this._handleSwipe(); 1044 execute(this._config.endCallback); 1045 } 1046 _move(event) { 1047 this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX; 1048 } 1049 _handleSwipe() { 1050 const absDeltaX = Math.abs(this._deltaX); 1051 if (absDeltaX <= SWIPE_THRESHOLD) { 1052 return; 1053 } 1054 const direction = absDeltaX / this._deltaX; 1055 this._deltaX = 0; 1056 if (!direction) { 1057 return; 1058 } 1059 execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback); 1060 } 1061 _initEvents() { 1062 if (this._supportPointerEvents) { 1063 EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event)); 1064 EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event)); 1065 this._element.classList.add(CLASS_NAME_POINTER_EVENT); 1066 } else { 1067 EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event)); 1068 EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event)); 1069 EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event)); 1070 } 1071 } 1072 _eventIsPointerPenTouch(event) { 1073 return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH); 1074 } 1075 1076 // Static 1077 static isSupported() { 1078 return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0; 1079 } 1080 } 1081 1082 /** 1083 * -------------------------------------------------------------------------- 1084 * Bootstrap carousel.js 1085 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 1086 * -------------------------------------------------------------------------- 1087 */ 1088 1089 1090 /** 1091 * Constants 1092 */ 1093 1094 const NAME$c = 'carousel'; 1095 const DATA_KEY$8 = 'bs.carousel'; 1096 const EVENT_KEY$8 = `.${DATA_KEY$8}`; 1097 const DATA_API_KEY$5 = '.data-api'; 1098 const ARROW_LEFT_KEY$1 = 'ArrowLeft'; 1099 const ARROW_RIGHT_KEY$1 = 'ArrowRight'; 1100 const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch 1101 1102 const ORDER_NEXT = 'next'; 1103 const ORDER_PREV = 'prev'; 1104 const DIRECTION_LEFT = 'left'; 1105 const DIRECTION_RIGHT = 'right'; 1106 const EVENT_SLIDE = `slide${EVENT_KEY$8}`; 1107 const EVENT_SLID = `slid${EVENT_KEY$8}`; 1108 const EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`; 1109 const EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`; 1110 const EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`; 1111 const EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`; 1112 const EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`; 1113 const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`; 1114 const CLASS_NAME_CAROUSEL = 'carousel'; 1115 const CLASS_NAME_ACTIVE$2 = 'active'; 1116 const CLASS_NAME_SLIDE = 'slide'; 1117 const CLASS_NAME_END = 'carousel-item-end'; 1118 const CLASS_NAME_START = 'carousel-item-start'; 1119 const CLASS_NAME_NEXT = 'carousel-item-next'; 1120 const CLASS_NAME_PREV = 'carousel-item-prev'; 1121 const SELECTOR_ACTIVE = '.active'; 1122 const SELECTOR_ITEM = '.carousel-item'; 1123 const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM; 1124 const SELECTOR_ITEM_IMG = '.carousel-item img'; 1125 const SELECTOR_INDICATORS = '.carousel-indicators'; 1126 const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'; 1127 const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'; 1128 const KEY_TO_DIRECTION = { 1129 [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT, 1130 [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT 1131 }; 1132 const Default$b = { 1133 interval: 5000, 1134 keyboard: true, 1135 pause: 'hover', 1136 ride: false, 1137 touch: true, 1138 wrap: true 1139 }; 1140 const DefaultType$b = { 1141 interval: '(number|boolean)', 1142 // TODO:v6 remove boolean support 1143 keyboard: 'boolean', 1144 pause: '(string|boolean)', 1145 ride: '(boolean|string)', 1146 touch: 'boolean', 1147 wrap: 'boolean' 1148 }; 1149 1150 /** 1151 * Class definition 1152 */ 1153 1154 class Carousel extends BaseComponent { 1155 constructor(element, config) { 1156 super(element, config); 1157 this._interval = null; 1158 this._activeElement = null; 1159 this._isSliding = false; 1160 this.touchTimeout = null; 1161 this._swipeHelper = null; 1162 this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element); 1163 this._addEventListeners(); 1164 if (this._config.ride === CLASS_NAME_CAROUSEL) { 1165 this.cycle(); 1166 } 1167 } 1168 1169 // Getters 1170 static get Default() { 1171 return Default$b; 1172 } 1173 static get DefaultType() { 1174 return DefaultType$b; 1175 } 1176 static get NAME() { 1177 return NAME$c; 1178 } 1179 1180 // Public 1181 next() { 1182 this._slide(ORDER_NEXT); 1183 } 1184 nextWhenVisible() { 1185 // FIXME TODO use `document.visibilityState` 1186 // Don't call next when the page isn't visible 1187 // or the carousel or its parent isn't visible 1188 if (!document.hidden && isVisible(this._element)) { 1189 this.next(); 1190 } 1191 } 1192 prev() { 1193 this._slide(ORDER_PREV); 1194 } 1195 pause() { 1196 if (this._isSliding) { 1197 triggerTransitionEnd(this._element); 1198 } 1199 this._clearInterval(); 1200 } 1201 cycle() { 1202 this._clearInterval(); 1203 this._updateInterval(); 1204 this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval); 1205 } 1206 _maybeEnableCycle() { 1207 if (!this._config.ride) { 1208 return; 1209 } 1210 if (this._isSliding) { 1211 EventHandler.one(this._element, EVENT_SLID, () => this.cycle()); 1212 return; 1213 } 1214 this.cycle(); 1215 } 1216 to(index) { 1217 const items = this._getItems(); 1218 if (index > items.length - 1 || index < 0) { 1219 return; 1220 } 1221 if (this._isSliding) { 1222 EventHandler.one(this._element, EVENT_SLID, () => this.to(index)); 1223 return; 1224 } 1225 const activeIndex = this._getItemIndex(this._getActive()); 1226 if (activeIndex === index) { 1227 return; 1228 } 1229 const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV; 1230 this._slide(order, items[index]); 1231 } 1232 dispose() { 1233 if (this._swipeHelper) { 1234 this._swipeHelper.dispose(); 1235 } 1236 super.dispose(); 1237 } 1238 1239 // Private 1240 _configAfterMerge(config) { 1241 config.defaultInterval = config.interval; 1242 return config; 1243 } 1244 _addEventListeners() { 1245 if (this._config.keyboard) { 1246 EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event)); 1247 } 1248 if (this._config.pause === 'hover') { 1249 EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause()); 1250 EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle()); 1251 } 1252 if (this._config.touch && Swipe.isSupported()) { 1253 this._addTouchEventListeners(); 1254 } 1255 } 1256 _addTouchEventListeners() { 1257 for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) { 1258 EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault()); 1259 } 1260 const endCallBack = () => { 1261 if (this._config.pause !== 'hover') { 1262 return; 1263 } 1264 1265 // If it's a touch-enabled device, mouseenter/leave are fired as 1266 // part of the mouse compatibility events on first tap - the carousel 1267 // would stop cycling until user tapped out of it; 1268 // here, we listen for touchend, explicitly pause the carousel 1269 // (as if it's the second time we tap on it, mouseenter compat event 1270 // is NOT fired) and after a timeout (to allow for mouse compatibility 1271 // events to fire) we explicitly restart cycling 1272 1273 this.pause(); 1274 if (this.touchTimeout) { 1275 clearTimeout(this.touchTimeout); 1276 } 1277 this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval); 1278 }; 1279 const swipeConfig = { 1280 leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)), 1281 rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)), 1282 endCallback: endCallBack 1283 }; 1284 this._swipeHelper = new Swipe(this._element, swipeConfig); 1285 } 1286 _keydown(event) { 1287 if (/input|textarea/i.test(event.target.tagName)) { 1288 return; 1289 } 1290 const direction = KEY_TO_DIRECTION[event.key]; 1291 if (direction) { 1292 event.preventDefault(); 1293 this._slide(this._directionToOrder(direction)); 1294 } 1295 } 1296 _getItemIndex(element) { 1297 return this._getItems().indexOf(element); 1298 } 1299 _setActiveIndicatorElement(index) { 1300 if (!this._indicatorsElement) { 1301 return; 1302 } 1303 const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement); 1304 activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2); 1305 activeIndicator.removeAttribute('aria-current'); 1306 const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement); 1307 if (newActiveIndicator) { 1308 newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2); 1309 newActiveIndicator.setAttribute('aria-current', 'true'); 1310 } 1311 } 1312 _updateInterval() { 1313 const element = this._activeElement || this._getActive(); 1314 if (!element) { 1315 return; 1316 } 1317 const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10); 1318 this._config.interval = elementInterval || this._config.defaultInterval; 1319 } 1320 _slide(order, element = null) { 1321 if (this._isSliding) { 1322 return; 1323 } 1324 const activeElement = this._getActive(); 1325 const isNext = order === ORDER_NEXT; 1326 const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap); 1327 if (nextElement === activeElement) { 1328 return; 1329 } 1330 const nextElementIndex = this._getItemIndex(nextElement); 1331 const triggerEvent = eventName => { 1332 return EventHandler.trigger(this._element, eventName, { 1333 relatedTarget: nextElement, 1334 direction: this._orderToDirection(order), 1335 from: this._getItemIndex(activeElement), 1336 to: nextElementIndex 1337 }); 1338 }; 1339 const slideEvent = triggerEvent(EVENT_SLIDE); 1340 if (slideEvent.defaultPrevented) { 1341 return; 1342 } 1343 if (!activeElement || !nextElement) { 1344 // Some weirdness is happening, so we bail 1345 // TODO: change tests that use empty divs to avoid this check 1346 return; 1347 } 1348 const isCycling = Boolean(this._interval); 1349 this.pause(); 1350 this._isSliding = true; 1351 this._setActiveIndicatorElement(nextElementIndex); 1352 this._activeElement = nextElement; 1353 const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END; 1354 const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV; 1355 nextElement.classList.add(orderClassName); 1356 reflow(nextElement); 1357 activeElement.classList.add(directionalClassName); 1358 nextElement.classList.add(directionalClassName); 1359 const completeCallBack = () => { 1360 nextElement.classList.remove(directionalClassName, orderClassName); 1361 nextElement.classList.add(CLASS_NAME_ACTIVE$2); 1362 activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName); 1363 this._isSliding = false; 1364 triggerEvent(EVENT_SLID); 1365 }; 1366 this._queueCallback(completeCallBack, activeElement, this._isAnimated()); 1367 if (isCycling) { 1368 this.cycle(); 1369 } 1370 } 1371 _isAnimated() { 1372 return this._element.classList.contains(CLASS_NAME_SLIDE); 1373 } 1374 _getActive() { 1375 return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); 1376 } 1377 _getItems() { 1378 return SelectorEngine.find(SELECTOR_ITEM, this._element); 1379 } 1380 _clearInterval() { 1381 if (this._interval) { 1382 clearInterval(this._interval); 1383 this._interval = null; 1384 } 1385 } 1386 _directionToOrder(direction) { 1387 if (isRTL()) { 1388 return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT; 1389 } 1390 return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV; 1391 } 1392 _orderToDirection(order) { 1393 if (isRTL()) { 1394 return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT; 1395 } 1396 return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT; 1397 } 1398 1399 // Static 1400 static jQueryInterface(config) { 1401 return this.each(function () { 1402 const data = Carousel.getOrCreateInstance(this, config); 1403 if (typeof config === 'number') { 1404 data.to(config); 1405 return; 1406 } 1407 if (typeof config === 'string') { 1408 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 1409 throw new TypeError(`No method named "${config}"`); 1410 } 1411 data[config](); 1412 } 1413 }); 1414 } 1415 } 1416 1417 /** 1418 * Data API implementation 1419 */ 1420 1421 EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) { 1422 const target = SelectorEngine.getElementFromSelector(this); 1423 if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { 1424 return; 1425 } 1426 event.preventDefault(); 1427 const carousel = Carousel.getOrCreateInstance(target); 1428 const slideIndex = this.getAttribute('data-bs-slide-to'); 1429 if (slideIndex) { 1430 carousel.to(slideIndex); 1431 carousel._maybeEnableCycle(); 1432 return; 1433 } 1434 if (Manipulator.getDataAttribute(this, 'slide') === 'next') { 1435 carousel.next(); 1436 carousel._maybeEnableCycle(); 1437 return; 1438 } 1439 carousel.prev(); 1440 carousel._maybeEnableCycle(); 1441 }); 1442 EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => { 1443 const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE); 1444 for (const carousel of carousels) { 1445 Carousel.getOrCreateInstance(carousel); 1446 } 1447 }); 1448 1449 /** 1450 * jQuery 1451 */ 1452 1453 defineJQueryPlugin(Carousel); 1454 1455 /** 1456 * -------------------------------------------------------------------------- 1457 * Bootstrap collapse.js 1458 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 1459 * -------------------------------------------------------------------------- 1460 */ 1461 1462 1463 /** 1464 * Constants 1465 */ 1466 1467 const NAME$b = 'collapse'; 1468 const DATA_KEY$7 = 'bs.collapse'; 1469 const EVENT_KEY$7 = `.${DATA_KEY$7}`; 1470 const DATA_API_KEY$4 = '.data-api'; 1471 const EVENT_SHOW$6 = `show${EVENT_KEY$7}`; 1472 const EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`; 1473 const EVENT_HIDE$6 = `hide${EVENT_KEY$7}`; 1474 const EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`; 1475 const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`; 1476 const CLASS_NAME_SHOW$7 = 'show'; 1477 const CLASS_NAME_COLLAPSE = 'collapse'; 1478 const CLASS_NAME_COLLAPSING = 'collapsing'; 1479 const CLASS_NAME_COLLAPSED = 'collapsed'; 1480 const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`; 1481 const CLASS_NAME_HORIZONTAL = 'collapse-horizontal'; 1482 const WIDTH = 'width'; 1483 const HEIGHT = 'height'; 1484 const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'; 1485 const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle="collapse"]'; 1486 const Default$a = { 1487 parent: null, 1488 toggle: true 1489 }; 1490 const DefaultType$a = { 1491 parent: '(null|element)', 1492 toggle: 'boolean' 1493 }; 1494 1495 /** 1496 * Class definition 1497 */ 1498 1499 class Collapse extends BaseComponent { 1500 constructor(element, config) { 1501 super(element, config); 1502 this._isTransitioning = false; 1503 this._triggerArray = []; 1504 const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4); 1505 for (const elem of toggleList) { 1506 const selector = SelectorEngine.getSelectorFromElement(elem); 1507 const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element); 1508 if (selector !== null && filterElement.length) { 1509 this._triggerArray.push(elem); 1510 } 1511 } 1512 this._initializeChildren(); 1513 if (!this._config.parent) { 1514 this._addAriaAndCollapsedClass(this._triggerArray, this._isShown()); 1515 } 1516 if (this._config.toggle) { 1517 this.toggle(); 1518 } 1519 } 1520 1521 // Getters 1522 static get Default() { 1523 return Default$a; 1524 } 1525 static get DefaultType() { 1526 return DefaultType$a; 1527 } 1528 static get NAME() { 1529 return NAME$b; 1530 } 1531 1532 // Public 1533 toggle() { 1534 if (this._isShown()) { 1535 this.hide(); 1536 } else { 1537 this.show(); 1538 } 1539 } 1540 show() { 1541 if (this._isTransitioning || this._isShown()) { 1542 return; 1543 } 1544 let activeChildren = []; 1545 1546 // find active children 1547 if (this._config.parent) { 1548 activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, { 1549 toggle: false 1550 })); 1551 } 1552 if (activeChildren.length && activeChildren[0]._isTransitioning) { 1553 return; 1554 } 1555 const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6); 1556 if (startEvent.defaultPrevented) { 1557 return; 1558 } 1559 for (const activeInstance of activeChildren) { 1560 activeInstance.hide(); 1561 } 1562 const dimension = this._getDimension(); 1563 this._element.classList.remove(CLASS_NAME_COLLAPSE); 1564 this._element.classList.add(CLASS_NAME_COLLAPSING); 1565 this._element.style[dimension] = 0; 1566 this._addAriaAndCollapsedClass(this._triggerArray, true); 1567 this._isTransitioning = true; 1568 const complete = () => { 1569 this._isTransitioning = false; 1570 this._element.classList.remove(CLASS_NAME_COLLAPSING); 1571 this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7); 1572 this._element.style[dimension] = ''; 1573 EventHandler.trigger(this._element, EVENT_SHOWN$6); 1574 }; 1575 const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); 1576 const scrollSize = `scroll${capitalizedDimension}`; 1577 this._queueCallback(complete, this._element, true); 1578 this._element.style[dimension] = `${this._element[scrollSize]}px`; 1579 } 1580 hide() { 1581 if (this._isTransitioning || !this._isShown()) { 1582 return; 1583 } 1584 const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6); 1585 if (startEvent.defaultPrevented) { 1586 return; 1587 } 1588 const dimension = this._getDimension(); 1589 this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`; 1590 reflow(this._element); 1591 this._element.classList.add(CLASS_NAME_COLLAPSING); 1592 this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7); 1593 for (const trigger of this._triggerArray) { 1594 const element = SelectorEngine.getElementFromSelector(trigger); 1595 if (element && !this._isShown(element)) { 1596 this._addAriaAndCollapsedClass([trigger], false); 1597 } 1598 } 1599 this._isTransitioning = true; 1600 const complete = () => { 1601 this._isTransitioning = false;
vendor: 4,876 bytes, lines 1602-1751
1602 this._element.classList.remove(CLASS_NAME_COLLAPSING); 1603 this._element.classList.add(CLASS_NAME_COLLAPSE); 1604 EventHandler.trigger(this._element, EVENT_HIDDEN$6); 1605 }; 1606 this._element.style[dimension] = ''; 1607 this._queueCallback(complete, this._element, true); 1608 } 1609 1610 // Private 1611 _isShown(element = this._element) { 1612 return element.classList.contains(CLASS_NAME_SHOW$7); 1613 } 1614 _configAfterMerge(config) { 1615 config.toggle = Boolean(config.toggle); // Coerce string values 1616 config.parent = getElement(config.parent); 1617 return config; 1618 } 1619 _getDimension() { 1620 return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT; 1621 } 1622 _initializeChildren() { 1623 if (!this._config.parent) { 1624 return; 1625 } 1626 const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4); 1627 for (const element of children) { 1628 const selected = SelectorEngine.getElementFromSelector(element); 1629 if (selected) { 1630 this._addAriaAndCollapsedClass([element], this._isShown(selected)); 1631 } 1632 } 1633 } 1634 _getFirstLevelChildren(selector) { 1635 const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent); 1636 // remove children if greater depth 1637 return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element)); 1638 } 1639 _addAriaAndCollapsedClass(triggerArray, isOpen) { 1640 if (!triggerArray.length) { 1641 return; 1642 } 1643 for (const element of triggerArray) { 1644 element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen); 1645 element.setAttribute('aria-expanded', isOpen); 1646 } 1647 } 1648 1649 // Static 1650 static jQueryInterface(config) { 1651 const _config = {}; 1652 if (typeof config === 'string' && /show|hide/.test(config)) { 1653 _config.toggle = false; 1654 } 1655 return this.each(function () { 1656 const data = Collapse.getOrCreateInstance(this, _config); 1657 if (typeof config === 'string') { 1658 if (typeof data[config] === 'undefined') { 1659 throw new TypeError(`No method named "${config}"`); 1660 } 1661 data[config](); 1662 } 1663 }); 1664 } 1665 } 1666 1667 /** 1668 * Data API implementation 1669 */ 1670 1671 EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) { 1672 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element 1673 if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') { 1674 event.preventDefault(); 1675 } 1676 for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) { 1677 Collapse.getOrCreateInstance(element, { 1678 toggle: false 1679 }).toggle(); 1680 } 1681 }); 1682 1683 /** 1684 * jQuery 1685 */ 1686 1687 defineJQueryPlugin(Collapse); 1688 1689 var top = 'top'; 1690 var bottom = 'bottom'; 1691 var right = 'right'; 1692 var left = 'left'; 1693 var auto = 'auto'; 1694 var basePlacements = [top, bottom, right, left]; 1695 var start = 'start'; 1696 var end = 'end'; 1697 var clippingParents = 'clippingParents'; 1698 var viewport = 'viewport'; 1699 var popper = 'popper'; 1700 var reference = 'reference'; 1701 var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) { 1702 return acc.concat([placement + "-" + start, placement + "-" + end]); 1703 }, []); 1704 var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) { 1705 return acc.concat([placement, placement + "-" + start, placement + "-" + end]); 1706 }, []); // modifiers that need to read the DOM 1707 1708 var beforeRead = 'beforeRead'; 1709 var read = 'read'; 1710 var afterRead = 'afterRead'; // pure-logic modifiers 1711 1712 var beforeMain = 'beforeMain'; 1713 var main = 'main'; 1714 var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state) 1715 1716 var beforeWrite = 'beforeWrite'; 1717 var write = 'write'; 1718 var afterWrite = 'afterWrite'; 1719 var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; 1720 1721 function getNodeName(element) { 1722 return element ? (element.nodeName || '').toLowerCase() : null; 1723 } 1724 1725 function getWindow(node) { 1726 if (node == null) { 1727 return window; 1728 } 1729 1730 if (node.toString() !== '[object Window]') { 1731 var ownerDocument = node.ownerDocument; 1732 return ownerDocument ? ownerDocument.defaultView || window : window; 1733 } 1734 1735 return node; 1736 } 1737 1738 function isElement(node) { 1739 var OwnElement = getWindow(node).Element; 1740 return node instanceof OwnElement || node instanceof Element; 1741 } 1742 1743 function isHTMLElement(node) { 1744 var OwnElement = getWindow(node).HTMLElement; 1745 return node instanceof OwnElement || node instanceof HTMLElement; 1746 } 1747 1748 function isShadowRoot(node) { 1749 // IE 11 has no ShadowRoot 1750 if (typeof ShadowRoot === 'undefined') { 1751 return false;
vendor: 26,262 bytes, lines 1752-2557
1752 } 1753 1754 var OwnElement = getWindow(node).ShadowRoot; 1755 return node instanceof OwnElement || node instanceof ShadowRoot; 1756 } 1757 1758 // and applies them to the HTMLElements such as popper and arrow 1759 1760 function applyStyles(_ref) { 1761 var state = _ref.state; 1762 Object.keys(state.elements).forEach(function (name) { 1763 var style = state.styles[name] || {}; 1764 var attributes = state.attributes[name] || {}; 1765 var element = state.elements[name]; // arrow is optional + virtual elements 1766 1767 if (!isHTMLElement(element) || !getNodeName(element)) { 1768 return; 1769 } // Flow doesn't support to extend this property, but it's the most 1770 // effective way to apply styles to an HTMLElement 1771 // $FlowFixMe[cannot-write] 1772 1773 1774 Object.assign(element.style, style); 1775 Object.keys(attributes).forEach(function (name) { 1776 var value = attributes[name]; 1777 1778 if (value === false) { 1779 element.removeAttribute(name); 1780 } else { 1781 element.setAttribute(name, value === true ? '' : value); 1782 } 1783 }); 1784 }); 1785 } 1786 1787 function effect$2(_ref2) { 1788 var state = _ref2.state; 1789 var initialStyles = { 1790 popper: { 1791 position: state.options.strategy, 1792 left: '0', 1793 top: '0', 1794 margin: '0' 1795 }, 1796 arrow: { 1797 position: 'absolute' 1798 }, 1799 reference: {} 1800 }; 1801 Object.assign(state.elements.popper.style, initialStyles.popper); 1802 state.styles = initialStyles; 1803 1804 if (state.elements.arrow) { 1805 Object.assign(state.elements.arrow.style, initialStyles.arrow); 1806 } 1807 1808 return function () { 1809 Object.keys(state.elements).forEach(function (name) { 1810 var element = state.elements[name]; 1811 var attributes = state.attributes[name] || {}; 1812 var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them 1813 1814 var style = styleProperties.reduce(function (style, property) { 1815 style[property] = ''; 1816 return style; 1817 }, {}); // arrow is optional + virtual elements 1818 1819 if (!isHTMLElement(element) || !getNodeName(element)) { 1820 return; 1821 } 1822 1823 Object.assign(element.style, style); 1824 Object.keys(attributes).forEach(function (attribute) { 1825 element.removeAttribute(attribute); 1826 }); 1827 }); 1828 }; 1829 } // eslint-disable-next-line import/no-unused-modules 1830 1831 1832 const applyStyles$1 = { 1833 name: 'applyStyles', 1834 enabled: true, 1835 phase: 'write', 1836 fn: applyStyles, 1837 effect: effect$2, 1838 requires: ['computeStyles'] 1839 }; 1840 1841 function getBasePlacement(placement) { 1842 return placement.split('-')[0]; 1843 } 1844 1845 var max = Math.max; 1846 var min = Math.min; 1847 var round = Math.round; 1848 1849 function getUAString() { 1850 var uaData = navigator.userAgentData; 1851 1852 if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) { 1853 return uaData.brands.map(function (item) { 1854 return item.brand + "/" + item.version; 1855 }).join(' '); 1856 } 1857 1858 return navigator.userAgent; 1859 } 1860 1861 function isLayoutViewport() { 1862 return !/^((?!chrome|android).)*safari/i.test(getUAString()); 1863 } 1864 1865 function getBoundingClientRect(element, includeScale, isFixedStrategy) { 1866 if (includeScale === void 0) { 1867 includeScale = false; 1868 } 1869 1870 if (isFixedStrategy === void 0) { 1871 isFixedStrategy = false; 1872 } 1873 1874 var clientRect = element.getBoundingClientRect(); 1875 var scaleX = 1; 1876 var scaleY = 1; 1877 1878 if (includeScale && isHTMLElement(element)) { 1879 scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1; 1880 scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1; 1881 } 1882 1883 var _ref = isElement(element) ? getWindow(element) : window, 1884 visualViewport = _ref.visualViewport; 1885 1886 var addVisualOffsets = !isLayoutViewport() && isFixedStrategy; 1887 var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX; 1888 var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY; 1889 var width = clientRect.width / scaleX; 1890 var height = clientRect.height / scaleY; 1891 return { 1892 width: width, 1893 height: height, 1894 top: y, 1895 right: x + width, 1896 bottom: y + height, 1897 left: x, 1898 x: x, 1899 y: y 1900 }; 1901 } 1902 1903 // means it doesn't take into account transforms. 1904 1905 function getLayoutRect(element) { 1906 var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed. 1907 // Fixes https://github.com/popperjs/popper-core/issues/1223 1908 1909 var width = element.offsetWidth; 1910 var height = element.offsetHeight; 1911 1912 if (Math.abs(clientRect.width - width) <= 1) { 1913 width = clientRect.width; 1914 } 1915 1916 if (Math.abs(clientRect.height - height) <= 1) { 1917 height = clientRect.height; 1918 } 1919 1920 return { 1921 x: element.offsetLeft, 1922 y: element.offsetTop, 1923 width: width, 1924 height: height 1925 }; 1926 } 1927 1928 function contains(parent, child) { 1929 var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method 1930 1931 if (parent.contains(child)) { 1932 return true; 1933 } // then fallback to custom implementation with Shadow DOM support 1934 else if (rootNode && isShadowRoot(rootNode)) { 1935 var next = child; 1936 1937 do { 1938 if (next && parent.isSameNode(next)) { 1939 return true; 1940 } // $FlowFixMe[prop-missing]: need a better way to handle this... 1941 1942 1943 next = next.parentNode || next.host; 1944 } while (next); 1945 } // Give up, the result is false 1946 1947 1948 return false; 1949 } 1950 1951 function getComputedStyle$1(element) { 1952 return getWindow(element).getComputedStyle(element); 1953 } 1954 1955 function isTableElement(element) { 1956 return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0; 1957 } 1958 1959 function getDocumentElement(element) { 1960 // $FlowFixMe[incompatible-return]: assume body is always available 1961 return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing] 1962 element.document) || window.document).documentElement; 1963 } 1964 1965 function getParentNode(element) { 1966 if (getNodeName(element) === 'html') { 1967 return element; 1968 } 1969 1970 return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle 1971 // $FlowFixMe[incompatible-return] 1972 // $FlowFixMe[prop-missing] 1973 element.assignedSlot || // step into the shadow DOM of the parent of a slotted node 1974 element.parentNode || ( // DOM Element detected 1975 isShadowRoot(element) ? element.host : null) || // ShadowRoot detected 1976 // $FlowFixMe[incompatible-call]: HTMLElement is a Node 1977 getDocumentElement(element) // fallback 1978 1979 ); 1980 } 1981 1982 function getTrueOffsetParent(element) { 1983 if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 1984 getComputedStyle$1(element).position === 'fixed') { 1985 return null; 1986 } 1987 1988 return element.offsetParent; 1989 } // `.offsetParent` reports `null` for fixed elements, while absolute elements 1990 // return the containing block 1991 1992 1993 function getContainingBlock(element) { 1994 var isFirefox = /firefox/i.test(getUAString()); 1995 var isIE = /Trident/i.test(getUAString()); 1996 1997 if (isIE && isHTMLElement(element)) { 1998 // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport 1999 var elementCss = getComputedStyle$1(element); 2000 2001 if (elementCss.position === 'fixed') { 2002 return null; 2003 } 2004 } 2005 2006 var currentNode = getParentNode(element); 2007 2008 if (isShadowRoot(currentNode)) { 2009 currentNode = currentNode.host; 2010 } 2011 2012 while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) { 2013 var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that 2014 // create a containing block. 2015 // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block 2016 2017 if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') { 2018 return currentNode; 2019 } else { 2020 currentNode = currentNode.parentNode; 2021 } 2022 } 2023 2024 return null; 2025 } // Gets the closest ancestor positioned element. Handles some edge cases, 2026 // such as table ancestors and cross browser bugs. 2027 2028 2029 function getOffsetParent(element) { 2030 var window = getWindow(element); 2031 var offsetParent = getTrueOffsetParent(element); 2032 2033 while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') { 2034 offsetParent = getTrueOffsetParent(offsetParent); 2035 } 2036 2037 if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static')) { 2038 return window; 2039 } 2040 2041 return offsetParent || getContainingBlock(element) || window; 2042 } 2043 2044 function getMainAxisFromPlacement(placement) { 2045 return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y'; 2046 } 2047 2048 function within(min$1, value, max$1) { 2049 return max(min$1, min(value, max$1)); 2050 } 2051 function withinMaxClamp(min, value, max) { 2052 var v = within(min, value, max); 2053 return v > max ? max : v; 2054 } 2055 2056 function getFreshSideObject() { 2057 return { 2058 top: 0, 2059 right: 0, 2060 bottom: 0, 2061 left: 0 2062 }; 2063 } 2064 2065 function mergePaddingObject(paddingObject) { 2066 return Object.assign({}, getFreshSideObject(), paddingObject); 2067 } 2068 2069 function expandToHashMap(value, keys) { 2070 return keys.reduce(function (hashMap, key) { 2071 hashMap[key] = value; 2072 return hashMap; 2073 }, {}); 2074 } 2075 2076 var toPaddingObject = function toPaddingObject(padding, state) { 2077 padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, { 2078 placement: state.placement 2079 })) : padding; 2080 return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); 2081 }; 2082 2083 function arrow(_ref) { 2084 var _state$modifiersData$; 2085 2086 var state = _ref.state, 2087 name = _ref.name, 2088 options = _ref.options; 2089 var arrowElement = state.elements.arrow; 2090 var popperOffsets = state.modifiersData.popperOffsets; 2091 var basePlacement = getBasePlacement(state.placement); 2092 var axis = getMainAxisFromPlacement(basePlacement); 2093 var isVertical = [left, right].indexOf(basePlacement) >= 0; 2094 var len = isVertical ? 'height' : 'width'; 2095 2096 if (!arrowElement || !popperOffsets) { 2097 return; 2098 } 2099 2100 var paddingObject = toPaddingObject(options.padding, state); 2101 var arrowRect = getLayoutRect(arrowElement); 2102 var minProp = axis === 'y' ? top : left; 2103 var maxProp = axis === 'y' ? bottom : right; 2104 var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len]; 2105 var startDiff = popperOffsets[axis] - state.rects.reference[axis]; 2106 var arrowOffsetParent = getOffsetParent(arrowElement); 2107 var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; 2108 var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is 2109 // outside of the popper bounds 2110 2111 var min = paddingObject[minProp]; 2112 var max = clientSize - arrowRect[len] - paddingObject[maxProp]; 2113 var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; 2114 var offset = within(min, center, max); // Prevents breaking syntax highlighting... 2115 2116 var axisProp = axis; 2117 state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$); 2118 } 2119 2120 function effect$1(_ref2) { 2121 var state = _ref2.state, 2122 options = _ref2.options; 2123 var _options$element = options.element, 2124 arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element; 2125 2126 if (arrowElement == null) { 2127 return; 2128 } // CSS selector 2129 2130 2131 if (typeof arrowElement === 'string') { 2132 arrowElement = state.elements.popper.querySelector(arrowElement); 2133 2134 if (!arrowElement) { 2135 return; 2136 } 2137 } 2138 2139 if (!contains(state.elements.popper, arrowElement)) { 2140 return; 2141 } 2142 2143 state.elements.arrow = arrowElement; 2144 } // eslint-disable-next-line import/no-unused-modules 2145 2146 2147 const arrow$1 = { 2148 name: 'arrow', 2149 enabled: true, 2150 phase: 'main', 2151 fn: arrow, 2152 effect: effect$1, 2153 requires: ['popperOffsets'], 2154 requiresIfExists: ['preventOverflow'] 2155 }; 2156 2157 function getVariation(placement) { 2158 return placement.split('-')[1]; 2159 } 2160 2161 var unsetSides = { 2162 top: 'auto', 2163 right: 'auto', 2164 bottom: 'auto', 2165 left: 'auto' 2166 }; // Round the offsets to the nearest suitable subpixel based on the DPR. 2167 // Zooming can change the DPR, but it seems to report a value that will 2168 // cleanly divide the values into the appropriate subpixels. 2169 2170 function roundOffsetsByDPR(_ref, win) { 2171 var x = _ref.x, 2172 y = _ref.y; 2173 var dpr = win.devicePixelRatio || 1; 2174 return { 2175 x: round(x * dpr) / dpr || 0, 2176 y: round(y * dpr) / dpr || 0 2177 }; 2178 } 2179 2180 function mapToStyles(_ref2) { 2181 var _Object$assign2; 2182 2183 var popper = _ref2.popper, 2184 popperRect = _ref2.popperRect, 2185 placement = _ref2.placement, 2186 variation = _ref2.variation, 2187 offsets = _ref2.offsets, 2188 position = _ref2.position, 2189 gpuAcceleration = _ref2.gpuAcceleration, 2190 adaptive = _ref2.adaptive, 2191 roundOffsets = _ref2.roundOffsets, 2192 isFixed = _ref2.isFixed; 2193 var _offsets$x = offsets.x, 2194 x = _offsets$x === void 0 ? 0 : _offsets$x, 2195 _offsets$y = offsets.y, 2196 y = _offsets$y === void 0 ? 0 : _offsets$y; 2197 2198 var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({ 2199 x: x, 2200 y: y 2201 }) : { 2202 x: x, 2203 y: y 2204 }; 2205 2206 x = _ref3.x; 2207 y = _ref3.y; 2208 var hasX = offsets.hasOwnProperty('x'); 2209 var hasY = offsets.hasOwnProperty('y'); 2210 var sideX = left; 2211 var sideY = top; 2212 var win = window; 2213 2214 if (adaptive) { 2215 var offsetParent = getOffsetParent(popper); 2216 var heightProp = 'clientHeight'; 2217 var widthProp = 'clientWidth'; 2218 2219 if (offsetParent === getWindow(popper)) { 2220 offsetParent = getDocumentElement(popper); 2221 2222 if (getComputedStyle$1(offsetParent).position !== 'static' && position === 'absolute') { 2223 heightProp = 'scrollHeight'; 2224 widthProp = 'scrollWidth'; 2225 } 2226 } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it 2227 2228 2229 offsetParent = offsetParent; 2230 2231 if (placement === top || (placement === left || placement === right) && variation === end) { 2232 sideY = bottom; 2233 var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing] 2234 offsetParent[heightProp]; 2235 y -= offsetY - popperRect.height; 2236 y *= gpuAcceleration ? 1 : -1; 2237 } 2238 2239 if (placement === left || (placement === top || placement === bottom) && variation === end) { 2240 sideX = right; 2241 var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing] 2242 offsetParent[widthProp]; 2243 x -= offsetX - popperRect.width; 2244 x *= gpuAcceleration ? 1 : -1; 2245 } 2246 } 2247 2248 var commonStyles = Object.assign({ 2249 position: position 2250 }, adaptive && unsetSides); 2251 2252 var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ 2253 x: x, 2254 y: y 2255 }, getWindow(popper)) : { 2256 x: x, 2257 y: y 2258 }; 2259 2260 x = _ref4.x; 2261 y = _ref4.y; 2262 2263 if (gpuAcceleration) { 2264 var _Object$assign; 2265 2266 return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); 2267 } 2268 2269 return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2)); 2270 } 2271 2272 function computeStyles(_ref5) { 2273 var state = _ref5.state, 2274 options = _ref5.options; 2275 var _options$gpuAccelerat = options.gpuAcceleration, 2276 gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, 2277 _options$adaptive = options.adaptive, 2278 adaptive = _options$adaptive === void 0 ? true : _options$adaptive, 2279 _options$roundOffsets = options.roundOffsets, 2280 roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; 2281 var commonStyles = { 2282 placement: getBasePlacement(state.placement), 2283 variation: getVariation(state.placement), 2284 popper: state.elements.popper, 2285 popperRect: state.rects.popper, 2286 gpuAcceleration: gpuAcceleration, 2287 isFixed: state.options.strategy === 'fixed' 2288 }; 2289 2290 if (state.modifiersData.popperOffsets != null) { 2291 state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { 2292 offsets: state.modifiersData.popperOffsets, 2293 position: state.options.strategy, 2294 adaptive: adaptive, 2295 roundOffsets: roundOffsets 2296 }))); 2297 } 2298 2299 if (state.modifiersData.arrow != null) { 2300 state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { 2301 offsets: state.modifiersData.arrow, 2302 position: 'absolute', 2303 adaptive: false, 2304 roundOffsets: roundOffsets 2305 }))); 2306 } 2307 2308 state.attributes.popper = Object.assign({}, state.attributes.popper, { 2309 'data-popper-placement': state.placement 2310 }); 2311 } // eslint-disable-next-line import/no-unused-modules 2312 2313 2314 const computeStyles$1 = { 2315 name: 'computeStyles', 2316 enabled: true, 2317 phase: 'beforeWrite', 2318 fn: computeStyles, 2319 data: {} 2320 }; 2321 2322 var passive = { 2323 passive: true 2324 }; 2325 2326 function effect(_ref) { 2327 var state = _ref.state, 2328 instance = _ref.instance, 2329 options = _ref.options; 2330 var _options$scroll = options.scroll, 2331 scroll = _options$scroll === void 0 ? true : _options$scroll, 2332 _options$resize = options.resize, 2333 resize = _options$resize === void 0 ? true : _options$resize; 2334 var window = getWindow(state.elements.popper); 2335 var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); 2336 2337 if (scroll) { 2338 scrollParents.forEach(function (scrollParent) { 2339 scrollParent.addEventListener('scroll', instance.update, passive); 2340 }); 2341 } 2342 2343 if (resize) { 2344 window.addEventListener('resize', instance.update, passive); 2345 } 2346 2347 return function () { 2348 if (scroll) { 2349 scrollParents.forEach(function (scrollParent) { 2350 scrollParent.removeEventListener('scroll', instance.update, passive); 2351 }); 2352 } 2353 2354 if (resize) { 2355 window.removeEventListener('resize', instance.update, passive); 2356 } 2357 }; 2358 } // eslint-disable-next-line import/no-unused-modules 2359 2360 2361 const eventListeners = { 2362 name: 'eventListeners', 2363 enabled: true, 2364 phase: 'write', 2365 fn: function fn() {}, 2366 effect: effect, 2367 data: {} 2368 }; 2369 2370 var hash$1 = { 2371 left: 'right', 2372 right: 'left', 2373 bottom: 'top', 2374 top: 'bottom' 2375 }; 2376 function getOppositePlacement(placement) { 2377 return placement.replace(/left|right|bottom|top/g, function (matched) { 2378 return hash$1[matched]; 2379 }); 2380 } 2381 2382 var hash = { 2383 start: 'end', 2384 end: 'start' 2385 }; 2386 function getOppositeVariationPlacement(placement) { 2387 return placement.replace(/start|end/g, function (matched) { 2388 return hash[matched]; 2389 }); 2390 } 2391 2392 function getWindowScroll(node) { 2393 var win = getWindow(node); 2394 var scrollLeft = win.pageXOffset; 2395 var scrollTop = win.pageYOffset; 2396 return { 2397 scrollLeft: scrollLeft, 2398 scrollTop: scrollTop 2399 }; 2400 } 2401 2402 function getWindowScrollBarX(element) { 2403 // If <html> has a CSS width greater than the viewport, then this will be 2404 // incorrect for RTL. 2405 // Popper 1 is broken in this case and never had a bug report so let's assume 2406 // it's not an issue. I don't think anyone ever specifies width on <html> 2407 // anyway. 2408 // Browsers where the left scrollbar doesn't cause an issue report `0` for 2409 // this (e.g. Edge 2019, IE11, Safari) 2410 return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; 2411 } 2412 2413 function getViewportRect(element, strategy) { 2414 var win = getWindow(element); 2415 var html = getDocumentElement(element); 2416 var visualViewport = win.visualViewport; 2417 var width = html.clientWidth; 2418 var height = html.clientHeight; 2419 var x = 0; 2420 var y = 0; 2421 2422 if (visualViewport) { 2423 width = visualViewport.width; 2424 height = visualViewport.height; 2425 var layoutViewport = isLayoutViewport(); 2426 2427 if (layoutViewport || !layoutViewport && strategy === 'fixed') { 2428 x = visualViewport.offsetLeft; 2429 y = visualViewport.offsetTop; 2430 } 2431 } 2432 2433 return { 2434 width: width, 2435 height: height, 2436 x: x + getWindowScrollBarX(element), 2437 y: y 2438 }; 2439 } 2440 2441 // of the `<html>` and `<body>` rect bounds if horizontally scrollable 2442 2443 function getDocumentRect(element) { 2444 var _element$ownerDocumen; 2445 2446 var html = getDocumentElement(element); 2447 var winScroll = getWindowScroll(element); 2448 var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; 2449 var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); 2450 var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); 2451 var x = -winScroll.scrollLeft + getWindowScrollBarX(element); 2452 var y = -winScroll.scrollTop; 2453 2454 if (getComputedStyle$1(body || html).direction === 'rtl') { 2455 x += max(html.clientWidth, body ? body.clientWidth : 0) - width; 2456 } 2457 2458 return { 2459 width: width, 2460 height: height, 2461 x: x, 2462 y: y 2463 }; 2464 } 2465 2466 function isScrollParent(element) { 2467 // Firefox wants us to check `-x` and `-y` variations as well 2468 var _getComputedStyle = getComputedStyle$1(element), 2469 overflow = _getComputedStyle.overflow, 2470 overflowX = _getComputedStyle.overflowX, 2471 overflowY = _getComputedStyle.overflowY; 2472 2473 return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); 2474 } 2475 2476 function getScrollParent(node) { 2477 if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) { 2478 // $FlowFixMe[incompatible-return]: assume body is always available 2479 return node.ownerDocument.body; 2480 } 2481 2482 if (isHTMLElement(node) && isScrollParent(node)) { 2483 return node; 2484 } 2485 2486 return getScrollParent(getParentNode(node)); 2487 } 2488 2489 /* 2490 given a DOM element, return the list of all scroll parents, up the list of ancesors 2491 until we get to the top window object. This list is what we attach scroll listeners 2492 to, because if any of these parent elements scroll, we'll need to re-calculate the 2493 reference element's position. 2494 */ 2495 2496 function listScrollParents(element, list) { 2497 var _element$ownerDocumen; 2498 2499 if (list === void 0) { 2500 list = []; 2501 } 2502 2503 var scrollParent = getScrollParent(element); 2504 var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); 2505 var win = getWindow(scrollParent); 2506 var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; 2507 var updatedList = list.concat(target); 2508 return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here 2509 updatedList.concat(listScrollParents(getParentNode(target))); 2510 } 2511 2512 function rectToClientRect(rect) { 2513 return Object.assign({}, rect, { 2514 left: rect.x, 2515 top: rect.y, 2516 right: rect.x + rect.width, 2517 bottom: rect.y + rect.height 2518 }); 2519 } 2520 2521 function getInnerBoundingClientRect(element, strategy) { 2522 var rect = getBoundingClientRect(element, false, strategy === 'fixed'); 2523 rect.top = rect.top + element.clientTop; 2524 rect.left = rect.left + element.clientLeft; 2525 rect.bottom = rect.top + element.clientHeight; 2526 rect.right = rect.left + element.clientWidth; 2527 rect.width = element.clientWidth; 2528 rect.height = element.clientHeight; 2529 rect.x = rect.left; 2530 rect.y = rect.top; 2531 return rect; 2532 } 2533 2534 function getClientRectFromMixedType(element, clippingParent, strategy) { 2535 return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element))); 2536 } // A "clipping parent" is an overflowable container with the characteristic of 2537 // clipping (or hiding) overflowing elements with a position different from 2538 // `initial` 2539 2540 2541 function getClippingParents(element) { 2542 var clippingParents = listScrollParents(getParentNode(element)); 2543 var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle$1(element).position) >= 0; 2544 var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; 2545 2546 if (!isElement(clipperElement)) { 2547 return []; 2548 } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414 2549 2550 2551 return clippingParents.filter(function (clippingParent) { 2552 return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body'; 2553 }); 2554 } // Gets the maximum area that the element is visible in due to any number of 2555 // clipping parents 2556 2557
vendor: 5,248 bytes, lines 2558-2686
2558 function getClippingRect(element, boundary, rootBoundary, strategy) { 2559 var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary); 2560 var clippingParents = [].concat(mainClippingParents, [rootBoundary]); 2561 var firstClippingParent = clippingParents[0]; 2562 var clippingRect = clippingParents.reduce(function (accRect, clippingParent) { 2563 var rect = getClientRectFromMixedType(element, clippingParent, strategy); 2564 accRect.top = max(rect.top, accRect.top); 2565 accRect.right = min(rect.right, accRect.right); 2566 accRect.bottom = min(rect.bottom, accRect.bottom); 2567 accRect.left = max(rect.left, accRect.left); 2568 return accRect; 2569 }, getClientRectFromMixedType(element, firstClippingParent, strategy)); 2570 clippingRect.width = clippingRect.right - clippingRect.left; 2571 clippingRect.height = clippingRect.bottom - clippingRect.top; 2572 clippingRect.x = clippingRect.left; 2573 clippingRect.y = clippingRect.top; 2574 return clippingRect; 2575 } 2576 2577 function computeOffsets(_ref) { 2578 var reference = _ref.reference, 2579 element = _ref.element, 2580 placement = _ref.placement; 2581 var basePlacement = placement ? getBasePlacement(placement) : null; 2582 var variation = placement ? getVariation(placement) : null; 2583 var commonX = reference.x + reference.width / 2 - element.width / 2; 2584 var commonY = reference.y + reference.height / 2 - element.height / 2; 2585 var offsets; 2586 2587 switch (basePlacement) { 2588 case top: 2589 offsets = { 2590 x: commonX, 2591 y: reference.y - element.height 2592 }; 2593 break; 2594 2595 case bottom: 2596 offsets = { 2597 x: commonX, 2598 y: reference.y + reference.height 2599 }; 2600 break; 2601 2602 case right: 2603 offsets = { 2604 x: reference.x + reference.width, 2605 y: commonY 2606 }; 2607 break; 2608 2609 case left: 2610 offsets = { 2611 x: reference.x - element.width, 2612 y: commonY 2613 }; 2614 break; 2615 2616 default: 2617 offsets = { 2618 x: reference.x, 2619 y: reference.y 2620 }; 2621 } 2622 2623 var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; 2624 2625 if (mainAxis != null) { 2626 var len = mainAxis === 'y' ? 'height' : 'width'; 2627 2628 switch (variation) { 2629 case start: 2630 offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2); 2631 break; 2632 2633 case end: 2634 offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2); 2635 break; 2636 } 2637 } 2638 2639 return offsets; 2640 } 2641 2642 function detectOverflow(state, options) { 2643 if (options === void 0) { 2644 options = {}; 2645 } 2646 2647 var _options = options, 2648 _options$placement = _options.placement, 2649 placement = _options$placement === void 0 ? state.placement : _options$placement, 2650 _options$strategy = _options.strategy, 2651 strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, 2652 _options$boundary = _options.boundary, 2653 boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, 2654 _options$rootBoundary = _options.rootBoundary, 2655 rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, 2656 _options$elementConte = _options.elementContext, 2657 elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, 2658 _options$altBoundary = _options.altBoundary, 2659 altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, 2660 _options$padding = _options.padding, 2661 padding = _options$padding === void 0 ? 0 : _options$padding; 2662 var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); 2663 var altContext = elementContext === popper ? reference : popper; 2664 var popperRect = state.rects.popper; 2665 var element = state.elements[altBoundary ? altContext : elementContext]; 2666 var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy); 2667 var referenceClientRect = getBoundingClientRect(state.elements.reference); 2668 var popperOffsets = computeOffsets({ 2669 reference: referenceClientRect, 2670 element: popperRect, 2671 placement: placement 2672 }); 2673 var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets)); 2674 var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect 2675 // 0 or negative = within the clipping rect 2676 2677 var overflowOffsets = { 2678 top: clippingClientRect.top - elementClientRect.top + paddingObject.top, 2679 bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, 2680 left: clippingClientRect.left - elementClientRect.left + paddingObject.left, 2681 right: elementClientRect.right - clippingClientRect.right + paddingObject.right 2682 }; 2683 var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element 2684 2685 if (elementContext === popper && offsetData) { 2686 var offset = offsetData[placement];
vendor: 4,315 bytes, lines 2687-2794
2687 Object.keys(overflowOffsets).forEach(function (key) { 2688 var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; 2689 var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x'; 2690 overflowOffsets[key] += offset[axis] * multiply; 2691 }); 2692 } 2693 2694 return overflowOffsets; 2695 } 2696 2697 function computeAutoPlacement(state, options) { 2698 if (options === void 0) { 2699 options = {}; 2700 } 2701 2702 var _options = options, 2703 placement = _options.placement, 2704 boundary = _options.boundary, 2705 rootBoundary = _options.rootBoundary, 2706 padding = _options.padding, 2707 flipVariations = _options.flipVariations, 2708 _options$allowedAutoP = _options.allowedAutoPlacements, 2709 allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; 2710 var variation = getVariation(placement); 2711 var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) { 2712 return getVariation(placement) === variation; 2713 }) : basePlacements; 2714 var allowedPlacements = placements$1.filter(function (placement) { 2715 return allowedAutoPlacements.indexOf(placement) >= 0; 2716 }); 2717 2718 if (allowedPlacements.length === 0) { 2719 allowedPlacements = placements$1; 2720 } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions... 2721 2722 2723 var overflows = allowedPlacements.reduce(function (acc, placement) { 2724 acc[placement] = detectOverflow(state, { 2725 placement: placement, 2726 boundary: boundary, 2727 rootBoundary: rootBoundary, 2728 padding: padding 2729 })[getBasePlacement(placement)]; 2730 return acc; 2731 }, {}); 2732 return Object.keys(overflows).sort(function (a, b) { 2733 return overflows[a] - overflows[b]; 2734 }); 2735 } 2736 2737 function getExpandedFallbackPlacements(placement) { 2738 if (getBasePlacement(placement) === auto) { 2739 return []; 2740 } 2741 2742 var oppositePlacement = getOppositePlacement(placement); 2743 return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; 2744 } 2745 2746 function flip(_ref) { 2747 var state = _ref.state, 2748 options = _ref.options, 2749 name = _ref.name; 2750 2751 if (state.modifiersData[name]._skip) { 2752 return; 2753 } 2754 2755 var _options$mainAxis = options.mainAxis, 2756 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, 2757 _options$altAxis = options.altAxis, 2758 checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, 2759 specifiedFallbackPlacements = options.fallbackPlacements, 2760 padding = options.padding, 2761 boundary = options.boundary, 2762 rootBoundary = options.rootBoundary, 2763 altBoundary = options.altBoundary, 2764 _options$flipVariatio = options.flipVariations, 2765 flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, 2766 allowedAutoPlacements = options.allowedAutoPlacements; 2767 var preferredPlacement = state.options.placement; 2768 var basePlacement = getBasePlacement(preferredPlacement); 2769 var isBasePlacement = basePlacement === preferredPlacement; 2770 var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); 2771 var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) { 2772 return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, { 2773 placement: placement, 2774 boundary: boundary, 2775 rootBoundary: rootBoundary, 2776 padding: padding, 2777 flipVariations: flipVariations, 2778 allowedAutoPlacements: allowedAutoPlacements 2779 }) : placement); 2780 }, []); 2781 var referenceRect = state.rects.reference; 2782 var popperRect = state.rects.popper; 2783 var checksMap = new Map(); 2784 var makeFallbackChecks = true; 2785 var firstFittingPlacement = placements[0]; 2786 2787 for (var i = 0; i < placements.length; i++) { 2788 var placement = placements[i]; 2789 2790 var _basePlacement = getBasePlacement(placement); 2791 2792 var isStartVariation = getVariation(placement) === start; 2793 var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; 2794 var len = isVertical ? 'width' : 'height';
vendor: 9,132 bytes, lines 2795-3083
2795 var overflow = detectOverflow(state, { 2796 placement: placement, 2797 boundary: boundary, 2798 rootBoundary: rootBoundary, 2799 altBoundary: altBoundary, 2800 padding: padding 2801 }); 2802 var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; 2803 2804 if (referenceRect[len] > popperRect[len]) { 2805 mainVariationSide = getOppositePlacement(mainVariationSide); 2806 } 2807 2808 var altVariationSide = getOppositePlacement(mainVariationSide); 2809 var checks = []; 2810 2811 if (checkMainAxis) { 2812 checks.push(overflow[_basePlacement] <= 0); 2813 } 2814 2815 if (checkAltAxis) { 2816 checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); 2817 } 2818 2819 if (checks.every(function (check) { 2820 return check; 2821 })) { 2822 firstFittingPlacement = placement; 2823 makeFallbackChecks = false; 2824 break; 2825 } 2826 2827 checksMap.set(placement, checks); 2828 } 2829 2830 if (makeFallbackChecks) { 2831 // `2` may be desired in some cases – research later 2832 var numberOfChecks = flipVariations ? 3 : 1; 2833 2834 var _loop = function _loop(_i) { 2835 var fittingPlacement = placements.find(function (placement) { 2836 var checks = checksMap.get(placement); 2837 2838 if (checks) { 2839 return checks.slice(0, _i).every(function (check) { 2840 return check; 2841 }); 2842 } 2843 }); 2844 2845 if (fittingPlacement) { 2846 firstFittingPlacement = fittingPlacement; 2847 return "break"; 2848 } 2849 }; 2850 2851 for (var _i = numberOfChecks; _i > 0; _i--) { 2852 var _ret = _loop(_i); 2853 2854 if (_ret === "break") break; 2855 } 2856 } 2857 2858 if (state.placement !== firstFittingPlacement) { 2859 state.modifiersData[name]._skip = true; 2860 state.placement = firstFittingPlacement; 2861 state.reset = true; 2862 } 2863 } // eslint-disable-next-line import/no-unused-modules 2864 2865 2866 const flip$1 = { 2867 name: 'flip', 2868 enabled: true, 2869 phase: 'main', 2870 fn: flip, 2871 requiresIfExists: ['offset'], 2872 data: { 2873 _skip: false 2874 } 2875 }; 2876 2877 function getSideOffsets(overflow, rect, preventedOffsets) { 2878 if (preventedOffsets === void 0) { 2879 preventedOffsets = { 2880 x: 0, 2881 y: 0 2882 }; 2883 } 2884 2885 return { 2886 top: overflow.top - rect.height - preventedOffsets.y, 2887 right: overflow.right - rect.width + preventedOffsets.x, 2888 bottom: overflow.bottom - rect.height + preventedOffsets.y, 2889 left: overflow.left - rect.width - preventedOffsets.x 2890 }; 2891 } 2892 2893 function isAnySideFullyClipped(overflow) { 2894 return [top, right, bottom, left].some(function (side) { 2895 return overflow[side] >= 0; 2896 }); 2897 } 2898 2899 function hide(_ref) { 2900 var state = _ref.state, 2901 name = _ref.name; 2902 var referenceRect = state.rects.reference; 2903 var popperRect = state.rects.popper; 2904 var preventedOffsets = state.modifiersData.preventOverflow; 2905 var referenceOverflow = detectOverflow(state, { 2906 elementContext: 'reference' 2907 }); 2908 var popperAltOverflow = detectOverflow(state, { 2909 altBoundary: true 2910 }); 2911 var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); 2912 var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); 2913 var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); 2914 var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); 2915 state.modifiersData[name] = { 2916 referenceClippingOffsets: referenceClippingOffsets, 2917 popperEscapeOffsets: popperEscapeOffsets, 2918 isReferenceHidden: isReferenceHidden, 2919 hasPopperEscaped: hasPopperEscaped 2920 }; 2921 state.attributes.popper = Object.assign({}, state.attributes.popper, { 2922 'data-popper-reference-hidden': isReferenceHidden, 2923 'data-popper-escaped': hasPopperEscaped 2924 }); 2925 } // eslint-disable-next-line import/no-unused-modules 2926 2927 2928 const hide$1 = { 2929 name: 'hide', 2930 enabled: true, 2931 phase: 'main', 2932 requiresIfExists: ['preventOverflow'], 2933 fn: hide 2934 }; 2935 2936 function distanceAndSkiddingToXY(placement, rects, offset) { 2937 var basePlacement = getBasePlacement(placement); 2938 var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; 2939 2940 var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, { 2941 placement: placement 2942 })) : offset, 2943 skidding = _ref[0], 2944 distance = _ref[1]; 2945 2946 skidding = skidding || 0; 2947 distance = (distance || 0) * invertDistance; 2948 return [left, right].indexOf(basePlacement) >= 0 ? { 2949 x: distance, 2950 y: skidding 2951 } : { 2952 x: skidding, 2953 y: distance 2954 }; 2955 } 2956 2957 function offset(_ref2) { 2958 var state = _ref2.state, 2959 options = _ref2.options, 2960 name = _ref2.name; 2961 var _options$offset = options.offset, 2962 offset = _options$offset === void 0 ? [0, 0] : _options$offset; 2963 var data = placements.reduce(function (acc, placement) { 2964 acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset); 2965 return acc; 2966 }, {}); 2967 var _data$state$placement = data[state.placement], 2968 x = _data$state$placement.x, 2969 y = _data$state$placement.y; 2970 2971 if (state.modifiersData.popperOffsets != null) { 2972 state.modifiersData.popperOffsets.x += x; 2973 state.modifiersData.popperOffsets.y += y; 2974 } 2975 2976 state.modifiersData[name] = data; 2977 } // eslint-disable-next-line import/no-unused-modules 2978 2979 2980 const offset$1 = { 2981 name: 'offset', 2982 enabled: true, 2983 phase: 'main', 2984 requires: ['popperOffsets'], 2985 fn: offset 2986 }; 2987 2988 function popperOffsets(_ref) { 2989 var state = _ref.state, 2990 name = _ref.name; 2991 // Offsets are the actual position the popper needs to have to be 2992 // properly positioned near its reference element 2993 // This is the most basic placement, and will be adjusted by 2994 // the modifiers in the next step 2995 state.modifiersData[name] = computeOffsets({ 2996 reference: state.rects.reference, 2997 element: state.rects.popper, 2998 placement: state.placement 2999 }); 3000 } // eslint-disable-next-line import/no-unused-modules 3001 3002 3003 const popperOffsets$1 = { 3004 name: 'popperOffsets', 3005 enabled: true, 3006 phase: 'read', 3007 fn: popperOffsets, 3008 data: {} 3009 }; 3010 3011 function getAltAxis(axis) { 3012 return axis === 'x' ? 'y' : 'x'; 3013 } 3014 3015 function preventOverflow(_ref) { 3016 var state = _ref.state, 3017 options = _ref.options, 3018 name = _ref.name; 3019 var _options$mainAxis = options.mainAxis, 3020 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, 3021 _options$altAxis = options.altAxis, 3022 checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, 3023 boundary = options.boundary, 3024 rootBoundary = options.rootBoundary, 3025 altBoundary = options.altBoundary, 3026 padding = options.padding, 3027 _options$tether = options.tether, 3028 tether = _options$tether === void 0 ? true : _options$tether, 3029 _options$tetherOffset = options.tetherOffset, 3030 tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; 3031 var overflow = detectOverflow(state, { 3032 boundary: boundary, 3033 rootBoundary: rootBoundary, 3034 padding: padding, 3035 altBoundary: altBoundary 3036 }); 3037 var basePlacement = getBasePlacement(state.placement); 3038 var variation = getVariation(state.placement); 3039 var isBasePlacement = !variation; 3040 var mainAxis = getMainAxisFromPlacement(basePlacement); 3041 var altAxis = getAltAxis(mainAxis); 3042 var popperOffsets = state.modifiersData.popperOffsets; 3043 var referenceRect = state.rects.reference; 3044 var popperRect = state.rects.popper; 3045 var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, { 3046 placement: state.placement 3047 })) : tetherOffset; 3048 var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? { 3049 mainAxis: tetherOffsetValue, 3050 altAxis: tetherOffsetValue 3051 } : Object.assign({ 3052 mainAxis: 0, 3053 altAxis: 0 3054 }, tetherOffsetValue); 3055 var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; 3056 var data = { 3057 x: 0, 3058 y: 0 3059 }; 3060 3061 if (!popperOffsets) { 3062 return; 3063 } 3064 3065 if (checkMainAxis) { 3066 var _offsetModifierState$; 3067 3068 var mainSide = mainAxis === 'y' ? top : left; 3069 var altSide = mainAxis === 'y' ? bottom : right; 3070 var len = mainAxis === 'y' ? 'height' : 'width'; 3071 var offset = popperOffsets[mainAxis]; 3072 var min$1 = offset + overflow[mainSide]; 3073 var max$1 = offset - overflow[altSide]; 3074 var additive = tether ? -popperRect[len] / 2 : 0; 3075 var minLen = variation === start ? referenceRect[len] : popperRect[len]; 3076 var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go 3077 // outside the reference bounds 3078 3079 var arrowElement = state.elements.arrow; 3080 var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { 3081 width: 0, 3082 height: 0 3083 };
vendor: 13,669 bytes, lines 3084-3440
3084 var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject(); 3085 var arrowPaddingMin = arrowPaddingObject[mainSide]; 3086 var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want 3087 // to include its full size in the calculation. If the reference is small 3088 // and near the edge of a boundary, the popper can overflow even if the 3089 // reference is not overflowing as well (e.g. virtual elements with no 3090 // width or height) 3091 3092 var arrowLen = within(0, referenceRect[len], arrowRect[len]); 3093 var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; 3094 var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; 3095 var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); 3096 var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; 3097 var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; 3098 var tetherMin = offset + minOffset - offsetModifierValue - clientOffset; 3099 var tetherMax = offset + maxOffset - offsetModifierValue; 3100 var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1); 3101 popperOffsets[mainAxis] = preventedOffset; 3102 data[mainAxis] = preventedOffset - offset; 3103 } 3104 3105 if (checkAltAxis) { 3106 var _offsetModifierState$2; 3107 3108 var _mainSide = mainAxis === 'x' ? top : left; 3109 3110 var _altSide = mainAxis === 'x' ? bottom : right; 3111 3112 var _offset = popperOffsets[altAxis]; 3113 3114 var _len = altAxis === 'y' ? 'height' : 'width'; 3115 3116 var _min = _offset + overflow[_mainSide]; 3117 3118 var _max = _offset - overflow[_altSide]; 3119 3120 var isOriginSide = [top, left].indexOf(basePlacement) !== -1; 3121 3122 var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; 3123 3124 var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; 3125 3126 var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; 3127 3128 var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); 3129 3130 popperOffsets[altAxis] = _preventedOffset; 3131 data[altAxis] = _preventedOffset - _offset; 3132 } 3133 3134 state.modifiersData[name] = data; 3135 } // eslint-disable-next-line import/no-unused-modules 3136 3137 3138 const preventOverflow$1 = { 3139 name: 'preventOverflow', 3140 enabled: true, 3141 phase: 'main', 3142 fn: preventOverflow, 3143 requiresIfExists: ['offset'] 3144 }; 3145 3146 function getHTMLElementScroll(element) { 3147 return { 3148 scrollLeft: element.scrollLeft, 3149 scrollTop: element.scrollTop 3150 }; 3151 } 3152 3153 function getNodeScroll(node) { 3154 if (node === getWindow(node) || !isHTMLElement(node)) { 3155 return getWindowScroll(node); 3156 } else { 3157 return getHTMLElementScroll(node); 3158 } 3159 } 3160 3161 function isElementScaled(element) { 3162 var rect = element.getBoundingClientRect(); 3163 var scaleX = round(rect.width) / element.offsetWidth || 1; 3164 var scaleY = round(rect.height) / element.offsetHeight || 1; 3165 return scaleX !== 1 || scaleY !== 1; 3166 } // Returns the composite rect of an element relative to its offsetParent. 3167 // Composite means it takes into account transforms as well as layout. 3168 3169 3170 function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { 3171 if (isFixed === void 0) { 3172 isFixed = false; 3173 } 3174 3175 var isOffsetParentAnElement = isHTMLElement(offsetParent); 3176 var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); 3177 var documentElement = getDocumentElement(offsetParent); 3178 var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed); 3179 var scroll = { 3180 scrollLeft: 0, 3181 scrollTop: 0 3182 }; 3183 var offsets = { 3184 x: 0, 3185 y: 0 3186 }; 3187 3188 if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { 3189 if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078 3190 isScrollParent(documentElement)) { 3191 scroll = getNodeScroll(offsetParent); 3192 } 3193 3194 if (isHTMLElement(offsetParent)) { 3195 offsets = getBoundingClientRect(offsetParent, true); 3196 offsets.x += offsetParent.clientLeft; 3197 offsets.y += offsetParent.clientTop; 3198 } else if (documentElement) { 3199 offsets.x = getWindowScrollBarX(documentElement); 3200 } 3201 } 3202 3203 return { 3204 x: rect.left + scroll.scrollLeft - offsets.x, 3205 y: rect.top + scroll.scrollTop - offsets.y, 3206 width: rect.width, 3207 height: rect.height 3208 }; 3209 } 3210 3211 function order(modifiers) { 3212 var map = new Map(); 3213 var visited = new Set(); 3214 var result = []; 3215 modifiers.forEach(function (modifier) { 3216 map.set(modifier.name, modifier); 3217 }); // On visiting object, check for its dependencies and visit them recursively 3218 3219 function sort(modifier) { 3220 visited.add(modifier.name); 3221 var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); 3222 requires.forEach(function (dep) { 3223 if (!visited.has(dep)) { 3224 var depModifier = map.get(dep); 3225 3226 if (depModifier) { 3227 sort(depModifier); 3228 } 3229 } 3230 }); 3231 result.push(modifier); 3232 } 3233 3234 modifiers.forEach(function (modifier) { 3235 if (!visited.has(modifier.name)) { 3236 // check for visited object 3237 sort(modifier); 3238 } 3239 }); 3240 return result; 3241 } 3242 3243 function orderModifiers(modifiers) { 3244 // order based on dependencies 3245 var orderedModifiers = order(modifiers); // order based on phase 3246 3247 return modifierPhases.reduce(function (acc, phase) { 3248 return acc.concat(orderedModifiers.filter(function (modifier) { 3249 return modifier.phase === phase; 3250 })); 3251 }, []); 3252 } 3253 3254 function debounce(fn) { 3255 var pending; 3256 return function () { 3257 if (!pending) { 3258 pending = new Promise(function (resolve) { 3259 Promise.resolve().then(function () { 3260 pending = undefined; 3261 resolve(fn()); 3262 }); 3263 }); 3264 } 3265 3266 return pending; 3267 }; 3268 } 3269 3270 function mergeByName(modifiers) { 3271 var merged = modifiers.reduce(function (merged, current) { 3272 var existing = merged[current.name]; 3273 merged[current.name] = existing ? Object.assign({}, existing, current, { 3274 options: Object.assign({}, existing.options, current.options), 3275 data: Object.assign({}, existing.data, current.data) 3276 }) : current; 3277 return merged; 3278 }, {}); // IE11 does not support Object.values 3279 3280 return Object.keys(merged).map(function (key) { 3281 return merged[key]; 3282 }); 3283 } 3284 3285 var DEFAULT_OPTIONS = { 3286 placement: 'bottom', 3287 modifiers: [], 3288 strategy: 'absolute' 3289 }; 3290 3291 function areValidElements() { 3292 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 3293 args[_key] = arguments[_key]; 3294 } 3295 3296 return !args.some(function (element) { 3297 return !(element && typeof element.getBoundingClientRect === 'function'); 3298 }); 3299 } 3300 3301 function popperGenerator(generatorOptions) { 3302 if (generatorOptions === void 0) { 3303 generatorOptions = {}; 3304 } 3305 3306 var _generatorOptions = generatorOptions, 3307 _generatorOptions$def = _generatorOptions.defaultModifiers, 3308 defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, 3309 _generatorOptions$def2 = _generatorOptions.defaultOptions, 3310 defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; 3311 return function createPopper(reference, popper, options) { 3312 if (options === void 0) { 3313 options = defaultOptions; 3314 } 3315 3316 var state = { 3317 placement: 'bottom', 3318 orderedModifiers: [], 3319 options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), 3320 modifiersData: {}, 3321 elements: { 3322 reference: reference, 3323 popper: popper 3324 }, 3325 attributes: {}, 3326 styles: {} 3327 }; 3328 var effectCleanupFns = []; 3329 var isDestroyed = false; 3330 var instance = { 3331 state: state, 3332 setOptions: function setOptions(setOptionsAction) { 3333 var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction; 3334 cleanupModifierEffects(); 3335 state.options = Object.assign({}, defaultOptions, state.options, options); 3336 state.scrollParents = { 3337 reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [], 3338 popper: listScrollParents(popper) 3339 }; // Orders the modifiers based on their dependencies and `phase` 3340 // properties 3341 3342 var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers 3343 3344 state.orderedModifiers = orderedModifiers.filter(function (m) { 3345 return m.enabled; 3346 }); 3347 runModifierEffects(); 3348 return instance.update(); 3349 }, 3350 // Sync update – it will always be executed, even if not necessary. This 3351 // is useful for low frequency updates where sync behavior simplifies the 3352 // logic. 3353 // For high frequency updates (e.g. `resize` and `scroll` events), always 3354 // prefer the async Popper#update method 3355 forceUpdate: function forceUpdate() { 3356 if (isDestroyed) { 3357 return; 3358 } 3359 3360 var _state$elements = state.elements, 3361 reference = _state$elements.reference, 3362 popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements 3363 // anymore 3364 3365 if (!areValidElements(reference, popper)) { 3366 return; 3367 } // Store the reference and popper rects to be read by modifiers 3368 3369 3370 state.rects = { 3371 reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'), 3372 popper: getLayoutRect(popper) 3373 }; // Modifiers have the ability to reset the current update cycle. The 3374 // most common use case for this is the `flip` modifier changing the 3375 // placement, which then needs to re-run all the modifiers, because the 3376 // logic was previously ran for the previous placement and is therefore 3377 // stale/incorrect 3378 3379 state.reset = false; 3380 state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier 3381 // is filled with the initial data specified by the modifier. This means 3382 // it doesn't persist and is fresh on each update. 3383 // To ensure persistent data, use `${name}#persistent` 3384 3385 state.orderedModifiers.forEach(function (modifier) { 3386 return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); 3387 }); 3388 3389 for (var index = 0; index < state.orderedModifiers.length; index++) { 3390 if (state.reset === true) { 3391 state.reset = false; 3392 index = -1; 3393 continue; 3394 } 3395 3396 var _state$orderedModifie = state.orderedModifiers[index], 3397 fn = _state$orderedModifie.fn, 3398 _state$orderedModifie2 = _state$orderedModifie.options, 3399 _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, 3400 name = _state$orderedModifie.name; 3401 3402 if (typeof fn === 'function') { 3403 state = fn({ 3404 state: state, 3405 options: _options, 3406 name: name, 3407 instance: instance 3408 }) || state; 3409 } 3410 } 3411 }, 3412 // Async and optimistically optimized update – it will not be executed if 3413 // not necessary (debounced to run at most once-per-tick) 3414 update: debounce(function () { 3415 return new Promise(function (resolve) { 3416 instance.forceUpdate(); 3417 resolve(state); 3418 }); 3419 }), 3420 destroy: function destroy() { 3421 cleanupModifierEffects(); 3422 isDestroyed = true; 3423 } 3424 }; 3425 3426 if (!areValidElements(reference, popper)) { 3427 return instance; 3428 } 3429 3430 instance.setOptions(options).then(function (state) { 3431 if (!isDestroyed && options.onFirstUpdate) { 3432 options.onFirstUpdate(state); 3433 } 3434 }); // Modifiers have the ability to execute arbitrary code before the first 3435 // update cycle runs. They will be executed in the same order as the update 3436 // cycle. This is useful when a modifier adds some persistent data that 3437 // other modifiers need to use, but the modifier is run after the dependent 3438 // one. 3439 3440 function runModifierEffects() {
vendor: 10,048 bytes, lines 3441-3731
3441 state.orderedModifiers.forEach(function (_ref) { 3442 var name = _ref.name, 3443 _ref$options = _ref.options, 3444 options = _ref$options === void 0 ? {} : _ref$options, 3445 effect = _ref.effect; 3446 3447 if (typeof effect === 'function') { 3448 var cleanupFn = effect({ 3449 state: state, 3450 name: name, 3451 instance: instance, 3452 options: options 3453 }); 3454 3455 var noopFn = function noopFn() {}; 3456 3457 effectCleanupFns.push(cleanupFn || noopFn); 3458 } 3459 }); 3460 } 3461 3462 function cleanupModifierEffects() { 3463 effectCleanupFns.forEach(function (fn) { 3464 return fn(); 3465 }); 3466 effectCleanupFns = []; 3467 } 3468 3469 return instance; 3470 }; 3471 } 3472 var createPopper$2 = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules 3473 3474 var defaultModifiers$1 = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1]; 3475 var createPopper$1 = /*#__PURE__*/popperGenerator({ 3476 defaultModifiers: defaultModifiers$1 3477 }); // eslint-disable-next-line import/no-unused-modules 3478 3479 var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1]; 3480 var createPopper = /*#__PURE__*/popperGenerator({ 3481 defaultModifiers: defaultModifiers 3482 }); // eslint-disable-next-line import/no-unused-modules 3483 3484 const Popper = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ 3485 __proto__: null, 3486 afterMain, 3487 afterRead, 3488 afterWrite, 3489 applyStyles: applyStyles$1, 3490 arrow: arrow$1, 3491 auto, 3492 basePlacements, 3493 beforeMain, 3494 beforeRead, 3495 beforeWrite, 3496 bottom, 3497 clippingParents, 3498 computeStyles: computeStyles$1, 3499 createPopper, 3500 createPopperBase: createPopper$2, 3501 createPopperLite: createPopper$1, 3502 detectOverflow, 3503 end, 3504 eventListeners, 3505 flip: flip$1, 3506 hide: hide$1, 3507 left, 3508 main, 3509 modifierPhases, 3510 offset: offset$1, 3511 placements, 3512 popper, 3513 popperGenerator, 3514 popperOffsets: popperOffsets$1, 3515 preventOverflow: preventOverflow$1, 3516 read, 3517 reference, 3518 right, 3519 start, 3520 top, 3521 variationPlacements, 3522 viewport, 3523 write 3524 }, Symbol.toStringTag, { value: 'Module' })); 3525 3526 /** 3527 * -------------------------------------------------------------------------- 3528 * Bootstrap dropdown.js 3529 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 3530 * -------------------------------------------------------------------------- 3531 */ 3532 3533 3534 /** 3535 * Constants 3536 */ 3537 3538 const NAME$a = 'dropdown'; 3539 const DATA_KEY$6 = 'bs.dropdown'; 3540 const EVENT_KEY$6 = `.${DATA_KEY$6}`; 3541 const DATA_API_KEY$3 = '.data-api'; 3542 const ESCAPE_KEY$2 = 'Escape'; 3543 const TAB_KEY$1 = 'Tab'; 3544 const ARROW_UP_KEY$1 = 'ArrowUp'; 3545 const ARROW_DOWN_KEY$1 = 'ArrowDown'; 3546 const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button 3547 3548 const EVENT_HIDE$5 = `hide${EVENT_KEY$6}`; 3549 const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`; 3550 const EVENT_SHOW$5 = `show${EVENT_KEY$6}`; 3551 const EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`; 3552 const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`; 3553 const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`; 3554 const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`; 3555 const CLASS_NAME_SHOW$6 = 'show'; 3556 const CLASS_NAME_DROPUP = 'dropup'; 3557 const CLASS_NAME_DROPEND = 'dropend'; 3558 const CLASS_NAME_DROPSTART = 'dropstart'; 3559 const CLASS_NAME_DROPUP_CENTER = 'dropup-center'; 3560 const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center'; 3561 const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)'; 3562 const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`; 3563 const SELECTOR_MENU = '.dropdown-menu'; 3564 const SELECTOR_NAVBAR = '.navbar'; 3565 const SELECTOR_NAVBAR_NAV = '.navbar-nav'; 3566 const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; 3567 const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start'; 3568 const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end'; 3569 const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start'; 3570 const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end'; 3571 const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start'; 3572 const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start'; 3573 const PLACEMENT_TOPCENTER = 'top'; 3574 const PLACEMENT_BOTTOMCENTER = 'bottom'; 3575 const Default$9 = { 3576 autoClose: true, 3577 boundary: 'clippingParents', 3578 display: 'dynamic', 3579 offset: [0, 2], 3580 popperConfig: null, 3581 reference: 'toggle' 3582 }; 3583 const DefaultType$9 = { 3584 autoClose: '(boolean|string)', 3585 boundary: '(string|element)', 3586 display: 'string', 3587 offset: '(array|string|function)', 3588 popperConfig: '(null|object|function)', 3589 reference: '(string|element|object)' 3590 }; 3591 3592 /** 3593 * Class definition 3594 */ 3595 3596 class Dropdown extends BaseComponent { 3597 constructor(element, config) { 3598 super(element, config); 3599 this._popper = null; 3600 this._parent = this._element.parentNode; // dropdown wrapper 3601 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/ 3602 this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent); 3603 this._inNavbar = this._detectNavbar(); 3604 } 3605 3606 // Getters 3607 static get Default() { 3608 return Default$9; 3609 } 3610 static get DefaultType() { 3611 return DefaultType$9; 3612 } 3613 static get NAME() { 3614 return NAME$a; 3615 } 3616 3617 // Public 3618 toggle() { 3619 return this._isShown() ? this.hide() : this.show(); 3620 } 3621 show() { 3622 if (isDisabled(this._element) || this._isShown()) { 3623 return; 3624 } 3625 const relatedTarget = { 3626 relatedTarget: this._element 3627 }; 3628 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget); 3629 if (showEvent.defaultPrevented) { 3630 return; 3631 } 3632 this._createPopper(); 3633 3634 // If this is a touch-enabled device we add extra 3635 // empty mouseover listeners to the body's immediate children; 3636 // only needed because of broken event delegation on iOS 3637 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 3638 if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) { 3639 for (const element of [].concat(...document.body.children)) { 3640 EventHandler.on(element, 'mouseover', noop); 3641 } 3642 } 3643 this._element.focus(); 3644 this._element.setAttribute('aria-expanded', true); 3645 this._menu.classList.add(CLASS_NAME_SHOW$6); 3646 this._element.classList.add(CLASS_NAME_SHOW$6); 3647 EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget); 3648 } 3649 hide() { 3650 if (isDisabled(this._element) || !this._isShown()) { 3651 return; 3652 } 3653 const relatedTarget = { 3654 relatedTarget: this._element 3655 }; 3656 this._completeHide(relatedTarget); 3657 } 3658 dispose() { 3659 if (this._popper) { 3660 this._popper.destroy(); 3661 } 3662 super.dispose(); 3663 } 3664 update() { 3665 this._inNavbar = this._detectNavbar(); 3666 if (this._popper) { 3667 this._popper.update(); 3668 } 3669 } 3670 3671 // Private 3672 _completeHide(relatedTarget) { 3673 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget); 3674 if (hideEvent.defaultPrevented) { 3675 return; 3676 } 3677 3678 // If this is a touch-enabled device we remove the extra 3679 // empty mouseover listeners we added for iOS support 3680 if ('ontouchstart' in document.documentElement) { 3681 for (const element of [].concat(...document.body.children)) { 3682 EventHandler.off(element, 'mouseover', noop); 3683 } 3684 } 3685 if (this._popper) { 3686 this._popper.destroy(); 3687 } 3688 this._menu.classList.remove(CLASS_NAME_SHOW$6); 3689 this._element.classList.remove(CLASS_NAME_SHOW$6); 3690 this._element.setAttribute('aria-expanded', 'false'); 3691 Manipulator.removeDataAttribute(this._menu, 'popper'); 3692 EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget); 3693 } 3694 _getConfig(config) { 3695 config = super._getConfig(config); 3696 if (typeof config.reference === 'object' && !isElement$1(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') { 3697 // Popper virtual elements require a getBoundingClientRect method 3698 throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`); 3699 } 3700 return config; 3701 } 3702 _createPopper() { 3703 if (typeof Popper === 'undefined') { 3704 throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org/docs/v2/)'); 3705 } 3706 let referenceElement = this._element; 3707 if (this._config.reference === 'parent') { 3708 referenceElement = this._parent; 3709 } else if (isElement$1(this._config.reference)) { 3710 referenceElement = getElement(this._config.reference); 3711 } else if (typeof this._config.reference === 'object') { 3712 referenceElement = this._config.reference; 3713 } 3714 const popperConfig = this._getPopperConfig(); 3715 this._popper = createPopper(referenceElement, this._menu, popperConfig); 3716 } 3717 _isShown() { 3718 return this._menu.classList.contains(CLASS_NAME_SHOW$6); 3719 } 3720 _getPlacement() { 3721 const parentDropdown = this._parent; 3722 if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) { 3723 return PLACEMENT_RIGHT; 3724 } 3725 if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) { 3726 return PLACEMENT_LEFT; 3727 } 3728 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) { 3729 return PLACEMENT_TOPCENTER; 3730 } 3731 if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENT
vendor: 10,917 bytes, lines 3731-4087
3731ER)) { 3732 return PLACEMENT_BOTTOMCENTER; 3733 } 3734 3735 // We need to trim the value because custom properties can also include spaces 3736 const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'; 3737 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) { 3738 return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP; 3739 } 3740 return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM; 3741 } 3742 _detectNavbar() { 3743 return this._element.closest(SELECTOR_NAVBAR) !== null; 3744 } 3745 _getOffset() { 3746 const { 3747 offset 3748 } = this._config; 3749 if (typeof offset === 'string') { 3750 return offset.split(',').map(value => Number.parseInt(value, 10)); 3751 } 3752 if (typeof offset === 'function') { 3753 return popperData => offset(popperData, this._element); 3754 } 3755 return offset; 3756 } 3757 _getPopperConfig() { 3758 const defaultBsPopperConfig = { 3759 placement: this._getPlacement(), 3760 modifiers: [{ 3761 name: 'preventOverflow', 3762 options: { 3763 boundary: this._config.boundary 3764 } 3765 }, { 3766 name: 'offset', 3767 options: { 3768 offset: this._getOffset() 3769 } 3770 }] 3771 }; 3772 3773 // Disable Popper if we have a static display or Dropdown is in Navbar 3774 if (this._inNavbar || this._config.display === 'static') { 3775 Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove 3776 defaultBsPopperConfig.modifiers = [{ 3777 name: 'applyStyles', 3778 enabled: false 3779 }]; 3780 } 3781 return { 3782 ...defaultBsPopperConfig, 3783 ...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig]) 3784 }; 3785 } 3786 _selectMenuItem({ 3787 key, 3788 target 3789 }) { 3790 const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element)); 3791 if (!items.length) { 3792 return; 3793 } 3794 3795 // if target isn't included in items (e.g. when expanding the dropdown) 3796 // allow cycling to get the last item in case key equals ARROW_UP_KEY 3797 getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus(); 3798 } 3799 3800 // Static 3801 static jQueryInterface(config) { 3802 return this.each(function () { 3803 const data = Dropdown.getOrCreateInstance(this, config); 3804 if (typeof config !== 'string') { 3805 return; 3806 } 3807 if (typeof data[config] === 'undefined') { 3808 throw new TypeError(`No method named "${config}"`); 3809 } 3810 data[config](); 3811 }); 3812 } 3813 static clearMenus(event) { 3814 if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) { 3815 return; 3816 } 3817 const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN); 3818 for (const toggle of openToggles) { 3819 const context = Dropdown.getInstance(toggle); 3820 if (!context || context._config.autoClose === false) { 3821 continue; 3822 } 3823 const composedPath = event.composedPath(); 3824 const isMenuTarget = composedPath.includes(context._menu); 3825 if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) { 3826 continue; 3827 } 3828 3829 // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu 3830 if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) { 3831 continue; 3832 } 3833 const relatedTarget = { 3834 relatedTarget: context._element 3835 }; 3836 if (event.type === 'click') { 3837 relatedTarget.clickEvent = event; 3838 } 3839 context._completeHide(relatedTarget); 3840 } 3841 } 3842 static dataApiKeydownHandler(event) { 3843 // If not an UP | DOWN | ESCAPE key => not a dropdown command 3844 // If input/textarea && if key is other than ESCAPE => not a dropdown command 3845 3846 const isInput = /input|textarea/i.test(event.target.tagName); 3847 const isEscapeEvent = event.key === ESCAPE_KEY$2; 3848 const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key); 3849 if (!isUpOrDownEvent && !isEscapeEvent) { 3850 return; 3851 } 3852 if (isInput && !isEscapeEvent) { 3853 return; 3854 } 3855 event.preventDefault(); 3856 3857 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/ 3858 const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode); 3859 const instance = Dropdown.getOrCreateInstance(getToggleButton); 3860 if (isUpOrDownEvent) { 3861 event.stopPropagation(); 3862 instance.show(); 3863 instance._selectMenuItem(event); 3864 return; 3865 } 3866 if (instance._isShown()) { 3867 // else is escape and we check if it is shown 3868 event.stopPropagation(); 3869 instance.hide(); 3870 getToggleButton.focus(); 3871 } 3872 } 3873 } 3874 3875 /** 3876 * Data API implementation 3877 */ 3878 3879 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler); 3880 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler); 3881 EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus); 3882 EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus); 3883 EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) { 3884 event.preventDefault(); 3885 Dropdown.getOrCreateInstance(this).toggle(); 3886 }); 3887 3888 /** 3889 * jQuery 3890 */ 3891 3892 defineJQueryPlugin(Dropdown); 3893 3894 /** 3895 * -------------------------------------------------------------------------- 3896 * Bootstrap util/backdrop.js 3897 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 3898 * -------------------------------------------------------------------------- 3899 */ 3900 3901 3902 /** 3903 * Constants 3904 */ 3905 3906 const NAME$9 = 'backdrop'; 3907 const CLASS_NAME_FADE$4 = 'fade'; 3908 const CLASS_NAME_SHOW$5 = 'show'; 3909 const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`; 3910 const Default$8 = { 3911 className: 'modal-backdrop', 3912 clickCallback: null, 3913 isAnimated: false, 3914 isVisible: true, 3915 // if false, we use the backdrop helper without adding any element to the dom 3916 rootElement: 'body' // give the choice to place backdrop under different elements 3917 }; 3918 const DefaultType$8 = { 3919 className: 'string', 3920 clickCallback: '(function|null)', 3921 isAnimated: 'boolean', 3922 isVisible: 'boolean', 3923 rootElement: '(element|string)' 3924 }; 3925 3926 /** 3927 * Class definition 3928 */ 3929 3930 class Backdrop extends Config { 3931 constructor(config) { 3932 super(); 3933 this._config = this._getConfig(config); 3934 this._isAppended = false; 3935 this._element = null; 3936 } 3937 3938 // Getters 3939 static get Default() { 3940 return Default$8; 3941 } 3942 static get DefaultType() { 3943 return DefaultType$8; 3944 } 3945 static get NAME() { 3946 return NAME$9; 3947 } 3948 3949 // Public 3950 show(callback) { 3951 if (!this._config.isVisible) { 3952 execute(callback); 3953 return; 3954 } 3955 this._append(); 3956 const element = this._getElement(); 3957 if (this._config.isAnimated) { 3958 reflow(element); 3959 } 3960 element.classList.add(CLASS_NAME_SHOW$5); 3961 this._emulateAnimation(() => { 3962 execute(callback); 3963 }); 3964 } 3965 hide(callback) { 3966 if (!this._config.isVisible) { 3967 execute(callback); 3968 return; 3969 } 3970 this._getElement().classList.remove(CLASS_NAME_SHOW$5); 3971 this._emulateAnimation(() => { 3972 this.dispose(); 3973 execute(callback); 3974 }); 3975 } 3976 dispose() { 3977 if (!this._isAppended) { 3978 return; 3979 } 3980 EventHandler.off(this._element, EVENT_MOUSEDOWN); 3981 this._element.remove(); 3982 this._isAppended = false; 3983 } 3984 3985 // Private 3986 _getElement() { 3987 if (!this._element) { 3988 const backdrop = document.createElement('div'); 3989 backdrop.className = this._config.className; 3990 if (this._config.isAnimated) { 3991 backdrop.classList.add(CLASS_NAME_FADE$4); 3992 } 3993 this._element = backdrop; 3994 } 3995 return this._element; 3996 } 3997 _configAfterMerge(config) { 3998 // use getElement() with the default "body" to get a fresh Element on each instantiation 3999 config.rootElement = getElement(config.rootElement); 4000 return config; 4001 } 4002 _append() { 4003 if (this._isAppended) { 4004 return; 4005 } 4006 const element = this._getElement(); 4007 this._config.rootElement.append(element); 4008 EventHandler.on(element, EVENT_MOUSEDOWN, () => { 4009 execute(this._config.clickCallback); 4010 }); 4011 this._isAppended = true; 4012 } 4013 _emulateAnimation(callback) { 4014 executeAfterTransition(callback, this._getElement(), this._config.isAnimated); 4015 } 4016 } 4017 4018 /** 4019 * -------------------------------------------------------------------------- 4020 * Bootstrap util/focustrap.js 4021 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4022 * -------------------------------------------------------------------------- 4023 */ 4024 4025 4026 /** 4027 * Constants 4028 */ 4029 4030 const NAME$8 = 'focustrap'; 4031 const DATA_KEY$5 = 'bs.focustrap'; 4032 const EVENT_KEY$5 = `.${DATA_KEY$5}`; 4033 const EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`; 4034 const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`; 4035 const TAB_KEY = 'Tab'; 4036 const TAB_NAV_FORWARD = 'forward'; 4037 const TAB_NAV_BACKWARD = 'backward'; 4038 const Default$7 = { 4039 autofocus: true, 4040 trapElement: null // The element to trap focus inside of 4041 }; 4042 const DefaultType$7 = { 4043 autofocus: 'boolean', 4044 trapElement: 'element' 4045 }; 4046 4047 /** 4048 * Class definition 4049 */ 4050 4051 class FocusTrap extends Config { 4052 constructor(config) { 4053 super(); 4054 this._config = this._getConfig(config); 4055 this._isActive = false; 4056 this._lastTabNavDirection = null; 4057 } 4058 4059 // Getters 4060 static get Default() { 4061 return Default$7; 4062 } 4063 static get DefaultType() { 4064 return DefaultType$7; 4065 } 4066 static get NAME() { 4067 return NAME$8; 4068 } 4069 4070 // Public 4071 activate() { 4072 if (this._isActive) { 4073 return; 4074 } 4075 if (this._config.autofocus) { 4076 this._config.trapElement.focus(); 4077 } 4078 EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop 4079 EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event)); 4080 EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event)); 4081 this._isActive = true; 4082 } 4083 deactivate() { 4084 if (!this._isActive) { 4085 return; 4086 } 4087 this._isActive = false;
vendor: 5,042 bytes, lines 4088-4230
4088 EventHandler.off(document, EVENT_KEY$5); 4089 } 4090 4091 // Private 4092 _handleFocusin(event) { 4093 const { 4094 trapElement 4095 } = this._config; 4096 if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) { 4097 return; 4098 } 4099 const elements = SelectorEngine.focusableChildren(trapElement); 4100 if (elements.length === 0) { 4101 trapElement.focus(); 4102 } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) { 4103 elements[elements.length - 1].focus(); 4104 } else { 4105 elements[0].focus(); 4106 } 4107 } 4108 _handleKeydown(event) { 4109 if (event.key !== TAB_KEY) { 4110 return; 4111 } 4112 this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD; 4113 } 4114 } 4115 4116 /** 4117 * -------------------------------------------------------------------------- 4118 * Bootstrap util/scrollBar.js 4119 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4120 * -------------------------------------------------------------------------- 4121 */ 4122 4123 4124 /** 4125 * Constants 4126 */ 4127 4128 const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'; 4129 const SELECTOR_STICKY_CONTENT = '.sticky-top'; 4130 const PROPERTY_PADDING = 'padding-right'; 4131 const PROPERTY_MARGIN = 'margin-right'; 4132 4133 /** 4134 * Class definition 4135 */ 4136 4137 class ScrollBarHelper { 4138 constructor() { 4139 this._element = document.body; 4140 } 4141 4142 // Public 4143 getWidth() { 4144 // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes 4145 const documentWidth = document.documentElement.clientWidth; 4146 return Math.abs(window.innerWidth - documentWidth); 4147 } 4148 hide() { 4149 const width = this.getWidth(); 4150 this._disableOverFlow(); 4151 // give padding to element to balance the hidden scrollbar width 4152 this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width); 4153 // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth 4154 this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width); 4155 this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width); 4156 } 4157 reset() { 4158 this._resetElementAttributes(this._element, 'overflow'); 4159 this._resetElementAttributes(this._element, PROPERTY_PADDING); 4160 this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING); 4161 this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN); 4162 } 4163 isOverflowing() { 4164 return this.getWidth() > 0; 4165 } 4166 4167 // Private 4168 _disableOverFlow() { 4169 this._saveInitialAttribute(this._element, 'overflow'); 4170 this._element.style.overflow = 'hidden'; 4171 } 4172 _setElementAttributes(selector, styleProperty, callback) { 4173 const scrollbarWidth = this.getWidth(); 4174 const manipulationCallBack = element => { 4175 if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) { 4176 return; 4177 } 4178 this._saveInitialAttribute(element, styleProperty); 4179 const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty); 4180 element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`); 4181 }; 4182 this._applyManipulationCallback(selector, manipulationCallBack); 4183 } 4184 _saveInitialAttribute(element, styleProperty) { 4185 const actualValue = element.style.getPropertyValue(styleProperty); 4186 if (actualValue) { 4187 Manipulator.setDataAttribute(element, styleProperty, actualValue); 4188 } 4189 } 4190 _resetElementAttributes(selector, styleProperty) { 4191 const manipulationCallBack = element => { 4192 const value = Manipulator.getDataAttribute(element, styleProperty); 4193 // We only want to remove the property if the value is `null`; the value can also be zero 4194 if (value === null) { 4195 element.style.removeProperty(styleProperty); 4196 return; 4197 } 4198 Manipulator.removeDataAttribute(element, styleProperty); 4199 element.style.setProperty(styleProperty, value); 4200 }; 4201 this._applyManipulationCallback(selector, manipulationCallBack); 4202 } 4203 _applyManipulationCallback(selector, callBack) { 4204 if (isElement$1(selector)) { 4205 callBack(selector); 4206 return; 4207 } 4208 for (const sel of SelectorEngine.find(selector, this._element)) { 4209 callBack(sel); 4210 } 4211 } 4212 } 4213 4214 /** 4215 * -------------------------------------------------------------------------- 4216 * Bootstrap modal.js 4217 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4218 * -------------------------------------------------------------------------- 4219 */ 4220 4221 4222 /** 4223 * Constants 4224 */ 4225 4226 const NAME$7 = 'modal'; 4227 const DATA_KEY$4 = 'bs.modal'; 4228 const EVENT_KEY$4 = `.${DATA_KEY$4}`; 4229 const DATA_API_KEY$2 = '.data-api'; 4230 const ESCAPE_KEY$1 = 'Escape';
vendor: 19,288 bytes, lines 4231-4837
4231 const EVENT_HIDE$4 = `hide${EVENT_KEY$4}`; 4232 const EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`; 4233 const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`; 4234 const EVENT_SHOW$4 = `show${EVENT_KEY$4}`; 4235 const EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`; 4236 const EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`; 4237 const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`; 4238 const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`; 4239 const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`; 4240 const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`; 4241 const CLASS_NAME_OPEN = 'modal-open'; 4242 const CLASS_NAME_FADE$3 = 'fade'; 4243 const CLASS_NAME_SHOW$4 = 'show'; 4244 const CLASS_NAME_STATIC = 'modal-static'; 4245 const OPEN_SELECTOR$1 = '.modal.show'; 4246 const SELECTOR_DIALOG = '.modal-dialog'; 4247 const SELECTOR_MODAL_BODY = '.modal-body'; 4248 const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="modal"]'; 4249 const Default$6 = { 4250 backdrop: true, 4251 focus: true, 4252 keyboard: true 4253 }; 4254 const DefaultType$6 = { 4255 backdrop: '(boolean|string)', 4256 focus: 'boolean', 4257 keyboard: 'boolean' 4258 }; 4259 4260 /** 4261 * Class definition 4262 */ 4263 4264 class Modal extends BaseComponent { 4265 constructor(element, config) { 4266 super(element, config); 4267 this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element); 4268 this._backdrop = this._initializeBackDrop(); 4269 this._focustrap = this._initializeFocusTrap(); 4270 this._isShown = false; 4271 this._isTransitioning = false; 4272 this._scrollBar = new ScrollBarHelper(); 4273 this._addEventListeners(); 4274 } 4275 4276 // Getters 4277 static get Default() { 4278 return Default$6; 4279 } 4280 static get DefaultType() { 4281 return DefaultType$6; 4282 } 4283 static get NAME() { 4284 return NAME$7; 4285 } 4286 4287 // Public 4288 toggle(relatedTarget) { 4289 return this._isShown ? this.hide() : this.show(relatedTarget); 4290 } 4291 show(relatedTarget) { 4292 if (this._isShown || this._isTransitioning) { 4293 return; 4294 } 4295 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, { 4296 relatedTarget 4297 }); 4298 if (showEvent.defaultPrevented) { 4299 return; 4300 } 4301 this._isShown = true; 4302 this._isTransitioning = true; 4303 this._scrollBar.hide(); 4304 document.body.classList.add(CLASS_NAME_OPEN); 4305 this._adjustDialog(); 4306 this._backdrop.show(() => this._showElement(relatedTarget)); 4307 } 4308 hide() { 4309 if (!this._isShown || this._isTransitioning) { 4310 return; 4311 } 4312 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4); 4313 if (hideEvent.defaultPrevented) { 4314 return; 4315 } 4316 this._isShown = false; 4317 this._isTransitioning = true; 4318 this._focustrap.deactivate(); 4319 this._element.classList.remove(CLASS_NAME_SHOW$4); 4320 this._queueCallback(() => this._hideModal(), this._element, this._isAnimated()); 4321 } 4322 dispose() { 4323 EventHandler.off(window, EVENT_KEY$4); 4324 EventHandler.off(this._dialog, EVENT_KEY$4); 4325 this._backdrop.dispose(); 4326 this._focustrap.deactivate(); 4327 super.dispose(); 4328 } 4329 handleUpdate() { 4330 this._adjustDialog(); 4331 } 4332 4333 // Private 4334 _initializeBackDrop() { 4335 return new Backdrop({ 4336 isVisible: Boolean(this._config.backdrop), 4337 // 'static' option will be translated to true, and booleans will keep their value, 4338 isAnimated: this._isAnimated() 4339 }); 4340 } 4341 _initializeFocusTrap() { 4342 return new FocusTrap({ 4343 trapElement: this._element 4344 }); 4345 } 4346 _showElement(relatedTarget) { 4347 // try to append dynamic modal 4348 if (!document.body.contains(this._element)) { 4349 document.body.append(this._element); 4350 } 4351 this._element.style.display = 'block'; 4352 this._element.removeAttribute('aria-hidden'); 4353 this._element.setAttribute('aria-modal', true); 4354 this._element.setAttribute('role', 'dialog'); 4355 this._element.scrollTop = 0; 4356 const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog); 4357 if (modalBody) { 4358 modalBody.scrollTop = 0; 4359 } 4360 reflow(this._element); 4361 this._element.classList.add(CLASS_NAME_SHOW$4); 4362 const transitionComplete = () => { 4363 if (this._config.focus) { 4364 this._focustrap.activate(); 4365 } 4366 this._isTransitioning = false; 4367 EventHandler.trigger(this._element, EVENT_SHOWN$4, { 4368 relatedTarget 4369 }); 4370 }; 4371 this._queueCallback(transitionComplete, this._dialog, this._isAnimated()); 4372 } 4373 _addEventListeners() { 4374 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => { 4375 if (event.key !== ESCAPE_KEY$1) { 4376 return; 4377 } 4378 if (this._config.keyboard) { 4379 this.hide(); 4380 return; 4381 } 4382 this._triggerBackdropTransition(); 4383 }); 4384 EventHandler.on(window, EVENT_RESIZE$1, () => { 4385 if (this._isShown && !this._isTransitioning) { 4386 this._adjustDialog(); 4387 } 4388 }); 4389 EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => { 4390 // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks 4391 EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => { 4392 if (this._element !== event.target || this._element !== event2.target) { 4393 return; 4394 } 4395 if (this._config.backdrop === 'static') { 4396 this._triggerBackdropTransition(); 4397 return; 4398 } 4399 if (this._config.backdrop) { 4400 this.hide(); 4401 } 4402 }); 4403 }); 4404 } 4405 _hideModal() { 4406 this._element.style.display = 'none'; 4407 this._element.setAttribute('aria-hidden', true); 4408 this._element.removeAttribute('aria-modal'); 4409 this._element.removeAttribute('role'); 4410 this._isTransitioning = false; 4411 this._backdrop.hide(() => { 4412 document.body.classList.remove(CLASS_NAME_OPEN); 4413 this._resetAdjustments(); 4414 this._scrollBar.reset(); 4415 EventHandler.trigger(this._element, EVENT_HIDDEN$4); 4416 }); 4417 } 4418 _isAnimated() { 4419 return this._element.classList.contains(CLASS_NAME_FADE$3); 4420 } 4421 _triggerBackdropTransition() { 4422 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1); 4423 if (hideEvent.defaultPrevented) { 4424 return; 4425 } 4426 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 4427 const initialOverflowY = this._element.style.overflowY; 4428 // return if the following background transition hasn't yet completed 4429 if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) { 4430 return; 4431 } 4432 if (!isModalOverflowing) { 4433 this._element.style.overflowY = 'hidden'; 4434 } 4435 this._element.classList.add(CLASS_NAME_STATIC); 4436 this._queueCallback(() => { 4437 this._element.classList.remove(CLASS_NAME_STATIC); 4438 this._queueCallback(() => { 4439 this._element.style.overflowY = initialOverflowY; 4440 }, this._dialog); 4441 }, this._dialog); 4442 this._element.focus(); 4443 } 4444 4445 /** 4446 * The following methods are used to handle overflowing modals 4447 */ 4448 4449 _adjustDialog() { 4450 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 4451 const scrollbarWidth = this._scrollBar.getWidth(); 4452 const isBodyOverflowing = scrollbarWidth > 0; 4453 if (isBodyOverflowing && !isModalOverflowing) { 4454 const property = isRTL() ? 'paddingLeft' : 'paddingRight'; 4455 this._element.style[property] = `${scrollbarWidth}px`; 4456 } 4457 if (!isBodyOverflowing && isModalOverflowing) { 4458 const property = isRTL() ? 'paddingRight' : 'paddingLeft'; 4459 this._element.style[property] = `${scrollbarWidth}px`; 4460 } 4461 } 4462 _resetAdjustments() { 4463 this._element.style.paddingLeft = ''; 4464 this._element.style.paddingRight = ''; 4465 } 4466 4467 // Static 4468 static jQueryInterface(config, relatedTarget) { 4469 return this.each(function () { 4470 const data = Modal.getOrCreateInstance(this, config); 4471 if (typeof config !== 'string') { 4472 return; 4473 } 4474 if (typeof data[config] === 'undefined') { 4475 throw new TypeError(`No method named "${config}"`); 4476 } 4477 data[config](relatedTarget); 4478 }); 4479 } 4480 } 4481 4482 /** 4483 * Data API implementation 4484 */ 4485 4486 EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) { 4487 const target = SelectorEngine.getElementFromSelector(this); 4488 if (['A', 'AREA'].includes(this.tagName)) { 4489 event.preventDefault(); 4490 } 4491 EventHandler.one(target, EVENT_SHOW$4, showEvent => { 4492 if (showEvent.defaultPrevented) { 4493 // only register focus restorer if modal will actually get shown 4494 return; 4495 } 4496 EventHandler.one(target, EVENT_HIDDEN$4, () => { 4497 if (isVisible(this)) { 4498 this.focus(); 4499 } 4500 }); 4501 }); 4502 4503 // avoid conflict when clicking modal toggler while another one is open 4504 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1); 4505 if (alreadyOpen) { 4506 Modal.getInstance(alreadyOpen).hide(); 4507 } 4508 const data = Modal.getOrCreateInstance(target); 4509 data.toggle(this); 4510 }); 4511 enableDismissTrigger(Modal); 4512 4513 /** 4514 * jQuery 4515 */ 4516 4517 defineJQueryPlugin(Modal); 4518 4519 /** 4520 * -------------------------------------------------------------------------- 4521 * Bootstrap offcanvas.js 4522 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4523 * -------------------------------------------------------------------------- 4524 */ 4525 4526 4527 /** 4528 * Constants 4529 */ 4530 4531 const NAME$6 = 'offcanvas'; 4532 const DATA_KEY$3 = 'bs.offcanvas'; 4533 const EVENT_KEY$3 = `.${DATA_KEY$3}`; 4534 const DATA_API_KEY$1 = '.data-api'; 4535 const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`; 4536 const ESCAPE_KEY = 'Escape'; 4537 const CLASS_NAME_SHOW$3 = 'show'; 4538 const CLASS_NAME_SHOWING$1 = 'showing'; 4539 const CLASS_NAME_HIDING = 'hiding'; 4540 const CLASS_NAME_BACKDROP = 'offcanvas-backdrop'; 4541 const OPEN_SELECTOR = '.offcanvas.show'; 4542 const EVENT_SHOW$3 = `show${EVENT_KEY$3}`; 4543 const EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`; 4544 const EVENT_HIDE$3 = `hide${EVENT_KEY$3}`; 4545 const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`; 4546 const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`; 4547 const EVENT_RESIZE = `resize${EVENT_KEY$3}`; 4548 const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`; 4549 const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`; 4550 const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]'; 4551 const Default$5 = { 4552 backdrop: true, 4553 keyboard: true, 4554 scroll: false 4555 }; 4556 const DefaultType$5 = { 4557 backdrop: '(boolean|string)', 4558 keyboard: 'boolean', 4559 scroll: 'boolean' 4560 }; 4561 4562 /** 4563 * Class definition 4564 */ 4565 4566 class Offcanvas extends BaseComponent { 4567 constructor(element, config) { 4568 super(element, config); 4569 this._isShown = false; 4570 this._backdrop = this._initializeBackDrop(); 4571 this._focustrap = this._initializeFocusTrap(); 4572 this._addEventListeners(); 4573 } 4574 4575 // Getters 4576 static get Default() { 4577 return Default$5; 4578 } 4579 static get DefaultType() { 4580 return DefaultType$5; 4581 } 4582 static get NAME() { 4583 return NAME$6; 4584 } 4585 4586 // Public 4587 toggle(relatedTarget) { 4588 return this._isShown ? this.hide() : this.show(relatedTarget); 4589 } 4590 show(relatedTarget) { 4591 if (this._isShown) { 4592 return; 4593 } 4594 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, { 4595 relatedTarget 4596 }); 4597 if (showEvent.defaultPrevented) { 4598 return; 4599 } 4600 this._isShown = true; 4601 this._backdrop.show(); 4602 if (!this._config.scroll) { 4603 new ScrollBarHelper().hide(); 4604 } 4605 this._element.setAttribute('aria-modal', true); 4606 this._element.setAttribute('role', 'dialog'); 4607 this._element.classList.add(CLASS_NAME_SHOWING$1); 4608 const completeCallBack = () => { 4609 if (!this._config.scroll || this._config.backdrop) { 4610 this._focustrap.activate(); 4611 } 4612 this._element.classList.add(CLASS_NAME_SHOW$3); 4613 this._element.classList.remove(CLASS_NAME_SHOWING$1); 4614 EventHandler.trigger(this._element, EVENT_SHOWN$3, { 4615 relatedTarget 4616 }); 4617 }; 4618 this._queueCallback(completeCallBack, this._element, true); 4619 } 4620 hide() { 4621 if (!this._isShown) { 4622 return; 4623 } 4624 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3); 4625 if (hideEvent.defaultPrevented) { 4626 return; 4627 } 4628 this._focustrap.deactivate(); 4629 this._element.blur(); 4630 this._isShown = false; 4631 this._element.classList.add(CLASS_NAME_HIDING); 4632 this._backdrop.hide(); 4633 const completeCallback = () => { 4634 this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING); 4635 this._element.removeAttribute('aria-modal'); 4636 this._element.removeAttribute('role'); 4637 if (!this._config.scroll) { 4638 new ScrollBarHelper().reset(); 4639 } 4640 EventHandler.trigger(this._element, EVENT_HIDDEN$3); 4641 }; 4642 this._queueCallback(completeCallback, this._element, true); 4643 } 4644 dispose() { 4645 this._backdrop.dispose(); 4646 this._focustrap.deactivate(); 4647 super.dispose(); 4648 } 4649 4650 // Private 4651 _initializeBackDrop() { 4652 const clickCallback = () => { 4653 if (this._config.backdrop === 'static') { 4654 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); 4655 return; 4656 } 4657 this.hide(); 4658 }; 4659 4660 // 'static' option will be translated to true, and booleans will keep their value 4661 const isVisible = Boolean(this._config.backdrop); 4662 return new Backdrop({ 4663 className: CLASS_NAME_BACKDROP, 4664 isVisible, 4665 isAnimated: true, 4666 rootElement: this._element.parentNode, 4667 clickCallback: isVisible ? clickCallback : null 4668 }); 4669 } 4670 _initializeFocusTrap() { 4671 return new FocusTrap({ 4672 trapElement: this._element 4673 }); 4674 } 4675 _addEventListeners() { 4676 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => { 4677 if (event.key !== ESCAPE_KEY) { 4678 return; 4679 } 4680 if (this._config.keyboard) { 4681 this.hide(); 4682 return; 4683 } 4684 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); 4685 }); 4686 } 4687 4688 // Static 4689 static jQueryInterface(config) { 4690 return this.each(function () { 4691 const data = Offcanvas.getOrCreateInstance(this, config); 4692 if (typeof config !== 'string') { 4693 return; 4694 } 4695 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 4696 throw new TypeError(`No method named "${config}"`); 4697 } 4698 data[config](this); 4699 }); 4700 } 4701 } 4702 4703 /** 4704 * Data API implementation 4705 */ 4706 4707 EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) { 4708 const target = SelectorEngine.getElementFromSelector(this); 4709 if (['A', 'AREA'].includes(this.tagName)) { 4710 event.preventDefault(); 4711 } 4712 if (isDisabled(this)) { 4713 return; 4714 } 4715 EventHandler.one(target, EVENT_HIDDEN$3, () => { 4716 // focus on trigger when it is closed 4717 if (isVisible(this)) { 4718 this.focus(); 4719 } 4720 }); 4721 4722 // avoid conflict when clicking a toggler of an offcanvas, while another is open 4723 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR); 4724 if (alreadyOpen && alreadyOpen !== target) { 4725 Offcanvas.getInstance(alreadyOpen).hide(); 4726 } 4727 const data = Offcanvas.getOrCreateInstance(target); 4728 data.toggle(this); 4729 }); 4730 EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => { 4731 for (const selector of SelectorEngine.find(OPEN_SELECTOR)) { 4732 Offcanvas.getOrCreateInstance(selector).show(); 4733 } 4734 }); 4735 EventHandler.on(window, EVENT_RESIZE, () => { 4736 for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) { 4737 if (getComputedStyle(element).position !== 'fixed') { 4738 Offcanvas.getOrCreateInstance(element).hide(); 4739 } 4740 } 4741 }); 4742 enableDismissTrigger(Offcanvas); 4743 4744 /** 4745 * jQuery 4746 */ 4747 4748 defineJQueryPlugin(Offcanvas); 4749 4750 /** 4751 * -------------------------------------------------------------------------- 4752 * Bootstrap util/sanitizer.js 4753 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4754 * -------------------------------------------------------------------------- 4755 */ 4756 4757 // js-docs-start allow-list 4758 const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; 4759 const DefaultAllowlist = { 4760 // Global attributes allowed on any supplied element below. 4761 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], 4762 a: ['target', 'href', 'title', 'rel'], 4763 area: [], 4764 b: [], 4765 br: [], 4766 col: [], 4767 code: [], 4768 dd: [], 4769 div: [], 4770 dl: [], 4771 dt: [], 4772 em: [], 4773 hr: [], 4774 h1: [], 4775 h2: [], 4776 h3: [], 4777 h4: [], 4778 h5: [], 4779 h6: [], 4780 i: [], 4781 img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], 4782 li: [], 4783 ol: [], 4784 p: [], 4785 pre: [], 4786 s: [], 4787 small: [], 4788 span: [], 4789 sub: [], 4790 sup: [], 4791 strong: [], 4792 u: [], 4793 ul: [] 4794 }; 4795 // js-docs-end allow-list 4796 4797 const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']); 4798 4799 /** 4800 * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation 4801 * contexts. 4802 * 4803 * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38 4804 */ 4805 const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i; 4806 const allowedAttribute = (attribute, allowedAttributeList) => { 4807 const attributeName = attribute.nodeName.toLowerCase(); 4808 if (allowedAttributeList.includes(attributeName)) { 4809 if (uriAttributes.has(attributeName)) { 4810 return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue)); 4811 } 4812 return true; 4813 } 4814 4815 // Check if a regular expression validates the attribute. 4816 return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName)); 4817 }; 4818 function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) { 4819 if (!unsafeHtml.length) { 4820 return unsafeHtml; 4821 } 4822 if (sanitizeFunction && typeof sanitizeFunction === 'function') { 4823 return sanitizeFunction(unsafeHtml); 4824 } 4825 const domParser = new window.DOMParser(); 4826 const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); 4827 const elements = [].concat(...createdDocument.body.querySelectorAll('*')); 4828 for (const element of elements) { 4829 const elementName = element.nodeName.toLowerCase(); 4830 if (!Object.keys(allowList).includes(elementName)) { 4831 element.remove(); 4832 continue; 4833 } 4834 const attributeList = [].concat(...element.attributes); 4835 const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []); 4836 for (const attribute of attributeList) { 4837 if (!allowedAttribute(attribute, allowedAttributes)) {
vendor: 9,698 bytes, lines 4838-5171
4838 element.removeAttribute(attribute.nodeName); 4839 } 4840 } 4841 } 4842 return createdDocument.body.innerHTML; 4843 } 4844 4845 /** 4846 * -------------------------------------------------------------------------- 4847 * Bootstrap util/template-factory.js 4848 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4849 * -------------------------------------------------------------------------- 4850 */ 4851 4852 4853 /** 4854 * Constants 4855 */ 4856 4857 const NAME$5 = 'TemplateFactory'; 4858 const Default$4 = { 4859 allowList: DefaultAllowlist, 4860 content: {}, 4861 // { selector : text , selector2 : text2 , } 4862 extraClass: '', 4863 html: false, 4864 sanitize: true, 4865 sanitizeFn: null, 4866 template: '<div></div>' 4867 }; 4868 const DefaultType$4 = { 4869 allowList: 'object', 4870 content: 'object', 4871 extraClass: '(string|function)', 4872 html: 'boolean', 4873 sanitize: 'boolean', 4874 sanitizeFn: '(null|function)', 4875 template: 'string' 4876 }; 4877 const DefaultContentType = { 4878 entry: '(string|element|function|null)', 4879 selector: '(string|element)' 4880 }; 4881 4882 /** 4883 * Class definition 4884 */ 4885 4886 class TemplateFactory extends Config { 4887 constructor(config) { 4888 super(); 4889 this._config = this._getConfig(config); 4890 } 4891 4892 // Getters 4893 static get Default() { 4894 return Default$4; 4895 } 4896 static get DefaultType() { 4897 return DefaultType$4; 4898 } 4899 static get NAME() { 4900 return NAME$5; 4901 } 4902 4903 // Public 4904 getContent() { 4905 return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean); 4906 } 4907 hasContent() { 4908 return this.getContent().length > 0; 4909 } 4910 changeContent(content) { 4911 this._checkContent(content); 4912 this._config.content = { 4913 ...this._config.content, 4914 ...content 4915 }; 4916 return this; 4917 } 4918 toHtml() { 4919 const templateWrapper = document.createElement('div'); 4920 templateWrapper.innerHTML = this._maybeSanitize(this._config.template); 4921 for (const [selector, text] of Object.entries(this._config.content)) { 4922 this._setContent(templateWrapper, text, selector); 4923 } 4924 const template = templateWrapper.children[0]; 4925 const extraClass = this._resolvePossibleFunction(this._config.extraClass); 4926 if (extraClass) { 4927 template.classList.add(...extraClass.split(' ')); 4928 } 4929 return template; 4930 } 4931 4932 // Private 4933 _typeCheckConfig(config) { 4934 super._typeCheckConfig(config); 4935 this._checkContent(config.content); 4936 } 4937 _checkContent(arg) { 4938 for (const [selector, content] of Object.entries(arg)) { 4939 super._typeCheckConfig({ 4940 selector, 4941 entry: content 4942 }, DefaultContentType); 4943 } 4944 } 4945 _setContent(template, content, selector) { 4946 const templateElement = SelectorEngine.findOne(selector, template); 4947 if (!templateElement) { 4948 return; 4949 } 4950 content = this._resolvePossibleFunction(content); 4951 if (!content) { 4952 templateElement.remove(); 4953 return; 4954 } 4955 if (isElement$1(content)) { 4956 this._putElementInTemplate(getElement(content), templateElement); 4957 return; 4958 } 4959 if (this._config.html) { 4960 templateElement.innerHTML = this._maybeSanitize(content); 4961 return; 4962 } 4963 templateElement.textContent = content; 4964 } 4965 _maybeSanitize(arg) { 4966 return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg; 4967 } 4968 _resolvePossibleFunction(arg) { 4969 return execute(arg, [undefined, this]); 4970 } 4971 _putElementInTemplate(element, templateElement) { 4972 if (this._config.html) { 4973 templateElement.innerHTML = ''; 4974 templateElement.append(element); 4975 return; 4976 } 4977 templateElement.textContent = element.textContent; 4978 } 4979 } 4980 4981 /** 4982 * -------------------------------------------------------------------------- 4983 * Bootstrap tooltip.js 4984 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4985 * -------------------------------------------------------------------------- 4986 */ 4987 4988 4989 /** 4990 * Constants 4991 */ 4992 4993 const NAME$4 = 'tooltip'; 4994 const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']); 4995 const CLASS_NAME_FADE$2 = 'fade'; 4996 const CLASS_NAME_MODAL = 'modal'; 4997 const CLASS_NAME_SHOW$2 = 'show'; 4998 const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; 4999 const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`; 5000 const EVENT_MODAL_HIDE = 'hide.bs.modal'; 5001 const TRIGGER_HOVER = 'hover'; 5002 const TRIGGER_FOCUS = 'focus'; 5003 const TRIGGER_CLICK = 'click'; 5004 const TRIGGER_MANUAL = 'manual'; 5005 const EVENT_HIDE$2 = 'hide'; 5006 const EVENT_HIDDEN$2 = 'hidden'; 5007 const EVENT_SHOW$2 = 'show'; 5008 const EVENT_SHOWN$2 = 'shown'; 5009 const EVENT_INSERTED = 'inserted'; 5010 const EVENT_CLICK$1 = 'click'; 5011 const EVENT_FOCUSIN$1 = 'focusin'; 5012 const EVENT_FOCUSOUT$1 = 'focusout'; 5013 const EVENT_MOUSEENTER = 'mouseenter'; 5014 const EVENT_MOUSELEAVE = 'mouseleave'; 5015 const AttachmentMap = { 5016 AUTO: 'auto', 5017 TOP: 'top', 5018 RIGHT: isRTL() ? 'left' : 'right', 5019 BOTTOM: 'bottom', 5020 LEFT: isRTL() ? 'right' : 'left' 5021 }; 5022 const Default$3 = { 5023 allowList: DefaultAllowlist, 5024 animation: true, 5025 boundary: 'clippingParents', 5026 container: false, 5027 customClass: '', 5028 delay: 0, 5029 fallbackPlacements: ['top', 'right', 'bottom', 'left'], 5030 html: false, 5031 offset: [0, 6], 5032 placement: 'top', 5033 popperConfig: null, 5034 sanitize: true, 5035 sanitizeFn: null, 5036 selector: false, 5037 template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>', 5038 title: '', 5039 trigger: 'hover focus' 5040 }; 5041 const DefaultType$3 = { 5042 allowList: 'object', 5043 animation: 'boolean', 5044 boundary: '(string|element)', 5045 container: '(string|element|boolean)', 5046 customClass: '(string|function)', 5047 delay: '(number|object)', 5048 fallbackPlacements: 'array', 5049 html: 'boolean', 5050 offset: '(array|string|function)', 5051 placement: '(string|function)', 5052 popperConfig: '(null|object|function)', 5053 sanitize: 'boolean', 5054 sanitizeFn: '(null|function)', 5055 selector: '(string|boolean)', 5056 template: 'string', 5057 title: '(string|element|function)', 5058 trigger: 'string' 5059 }; 5060 5061 /** 5062 * Class definition 5063 */ 5064 5065 class Tooltip extends BaseComponent { 5066 constructor(element, config) { 5067 if (typeof Popper === 'undefined') { 5068 throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org/docs/v2/)'); 5069 } 5070 super(element, config); 5071 5072 // Private 5073 this._isEnabled = true; 5074 this._timeout = 0; 5075 this._isHovered = null; 5076 this._activeTrigger = {}; 5077 this._popper = null; 5078 this._templateFactory = null; 5079 this._newContent = null; 5080 5081 // Protected 5082 this.tip = null; 5083 this._setListeners(); 5084 if (!this._config.selector) { 5085 this._fixTitle(); 5086 } 5087 } 5088 5089 // Getters 5090 static get Default() { 5091 return Default$3; 5092 } 5093 static get DefaultType() { 5094 return DefaultType$3; 5095 } 5096 static get NAME() { 5097 return NAME$4; 5098 } 5099 5100 // Public 5101 enable() { 5102 this._isEnabled = true; 5103 } 5104 disable() { 5105 this._isEnabled = false; 5106 } 5107 toggleEnabled() { 5108 this._isEnabled = !this._isEnabled; 5109 } 5110 toggle() { 5111 if (!this._isEnabled) { 5112 return; 5113 } 5114 if (this._isShown()) { 5115 this._leave(); 5116 return; 5117 } 5118 this._enter(); 5119 } 5120 dispose() { 5121 clearTimeout(this._timeout); 5122 EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); 5123 if (this._element.getAttribute('data-bs-original-title')) { 5124 this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title')); 5125 } 5126 this._disposePopper(); 5127 super.dispose(); 5128 } 5129 show() { 5130 if (this._element.style.display === 'none') { 5131 throw new Error('Please use show on visible elements'); 5132 } 5133 if (!(this._isWithContent() && this._isEnabled)) { 5134 return; 5135 } 5136 const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2)); 5137 const shadowRoot = findShadowRoot(this._element); 5138 const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element); 5139 if (showEvent.defaultPrevented || !isInTheDom) { 5140 return; 5141 } 5142 5143 // TODO: v6 remove this or make it optional 5144 this._disposePopper(); 5145 const tip = this._getTipElement(); 5146 this._element.setAttribute('aria-describedby', tip.getAttribute('id')); 5147 const { 5148 container 5149 } = this._config; 5150 if (!this._element.ownerDocument.documentElement.contains(this.tip)) { 5151 container.append(tip); 5152 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED)); 5153 } 5154 this._popper = this._createPopper(tip); 5155 tip.classList.add(CLASS_NAME_SHOW$2); 5156 5157 // If this is a touch-enabled device we add extra 5158 // empty mouseover listeners to the body's immediate children; 5159 // only needed because of broken event delegation on iOS 5160 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 5161 if ('ontouchstart' in document.documentElement) { 5162 for (const element of [].concat(...document.body.children)) { 5163 EventHandler.on(element, 'mouseover', noop); 5164 } 5165 } 5166 const complete = () => { 5167 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2)); 5168 if (this._isHovered === false) { 5169 this._leave(); 5170 } 5171 this._isHovered = false;
vendor: 2,145 bytes, lines 5172-5236
5172 }; 5173 this._queueCallback(complete, this.tip, this._isAnimated()); 5174 } 5175 hide() { 5176 if (!this._isShown()) { 5177 return; 5178 } 5179 const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2)); 5180 if (hideEvent.defaultPrevented) { 5181 return; 5182 } 5183 const tip = this._getTipElement(); 5184 tip.classList.remove(CLASS_NAME_SHOW$2); 5185 5186 // If this is a touch-enabled device we remove the extra 5187 // empty mouseover listeners we added for iOS support 5188 if ('ontouchstart' in document.documentElement) { 5189 for (const element of [].concat(...document.body.children)) { 5190 EventHandler.off(element, 'mouseover', noop); 5191 } 5192 } 5193 this._activeTrigger[TRIGGER_CLICK] = false; 5194 this._activeTrigger[TRIGGER_FOCUS] = false; 5195 this._activeTrigger[TRIGGER_HOVER] = false; 5196 this._isHovered = null; // it is a trick to support manual triggering 5197 5198 const complete = () => { 5199 if (this._isWithActiveTrigger()) { 5200 return; 5201 } 5202 if (!this._isHovered) { 5203 this._disposePopper(); 5204 } 5205 this._element.removeAttribute('aria-describedby'); 5206 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2)); 5207 }; 5208 this._queueCallback(complete, this.tip, this._isAnimated()); 5209 } 5210 update() { 5211 if (this._popper) { 5212 this._popper.update(); 5213 } 5214 } 5215 5216 // Protected 5217 _isWithContent() { 5218 return Boolean(this._getTitle()); 5219 } 5220 _getTipElement() { 5221 if (!this.tip) { 5222 this.tip = this._createTipElement(this._newContent || this._getContentForTemplate()); 5223 } 5224 return this.tip; 5225 } 5226 _createTipElement(content) { 5227 const tip = this._getTemplateFactory(content).toHtml(); 5228 5229 // TODO: remove this check in v6 5230 if (!tip) { 5231 return null; 5232 } 5233 tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2); 5234 // TODO: v6 the following can be achieved with CSS only 5235 tip.classList.add(`bs-${this.constructor.NAME}-auto`); 5236 const tipId = getUID(this.constructor.NAME).toString();
vendor: 5,941 bytes, lines 5237-5400
5237 tip.setAttribute('id', tipId); 5238 if (this._isAnimated()) { 5239 tip.classList.add(CLASS_NAME_FADE$2); 5240 } 5241 return tip; 5242 } 5243 setContent(content) { 5244 this._newContent = content; 5245 if (this._isShown()) { 5246 this._disposePopper(); 5247 this.show(); 5248 } 5249 } 5250 _getTemplateFactory(content) { 5251 if (this._templateFactory) { 5252 this._templateFactory.changeContent(content); 5253 } else { 5254 this._templateFactory = new TemplateFactory({ 5255 ...this._config, 5256 // the `content` var has to be after `this._config` 5257 // to override config.content in case of popover 5258 content, 5259 extraClass: this._resolvePossibleFunction(this._config.customClass) 5260 }); 5261 } 5262 return this._templateFactory; 5263 } 5264 _getContentForTemplate() { 5265 return { 5266 [SELECTOR_TOOLTIP_INNER]: this._getTitle() 5267 }; 5268 } 5269 _getTitle() { 5270 return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title'); 5271 } 5272 5273 // Private 5274 _initializeOnDelegatedTarget(event) { 5275 return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig()); 5276 } 5277 _isAnimated() { 5278 return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2); 5279 } 5280 _isShown() { 5281 return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2); 5282 } 5283 _createPopper(tip) { 5284 const placement = execute(this._config.placement, [this, tip, this._element]); 5285 const attachment = AttachmentMap[placement.toUpperCase()]; 5286 return createPopper(this._element, tip, this._getPopperConfig(attachment)); 5287 } 5288 _getOffset() { 5289 const { 5290 offset 5291 } = this._config; 5292 if (typeof offset === 'string') { 5293 return offset.split(',').map(value => Number.parseInt(value, 10)); 5294 } 5295 if (typeof offset === 'function') { 5296 return popperData => offset(popperData, this._element); 5297 } 5298 return offset; 5299 } 5300 _resolvePossibleFunction(arg) { 5301 return execute(arg, [this._element, this._element]); 5302 } 5303 _getPopperConfig(attachment) { 5304 const defaultBsPopperConfig = { 5305 placement: attachment, 5306 modifiers: [{ 5307 name: 'flip', 5308 options: { 5309 fallbackPlacements: this._config.fallbackPlacements 5310 } 5311 }, { 5312 name: 'offset', 5313 options: { 5314 offset: this._getOffset() 5315 } 5316 }, { 5317 name: 'preventOverflow', 5318 options: { 5319 boundary: this._config.boundary 5320 } 5321 }, { 5322 name: 'arrow', 5323 options: { 5324 element: `.${this.constructor.NAME}-arrow` 5325 } 5326 }, { 5327 name: 'preSetPlacement', 5328 enabled: true, 5329 phase: 'beforeMain', 5330 fn: data => { 5331 // Pre-set Popper's placement attribute in order to read the arrow sizes properly. 5332 // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement 5333 this._getTipElement().setAttribute('data-popper-placement', data.state.placement); 5334 } 5335 }] 5336 }; 5337 return { 5338 ...defaultBsPopperConfig, 5339 ...execute(this._config.popperConfig, [undefined, defaultBsPopperConfig]) 5340 }; 5341 } 5342 _setListeners() { 5343 const triggers = this._config.trigger.split(' '); 5344 for (const trigger of triggers) { 5345 if (trigger === 'click') { 5346 EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => { 5347 const context = this._initializeOnDelegatedTarget(event); 5348 context._activeTrigger[TRIGGER_CLICK] = !(context._isShown() && context._activeTrigger[TRIGGER_CLICK]); 5349 context.toggle(); 5350 }); 5351 } else if (trigger !== TRIGGER_MANUAL) { 5352 const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1); 5353 const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1); 5354 EventHandler.on(this._element, eventIn, this._config.selector, event => { 5355 const context = this._initializeOnDelegatedTarget(event); 5356 context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; 5357 context._enter(); 5358 }); 5359 EventHandler.on(this._element, eventOut, this._config.selector, event => { 5360 const context = this._initializeOnDelegatedTarget(event); 5361 context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget); 5362 context._leave(); 5363 }); 5364 } 5365 } 5366 this._hideModalHandler = () => { 5367 if (this._element) { 5368 this.hide(); 5369 } 5370 }; 5371 EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); 5372 } 5373 _fixTitle() { 5374 const title = this._element.getAttribute('title'); 5375 if (!title) { 5376 return; 5377 } 5378 if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) { 5379 this._element.setAttribute('aria-label', title); 5380 } 5381 this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility 5382 this._element.removeAttribute('title'); 5383 } 5384 _enter() { 5385 if (this._isShown() || this._isHovered) { 5386 this._isHovered = true; 5387 return; 5388 } 5389 this._isHovered = true; 5390 this._setTimeout(() => { 5391 if (this._isHovered) { 5392 this.show(); 5393 } 5394 }, this._config.delay.show); 5395 } 5396 _leave() { 5397 if (this._isWithActiveTrigger()) { 5398 return; 5399 } 5400 this._isHovered = false;
vendor: 28,535 bytes, lines 5401-6312
5401 this._setTimeout(() => { 5402 if (!this._isHovered) { 5403 this.hide(); 5404 } 5405 }, this._config.delay.hide); 5406 } 5407 _setTimeout(handler, timeout) { 5408 clearTimeout(this._timeout); 5409 this._timeout = setTimeout(handler, timeout); 5410 } 5411 _isWithActiveTrigger() { 5412 return Object.values(this._activeTrigger).includes(true); 5413 } 5414 _getConfig(config) { 5415 const dataAttributes = Manipulator.getDataAttributes(this._element); 5416 for (const dataAttribute of Object.keys(dataAttributes)) { 5417 if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) { 5418 delete dataAttributes[dataAttribute]; 5419 } 5420 } 5421 config = { 5422 ...dataAttributes, 5423 ...(typeof config === 'object' && config ? config : {}) 5424 }; 5425 config = this._mergeConfigObj(config); 5426 config = this._configAfterMerge(config); 5427 this._typeCheckConfig(config); 5428 return config; 5429 } 5430 _configAfterMerge(config) { 5431 config.container = config.container === false ? document.body : getElement(config.container); 5432 if (typeof config.delay === 'number') { 5433 config.delay = { 5434 show: config.delay, 5435 hide: config.delay 5436 }; 5437 } 5438 if (typeof config.title === 'number') { 5439 config.title = config.title.toString(); 5440 } 5441 if (typeof config.content === 'number') { 5442 config.content = config.content.toString(); 5443 } 5444 return config; 5445 } 5446 _getDelegateConfig() { 5447 const config = {}; 5448 for (const [key, value] of Object.entries(this._config)) { 5449 if (this.constructor.Default[key] !== value) { 5450 config[key] = value; 5451 } 5452 } 5453 config.selector = false; 5454 config.trigger = 'manual'; 5455 5456 // In the future can be replaced with: 5457 // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]]) 5458 // `Object.fromEntries(keysWithDifferentValues)` 5459 return config; 5460 } 5461 _disposePopper() { 5462 if (this._popper) { 5463 this._popper.destroy(); 5464 this._popper = null; 5465 } 5466 if (this.tip) { 5467 this.tip.remove(); 5468 this.tip = null; 5469 } 5470 } 5471 5472 // Static 5473 static jQueryInterface(config) { 5474 return this.each(function () { 5475 const data = Tooltip.getOrCreateInstance(this, config); 5476 if (typeof config !== 'string') { 5477 return; 5478 } 5479 if (typeof data[config] === 'undefined') { 5480 throw new TypeError(`No method named "${config}"`); 5481 } 5482 data[config](); 5483 }); 5484 } 5485 } 5486 5487 /** 5488 * jQuery 5489 */ 5490 5491 defineJQueryPlugin(Tooltip); 5492 5493 /** 5494 * -------------------------------------------------------------------------- 5495 * Bootstrap popover.js 5496 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5497 * -------------------------------------------------------------------------- 5498 */ 5499 5500 5501 /** 5502 * Constants 5503 */ 5504 5505 const NAME$3 = 'popover'; 5506 const SELECTOR_TITLE = '.popover-header'; 5507 const SELECTOR_CONTENT = '.popover-body'; 5508 const Default$2 = { 5509 ...Tooltip.Default, 5510 content: '', 5511 offset: [0, 8], 5512 placement: 'right', 5513 template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>', 5514 trigger: 'click' 5515 }; 5516 const DefaultType$2 = { 5517 ...Tooltip.DefaultType, 5518 content: '(null|string|element|function)' 5519 }; 5520 5521 /** 5522 * Class definition 5523 */ 5524 5525 class Popover extends Tooltip { 5526 // Getters 5527 static get Default() { 5528 return Default$2; 5529 } 5530 static get DefaultType() { 5531 return DefaultType$2; 5532 } 5533 static get NAME() { 5534 return NAME$3; 5535 } 5536 5537 // Overrides 5538 _isWithContent() { 5539 return this._getTitle() || this._getContent(); 5540 } 5541 5542 // Private 5543 _getContentForTemplate() { 5544 return { 5545 [SELECTOR_TITLE]: this._getTitle(), 5546 [SELECTOR_CONTENT]: this._getContent() 5547 }; 5548 } 5549 _getContent() { 5550 return this._resolvePossibleFunction(this._config.content); 5551 } 5552 5553 // Static 5554 static jQueryInterface(config) { 5555 return this.each(function () { 5556 const data = Popover.getOrCreateInstance(this, config); 5557 if (typeof config !== 'string') { 5558 return; 5559 } 5560 if (typeof data[config] === 'undefined') { 5561 throw new TypeError(`No method named "${config}"`); 5562 } 5563 data[config](); 5564 }); 5565 } 5566 } 5567 5568 /** 5569 * jQuery 5570 */ 5571 5572 defineJQueryPlugin(Popover); 5573 5574 /** 5575 * -------------------------------------------------------------------------- 5576 * Bootstrap scrollspy.js 5577 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5578 * -------------------------------------------------------------------------- 5579 */ 5580 5581 5582 /** 5583 * Constants 5584 */ 5585 5586 const NAME$2 = 'scrollspy'; 5587 const DATA_KEY$2 = 'bs.scrollspy'; 5588 const EVENT_KEY$2 = `.${DATA_KEY$2}`; 5589 const DATA_API_KEY = '.data-api'; 5590 const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`; 5591 const EVENT_CLICK = `click${EVENT_KEY$2}`; 5592 const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`; 5593 const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'; 5594 const CLASS_NAME_ACTIVE$1 = 'active'; 5595 const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]'; 5596 const SELECTOR_TARGET_LINKS = '[href]'; 5597 const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'; 5598 const SELECTOR_NAV_LINKS = '.nav-link'; 5599 const SELECTOR_NAV_ITEMS = '.nav-item'; 5600 const SELECTOR_LIST_ITEMS = '.list-group-item'; 5601 const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`; 5602 const SELECTOR_DROPDOWN = '.dropdown'; 5603 const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle'; 5604 const Default$1 = { 5605 offset: null, 5606 // TODO: v6 @deprecated, keep it for backwards compatibility reasons 5607 rootMargin: '0px 0px -25%', 5608 smoothScroll: false, 5609 target: null, 5610 threshold: [0.1, 0.5, 1] 5611 }; 5612 const DefaultType$1 = { 5613 offset: '(number|null)', 5614 // TODO v6 @deprecated, keep it for backwards compatibility reasons 5615 rootMargin: 'string', 5616 smoothScroll: 'boolean', 5617 target: 'element', 5618 threshold: 'array' 5619 }; 5620 5621 /** 5622 * Class definition 5623 */ 5624 5625 class ScrollSpy extends BaseComponent { 5626 constructor(element, config) { 5627 super(element, config); 5628 5629 // this._element is the observablesContainer and config.target the menu links wrapper 5630 this._targetLinks = new Map(); 5631 this._observableSections = new Map(); 5632 this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element; 5633 this._activeTarget = null; 5634 this._observer = null; 5635 this._previousScrollData = { 5636 visibleEntryTop: 0, 5637 parentScrollTop: 0 5638 }; 5639 this.refresh(); // initialize 5640 } 5641 5642 // Getters 5643 static get Default() { 5644 return Default$1; 5645 } 5646 static get DefaultType() { 5647 return DefaultType$1; 5648 } 5649 static get NAME() { 5650 return NAME$2; 5651 } 5652 5653 // Public 5654 refresh() { 5655 this._initializeTargetsAndObservables(); 5656 this._maybeEnableSmoothScroll(); 5657 if (this._observer) { 5658 this._observer.disconnect(); 5659 } else { 5660 this._observer = this._getNewObserver(); 5661 } 5662 for (const section of this._observableSections.values()) { 5663 this._observer.observe(section); 5664 } 5665 } 5666 dispose() { 5667 this._observer.disconnect(); 5668 super.dispose(); 5669 } 5670 5671 // Private 5672 _configAfterMerge(config) { 5673 // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case 5674 config.target = getElement(config.target) || document.body; 5675 5676 // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only 5677 config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin; 5678 if (typeof config.threshold === 'string') { 5679 config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value)); 5680 } 5681 return config; 5682 } 5683 _maybeEnableSmoothScroll() { 5684 if (!this._config.smoothScroll) { 5685 return; 5686 } 5687 5688 // unregister any previous listeners 5689 EventHandler.off(this._config.target, EVENT_CLICK); 5690 EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => { 5691 const observableSection = this._observableSections.get(event.target.hash); 5692 if (observableSection) { 5693 event.preventDefault(); 5694 const root = this._rootElement || window; 5695 const height = observableSection.offsetTop - this._element.offsetTop; 5696 if (root.scrollTo) { 5697 root.scrollTo({ 5698 top: height, 5699 behavior: 'smooth' 5700 }); 5701 return; 5702 } 5703 5704 // Chrome 60 doesn't support `scrollTo` 5705 root.scrollTop = height; 5706 } 5707 }); 5708 } 5709 _getNewObserver() { 5710 const options = { 5711 root: this._rootElement, 5712 threshold: this._config.threshold, 5713 rootMargin: this._config.rootMargin 5714 }; 5715 return new IntersectionObserver(entries => this._observerCallback(entries), options); 5716 } 5717 5718 // The logic of selection 5719 _observerCallback(entries) { 5720 const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`); 5721 const activate = entry => { 5722 this._previousScrollData.visibleEntryTop = entry.target.offsetTop; 5723 this._process(targetElement(entry)); 5724 }; 5725 const parentScrollTop = (this._rootElement || document.documentElement).scrollTop; 5726 const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop; 5727 this._previousScrollData.parentScrollTop = parentScrollTop; 5728 for (const entry of entries) { 5729 if (!entry.isIntersecting) { 5730 this._activeTarget = null; 5731 this._clearActiveClass(targetElement(entry)); 5732 continue; 5733 } 5734 const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; 5735 // if we are scrolling down, pick the bigger offsetTop 5736 if (userScrollsDown && entryIsLowerThanPrevious) { 5737 activate(entry); 5738 // if parent isn't scrolled, let's keep the first visible item, breaking the iteration 5739 if (!parentScrollTop) { 5740 return; 5741 } 5742 continue; 5743 } 5744 5745 // if we are scrolling up, pick the smallest offsetTop 5746 if (!userScrollsDown && !entryIsLowerThanPrevious) { 5747 activate(entry); 5748 } 5749 } 5750 } 5751 _initializeTargetsAndObservables() { 5752 this._targetLinks = new Map(); 5753 this._observableSections = new Map(); 5754 const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target); 5755 for (const anchor of targetLinks) { 5756 // ensure that the anchor has an id and is not disabled 5757 if (!anchor.hash || isDisabled(anchor)) { 5758 continue; 5759 } 5760 const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element); 5761 5762 // ensure that the observableSection exists & is visible 5763 if (isVisible(observableSection)) { 5764 this._targetLinks.set(decodeURI(anchor.hash), anchor); 5765 this._observableSections.set(anchor.hash, observableSection); 5766 } 5767 } 5768 } 5769 _process(target) { 5770 if (this._activeTarget === target) { 5771 return; 5772 } 5773 this._clearActiveClass(this._config.target); 5774 this._activeTarget = target; 5775 target.classList.add(CLASS_NAME_ACTIVE$1); 5776 this._activateParents(target); 5777 EventHandler.trigger(this._element, EVENT_ACTIVATE, { 5778 relatedTarget: target 5779 }); 5780 } 5781 _activateParents(target) { 5782 // Activate dropdown parents 5783 if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) { 5784 SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1); 5785 return; 5786 } 5787 for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) { 5788 // Set triggered links parents as active 5789 // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor 5790 for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) { 5791 item.classList.add(CLASS_NAME_ACTIVE$1); 5792 } 5793 } 5794 } 5795 _clearActiveClass(parent) { 5796 parent.classList.remove(CLASS_NAME_ACTIVE$1); 5797 const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`, parent); 5798 for (const node of activeNodes) { 5799 node.classList.remove(CLASS_NAME_ACTIVE$1); 5800 } 5801 } 5802 5803 // Static 5804 static jQueryInterface(config) { 5805 return this.each(function () { 5806 const data = ScrollSpy.getOrCreateInstance(this, config); 5807 if (typeof config !== 'string') { 5808 return; 5809 } 5810 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 5811 throw new TypeError(`No method named "${config}"`); 5812 } 5813 data[config](); 5814 }); 5815 } 5816 } 5817 5818 /** 5819 * Data API implementation 5820 */ 5821 5822 EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => { 5823 for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) { 5824 ScrollSpy.getOrCreateInstance(spy); 5825 } 5826 }); 5827 5828 /** 5829 * jQuery 5830 */ 5831 5832 defineJQueryPlugin(ScrollSpy); 5833 5834 /** 5835 * -------------------------------------------------------------------------- 5836 * Bootstrap tab.js 5837 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5838 * -------------------------------------------------------------------------- 5839 */ 5840 5841 5842 /** 5843 * Constants 5844 */ 5845 5846 const NAME$1 = 'tab'; 5847 const DATA_KEY$1 = 'bs.tab'; 5848 const EVENT_KEY$1 = `.${DATA_KEY$1}`; 5849 const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`; 5850 const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`; 5851 const EVENT_SHOW$1 = `show${EVENT_KEY$1}`; 5852 const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`; 5853 const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}`; 5854 const EVENT_KEYDOWN = `keydown${EVENT_KEY$1}`; 5855 const EVENT_LOAD_DATA_API = `load${EVENT_KEY$1}`; 5856 const ARROW_LEFT_KEY = 'ArrowLeft'; 5857 const ARROW_RIGHT_KEY = 'ArrowRight'; 5858 const ARROW_UP_KEY = 'ArrowUp'; 5859 const ARROW_DOWN_KEY = 'ArrowDown'; 5860 const HOME_KEY = 'Home'; 5861 const END_KEY = 'End'; 5862 const CLASS_NAME_ACTIVE = 'active'; 5863 const CLASS_NAME_FADE$1 = 'fade'; 5864 const CLASS_NAME_SHOW$1 = 'show'; 5865 const CLASS_DROPDOWN = 'dropdown'; 5866 const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'; 5867 const SELECTOR_DROPDOWN_MENU = '.dropdown-menu'; 5868 const NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`; 5869 const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]'; 5870 const SELECTOR_OUTER = '.nav-item, .list-group-item'; 5871 const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`; 5872 const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6 5873 const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`; 5874 const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`; 5875 5876 /** 5877 * Class definition 5878 */ 5879 5880 class Tab extends BaseComponent { 5881 constructor(element) { 5882 super(element); 5883 this._parent = this._element.closest(SELECTOR_TAB_PANEL); 5884 if (!this._parent) { 5885 return; 5886 // TODO: should throw exception in v6 5887 // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`) 5888 } 5889 5890 // Set up initial aria attributes 5891 this._setInitialAttributes(this._parent, this._getChildren()); 5892 EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event)); 5893 } 5894 5895 // Getters 5896 static get NAME() { 5897 return NAME$1; 5898 } 5899 5900 // Public 5901 show() { 5902 // Shows this elem and deactivate the active sibling if exists 5903 const innerElem = this._element; 5904 if (this._elemIsActive(innerElem)) { 5905 return; 5906 } 5907 5908 // Search for active tab on same parent to deactivate it 5909 const active = this._getActiveElem(); 5910 const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE$1, { 5911 relatedTarget: innerElem 5912 }) : null; 5913 const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW$1, { 5914 relatedTarget: active 5915 }); 5916 if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) { 5917 return; 5918 } 5919 this._deactivate(active, innerElem); 5920 this._activate(innerElem, active); 5921 } 5922 5923 // Private 5924 _activate(element, relatedElem) { 5925 if (!element) { 5926 return; 5927 } 5928 element.classList.add(CLASS_NAME_ACTIVE); 5929 this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section 5930 5931 const complete = () => { 5932 if (element.getAttribute('role') !== 'tab') { 5933 element.classList.add(CLASS_NAME_SHOW$1); 5934 return; 5935 } 5936 element.removeAttribute('tabindex'); 5937 element.setAttribute('aria-selected', true); 5938 this._toggleDropDown(element, true); 5939 EventHandler.trigger(element, EVENT_SHOWN$1, { 5940 relatedTarget: relatedElem 5941 }); 5942 }; 5943 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1)); 5944 } 5945 _deactivate(element, relatedElem) { 5946 if (!element) { 5947 return; 5948 } 5949 element.classList.remove(CLASS_NAME_ACTIVE); 5950 element.blur(); 5951 this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too 5952 5953 const complete = () => { 5954 if (element.getAttribute('role') !== 'tab') { 5955 element.classList.remove(CLASS_NAME_SHOW$1); 5956 return; 5957 } 5958 element.setAttribute('aria-selected', false); 5959 element.setAttribute('tabindex', '-1'); 5960 this._toggleDropDown(element, false); 5961 EventHandler.trigger(element, EVENT_HIDDEN$1, { 5962 relatedTarget: relatedElem 5963 }); 5964 }; 5965 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1)); 5966 } 5967 _keydown(event) { 5968 if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) { 5969 return; 5970 } 5971 event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page 5972 event.preventDefault(); 5973 const children = this._getChildren().filter(element => !isDisabled(element)); 5974 let nextActiveElement; 5975 if ([HOME_KEY, END_KEY].includes(event.key)) { 5976 nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1]; 5977 } else { 5978 const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key); 5979 nextActiveElement = getNextActiveElement(children, event.target, isNext, true); 5980 } 5981 if (nextActiveElement) { 5982 nextActiveElement.focus({ 5983 preventScroll: true 5984 }); 5985 Tab.getOrCreateInstance(nextActiveElement).show(); 5986 } 5987 } 5988 _getChildren() { 5989 // collection of inner elements 5990 return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent); 5991 } 5992 _getActiveElem() { 5993 return this._getChildren().find(child => this._elemIsActive(child)) || null; 5994 } 5995 _setInitialAttributes(parent, children) { 5996 this._setAttributeIfNotExists(parent, 'role', 'tablist'); 5997 for (const child of children) { 5998 this._setInitialAttributesOnChild(child); 5999 } 6000 } 6001 _setInitialAttributesOnChild(child) { 6002 child = this._getInnerElement(child); 6003 const isActive = this._elemIsActive(child); 6004 const outerElem = this._getOuterElement(child); 6005 child.setAttribute('aria-selected', isActive); 6006 if (outerElem !== child) { 6007 this._setAttributeIfNotExists(outerElem, 'role', 'presentation'); 6008 } 6009 if (!isActive) { 6010 child.setAttribute('tabindex', '-1'); 6011 } 6012 this._setAttributeIfNotExists(child, 'role', 'tab'); 6013 6014 // set attributes to the related panel too 6015 this._setInitialAttributesOnTargetPanel(child); 6016 } 6017 _setInitialAttributesOnTargetPanel(child) { 6018 const target = SelectorEngine.getElementFromSelector(child); 6019 if (!target) { 6020 return; 6021 } 6022 this._setAttributeIfNotExists(target, 'role', 'tabpanel'); 6023 if (child.id) { 6024 this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`); 6025 } 6026 } 6027 _toggleDropDown(element, open) { 6028 const outerElem = this._getOuterElement(element); 6029 if (!outerElem.classList.contains(CLASS_DROPDOWN)) { 6030 return; 6031 } 6032 const toggle = (selector, className) => { 6033 const element = SelectorEngine.findOne(selector, outerElem); 6034 if (element) { 6035 element.classList.toggle(className, open); 6036 } 6037 }; 6038 toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE); 6039 toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW$1); 6040 outerElem.setAttribute('aria-expanded', open); 6041 } 6042 _setAttributeIfNotExists(element, attribute, value) { 6043 if (!element.hasAttribute(attribute)) { 6044 element.setAttribute(attribute, value); 6045 } 6046 } 6047 _elemIsActive(elem) { 6048 return elem.classList.contains(CLASS_NAME_ACTIVE); 6049 } 6050 6051 // Try to get the inner element (usually the .nav-link) 6052 _getInnerElement(elem) { 6053 return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem); 6054 } 6055 6056 // Try to get the outer element (usually the .nav-item) 6057 _getOuterElement(elem) { 6058 return elem.closest(SELECTOR_OUTER) || elem; 6059 } 6060 6061 // Static 6062 static jQueryInterface(config) { 6063 return this.each(function () { 6064 const data = Tab.getOrCreateInstance(this); 6065 if (typeof config !== 'string') { 6066 return; 6067 } 6068 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 6069 throw new TypeError(`No method named "${config}"`); 6070 } 6071 data[config](); 6072 }); 6073 } 6074 } 6075 6076 /** 6077 * Data API implementation 6078 */ 6079 6080 EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { 6081 if (['A', 'AREA'].includes(this.tagName)) { 6082 event.preventDefault(); 6083 } 6084 if (isDisabled(this)) { 6085 return; 6086 } 6087 Tab.getOrCreateInstance(this).show(); 6088 }); 6089 6090 /** 6091 * Initialize on focus 6092 */ 6093 EventHandler.on(window, EVENT_LOAD_DATA_API, () => { 6094 for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) { 6095 Tab.getOrCreateInstance(element); 6096 } 6097 }); 6098 /** 6099 * jQuery 6100 */ 6101 6102 defineJQueryPlugin(Tab); 6103 6104 /** 6105 * -------------------------------------------------------------------------- 6106 * Bootstrap toast.js 6107 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6108 * -------------------------------------------------------------------------- 6109 */ 6110 6111 6112 /** 6113 * Constants 6114 */ 6115 6116 const NAME = 'toast'; 6117 const DATA_KEY = 'bs.toast'; 6118 const EVENT_KEY = `.${DATA_KEY}`; 6119 const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`; 6120 const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`; 6121 const EVENT_FOCUSIN = `focusin${EVENT_KEY}`; 6122 const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`; 6123 const EVENT_HIDE = `hide${EVENT_KEY}`; 6124 const EVENT_HIDDEN = `hidden${EVENT_KEY}`; 6125 const EVENT_SHOW = `show${EVENT_KEY}`; 6126 const EVENT_SHOWN = `shown${EVENT_KEY}`; 6127 const CLASS_NAME_FADE = 'fade'; 6128 const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility 6129 const CLASS_NAME_SHOW = 'show'; 6130 const CLASS_NAME_SHOWING = 'showing'; 6131 const DefaultType = { 6132 animation: 'boolean', 6133 autohide: 'boolean', 6134 delay: 'number' 6135 }; 6136 const Default = { 6137 animation: true, 6138 autohide: true, 6139 delay: 5000 6140 }; 6141 6142 /** 6143 * Class definition 6144 */ 6145 6146 class Toast extends BaseComponent { 6147 constructor(element, config) { 6148 super(element, config); 6149 this._timeout = null; 6150 this._hasMouseInteraction = false; 6151 this._hasKeyboardInteraction = false; 6152 this._setListeners(); 6153 } 6154 6155 // Getters 6156 static get Default() { 6157 return Default; 6158 } 6159 static get DefaultType() { 6160 return DefaultType; 6161 } 6162 static get NAME() { 6163 return NAME; 6164 } 6165 6166 // Public 6167 show() { 6168 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW); 6169 if (showEvent.defaultPrevented) { 6170 return; 6171 } 6172 this._clearTimeout(); 6173 if (this._config.animation) { 6174 this._element.classList.add(CLASS_NAME_FADE); 6175 } 6176 const complete = () => { 6177 this._element.classList.remove(CLASS_NAME_SHOWING); 6178 EventHandler.trigger(this._element, EVENT_SHOWN); 6179 this._maybeScheduleHide(); 6180 }; 6181 this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated 6182 reflow(this._element); 6183 this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING); 6184 this._queueCallback(complete, this._element, this._config.animation); 6185 } 6186 hide() { 6187 if (!this.isShown()) { 6188 return; 6189 } 6190 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE); 6191 if (hideEvent.defaultPrevented) { 6192 return; 6193 } 6194 const complete = () => { 6195 this._element.classList.add(CLASS_NAME_HIDE); // @deprecated 6196 this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW); 6197 EventHandler.trigger(this._element, EVENT_HIDDEN); 6198 }; 6199 this._element.classList.add(CLASS_NAME_SHOWING); 6200 this._queueCallback(complete, this._element, this._config.animation); 6201 } 6202 dispose() { 6203 this._clearTimeout(); 6204 if (this.isShown()) { 6205 this._element.classList.remove(CLASS_NAME_SHOW); 6206 } 6207 super.dispose(); 6208 } 6209 isShown() { 6210 return this._element.classList.contains(CLASS_NAME_SHOW); 6211 } 6212 6213 // Private 6214 _maybeScheduleHide() { 6215 if (!this._config.autohide) { 6216 return; 6217 } 6218 if (this._hasMouseInteraction || this._hasKeyboardInteraction) { 6219 return; 6220 } 6221 this._timeout = setTimeout(() => { 6222 this.hide(); 6223 }, this._config.delay); 6224 } 6225 _onInteraction(event, isInteracting) { 6226 switch (event.type) { 6227 case 'mouseover': 6228 case 'mouseout': 6229 { 6230 this._hasMouseInteraction = isInteracting; 6231 break; 6232 } 6233 case 'focusin': 6234 case 'focusout': 6235 { 6236 this._hasKeyboardInteraction = isInteracting; 6237 break; 6238 } 6239 } 6240 if (isInteracting) { 6241 this._clearTimeout(); 6242 return; 6243 } 6244 const nextElement = event.relatedTarget; 6245 if (this._element === nextElement || this._element.contains(nextElement)) { 6246 return; 6247 } 6248 this._maybeScheduleHide(); 6249 } 6250 _setListeners() { 6251 EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true)); 6252 EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false)); 6253 EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true)); 6254 EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false)); 6255 } 6256 _clearTimeout() { 6257 clearTimeout(this._timeout); 6258 this._timeout = null; 6259 } 6260 6261 // Static 6262 static jQueryInterface(config) { 6263 return this.each(function () { 6264 const data = Toast.getOrCreateInstance(this, config); 6265 if (typeof config === 'string') { 6266 if (typeof data[config] === 'undefined') { 6267 throw new TypeError(`No method named "${config}"`); 6268 } 6269 data[config](this); 6270 } 6271 }); 6272 } 6273 } 6274 6275 /** 6276 * Data API implementation 6277 */ 6278 6279 enableDismissTrigger(Toast); 6280 6281 /** 6282 * jQuery 6283 */ 6284 6285 defineJQueryPlugin(Toast); 6286 6287 /** 6288 * -------------------------------------------------------------------------- 6289 * Bootstrap index.umd.js 6290 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6291 * -------------------------------------------------------------------------- 6292 */ 6293 6294 const index_umd = { 6295 Alert, 6296 Button, 6297 Carousel, 6298 Collapse, 6299 Dropdown, 6300 Modal, 6301 Offcanvas, 6302 Popover, 6303 ScrollSpy, 6304 Tab, 6305 Toast, 6306 Tooltip 6307 }; 6308 6309 return index_umd; 6310 6311})); 6312//# sourceMappingURL=bootstrap.
6312bundle.js.map 6313 6314; 6315(function ($) { 6316 'use strict'; 6317 6318 var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; 6319 6320 var uriAttrs = [ 6321 'background', 6322 'cite', 6323 'href', 6324 'itemtype', 6325 'longdesc', 6326 'poster', 6327 'src', 6328 'xlink:href' 6329 ]; 6330 6331 var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; 6332 6333 var DefaultWhitelist = { 6334 // Global attributes allowed on any supplied element below. 6335 '*': ['class', 'dir', 'id', 'lang', 'role', 'tabindex', 'style', ARIA_ATTRIBUTE_PATTERN], 6336 a: ['target', 'href', 'title', 'rel'], 6337 area: [], 6338 b: [], 6339 br: [], 6340 col: [], 6341 code: [], 6342 div: [], 6343 em: [], 6344 hr: [], 6345 h1: [], 6346 h2: [], 6347 h3: [], 6348 h4: [], 6349 h5: [], 6350 h6: [], 6351 i: [], 6352 img: ['src', 'alt', 'title', 'width', 'height'], 6353 li: [], 6354 ol: [], 6355 p: [], 6356 pre: [], 6357 s: [], 6358 small: [], 6359 span: [], 6360 sub: [], 6361 sup: [], 6362 strong: [], 6363 u: [], 6364 ul: [] 6365 }; 6366 6367 /** 6368 * A pattern that recognizes a commonly useful subset of URLs that are safe. 6369 * 6370 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts 6371 */ 6372 var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi; 6373 6374 /** 6375 * A pattern that matches safe data URLs. Only matches image, video and audio types. 6376 * 6377 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts 6378 */ 6379 var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i; 6380 6381 var ParseableAttributes = ['title', 'placeholder']; // attributes to use as settings, can add others in the future 6382 6383 function allowedAttribute (attr, allowedAttributeList) { 6384 var attrName = attr.nodeName.toLowerCase(); 6385 6386 if ($.inArray(attrName, allowedAttributeList) !== -1) { 6387 if ($.inArray(attrName, uriAttrs) !== -1) { 6388 return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); 6389 } 6390 6391 return true; 6392 } 6393 6394 var regExp = $(allowedAttributeList).filter(function (index, value) { 6395 return value instanceof RegExp; 6396 }); 6397 6398 // Check if a regular expression validates the attribute. 6399 for (var i = 0, l = regExp.length; i < l; i++) { 6400 if (attrName.match(regExp[i])) { 6401 return true; 6402 } 6403 } 6404 6405 return false; 6406 } 6407 6408 function sanitizeHtml (unsafeElements, whiteList, sanitizeFn) { 6409 if (sanitizeFn && typeof sanitizeFn === 'function') { 6410 return sanitizeFn(unsafeElements); 6411 } 6412 6413 var whitelistKeys = Object.keys(whiteList); 6414 6415 for (var i = 0, len = unsafeElements.length; i < len; i++) { 6416 var elements = unsafeElements[i].querySelectorAll('*'); 6417 6418 for (var j = 0, len2 = elements.length; j < len2; j++) { 6419 var el = elements[j]; 6420 var elName = el.nodeName.toLowerCase(); 6421 6422 if (whitelistKeys.indexOf(elName) === -1) { 6423 el.parentNode.removeChild(el); 6424 6425 continue; 6426 } 6427 6428 var attributeList = [].slice.call(el.attributes); 6429 var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); 6430 6431 for (var k = 0, len3 = attributeList.length; k < len3; k++) { 6432 var attr = attributeList[k]; 6433 6434 if (!allowedAttribute(attr, whitelistedAttributes)) { 6435 el.removeAttribute(attr.nodeName); 6436 } 6437 } 6438 } 6439 } 6440 } 6441 6442 function getAttributesObject ($select) { 6443 var attributesObject = {}, 6444 attrVal; 6445
6446 ParseableAttributes.forEach(function (item) { 6447 attrVal = $select.attr(item); 6448 if (attrVal) attributesObject[item] = attrVal; 6449 }); 6450 6451 // for backwards compatibility 6452 // (using title as placeholder is deprecated - remove in v2.0.0) 6453 if (!attributesObject.placeholder && attributesObject.title) { 6454 attributesObject.placeholder = attributesObject.title; 6455 } 6456 6457 return attributesObject; 6458 } 6459 6460 // Polyfill for browsers with no classList support 6461 // Remove in v2 6462 if (!('classList' in document.createElement('_'))) { 6463 (function (view) { 6464 if (!('Element' in view)) return; 6465 6466 var classListProp = 'classList', 6467 protoProp = 'prototype', 6468 elemCtrProto = view.Element[protoProp], 6469 objCtr = Object, 6470 classListGetter = function () { 6471 var $elem = $(this); 6472 6473 return { 6474 add: function (classes) { 6475 classes = Array.prototype.slice.call(arguments).join(' '); 6476 return $elem.addClass(classes); 6477 }, 6478 remove: function (classes) { 6479 classes = Array.prototype.slice.call(arguments).join(' '); 6480 return $elem.removeClass(classes); 6481 }, 6482 toggle: function (classes, force) { 6483 return $elem.toggleClass(classes, force); 6484 }, 6485 contains: function (classes) {
6486 return $elem.hasClass(classes); 6487 } 6488 }; 6489 }; 6490 6491 if (objCtr.defineProperty) { 6492 var classListPropDesc = { 6493 get: classListGetter, 6494 enumerable: true, 6495 configurable: true 6496 }; 6497 try { 6498 objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 6499 } catch (ex) { // IE 8 doesn't support enumerable:true 6500 // adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36 6501 // modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected 6502 if (ex.number === undefined || ex.number === -0x7FF5EC54) { 6503 classListPropDesc.enumerable = false; 6504 objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 6505 } 6506 } 6507 } else if (objCtr[protoProp].__defineGetter__) { 6508 elemCtrProto.__defineGetter__(classListProp, classListGetter); 6509 } 6510 }(window)); 6511 } 6512 6513 var testElement = document.createElement('_'); 6514 6515 testElement.classList.add('c1', 'c2'); 6516 6517 if (!testElement.classList.contains('c2')) { 6518 var _add = DOMTokenList.prototype.add, 6519 _remove = DOMTokenList.prototype.remove; 6520 6521 DOMTokenList.prototype.add = function () { 6522 Array.prototype.forEach.call(arguments, _add.bind(this)); 6523 }; 6524 6525 DOMTokenList.prototype.remove = function () { 6526 Array.prototype.forEach.call(arguments, _remove.bind(this)); 6527 }; 6528 } 6529 6530 testElement.classList.toggle('c3', false); 6531 6532 // Polyfill for IE 10 and Firefox <24, where classList.toggle does not 6533 // support the second argument. 6534 if (testElement.classList.contains('c3')) { 6535 var _toggle = DOMTokenList.prototype.toggle; 6536 6537 DOMTokenList.prototype.toggle = function (token, force) { 6538 if (1 in arguments && !this.contains(token) === !force) { 6539 return force; 6540 } else { 6541 return _toggle.call(this, token); 6542 } 6543 }; 6544 } 6545 6546 testElement = null; 6547 6548 // Polyfill for IE (remove in v2) 6549 Object.values = typeof Object.values === 'function' ? Object.values : function (obj) { 6550 return Object.keys(obj).map(function (key) { 6551 return obj[key]; 6552 }); 6553 }; 6554 6555 // shallow array comparison 6556 function isEqual (array1, array2) { 6557 return array1.length === array2.length && array1.every(function (element, index) { 6558 return element === array2[index]; 6559 }); 6560 }; 6561 6562 // <editor-fold desc="Shims"> 6563 if (!String.prototype.startsWith) { 6564 (function () { 6565 'use strict'; // needed to support `apply`/`call` with `undefined`/`null` 6566 var toString = {}.toString; 6567 var startsWith = function (search) { 6568 if (this == null) { 6569 throw new TypeError(); 6570 } 6571 var string = String(this); 6572 if (search && toString.call(search) == '[object RegExp]') { 6573 throw new TypeError(); 6574 } 6575 var stringLength = string.length; 6576 var searchString = String(search); 6577 var searchLength = searchString.length; 6578 var position = arguments.length > 1 ? arguments[1] : undefined; 6579 // `ToInteger` 6580 var pos = position ? Number(position) : 0; 6581 if (pos != pos) { // better `isNaN` 6582 pos = 0; 6583 } 6584 var start = Math.min(Math.max(pos, 0), stringLength); 6585 // Avoid the `indexOf` call if no match is possible 6586 if (searchLength + start > stringLength) { 6587 return false; 6588 } 6589 var index = -1; 6590 while (++index < searchLength) { 6591 if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) { 6592 return false; 6593 } 6594 } 6595 return true; 6596 }; 6597 if (Object.defineProperty) { 6598 Object.defineProperty(String.prototype, 'startsWith', { 6599 'value': startsWith, 6600 'configurable': true, 6601 'writable': true 6602 }); 6603 } else { 6604 String.prototype.startsWith = startsWith; 6605 } 6606 }()); 6607 } 6608 6609 function toKebabCase (str) { 6610 return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, function ($, ofs) { 6611 return (ofs ? '-' : '') + $.toLowerCase(); 6612 }); 6613 } 6614 6615 function getSelectedOptions () { 6616 var options = this.selectpicker.main.data; 6617 6618 if (this.options.source.data || this.options.source.search) { 6619 options = Object.values(this.selectpicker.optionValuesDataMap); 6620 } 6621 6622 var selectedOptions = options.filter(function (item) { 6623 if (item.selected) { 6624 if (this.options.hideDisabled && item.disabled) return false;
6625 return true; 6626 } 6627 6628 return false; 6629 }, this); 6630 6631 // ensure only 1 option is selected if multiple are set in the data source 6632 if (this.options.source.data && !this.multiple && selectedOptions.length > 1) { 6633 for (var i = 0; i < selectedOptions.length - 1; i++) { 6634 selectedOptions[i].selected = false; 6635 } 6636 6637 selectedOptions = [ selectedOptions[selectedOptions.length - 1] ]; 6638 } 6639 6640 return selectedOptions; 6641 } 6642 6643 // much faster than $.val() 6644 function getSelectValues (selectedOptions) { 6645 var value = [], 6646 options = selectedOptions || getSelectedOptions.call(this), 6647 opt; 6648 6649 for (var i = 0, len = options.length; i < len; i++) { 6650 opt = options[i]; 6651 6652 if (!opt.disabled) { 6653 value.push(opt.value === undefined ? opt.text : opt.value); 6654 } 6655 } 6656 6657 if (!this.multiple) { 6658 return !value.length ? null : value[0]; 6659 } 6660 6661 return value; 6662 } 6663 6664 // set data-selected on select element if the value has been programmatically selected 6665 // prior to initialization of bootstrap-select 6666 // * consider removing or replacing an alternative method * 6667 var valHooks = { 6668 useDefault: false, 6669 _set: $.valHooks.select.set 6670 }; 6671 6672 $.valHooks.select.set = function (elem, value) { 6673 if (value && !valHooks.useDefault) $(elem).data('selected', true); 6674 6675 return valHooks._set.apply(this, arguments); 6676 }; 6677 6678 var changedArguments = null; 6679 6680 var EventIsSupported = (function () { 6681 try { 6682 new Event('change'); 6683 return true; 6684 } catch (e) { 6685 return false; 6686 } 6687 })(); 6688 6689 $.fn.triggerNative = function (eventName) { 6690 var el = this[0], 6691 event; 6692 6693 if (el.dispatchEvent) { // for modern browsers & IE9+ 6694 if (EventIsSupported) { 6695 // For modern browsers 6696 event = new Event(eventName, { 6697 bubbles: true 6698 }); 6699 } else { 6700 // For IE since it doesn't support Event constructor 6701 event = document.createEvent('Event'); 6702 event.initEvent(eventName, true, false); 6703 } 6704 6705 el.dispatchEvent(event); 6706 } 6707 }; 6708 // </editor-fold> 6709 6710 function stringSearch (li, searchString, method, normalize) { 6711 var stringTypes = [ 6712 'display', 6713 'subtext', 6714 'tokens' 6715 ], 6716 searchSuccess = false; 6717 6718 for (var i = 0; i < stringTypes.length; i++) { 6719 var stringType = stringTypes[i], 6720 string = li[stringType]; 6721 6722 if (string) { 6723 string = string.toString(); 6724 6725 // Strip HTML tags. This isn't perfect, but it's much faster than any other method 6726 if (stringType === 'display') { 6727 string = string.replace(/<[^>]+>/g, ''); 6728 } 6729 6730 if (normalize) string = normalizeToBase(string); 6731 string = string.toUpperCase(); 6732 6733 if (typeof method === 'function') { 6734 searchSuccess = method(string, searchString); 6735 } else if (method === 'contains') { 6736 searchSuccess = string.indexOf(searchString) >= 0; 6737 } else { 6738 searchSuccess = string.startsWith(searchString); 6739 } 6740 6741 if (searchSuccess) break; 6742 } 6743 } 6744 6745 return searchSuccess; 6746 } 6747 6748 function toInteger (value) { 6749 return parseInt(value, 10) || 0; 6750 } 6751 6752 // Borrowed from Lodash (_.deburr) 6753 /** Used to map Latin Unicode letters to basic Latin letters. */ 6754 var deburredLetters = { 6755 // Latin-1 Supplement block. 6756 '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', 6757 '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', 6758 '\xc7': 'C', '\xe7': 'c', 6759 '\xd0': 'D', '\xf0': 'd', 6760 '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', 6761 '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', 6762 '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', 6763 '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', 6764 '\xd1': 'N', '\xf1': 'n', 6765 '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', 6766 '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', 6767 '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', 6768 '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', 6769 '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', 6770 '\xc6': 'Ae', '\xe6': 'ae', 6771 '\xde': 'Th', '\xfe': 'th', 6772 '\xdf': 'ss', 6773 // Latin Extended-A block. 6774 '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', 6775 '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', 6776 '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', 6777 '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', 6778 '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', 6779 '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', 6780 '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', 6781 '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', 6782 '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', 6783 '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', 6784 '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', 6785 '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', 6786 '\u0134': 'J', '\u0135': 'j', 6787 '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', 6788 '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', 6789 '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', 6790 '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', 6791 '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', 6792 '\u014c': 'O', '\u014e': 'O', '\u0150': 'O',
6793 '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', 6794 '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', 6795 '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', 6796 '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', 6797 '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', 6798 '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', 6799 '\u0163': 't', '\u0165': 't', '\u0167': 't', 6800 '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', 6801 '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', 6802 '\u0174': 'W', '\u0175': 'w', 6803 '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', 6804 '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', 6805 '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', 6806 '\u0132': 'IJ', '\u0133': 'ij', 6807 '\u0152': 'Oe', '\u0153': 'oe', 6808 '\u0149': "'n", '\u017f': 's' 6809 }; 6810 6811 /** Used to match Latin Unicode letters (excluding mathematical operators). */ 6812 var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; 6813 6814 /** Used to compose unicode character classes. */ 6815 var rsComboMarksRange = '\\u0300-\\u036f', 6816 reComboHalfMarksRange = '\\ufe20-\\ufe2f', 6817 rsComboSymbolsRange = '\\u20d0-\\u20ff', 6818 rsComboMarksExtendedRange = '\\u1ab0-\\u1aff', 6819 rsComboMarksSupplementRange = '\\u1dc0-\\u1dff', 6820 rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange + rsComboMarksExtendedRange + rsComboMarksSupplementRange; 6821 6822 /** Used to compose unicode capture groups. */ 6823 var rsCombo = '[' + rsComboRange + ']'; 6824 6825 /** 6826 * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and 6827 * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). 6828 */ 6829 var reComboMark = RegExp(rsCombo, 'g'); 6830 6831 function deburrLetter (key) { 6832 return deburredLetters[key]; 6833 }; 6834 6835 function normalizeToBase (string) { 6836 string = string.toString(); 6837 return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); 6838 } 6839 6840 // List of HTML entities for escaping. 6841 var escapeMap = { 6842 '&': '&', 6843 '<': '<', 6844 '>': '>', 6845 '"': '"', 6846 "'": ''', 6847 '`': '`' 6848 }; 6849 6850 // Functions for escaping and unescaping strings to/from HTML interpolation. 6851 var createEscaper = function (map) { 6852 var escaper = function (match) { 6853 return map[match]; 6854 }; 6855 // Regexes for identifying a key that needs to be escaped. 6856 var source = '(?:' + Object.keys(map).join('|') + ')'; 6857 var testRegexp = RegExp(source); 6858 var replaceRegexp = RegExp(source, 'g'); 6859 return function (string) { 6860 string = string == null ? '' : '' + string; 6861 return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; 6862 }; 6863 }; 6864 6865 var htmlEscape = createEscaper(escapeMap); 6866 6867 /** 6868 * ------------------------------------------------------------------------ 6869 * Constants 6870 * ------------------------------------------------------------------------ 6871 */ 6872 6873 var keyCodeMap = { 6874 32: ' ', 6875 48: '0', 6876 49: '1', 6877 50: '2', 6878 51: '3', 6879 52: '4', 6880 53: '5', 6881 54: '6', 6882 55: '7', 6883 56: '8', 6884 57: '9', 6885 59: ';', 6886 65: 'A', 6887 66: 'B', 6888 67: 'C', 6889 68: 'D', 6890 69: 'E', 6891 70: 'F', 6892 71: 'G', 6893 72: 'H', 6894 73: 'I', 6895 74: 'J', 6896 75: 'K', 6897 76: 'L', 6898 77: 'M', 6899 78: 'N', 6900 79: 'O', 6901 80: 'P', 6902 81: 'Q', 6903 82: 'R', 6904 83: 'S', 6905 84: 'T', 6906 85: 'U', 6907 86: 'V', 6908 87: 'W', 6909 88: 'X', 6910 89: 'Y', 6911 90: 'Z', 6912 96: '0', 6913 97: '1', 6914 98: '2', 6915 99: '3', 6916 100: '4', 6917 101: '5', 6918 102: '6', 6919 103: '7', 6920 104: '8', 6921 105: '9' 6922 }; 6923 6924 var keyCodes = { 6925 ESCAPE: 27, // KeyboardEvent.which value for Escape (Esc) key 6926 ENTER: 13, // KeyboardEvent.which value for Enter key 6927 SPACE: 32, // KeyboardEvent.which value for space key 6928 TAB: 9, // KeyboardEvent.which value for tab key 6929 ARROW_UP: 38, // KeyboardEvent.which value for up arrow key 6930 ARROW_DOWN: 40 // KeyboardEvent.which value for down arrow key 6931 }; 6932 6933 // eslint-disable-next-line no-undef 6934 var Dropdown = window.Dropdown || bootstrap.Dropdown; 6935 6936 function getVersion () { 6937 var version; 6938 6939 try { 6940 version = $.fn.dropdown.Constructor.VERSION; 6941 } catch (err) { 6942 version = Dropdown.VERSION; 6943 } 6944 6945 return version; 6946 } 6947 6948 var version = { 6949 success: false, 6950 major: '3' 6951 }; 6952 6953 try { 6954 version.full = (getVersion() || '').split(' ')[0].split('.'); 6955 version.major = version.full[0]; 6956 version.success = true; 6957 } catch (err) { 6958 // do nothing 6959 } 6960 6961 var selectId = 0; 6962 6963 var EVENT_KEY = '.bs.select'; 6964 6965 var classNames = { 6966 DISABLED: 'disabled',
6967 DIVIDER: 'divider', 6968 SHOW: 'open', 6969 DROPUP: 'dropup', 6970 MENU: 'dropdown-menu', 6971 MENURIGHT: 'dropdown-menu-right', 6972 MENULEFT: 'dropdown-menu-left', 6973 // to-do: replace with more advanced template/customization options 6974 BUTTONCLASS: 'btn-default', 6975 POPOVERHEADER: 'popover-title', 6976 ICONBASE: 'glyphicon', 6977 TICKICON: 'glyphicon-ok' 6978 }; 6979 6980 var Selector = { 6981 MENU: '.' + classNames.MENU, 6982 DATA_TOGGLE: 'data-toggle="dropdown"' 6983 }; 6984 6985 var elementTemplates = { 6986 div: document.createElement('div'), 6987 span: document.createElement('span'), 6988 i: document.createElement('i'), 6989 subtext: document.createElement('small'), 6990 a: document.createElement('a'), 6991 li: document.createElement('li'), 6992 whitespace: document.createTextNode('\u00A0'), 6993 fragment: document.createDocumentFragment(), 6994 option: document.createElement('option') 6995 }; 6996 6997 elementTemplates.selectedOption = elementTemplates.option.cloneNode(false); 6998 elementTemplates.selectedOption.setAttribute('selected', true); 6999 7000 elementTemplates.noResults = elementTemplates.li.cloneNode(false); 7001 elementTemplates.noResults.className = 'no-results'; 7002 7003 elementTemplates.a.setAttribute('role', 'option'); 7004 elementTemplates.a.className = 'dropdown-item'; 7005 7006 elementTemplates.subtext.className = 'text-muted'; 7007 7008 elementTemplates.text = elementTemplates.span.cloneNode(false); 7009 elementTemplates.text.className = 'text'; 7010 7011 elementTemplates.checkMark = elementTemplates.span.cloneNode(false); 7012 7013 var REGEXP_ARROW = new RegExp(keyCodes.ARROW_UP + '|' + keyCodes.ARROW_DOWN); 7014 var REGEXP_TAB_OR_ESCAPE = new RegExp('^' + keyCodes.TAB + '$|' + keyCodes.ESCAPE); 7015 7016 var generateOption = { 7017 li: function (content, classes, optgroup) { 7018 var li = elementTemplates.li.cloneNode(false); 7019 7020 if (content) { 7021 if (content.nodeType === 1 || content.nodeType === 11) { 7022 li.appendChild(content); 7023 } else { 7024 li.innerHTML = content; 7025 } 7026 } 7027 7028 if (typeof classes !== 'undefined' && classes !== '') li.className = classes; 7029 if (typeof optgroup !== 'undefined' && optgroup !== null) li.classList.add('optgroup-' + optgroup); 7030 7031 return li; 7032 }, 7033 7034 a: function (text, classes, inline) { 7035 var a = elementTemplates.a.cloneNode(true); 7036 7037 if (text) { 7038 if (text.nodeType === 11) { 7039 a.appendChild(text); 7040 } else { 7041 a.insertAdjacentHTML('beforeend', text); 7042 } 7043 } 7044 7045 if (typeof classes !== 'undefined' && classes !== '') a.classList.add.apply(a.classList, classes.split(/\s+/)); 7046 if (inline) a.setAttribute('style', inline); 7047 7048 return a; 7049 }, 7050 7051 text: function (options, useFragment) { 7052 var textElement = elementTemplates.text.cloneNode(false), 7053 subtextElement, 7054 iconElement; 7055 7056 if (options.content) { 7057 textElement.innerHTML = options.content; 7058 } else { 7059 textElement.textContent = options.text; 7060 7061 if (options.icon) { 7062 var whitespace = elementTemplates.whitespace.cloneNode(false); 7063 7064 // need to use <i> for icons in the button to prevent a breaking change 7065 // note: switch to span in next major release 7066 iconElement = (useFragment === true ? elementTemplates.i : elementTemplates.span).cloneNode(false); 7067 iconElement.className = this.options.iconBase + ' ' + options.icon; 7068 7069 elementTemplates.fragment.appendChild(iconElement); 7070 elementTemplates.fragment.appendChild(whitespace); 7071 } 7072 7073 if (options.subtext) { 7074 subtextElement = elementTemplates.subtext.cloneNode(false); 7075 subtextElement.textContent = options.subtext; 7076 textElement.appendChild(subtextElement); 7077 } 7078 } 7079 7080 if (useFragment === true) { 7081 while (textElement.childNodes.length > 0) { 7082 elementTemplates.fragment.appendChild(textElement.childNodes[0]); 7083 } 7084 } else { 7085 elementTemplates.fragment.appendChild(textElement); 7086 } 7087 7088 return elementTemplates.fragment; 7089 }, 7090 7091 label: function (options) { 7092 var textElement = elementTemplates.text.cloneNode(false), 7093 subtextElement, 7094 iconElement; 7095 7096 textElement.innerHTML = options.display; 7097 7098 if (options.icon) { 7099 var whitespace = elementTemplates.whitespace.cloneNode(false); 7100 7101 iconElement = elementTemplates.span.cloneNode(false); 7102 iconElement.className = this.options.iconBase + ' ' + options.icon; 7103 7104 elementTemplates.fragment.appendChild(iconElement); 7105 elementTemplates.fragment.appendChild(whitespace); 7106 } 7107 7108 if (options.subtext) { 7109 subtextElement = elementTemplates.subtext.cloneNode(false); 7110 subtextElement.textContent = options.subtext; 7111 textElement.appendChild(subtextElement); 7112 } 7113 7114 elementTemplates.fragment.appendChild(textElement); 7115 7116 return elementTemplates.fragment; 7117 } 7118 }; 7119 7120 var getOptionData = { 7121 fromOption: function (option, type) { 7122 var value; 7123 7124 switch (type) {
7125 case 'divider': 7126 value = option.getAttribute('data-divider') === 'true'; 7127 break; 7128 7129 case 'text': 7130 value = option.textContent; 7131 break; 7132 7133 case 'label': 7134 value = option.label; 7135 break; 7136 7137 case 'style': 7138 value = option.style.cssText; 7139 break; 7140 7141 case 'title': 7142 value = option.title; 7143 break; 7144 7145 default: 7146 value = option.getAttribute('data-' + toKebabCase(type)); 7147 break; 7148 } 7149 7150 return value; 7151 }, 7152 fromDataSource: function (option, type) { 7153 var value; 7154 7155 switch (type) { 7156 case 'text': 7157 case 'label': 7158 value = option.text || option.value || ''; 7159 break; 7160 7161 default: 7162 value = option[type]; 7163 break; 7164 } 7165 7166 return value; 7167 } 7168 }; 7169 7170 function showNoResults (searchMatch, searchValue) { 7171 if (!searchMatch.length) { 7172 elementTemplates.noResults.innerHTML = this.options.noneResultsText.replace('{0}', '"' + htmlEscape(searchValue) + '"'); 7173 this.$menuInner[0].firstChild.appendChild(elementTemplates.noResults); 7174 } 7175 } 7176 7177 function filterHidden (item) { 7178 return !(item.hidden || this.options.hideDisabled && item.disabled); 7179 } 7180 7181 var Selectpicker = function (element, options) { 7182 var that = this; 7183 7184 // bootstrap-select has been initialized - revert valHooks.select.set back to its original function 7185 if (!valHooks.useDefault) { 7186 $.valHooks.select.set = valHooks._set; 7187 valHooks.useDefault = true; 7188 } 7189 7190 this.$element = $(element); 7191 this.$newElement = null; 7192 this.$button = null; 7193 this.$menu = null; 7194 this.options = options; 7195 this.selectpicker = { 7196 main: { 7197 data: [], 7198 optionQueue: elementTemplates.fragment.cloneNode(false), 7199 hasMore: false 7200 }, 7201 search: { 7202 data: [], 7203 hasMore: false 7204 }, 7205 current: {}, // current is either equal to main or search depending on if a search is in progress 7206 view: {}, 7207 // map of option values and their respective data (only used in conjunction with options.source) 7208 optionValuesDataMap: {}, 7209 isSearching: false, 7210 keydown: { 7211 keyHistory: '', 7212 resetKeyHistory: { 7213 start: function () { 7214 return setTimeout(function () { 7215 that.selectpicker.keydown.keyHistory = ''; 7216 }, 800); 7217 } 7218 } 7219 } 7220 }; 7221 7222 this.sizeInfo = {}; 7223 7224 // Format window padding 7225 var winPad = this.options.windowPadding; 7226 if (typeof winPad === 'number') { 7227 this.options.windowPadding = [winPad, winPad, winPad, winPad]; 7228 } 7229 7230 // Expose public methods 7231 this.val = Selectpicker.prototype.val; 7232 this.render = Selectpicker.prototype.render; 7233 this.refresh = Selectpicker.prototype.refresh; 7234 this.setStyle = Selectpicker.prototype.setStyle; 7235 this.selectAll = Selectpicker.prototype.selectAll; 7236 this.deselectAll = Selectpicker.prototype.deselectAll; 7237 this.destroy = Selectpicker.prototype.destroy; 7238 this.remove = Selectpicker.prototype.remove; 7239 this.show = Selectpicker.prototype.show; 7240 this.hide = Selectpicker.prototype.hide; 7241 7242 this.init(); 7243 }; 7244 7245 Selectpicker.VERSION = '1.14.0-beta3'; 7246 7247 // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both. 7248 Selectpicker.DEFAULTS = { 7249 noneSelectedText: 'Nothing selected', 7250 noneResultsText: 'No results matched {0}', 7251 countSelectedText: function (numSelected, numTotal) { 7252 return (numSelected == 1) ? '{0} item selected' : '{0} items selected'; 7253 }, 7254 maxOptionsText: function (numAll, numGroup) { 7255 return [ 7256 (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)', 7257 (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)' 7258 ]; 7259 }, 7260 selectAllText: 'Select All', 7261 deselectAllText: 'Deselect All', 7262 source: { 7263 pageSize: 40 7264 }, 7265 chunkSize: 40, 7266 doneButton: false, 7267 doneButtonText: 'Close', 7268 multipleSeparator: ', ', 7269 styleBase: 'btn', 7270 style: classNames.BUTTONCLASS, 7271 size: 'auto', 7272 title: null, 7273 placeholder: null, 7274 allowClear: false, 7275 selectedTextFormat: 'values', 7276 width: false, 7277 container: false, 7278 hideDisabled: false, 7279 showSubtext: false, 7280 showIcon: true, 7281 showContent: true, 7282 dropupAuto: true, 7283 header: false, 7284 liveSearch: false, 7285 liveSearchPlaceholder: null, 7286 liveSearchNormalize: false, 7287 liveSearchStyle: 'contains', 7288 actionsBox: false, 7289 iconBase: classNames.ICONBASE, 7290 tickIcon: classNames.TICKICON, 7291 showTick: false, 7292 template: { 7293 caret: '<span class="caret"></span>' 7294 }, 7295 maxOptions: false, 7296 mobile: false, 7297 selectOnTab: true, 7298 dropdownAlignRight: false, 7299 windowPadding: 0, 7300 virtualScroll: 600, 7301 display: false, 7302 sanitize: true, 7303 sanitizeFn: null, 7304 whiteList: DefaultWhitelist 7305 }; 7306 7307 Selectpicker.prototype = { 7308 7309 constructor: Selectpicker, 7310 7311 init: function () { 7312 var that = this, 7313 id = this.$element.attr('id'), 7314 element = this.$element[0], 7315 form = element.form; 7316 7317 selectId++; 7318 this.selectId = 'bs-select-' + selectId; 7319 7320 element.classList.add('bs-select-hidden'); 7321 7322 this.multiple = this.$element.prop('multiple'); 7323 this.autofocus = this.$element.prop('autofocus'); 7324 7325 if (element.classList.contains('show-tick')) { 7326 this.options.showTick = true; 7327 } 7328 7329 this.$newElement = this.createDropdown(); 7330 7331 this.$element 7332 .after(this.$newElement) 7333 .prependTo(this.$newElement); 7334 7335 // ensure select is associated with form element if it got unlinked after mov
7335ing it inside newElement 7336 if (form && element.form === null) { 7337 if (!form.id) form.id = 'form-' + this.selectId; 7338 element.setAttribute('form', form.id); 7339 } 7340 7341 this.$button = this.$newElement.children('button'); 7342 if (this.options.allowClear) this.$clearButton = this.$button.children('.bs-select-clear-selected'); 7343 this.$menu = this.$newElement.children(Selector.MENU); 7344 this.$menuInner = this.$menu.children('.inner'); 7345 this.$searchbox = this.$menu.find('input'); 7346 7347 element.classList.remove('bs-select-hidden'); 7348 7349 this.fetchData(function () { 7350 that.render(true); 7351 that.buildList(); 7352 7353 requestAnimationFrame(function () { 7354 that.$element.trigger('loaded' + EVENT_KEY); 7355 }); 7356 }); 7357 7358 if (this.options.dropdownAlignRight === true) this.$menu[0].classList.add(classNames.MENURIGHT); 7359 7360 if (typeof id !== 'undefined') { 7361 this.$button.attr('data-id', id); 7362 } 7363 7364 this.checkDisabled(); 7365 this.clickListener(); 7366 7367 if (version.major > 4) this.dropdown = new Dropdown(this.$button[0]); 7368 7369 if (this.options.liveSearch) { 7370 this.liveSearchListener(); 7371 this.focusedParent = this.$searchbox[0]; 7372 } else { 7373 this.focusedParent = this.$menuInner[0]; 7374 } 7375 7376 this.setStyle(); 7377 this.setWidth(); 7378 if (this.options.container) { 7379 this.selectPosition(); 7380 } else { 7381 this.$element.on('hide' + EVENT_KEY, function () { 7382 if (that.isVirtual()) { 7383 // empty menu on close 7384 var menuInner = that.$menuInner[0], 7385 emptyMenu = menuInner.firstChild.cloneNode(false); 7386 7387 // replace the existing UL with an empty one - this is faster than $.empty() or innerHTML = '' 7388 menuInner.replaceChild(emptyMenu, menuInner.firstChild); 7389 menuInner.scrollTop = 0; 7390 } 7391 }); 7392 } 7393 this.$menu.data('this', this); 7394 this.$newElement.data('this', this); 7395 if (this.options.mobile) this.mobile(); 7396 7397 this.$newElement.on({ 7398 'hide.bs.dropdown': function (e) { 7399 that.$element.trigger('hide' + EVENT_KEY, e); 7400 }, 7401 'hidden.bs.dropdown': function (e) { 7402 that.$element.trigger('hidden' + EVENT_KEY, e); 7403 }, 7404 'show.bs.dropdown': function (e) { 7405 that.$element.trigger('show' + EVENT_KEY, e); 7406 }, 7407 'shown.bs.dropdown': function (e) { 7408 that.$element.trigger('shown' + EVENT_KEY, e); 7409 } 7410 }); 7411 7412 if (element.hasAttribute('required')) { 7413 this.$element.on('invalid' + EVENT_KEY, function () { 7414 that.$button[0].classList.add('bs-invalid'); 7415 7416 that.$element 7417 .on('shown' + EVENT_KEY + '.invalid', function () { 7418 that.$element 7419 .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened 7420 .off('shown' + EVENT_KEY + '.invalid'); 7421 }) 7422 .on('rendered' + EVENT_KEY, function () { 7423 // if select is no longer invalid, remove the bs-invalid class 7424 if (this.validity.valid) that.$button[0].classList.remove('bs-invalid'); 7425 that.$element.off('rendered' + EVENT_KEY); 7426 }); 7427 7428 that.$button.on('blur' + EVENT_KEY, function () { 7429 that.$element.trigger('focus').trigger('blur'); 7430 that.$button.off('blur' + EVENT_KEY); 7431 }); 7432 }); 7433 } 7434 7435 if (form) { 7436 $(form).on('reset' + EVENT_KEY, function () { 7437 requestAnimationFrame(function () { 7438 that.render(); 7439 }); 7440 }); 7441 } 7442 }, 7443 7444 createDropdown: function () { 7445 // Options 7446 // If we are multiple or showTick option is set, then add the show-tick class 7447 var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '', 7448 multiselectable = this.multiple ? ' aria-multiselectable="true"' : '', 7449 inputGroup = '', 7450 autofocus = this.autofocus ? ' autofocus' : ''; 7451 7452 if (version.major < 4 && this.$element.parent().hasClass('input-group')) { 7453 inputGroup = ' input-group-btn'; 7454 } 7455 7456 // Elements 7457 var drop, 7458 header = '', 7459 searchbox = '', 7460 actionsbox = '', 7461 donebutton = '', 7462 clearButton = ''; 7463 7464 if (this.options.header) { 7465 header = 7466 '<div class="' + classNames.POPOVERHEADER + '">' + 7467 '<button type="button" class="close" aria-hidden="true">×</button>' + 7468 this.options.header + 7469 '</div>'; 7470 } 7471 7472 if (this.options.liveSearch) { 7473 searchbox = 7474 '<div class="bs-searchbox">' + 7475 '<input type="search" class="form-control" autocomplete="off"' + 7476 ( 7477 this.options.liveSearchPlaceholder === null ? '' 7478 : 7479 ' placeholder="' + htmlEscape(this.options.liveSearchPlaceholder) + '"' 7480 ) + 7481 ' role="combobox" aria-label="Search" aria-controls="' + this.selectId + '" aria-autocomplete="list">' + 7482 '</div>'; 7483 } 7484 7485 if (this.multiple && this.options.actionsBox) { 7486 actionsbox = 7487 '<div class="bs-actionsbox">' + 7488 '<div class="btn-group btn-group-sm">
vendor: 14,764 bytes, lines 7488-7860
7488' + 7489 '<button type="button" class="actions-btn bs-select-all btn ' + classNames.BUTTONCLASS + '">' + 7490 this.options.selectAllText + 7491 '</button>' + 7492 '<button type="button" class="actions-btn bs-deselect-all btn ' + classNames.BUTTONCLASS + '">' + 7493 this.options.deselectAllText + 7494 '</button>' + 7495 '</div>' + 7496 '</div>'; 7497 } 7498 7499 if (this.multiple && this.options.doneButton) { 7500 donebutton = 7501 '<div class="bs-donebutton">' + 7502 '<div class="btn-group">' + 7503 '<button type="button" class="btn btn-sm ' + classNames.BUTTONCLASS + '">' + 7504 this.options.doneButtonText + 7505 '</button>' + 7506 '</div>' + 7507 '</div>'; 7508 } 7509 7510 if (this.options.allowClear) { 7511 clearButton = '<span class="close bs-select-clear-selected" title="' + this.options.deselectAllText + '"><span>×</span>'; 7512 } 7513 7514 drop = 7515 '<div class="dropdown bootstrap-select' + showTick + inputGroup + '">' + 7516 '<button type="button" tabindex="-1" class="' + 7517 this.options.styleBase + 7518 ' dropdown-toggle" ' + 7519 (this.options.display === 'static' ? 'data-display="static"' : '') + 7520 Selector.DATA_TOGGLE + 7521 autofocus + 7522 ' role="combobox" aria-owns="' + 7523 this.selectId + 7524 '" aria-haspopup="listbox" aria-expanded="false">' + 7525 '<div class="filter-option">' + 7526 '<div class="filter-option-inner">' + 7527 '<div class="filter-option-inner-inner"> </div>' + 7528 '</div> ' + 7529 '</div>' + 7530 clearButton + 7531 '</span>' + 7532 ( 7533 version.major >= '4' ? '' 7534 : 7535 '<span class="bs-caret">' + 7536 this.options.template.caret + 7537 '</span>' 7538 ) + 7539 '</button>' + 7540 '<div class="' + classNames.MENU + ' ' + (version.major >= '4' ? '' : classNames.SHOW) + '">' + 7541 header + 7542 searchbox + 7543 actionsbox + 7544 '<div class="inner ' + classNames.SHOW + '" role="listbox" id="' + this.selectId + '" tabindex="-1" ' + multiselectable + '>' + 7545 '<ul class="' + classNames.MENU + ' inner ' + (version.major >= '4' ? classNames.SHOW : '') + '" role="presentation">' + 7546 '</ul>' + 7547 '</div>' + 7548 donebutton + 7549 '</div>' + 7550 '</div>'; 7551 7552 return $(drop); 7553 }, 7554 7555 setPositionData: function () { 7556 this.selectpicker.view.canHighlight = []; 7557 this.selectpicker.view.size = 0; 7558 this.selectpicker.view.firstHighlightIndex = false; 7559 7560 for (var i = 0; i < this.selectpicker.current.data.length; i++) { 7561 var li = this.selectpicker.current.data[i], 7562 canHighlight = true; 7563 7564 if (li.type === 'divider') { 7565 canHighlight = false; 7566 li.height = this.sizeInfo.dividerHeight; 7567 } else if (li.type === 'optgroup-label') { 7568 canHighlight = false; 7569 li.height = this.sizeInfo.dropdownHeaderHeight; 7570 } else { 7571 li.height = this.sizeInfo.liHeight; 7572 } 7573 7574 if (li.disabled) canHighlight = false; 7575 7576 this.selectpicker.view.canHighlight.push(canHighlight); 7577 7578 if (canHighlight) { 7579 this.selectpicker.view.size++; 7580 li.posinset = this.selectpicker.view.size; 7581 if (this.selectpicker.view.firstHighlightIndex === false) this.selectpicker.view.firstHighlightIndex = i; 7582 } 7583 7584 li.position = (i === 0 ? 0 : this.selectpicker.current.data[i - 1].position) + li.height; 7585 } 7586 }, 7587 7588 isVirtual: function () { 7589 return (this.options.virtualScroll !== false) && (this.selectpicker.main.data.length >= this.options.virtualScroll) || this.options.virtualScroll === true; 7590 }, 7591 7592 createView: function (isSearching, setSize, refresh) { 7593 var that = this, 7594 scrollTop = 0; 7595 7596 this.selectpicker.isSearching = isSearching; 7597 this.selectpicker.current = isSearching ? this.selectpicker.search : this.selectpicker.main; 7598 7599 this.setPositionData(); 7600 7601 if (setSize) { 7602 if (refresh) { 7603 scrollTop = this.$menuInner[0].scrollTop; 7604 } else if (!that.multiple) { 7605 var element = that.$element[0], 7606 selectedIndex = (element.options[element.selectedIndex] || {}).liIndex; 7607 7608 if (typeof selectedIndex === 'number' && that.options.size !== false) { 7609 var selectedData = that.selectpicker.main.data[selectedIndex], 7610 position = selectedData && selectedData.position; 7611 7612 if (position) { 7613 scrollTop = position - ((that.sizeInfo.menuInnerHeight + that.sizeInfo.liHeight) / 2); 7614 } 7615 } 7616 } 7617 } 7618 7619 scroll(scrollTop, true); 7620 7621 this.$menuInner.off('scroll.createView').on('scroll.createView', function (e, updateValue) { 7622 if (!that.noScroll) scroll(this.scrollTop, updateValue); 7623 that.noScroll = false; 7624 }); 7625 7626 function scroll (scrollTop, init) { 7627 var size = that.selectpicker.current.data.length, 7628 chunks = [], 7629 chunkSize, 7630 chunkCount, 7631 firstChunk, 7632 lastChunk, 7633 currentChunk, 7634 prevPositions, 7635 positionIsDifferent, 7636 previousElements, 7637 menuIsDifferent = true, 7638 isVirtual = that.isVirtual(); 7639 7640 that.selectpicker.view.scrollTop = scrollTop; 7641 7642 chunkSize = that.options.chunkSize; // number of options in a chunk 7643 chunkCount = Math.ceil(size / chunkSize) || 1; // number of chunks 7644 7645 for (var i = 0; i < chunkCount; i++) { 7646 var endOfChunk = (i + 1) * chunkSize; 7647 7648 if (i === chunkCount - 1) { 7649 endOfChunk = size; 7650 } 7651 7652 chunks[i] = [ 7653 (i) * chunkSize + (!i ? 0 : 1), 7654 endOfChunk 7655 ]; 7656 7657 if (!size) break; 7658 7659 if (currentChunk === undefined && scrollTop - 1 <= that.selectpicker.current.data[endOfChunk - 1].position - that.sizeInfo.menuInnerHeight) { 7660 currentChunk = i; 7661 } 7662 } 7663 7664 if (currentChunk === undefined) currentChunk = 0; 7665 7666 prevPositions = [that.selectpicker.view.position0, that.selectpicker.view.position1]; 7667 7668 // always display previous, current, and next chunks 7669 firstChunk = Math.max(0, currentChunk - 1); 7670 lastChunk = Math.min(chunkCount - 1, currentChunk + 1); 7671 7672 that.selectpicker.view.position0 = isVirtual === false ? 0 : (Math.max(0, chunks[firstChunk][0]) || 0); 7673 that.selectpicker.view.position1 = isVirtual === false ? size : (Math.min(size, chunks[lastChunk][1]) || 0); 7674 7675 positionIsDifferent = prevPositions[0] !== that.selectpicker.view.position0 || prevPositions[1] !== that.selectpicker.view.position1; 7676 7677 if (that.activeElement !== undefined) { 7678 if (init) { 7679 if (that.activeElement !== that.selectedElement) { 7680 that.defocusItem(that.activeElement); 7681 } 7682 that.activeElement = undefined; 7683 } 7684 7685 if (that.activeElement !== that.selectedElement) { 7686 that.defocusItem(that.selectedElement); 7687 } 7688 } 7689 7690 if (that.prevActiveElement !== undefined && that.prevActiveElement !== that.activeElement && that.prevActiveElement !== that.selectedElement) { 7691 that.defocusItem(that.prevActiveElement); 7692 } 7693 7694 if (init || positionIsDifferent || that.selectpicker.current.hasMore) { 7695 previousElements = that.selectpicker.view.visibleElements ? that.selectpicker.view.visibleElements.slice() : []; 7696 7697 if (isVirtual === false) { 7698 that.selectpicker.view.visibleElements = that.selectpicker.current.elements; 7699 } else { 7700 that.selectpicker.view.visibleElements = that.selectpicker.current.elements.slice(that.selectpicker.view.position0, that.selectpicker.view.position1); 7701 } 7702 7703 that.setOptionStatus(); 7704 7705 // if searching, check to make sure the list has actually been updated before updating DOM 7706 // this prevents unnecessary repaints 7707 if (isSearching || (isVirtual === false && init)) menuIsDifferent = !isEqual(previousElements, that.selectpicker.view.visibleElements); 7708 7709 // if virtual scroll is disabled and not searching, 7710 // menu should never need to be updated more than once 7711 if ((init || isVirtual === true) && menuIsDifferent) { 7712 var menuInner = that.$menuInner[0], 7713 menuFragment = document.createDocumentFragment(), 7714 emptyMenu = menuInner.firstChild.cloneNode(false), 7715 marginTop, 7716 marginBottom, 7717 elements = that.selectpicker.view.visibleElements, 7718 toSanitize = []; 7719 7720 // replace the existing UL with an empty one - this is faster than $.empty() 7721 menuInner.replaceChild(emptyMenu, menuInner.firstChild); 7722 7723 for (var i = 0, visibleElementsLen = elements.length; i < visibleElementsLen; i++) { 7724 var element = elements[i], 7725 elText, 7726 elementData; 7727 7728 if (that.options.sanitize) { 7729 elText = element.lastChild; 7730 7731 if (elText) { 7732 elementData = that.selectpicker.current.data[i + that.selectpicker.view.position0]; 7733 7734 if (elementData && elementData.content && !elementData.sanitized) { 7735 toSanitize.push(elText); 7736 elementData.sanitized = true; 7737 } 7738 } 7739 } 7740 7741 menuFragment.appendChild(element); 7742 } 7743 7744 if (that.options.sanitize && toSanitize.length) { 7745 sanitizeHtml(toSanitize, that.options.whiteList, that.options.sanitizeFn); 7746 } 7747 7748 if (isVirtual === true) { 7749 marginTop = (that.selectpicker.view.position0 === 0 ? 0 : that.selectpicker.current.data[that.selectpicker.view.position0 - 1].position); 7750 marginBottom = (that.selectpicker.view.position1 > size - 1 ? 0 : that.selectpicker.current.data[size - 1].position - that.selectpicker.current.data[that.selectpicker.view.position1 - 1].position); 7751 7752 menuInner.firstChild.style.marginTop = marginTop + 'px'; 7753 menuInner.firstChild.style.marginBottom = marginBottom + 'px'; 7754 } else { 7755 menuInner.firstChild.style.marginTop = 0; 7756 menuInner.firstChild.style.marginBottom = 0; 7757 } 7758 7759 menuInner.firstChild.appendChild(menuFragment); 7760 7761 // if an option is encountered that is wider than the current menu width, update the menu width accordingly 7762 // switch to ResizeObserver with increased browser support 7763 if (isVirtual === true && that.sizeInfo.hasScrollBar) { 7764 var menuInnerInnerWidth = menuInner.firstChild.offsetWidth; 7765 7766 if (init && menuInnerInnerWidth < that.sizeInfo.menuInnerInnerWidth && that.sizeInfo.totalMenuWidth > that.sizeInfo.selectWidth) { 7767 menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; 7768 } else if (menuInnerInnerWidth > that.sizeInfo.menuInnerInnerWidth) { 7769 // set to 0 to get actual width of menu 7770 that.$menu[0].style.minWidth = 0; 7771 7772 var actualMenuWidth = menuInner.firstChild.offsetWidth; 7773 7774 if (actualMenuWidth > that.sizeInfo.menuInnerInnerWidth) { 7775 that.sizeInfo.menuInnerInnerWidth = actualMenuWidth; 7776 menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; 7777 } 7778 7779 // reset to default CSS styling 7780 that.$menu[0].style.minWidth = ''; 7781 } 7782 } 7783 } 7784 7785 if ((!isSearching && that.options.source.data || isSearching && that.options.source.search) && that.selectpicker.current.hasMore && currentChunk === chunkCount - 1) { 7786 // Don't load the next chunk until scrolling has started 7787 // This prevents unnecessary requests while the user is typing if pageSize is <= chunkSize 7788 if (scrollTop > 0) { 7789 // Chunks use 0-based indexing, but pages use 1-based. Add 1 to convert and add 1 again to get next page 7790 var page = Math.floor((currentChunk * that.options.chunkSize) / that.options.source.pageSize) + 2; 7791 7792 that.fetchData(function () { 7793 that.render(); 7794 that.buildList(size, isSearching); 7795 that.setPositionData(); 7796 scroll(scrollTop); 7797 }, isSearching ? 'search' : 'data', page, isSearching ? that.selectpicker.search.previousValue : undefined); 7798 } 7799 } 7800 } 7801 7802 that.prevActiveElement = that.activeElement; 7803 7804 if (!that.options.liveSearch) { 7805 that.$menuInner.trigger('focus'); 7806 } else if (isSearching && init) { 7807 var index = 0, 7808 newActive; 7809 7810 if (!that.selectpicker.view.canHighlight[index]) { 7811 index = 1 + that.selectpicker.view.canHighlight.slice(1).indexOf(true); 7812 } 7813 7814 newActive = that.selectpicker.view.visibleElements[index]; 7815 7816 that.defocusItem(that.selectpicker.view.currentActive); 7817 7818 that.activeElement = (that.selectpicker.current.data[index] || {}).element; 7819 7820 that.focusItem(newActive); 7821 } 7822 } 7823 7824 $(window) 7825 .off('resize' + EVENT_KEY + '.' + this.selectId + '.createView') 7826 .on('resize' + EVENT_KEY + '.' + this.selectId + '.createView', function () { 7827 var isActive = that.$newElement.hasClass(classNames.SHOW); 7828 7829 if (isActive) scroll(that.$menuInner[0].scrollTop); 7830 }); 7831 }, 7832 7833 focusItem: function (li, liData, noStyle) { 7834 if (li) { 7835 liData = liData || this.selectpicker.current.data[this.selectpicker.current.elements.indexOf(this.activeElement)]; 7836 var a = li.firstChild; 7837 7838 if (a) { 7839 a.setAttribute('aria-setsize', this.selectpicker.view.size); 7840 a.setAttribute('aria-posinset', liData.posinset); 7841 7842 if (noStyle !== true) { 7843 this.focusedParent.setAttribute('aria-activedescendant', a.id); 7844 li.classList.add('active'); 7845 a.classList.add('active'); 7846 } 7847 } 7848 } 7849 }, 7850 7851 defocusItem: function (li) { 7852 if (li) { 7853 li.classList.remove('active'); 7854 if (li.firstChild) li.firstChild.classList.remove('active'); 7855 } 7856 }, 7857 7858 setPlaceholder: function () { 7859 var that = this, 7860 updateIndex = false;
7861 7862 if ((this.options.placeholder || this.options.allowClear) && !this.multiple) { 7863 if (!this.selectpicker.view.titleOption) this.selectpicker.view.titleOption = document.createElement('option'); 7864 7865 // this option doesn't create a new <li> element, but does add a new option at the start, 7866 // so startIndex should increase to prevent having to check every option for the bs-title-option class 7867 updateIndex = true; 7868 7869 var element = this.$element[0], 7870 selectTitleOption = false, 7871 titleNotAppended = !this.selectpicker.view.titleOption.parentNode, 7872 selectedIndex = element.selectedIndex, 7873 selectedOption = element.options[selectedIndex], 7874 firstSelectable = element.querySelector('select > *:not(:disabled)'), 7875 firstSelectableIndex = firstSelectable ? firstSelectable.index : 0, 7876 navigation = window.performance && window.performance.getEntriesByType('navigation'), 7877 // Safari doesn't support getEntriesByType('navigation') - fall back to performance.navigation 7878 isNotBackForward = (navigation && navigation.length) ? navigation[0].type !== 'back_forward' : window.performance.navigation.type !== 2; 7879 7880 if (titleNotAppended) { 7881 // Use native JS to prepend option (faster) 7882 this.selectpicker.view.titleOption.className = 'bs-title-option'; 7883 this.selectpicker.view.titleOption.value = ''; 7884 7885 // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option. 7886 // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs, 7887 // if so, the select will have the data-selected attribute 7888 selectTitleOption = !selectedOption || (selectedIndex === firstSelectableIndex && selectedOption.defaultSelected === false && this.$element.data('selected') === undefined); 7889 } 7890 7891 if (titleNotAppended || this.selectpicker.view.titleOption.index !== 0) { 7892 element.insertBefore(this.selectpicker.view.titleOption, element.firstChild); 7893 } 7894 7895 // Set selected *after* appending to select, 7896 // otherwise the option doesn't get selected in IE 7897 // set using selectedIndex, as setting the selected attr to true here doesn't work in IE11 7898 if (selectTitleOption && isNotBackForward) { 7899 element.selectedIndex = 0; 7900 } else if (document.readyState !== 'complete') { 7901 // if navigation type is back_forward, there's a chance the select will have its value set by BFCache 7902 // wait for that value to be set, then run render again 7903 window.addEventListener('pageshow', function () { 7904 if (that.selectpicker.view.displayedValue !== element.value) that.render(); 7905 }); 7906 } 7907 } 7908 7909 return updateIndex; 7910 }, 7911 7912 fetchData: function (callback, type, page, searchValue) { 7913 page = page || 1; 7914 type = type || 'data'; 7915 7916 var that = this, 7917 data = this.options.source[type], 7918 builtData; 7919 7920 if (data) { 7921 this.options.virtualScroll = true; 7922 7923 if (typeof data === 'function') { 7924 data.call( 7925 this, 7926 function (data, more, totalItems) { 7927 var current = that.selectpicker[type === 'search' ? 'search' : 'main']; 7928 current.hasMore = more; 7929 current.totalItems = totalItems; 7930 builtData = that.buildData(data, type); 7931 callback.call(that, builtData); 7932 that.$element.trigger('fetched' + EVENT_KEY); 7933 }, 7934 page, 7935 searchValue 7936 ); 7937 } else if (Array.isArray(data)) { 7938 builtData = that.buildData(data, type); 7939 callback.call(that, builtData); 7940 } 7941 } else { 7942 builtData = this.buildData(false, type); 7943 callback.call(that, builtData); 7944 } 7945 }, 7946 7947 buildData: function (data, type) { 7948 var that = this; 7949 var dataGetter = data === false ? getOptionData.fromOption : getOptionData.fromDataSource; 7950 7951 var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([style*="display: none"])', 7952 mainData = [], 7953 startLen = this.selectpicker.main.data ? this.selectpicker.main.data.length : 0, 7954 optID = 0, 7955 startIndex = this.setPlaceholder() && !data ? 1 : 0; // append the titleOption if necessary and skip the first option in the loop 7956 7957 if (type === 'search') { 7958 startLen = this.selectpicker.search.data.length; 7959 } 7960 7961 if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; 7962 7963 var selectOptions = data ? data.filter(filterHidden, this) : this.$element[0].querySelectorAll('select > *' + optionSelector); 7964 7965 function addDivider (config) { 7966 var previousData = mainData[mainData.length - 1]; 7967 7968 // ensure optgroup doesn't create back-to-back dividers 7969 if ( 7970 previousData && 7971 previousData.type === 'divider' && 7972 (previousData.optID || config.optID) 7973 ) { 7974 return; 7975 } 7976 7977 config = config || {}; 7978 config.type = 'divider'; 7979 7980 mainData.push(config); 7981 } 7982 7983 function addOption (item, config) { 7984 config = config || {}; 7985
7986 config.divider = dataGetter(item, 'divider'); 7987 7988 if (config.divider === true) { 7989 addDivider({ 7990 optID: config.optID 7991 }); 7992 } else { 7993 var liIndex = mainData.length + startLen, 7994 cssText = dataGetter(item, 'style'), 7995 inlineStyle = cssText ? htmlEscape(cssText) : '', 7996 optionClass = (item.className || '') + (config.optgroupClass || ''); 7997 7998 if (config.optID) optionClass = 'opt ' + optionClass; 7999 8000 config.optionClass = optionClass.trim(); 8001 config.inlineStyle = inlineStyle; 8002 8003 config.text = dataGetter(item, 'text'); 8004 config.title = dataGetter(item, 'title'); 8005 config.content = dataGetter(item, 'content'); 8006 config.tokens = dataGetter(item, 'tokens'); 8007 config.subtext = dataGetter(item, 'subtext'); 8008 config.icon = dataGetter(item, 'icon'); 8009 8010 config.display = config.content || config.text; 8011 config.value = item.value === undefined ? item.text : item.value; 8012 config.type = 'option'; 8013 config.index = liIndex; 8014 8015 config.option = !item.option ? item : item.option; // reference option element if it exists 8016 config.option.liIndex = liIndex; 8017 config.selected = !!item.selected; 8018 config.disabled = config.disabled || !!item.disabled; 8019 8020 if (data !== false) { 8021 if (that.selectpicker.optionValuesDataMap[config.value]) { 8022 config = $.extend(that.selectpicker.optionValuesDataMap[config.value], config); 8023 } else { 8024 that.selectpicker.optionValuesDataMap[config.value] = config; 8025 } 8026 } 8027 8028 mainData.push(config); 8029 } 8030 } 8031 8032 function addOptgroup (index, selectOptions) { 8033 var optgroup = selectOptions[index], 8034 // skip placeholder option 8035 previous = index - 1 < startIndex ? false : selectOptions[index - 1], 8036 next = selectOptions[index + 1], 8037 options = data ? optgroup.children.filter(filterHidden, this) : optgroup.querySelectorAll('option' + optionSelector); 8038 8039 if (!options.length) return; 8040 8041 var config = { 8042 display: htmlEscape(dataGetter(item, 'label')), 8043 subtext: dataGetter(optgroup, 'subtext'), 8044 icon: dataGetter(optgroup, 'icon'), 8045 type: 'optgroup-label', 8046 optgroupClass: ' ' + (optgroup.className || ''), 8047 optgroup: optgroup 8048 }, 8049 headerIndex, 8050 lastIndex; 8051 8052 optID++; 8053 8054 if (previous) { 8055 addDivider({ optID: optID }); 8056 } 8057 8058 config.optID = optID; 8059 8060 mainData.push(config); 8061 8062 for (var j = 0, len = options.length; j < len; j++) { 8063 var option = options[j]; 8064 8065 if (j === 0) { 8066 headerIndex = mainData.length - 1; 8067 lastIndex = headerIndex + len; 8068 } 8069 8070 addOption(option, { 8071 headerIndex: headerIndex, 8072 lastIndex: lastIndex, 8073 optID: config.optID, 8074 optgroupClass: config.optgroupClass, 8075 disabled: optgroup.disabled 8076 }); 8077 } 8078 8079 if (next) { 8080 addDivider({ optID: optID }); 8081 } 8082 } 8083 8084 for (var len = selectOptions.length, i = startIndex; i < len; i++) { 8085 var item = selectOptions[i], 8086 children = item.children; 8087 8088 if (children && children.length) { 8089 addOptgroup.call(this, i, selectOptions); 8090 } else { 8091 addOption.call(this, item, {}); 8092 } 8093 } 8094 8095 switch (type) { 8096 case 'data': { 8097 if (!this.selectpicker.main.data) { 8098 this.selectpicker.main.data = []; 8099 } 8100 Array.prototype.push.apply(this.selectpicker.main.data, mainData); 8101 this.selectpicker.current.data = this.selectpicker.main.data; 8102 break; 8103 } 8104 case 'search': { 8105 Array.prototype.push.apply(this.selectpicker.search.data, mainData); 8106 break; 8107 } 8108 } 8109 8110 return mainData; 8111 }, 8112 8113 buildList: function (size, searching) { 8114 var that = this, 8115 selectData = searching ? this.selectpicker.search.data : this.selectpicker.main.data, 8116 mainElements = [], 8117 widestOptionLength = 0; 8118 8119 if ((that.options.showTick || that.multiple) && !elementTemplates.checkMark.parentNode) { 8120 elementTemplates.checkMark.className = this.options.iconBase + ' ' + that.options.tickIcon + ' check-mark'; 8121 elementTemplates.a.appendChild(elementTemplates.checkMark); 8122 } 8123 8124 function buildElement (mainElements, item) { 8125 var liElement, 8126 combinedLength = 0; 8127 8128 switch (item.type) {
vendor: 24,295 bytes, lines 8129-8705
8129 case 'divider': 8130 liElement = generateOption.li( 8131 false, 8132 classNames.DIVIDER, 8133 (item.optID ? item.optID + 'div' : undefined) 8134 ); 8135 8136 break; 8137 8138 case 'option': 8139 liElement = generateOption.li( 8140 generateOption.a( 8141 generateOption.text.call(that, item), 8142 item.optionClass, 8143 item.inlineStyle 8144 ), 8145 '', 8146 item.optID 8147 ); 8148 8149 if (liElement.firstChild) { 8150 liElement.firstChild.id = that.selectId + '-' + item.index; 8151 } 8152 8153 break; 8154 8155 case 'optgroup-label': 8156 liElement = generateOption.li( 8157 generateOption.label.call(that, item), 8158 'dropdown-header' + item.optgroupClass, 8159 item.optID 8160 ); 8161 8162 break; 8163 } 8164 8165 if (!item.element) { 8166 item.element = liElement; 8167 } else { 8168 item.element.innerHTML = liElement.innerHTML; 8169 } 8170 mainElements.push(item.element); 8171 8172 // count the number of characters in the option - not perfect, but should work in most cases 8173 if (item.display) combinedLength += item.display.length; 8174 if (item.subtext) combinedLength += item.subtext.length; 8175 // if there is an icon, ensure this option's width is checked 8176 if (item.icon) combinedLength += 1; 8177 8178 if (combinedLength > widestOptionLength) { 8179 widestOptionLength = combinedLength; 8180 8181 // guess which option is the widest 8182 // use this when calculating menu width 8183 // not perfect, but it's fast, and the width will be updating accordingly when scrolling 8184 that.selectpicker.view.widestOption = mainElements[mainElements.length - 1]; 8185 } 8186 } 8187 8188 var startIndex = size || 0; 8189 8190 for (var len = selectData.length, i = startIndex; i < len; i++) { 8191 var item = selectData[i]; 8192 8193 buildElement(mainElements, item); 8194 } 8195 8196 if (size) { 8197 if (searching) { 8198 Array.prototype.push.apply(this.selectpicker.search.elements, mainElements); 8199 } else { 8200 Array.prototype.push.apply(this.selectpicker.main.elements, mainElements); 8201 this.selectpicker.current.elements = this.selectpicker.main.elements; 8202 } 8203 } else { 8204 if (searching) { 8205 this.selectpicker.search.elements = mainElements; 8206 } else { 8207 this.selectpicker.main.elements = this.selectpicker.current.elements = mainElements; 8208 } 8209 } 8210 }, 8211 8212 findLis: function () { 8213 return this.$menuInner.find('.inner > li'); 8214 }, 8215 8216 render: function (init) { 8217 var that = this, 8218 element = this.$element[0], 8219 // ensure titleOption is appended and selected (if necessary) before getting selectedOptions 8220 placeholderSelected = this.setPlaceholder() && element.selectedIndex === 0, 8221 selectedOptions = getSelectedOptions.call(this), 8222 selectedCount = selectedOptions.length, 8223 selectedValues = getSelectValues.call(this, selectedOptions), 8224 button = this.$button[0], 8225 buttonInner = button.querySelector('.filter-option-inner-inner'), 8226 multipleSeparator = document.createTextNode(this.options.multipleSeparator), 8227 titleFragment = elementTemplates.fragment.cloneNode(false), 8228 showCount, 8229 countMax, 8230 hasContent = false; 8231 8232 function createSelected (item) { 8233 if (item.selected) { 8234 that.createOption(item, true); 8235 } else if (item.children && item.children.length) { 8236 item.children.map(createSelected); 8237 } 8238 } 8239 8240 // create selected option elements to ensure select value is correct 8241 if (this.options.source.data && init) { 8242 selectedOptions.map(createSelected); 8243 element.appendChild(this.selectpicker.main.optionQueue); 8244 8245 if (placeholderSelected) placeholderSelected = element.selectedIndex === 0; 8246 } 8247 8248 button.classList.toggle('bs-placeholder', that.multiple ? !selectedCount : !selectedValues && selectedValues !== 0); 8249 8250 if (!that.multiple && selectedOptions.length === 1) { 8251 that.selectpicker.view.displayedValue = selectedValues; 8252 } 8253 8254 if (this.options.selectedTextFormat === 'static') { 8255 titleFragment = generateOption.text.call(this, { text: this.options.placeholder }, true); 8256 } else { 8257 showCount = this.multiple && this.options.selectedTextFormat.indexOf('count') !== -1 && selectedCount > 0; 8258 8259 // determine if the number of selected options will be shown (showCount === true) 8260 if (showCount) { 8261 countMax = this.options.selectedTextFormat.split('>'); 8262 showCount = (countMax.length > 1 && selectedCount > countMax[1]) || (countMax.length === 1 && selectedCount >= 2); 8263 } 8264 8265 // only loop through all selected options if the count won't be shown 8266 if (showCount === false) { 8267 if (!placeholderSelected) { 8268 for (var selectedIndex = 0; selectedIndex < selectedCount; selectedIndex++) { 8269 if (selectedIndex < 50) { 8270 var option = selectedOptions[selectedIndex], 8271 titleOptions = {}; 8272 8273 if (option) { 8274 if (this.multiple && selectedIndex > 0) { 8275 titleFragment.appendChild(multipleSeparator.cloneNode(false)); 8276 } 8277 8278 if (option.title) { 8279 titleOptions.text = option.title; 8280 } else if (option.content && that.options.showContent) { 8281 titleOptions.content = option.content.toString(); 8282 hasContent = true; 8283 } else { 8284 if (that.options.showIcon) { 8285 titleOptions.icon = option.icon; 8286 } 8287 if (that.options.showSubtext && !that.multiple && option.subtext) titleOptions.subtext = ' ' + option.subtext; 8288 titleOptions.text = option.text.trim(); 8289 } 8290 8291 titleFragment.appendChild(generateOption.text.call(this, titleOptions, true)); 8292 } 8293 } else { 8294 break; 8295 } 8296 } 8297 8298 // add ellipsis 8299 if (selectedCount > 49) { 8300 titleFragment.appendChild(document.createTextNode('...')); 8301 } 8302 } 8303 } else { 8304 var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([data-divider="true"]):not([style*="display: none"])'; 8305 if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; 8306 8307 // If this is a multiselect, and selectedTextFormat is count, then show 1 of 2 selected, etc. 8308 var totalCount = this.$element[0].querySelectorAll('select > option' + optionSelector + ', optgroup' + optionSelector + ' option' + optionSelector).length, 8309 tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedCount, totalCount) : this.options.countSelectedText; 8310 8311 titleFragment = generateOption.text.call(this, { 8312 text: tr8nText.replace('{0}', selectedCount.toString()).replace('{1}', totalCount.toString()) 8313 }, true); 8314 } 8315 } 8316 8317 // If the select doesn't have a title, then use the default, or if nothing is set at all, use noneSelectedText 8318 if (!titleFragment.childNodes.length) { 8319 titleFragment = generateOption.text.call(this, { 8320 text: this.options.placeholder ? this.options.placeholder : this.options.noneSelectedText 8321 }, true); 8322 } 8323 8324 // if the select has a title, apply it to the button, and if not, apply titleFragment text 8325 // strip all HTML tags and trim the result, then unescape any escaped tags 8326 button.title = titleFragment.textContent.replace(/<[^>]*>?/g, '').trim(); 8327 8328 if (this.options.sanitize && hasContent) { 8329 sanitizeHtml([titleFragment], that.options.whiteList, that.options.sanitizeFn); 8330 } 8331 8332 buttonInner.innerHTML = ''; 8333 buttonInner.appendChild(titleFragment); 8334 8335 if (version.major < 4 && this.$newElement[0].classList.contains('bs3-has-addon')) { 8336 var filterExpand = button.querySelector('.filter-expand'), 8337 clone = buttonInner.cloneNode(true); 8338 8339 clone.className = 'filter-expand'; 8340 8341 if (filterExpand) { 8342 button.replaceChild(clone, filterExpand); 8343 } else { 8344 button.appendChild(clone); 8345 } 8346 } 8347 8348 this.$element.trigger('rendered' + EVENT_KEY); 8349 }, 8350 8351 /** 8352 * @param [style] 8353 * @param [status] 8354 */ 8355 setStyle: function (newStyle, status) { 8356 var button = this.$button[0], 8357 newElement = this.$newElement[0], 8358 style = this.options.style.trim(), 8359 buttonClass; 8360 8361 if (this.$element.attr('class')) { 8362 this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi, '')); 8363 } 8364 8365 if (version.major < 4) { 8366 newElement.classList.add('bs3'); 8367 8368 if (newElement.parentNode.classList && newElement.parentNode.classList.contains('input-group') && 8369 (newElement.previousElementSibling || newElement.nextElementSibling) && 8370 (newElement.previousElementSibling || newElement.nextElementSibling).classList.contains('input-group-addon') 8371 ) { 8372 newElement.classList.add('bs3-has-addon'); 8373 } 8374 } 8375 8376 if (newStyle) { 8377 buttonClass = newStyle.trim(); 8378 } else { 8379 buttonClass = style; 8380 } 8381 8382 if (status == 'add') { 8383 if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); 8384 } else if (status == 'remove') { 8385 if (buttonClass) button.classList.remove.apply(button.classList, buttonClass.split(' ')); 8386 } else { 8387 if (style) button.classList.remove.apply(button.classList, style.split(' ')); 8388 if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); 8389 } 8390 }, 8391 8392 liHeight: function (refresh) { 8393 if (!refresh && (this.options.size === false || Object.keys(this.sizeInfo).length)) return; 8394 8395 var newElement = elementTemplates.div.cloneNode(false), 8396 menu = elementTemplates.div.cloneNode(false), 8397 menuInner = elementTemplates.div.cloneNode(false), 8398 menuInnerInner = document.createElement('ul'), 8399 divider = elementTemplates.li.cloneNode(false), 8400 dropdownHeader = elementTemplates.li.cloneNode(false), 8401 li, 8402 a = elementTemplates.a.cloneNode(false), 8403 text = elementTemplates.span.cloneNode(false), 8404 header = this.options.header && this.$menu.find('.' + classNames.POPOVERHEADER).length > 0 ? this.$menu.find('.' + classNames.POPOVERHEADER)[0].cloneNode(true) : null, 8405 search = this.options.liveSearch ? elementTemplates.div.cloneNode(false) : null, 8406 actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null, 8407 doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null, 8408 firstOption = this.$element[0].options[0]; 8409 8410 this.sizeInfo.selectWidth = this.$newElement[0].offsetWidth; 8411 8412 text.className = 'text'; 8413 a.className = 'dropdown-item ' + (firstOption ? firstOption.className : ''); 8414 newElement.className = this.$menu[0].parentNode.className + ' ' + classNames.SHOW; 8415 newElement.style.width = 0; // ensure button width doesn't affect natural width of menu when calculating 8416 if (this.options.width === 'auto') menu.style.minWidth = 0; 8417 menu.className = classNames.MENU + ' ' + classNames.SHOW; 8418 menuInner.className = 'inner ' + classNames.SHOW; 8419 menuInnerInner.className = classNames.MENU + ' inner ' + (version.major >= '4' ? classNames.SHOW : ''); 8420 divider.className = classNames.DIVIDER; 8421 dropdownHeader.className = 'dropdown-header'; 8422 8423 text.appendChild(document.createTextNode('\u200b')); 8424 8425 if (this.selectpicker.current.data.length) { 8426 for (var i = 0; i < this.selectpicker.current.data.length; i++) { 8427 var data = this.selectpicker.current.data[i]; 8428 if (data.type === 'option' && $(data.element.firstChild).css('display') !== 'none') { 8429 li = data.element; 8430 break; 8431 } 8432 } 8433 } else { 8434 li = elementTemplates.li.cloneNode(false); 8435 a.appendChild(text); 8436 li.appendChild(a); 8437 } 8438 8439 dropdownHeader.appendChild(text.cloneNode(true)); 8440 8441 if (this.selectpicker.view.widestOption) { 8442 menuInnerInner.appendChild(this.selectpicker.view.widestOption.cloneNode(true)); 8443 } 8444 8445 menuInnerInner.appendChild(li); 8446 menuInnerInner.appendChild(divider); 8447 menuInnerInner.appendChild(dropdownHeader); 8448 if (header) menu.appendChild(header); 8449 if (search) { 8450 var input = document.createElement('input'); 8451 search.className = 'bs-searchbox'; 8452 input.className = 'form-control'; 8453 search.appendChild(input); 8454 menu.appendChild(search); 8455 } 8456 if (actions) menu.appendChild(actions); 8457 menuInner.appendChild(menuInnerInner); 8458 menu.appendChild(menuInner); 8459 if (doneButton) menu.appendChild(doneButton); 8460 newElement.appendChild(menu); 8461 8462 document.body.appendChild(newElement); 8463 8464 var liHeight = li.offsetHeight, 8465 dropdownHeaderHeight = dropdownHeader ? dropdownHeader.offsetHeight : 0, 8466 headerHeight = header ? header.offsetHeight : 0, 8467 searchHeight = search ? search.offsetHeight : 0, 8468 actionsHeight = actions ? actions.offsetHeight : 0, 8469 doneButtonHeight = doneButton ? doneButton.offsetHeight : 0, 8470 dividerHeight = $(divider).outerHeight(true), 8471 menuStyle = window.getComputedStyle(menu), 8472 menuWidth = menu.offsetWidth, 8473 menuPadding = { 8474 vert: toInteger(menuStyle.paddingTop) + 8475 toInteger(menuStyle.paddingBottom) + 8476 toInteger(menuStyle.borderTopWidth) + 8477 toInteger(menuStyle.borderBottomWidth), 8478 horiz: toInteger(menuStyle.paddingLeft) + 8479 toInteger(menuStyle.paddingRight) + 8480 toInteger(menuStyle.borderLeftWidth) + 8481 toInteger(menuStyle.borderRightWidth) 8482 }, 8483 menuExtras = { 8484 vert: menuPadding.vert + 8485 toInteger(menuStyle.marginTop) + 8486 toInteger(menuStyle.marginBottom) + 2, 8487 horiz: menuPadding.horiz + 8488 toInteger(menuStyle.marginLeft) + 8489 toInteger(menuStyle.marginRight) + 2 8490 }, 8491 scrollBarWidth; 8492 8493 menuInner.style.overflowY = 'scroll'; 8494 8495 scrollBarWidth = menu.offsetWidth - menuWidth; 8496 8497 document.body.removeChild(newElement); 8498 8499 this.sizeInfo.liHeight = liHeight; 8500 this.sizeInfo.dropdownHeaderHeight = dropdownHeaderHeight; 8501 this.sizeInfo.headerHeight = headerHeight; 8502 this.sizeInfo.searchHeight = searchHeight; 8503 this.sizeInfo.actionsHeight = actionsHeight; 8504 this.sizeInfo.doneButtonHeight = doneButtonHeight; 8505 this.sizeInfo.dividerHeight = dividerHeight; 8506 this.sizeInfo.menuPadding = menuPadding; 8507 this.sizeInfo.menuExtras = menuExtras; 8508 this.sizeInfo.menuWidth = menuWidth; 8509 this.sizeInfo.menuInnerInnerWidth = menuWidth - menuPadding.horiz; 8510 this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth; 8511 this.sizeInfo.scrollBarWidth = scrollBarWidth; 8512 this.sizeInfo.selectHeight = this.$newElement[0].offsetHeight; 8513 8514 this.setPositionData(); 8515 }, 8516 8517 getSelectPosition: function () { 8518 var that = this, 8519 $window = $(window), 8520 pos = that.$newElement.offset(), 8521 $container = $(that.options.container), 8522 containerPos; 8523 8524 if (that.options.container && $container.length && !$container.is('body')) { 8525 containerPos = $container.offset(); 8526 containerPos.top += parseInt($container.css('borderTopWidth')); 8527 containerPos.left += parseInt($container.css('borderLeftWidth')); 8528 } else { 8529 containerPos = { top: 0, left: 0 }; 8530 } 8531 8532 var winPad = that.options.windowPadding; 8533 8534 this.sizeInfo.selectOffsetTop = pos.top - containerPos.top - $window.scrollTop(); 8535 this.sizeInfo.selectOffsetBot = $window.height() - this.sizeInfo.selectOffsetTop - this.sizeInfo.selectHeight - containerPos.top - winPad[2]; 8536 this.sizeInfo.selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft(); 8537 this.sizeInfo.selectOffsetRight = $window.width() - this.sizeInfo.selectOffsetLeft - this.sizeInfo.selectWidth - containerPos.left - winPad[1]; 8538 this.sizeInfo.selectOffsetTop -= winPad[0]; 8539 this.sizeInfo.selectOffsetLeft -= winPad[3]; 8540 }, 8541 8542 setMenuSize: function (isAuto) { 8543 this.getSelectPosition(); 8544 8545 var selectWidth = this.sizeInfo.selectWidth, 8546 liHeight = this.sizeInfo.liHeight, 8547 headerHeight = this.sizeInfo.headerHeight, 8548 searchHeight = this.sizeInfo.searchHeight, 8549 actionsHeight = this.sizeInfo.actionsHeight, 8550 doneButtonHeight = this.sizeInfo.doneButtonHeight, 8551 divHeight = this.sizeInfo.dividerHeight, 8552 menuPadding = this.sizeInfo.menuPadding, 8553 menuInnerHeight, 8554 menuHeight, 8555 divLength = 0, 8556 minHeight, 8557 _minHeight, 8558 maxHeight, 8559 menuInnerMinHeight, 8560 estimate, 8561 isDropup; 8562 8563 if (this.options.dropupAuto) { 8564 // Get the estimated height of the menu without scrollbars. 8565 // This is useful for smaller menus, where there might be plenty of room 8566 // below the button without setting dropup, but we can't know 8567 // the exact height of the menu until createView is called later 8568 estimate = liHeight * this.selectpicker.current.data.length + menuPadding.vert; 8569 8570 isDropup = this.sizeInfo.selectOffsetTop - this.sizeInfo.selectOffsetBot > this.sizeInfo.menuExtras.vert && estimate + this.sizeInfo.menuExtras.vert + 50 > this.sizeInfo.selectOffsetBot; 8571 8572 // ensure dropup doesn't change while searching (so menu doesn't bounce back and forth) 8573 if (this.selectpicker.isSearching === true) { 8574 isDropup = this.selectpicker.dropup; 8575 } 8576 8577 this.$newElement.toggleClass(classNames.DROPUP, isDropup); 8578 this.selectpicker.dropup = isDropup; 8579 } 8580 8581 if (this.options.size === 'auto') { 8582 _minHeight = this.selectpicker.current.data.length > 3 ? this.sizeInfo.liHeight * 3 + this.sizeInfo.menuExtras.vert - 2 : 0; 8583 menuHeight = this.sizeInfo.selectOffsetBot - this.sizeInfo.menuExtras.vert; 8584 minHeight = _minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; 8585 menuInnerMinHeight = Math.max(_minHeight - menuPadding.vert, 0); 8586 8587 if (this.$newElement.hasClass(classNames.DROPUP)) { 8588 menuHeight = this.sizeInfo.selectOffsetTop - this.sizeInfo.menuExtras.vert; 8589 } 8590 8591 maxHeight = menuHeight; 8592 menuInnerHeight = menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert; 8593 } else if (this.options.size && this.options.size != 'auto' && this.selectpicker.current.elements.length > this.options.size) { 8594 for (var i = 0; i < this.options.size; i++) { 8595 if (this.selectpicker.current.data[i].type === 'divider') divLength++; 8596 } 8597 8598 menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert; 8599 menuInnerHeight = menuHeight - menuPadding.vert; 8600 maxHeight = menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; 8601 minHeight = menuInnerMinHeight = ''; 8602 } 8603 8604 this.$menu.css({ 8605 'max-height': maxHeight + 'px', 8606 'overflow': 'hidden', 8607 'min-height': minHeight + 'px' 8608 }); 8609 8610 this.$menuInner.css({ 8611 'max-height': menuInnerHeight + 'px', 8612 'overflow': 'hidden auto', 8613 'min-height': menuInnerMinHeight + 'px' 8614 }); 8615 8616 // ensure menuInnerHeight is always a positive number to prevent issues calculating chunkSize in createView 8617 this.sizeInfo.menuInnerHeight = Math.max(menuInnerHeight, 1); 8618 8619 if (this.selectpicker.current.data.length && this.selectpicker.current.data[this.selectpicker.current.data.length - 1].position > this.sizeInfo.menuInnerHeight) { 8620 this.sizeInfo.hasScrollBar = true; 8621 this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth + this.sizeInfo.scrollBarWidth; 8622 } 8623 8624 if (this.options.dropdownAlignRight === 'auto') { 8625 this.$menu.toggleClass(classNames.MENURIGHT, this.sizeInfo.selectOffsetLeft > this.sizeInfo.selectOffsetRight && this.sizeInfo.selectOffsetRight < (this.sizeInfo.totalMenuWidth - selectWidth)); 8626 } 8627 8628 if (this.dropdown && this.dropdown._popper) this.dropdown._popper.update(); 8629 }, 8630 8631 setSize: function (refresh) { 8632 this.liHeight(refresh); 8633 8634 if (this.options.header) this.$menu.css('padding-top', 0); 8635 8636 if (this.options.size !== false) { 8637 var that = this, 8638 $window = $(window); 8639 8640 this.setMenuSize(); 8641 8642 if (this.options.liveSearch) { 8643 this.$searchbox 8644 .off('input.setMenuSize propertychange.setMenuSize') 8645 .on('input.setMenuSize propertychange.setMenuSize', function () { 8646 return that.setMenuSize(); 8647 }); 8648 } 8649 8650 if (this.options.size === 'auto') { 8651 $window 8652 .off('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize') 8653 .on('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize', function () { 8654 return that.setMenuSize(); 8655 }); 8656 } else if (this.options.size && this.options.size != 'auto' && this.selectpicker.current.elements.length > this.options.size) { 8657 $window.off('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize'); 8658 } 8659 } 8660 8661 this.createView(false, true, refresh); 8662 }, 8663 8664 setWidth: function () { 8665 var that = this; 8666 8667 if (this.options.width === 'auto') { 8668 requestAnimationFrame(function () { 8669 that.$menu.css('min-width', '0'); 8670 8671 that.$element.on('loaded' + EVENT_KEY, function () { 8672 that.liHeight(); 8673 that.setMenuSize(); 8674 8675 // Get correct width if element is hidden 8676 var $selectClone = that.$newElement.clone().appendTo('body'), 8677 btnWidth = $selectClone.css('width', 'auto').children('button').outerWidth(); 8678 8679 $selectClone.remove(); 8680 8681 // Set width to whatever's larger, button title or longest option 8682 that.sizeInfo.selectWidth = Math.max(that.sizeInfo.totalMenuWidth, btnWidth); 8683 that.$newElement.css('width', that.sizeInfo.selectWidth + 'px'); 8684 }); 8685 }); 8686 } else if (this.options.width === 'fit') { 8687 // Remove inline min-width so width can be changed from 'auto' 8688 this.$menu.css('min-width', ''); 8689 this.$newElement.css('width', '').addClass('fit-width'); 8690 } else if (this.options.width) { 8691 // Remove inline min-width so width can be changed from 'auto' 8692 this.$menu.css('min-width', ''); 8693 this.$newElement.css('width', this.options.width); 8694 } else { 8695 // Remove inline min-width/width so width can be changed 8696 this.$menu.css('min-width', ''); 8697 this.$newElement.css('width', ''); 8698 } 8699 // Remove fit-width class if width is changed programmatically 8700 if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') { 8701 this.$newElement[0].classList.remove('fit-width'); 8702 } 8703 }, 8704 8705 selectPosition: function () {
8706 this.$bsContainer = $('<div class="bs-container" />'); 8707 8708 var that = this, 8709 $container = $(this.options.container), 8710 pos, 8711 containerPos, 8712 actualHeight, 8713 getPlacement = function ($element) { 8714 var containerPosition = {}, 8715 // fall back to dropdown's default display setting if display is not manually set 8716 display = that.options.display || ( 8717 // Bootstrap 3 doesn't have $.fn.dropdown.Constructor.Default 8718 $.fn.dropdown.Constructor.Default ? $.fn.dropdown.Constructor.Default.display 8719 : false 8720 ); 8721 8722 that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass(classNames.DROPUP, $element.hasClass(classNames.DROPUP)); 8723 pos = $element.offset(); 8724 8725 if (!$container.is('body')) { 8726 containerPos = $container.offset(); 8727 containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop(); 8728 containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft(); 8729 } else { 8730 containerPos = { top: 0, left: 0 }; 8731 } 8732 8733 actualHeight = $element.hasClass(classNames.DROPUP) ? 0 : $element[0].offsetHeight; 8734 8735 // Bootstrap 4+ uses Popper for menu positioning 8736 if (version.major < 4 || display === 'static') { 8737 containerPosition.top = pos.top - containerPos.top + actualHeight; 8738 containerPosition.left = pos.left - containerPos.left; 8739 } 8740 8741 containerPosition.width = $element[0].offsetWidth; 8742 8743 that.$bsContainer.css(containerPosition); 8744 }; 8745 8746 this.$button.on('click.bs.dropdown.data-api', function () { 8747 if (that.isDisabled()) { 8748 return; 8749 } 8750 8751 getPlacement(that.$newElement); 8752 8753 that.$bsContainer 8754 .appendTo(that.options.container) 8755 .toggleClass(classNames.SHOW, !that.$button.hasClass(classNames.SHOW)) 8756 .append(that.$menu); 8757 }); 8758 8759 $(window) 8760 .off('resize' + EVENT_KEY + '.' + this.selectId + ' scroll' + EVENT_KEY + '.' + this.selectId) 8761 .on('resize' + EVENT_KEY + '.' + this.selectId + ' scroll' + EVENT_KEY + '.' + this.selectId, function () { 8762 var isActive = that.$newElement.hasClass(classNames.SHOW); 8763 8764 if (isActive) getPlacement(that.$newElement); 8765 }); 8766 8767 this.$element.on('hide' + EVENT_KEY, function () { 8768 that.$menu.data('height', that.$menu.height()); 8769 that.$bsContainer.detach(); 8770 }); 8771 }, 8772 8773 createOption: function (data, init) { 8774 var optionData = !data.option ? data : data.option; 8775 8776 if (optionData && optionData.nodeType !== 1) { 8777 var option = (init ? elementTemplates.selectedOption : elementTemplates.option).cloneNode(true); 8778 if (optionData.value !== undefined) option.value = optionData.value; 8779 option.textContent = optionData.text; 8780 8781 option.selected = true; 8782 8783 if (optionData.liIndex !== undefined) { 8784 option.liIndex = optionData.liIndex; 8785 } else if (!init) { 8786 option.liIndex = data.index; 8787 } 8788 8789 data.option = option; 8790 8791 this.selectpicker.main.optionQueue.appendChild(option); 8792 } 8793 }, 8794 8795 setOptionStatus: function (selectedOnly) { 8796 var that = this; 8797 8798 that.noScroll = false; 8799 8800 if (that.selectpicker.view.visibleElements && that.selectpicker.view.visibleElements.length) { 8801 for (var i = 0; i < that.selectpicker.view.visibleElements.length; i++) { 8802 var liData = that.selectpicker.current.data[i + that.selectpicker.view.position0], 8803 option = liData.option; 8804 8805 if (option) { 8806 if (selectedOnly !== true) { 8807 that.setDisabled(liData); 8808 } 8809 8810 that.setSelected(liData); 8811 } 8812 } 8813 8814 // append optionQueue (documentFragment with option elements for select options) 8815 if (this.options.source.data) this.$element[0].appendChild(this.selectpicker.main.optionQueue); 8816 } 8817 }, 8818 8819 /** 8820 * @param {Object} liData - the option object that is being changed 8821 * @param {boolean} selected - true if the option is being selected, false if being deselected 8822 */ 8823 setSelected: function (liData, selected) { 8824 selected = selected === undefined ? liData.selected : selected; 8825 8826 var li = liData.element, 8827 activeElementIsSet = this.activeElement !== undefined, 8828 thisIsActive = this.activeElement === li, 8829 prevActive, 8830 a, 8831 // if current option is already active 8832 // OR
8833 // if the current option is being selected, it's NOT multiple, and 8834 // activeElement is undefined: 8835 // - when the menu is first being opened, OR 8836 // - after a search has been performed, OR 8837 // - when retainActive is false when selecting a new option (i.e. index of the newly selected option is not the same as the current activeElement) 8838 keepActive = thisIsActive || (selected && !this.multiple && !activeElementIsSet); 8839 8840 if (!li) return; 8841 8842 if (selected !== undefined) { 8843 liData.selected = selected; 8844 if (liData.option) liData.option.selected = selected; 8845 } 8846 8847 if (selected && this.options.source.data) { 8848 this.createOption(liData, false); 8849 } 8850 8851 a = li.firstChild; 8852 8853 if (selected) { 8854 this.selectedElement = li; 8855 } 8856 8857 li.classList.toggle('selected', selected); 8858 8859 if (keepActive) { 8860 this.focusItem(li, liData); 8861 this.selectpicker.view.currentActive = li; 8862 this.activeElement = li; 8863 } else { 8864 this.defocusItem(li); 8865 } 8866 8867 if (a) { 8868 a.classList.toggle('selected', selected); 8869 8870 if (selected) { 8871 a.setAttribute('aria-selected', true); 8872 } else { 8873 if (this.multiple) { 8874 a.setAttribute('aria-selected', false); 8875 } else { 8876 a.removeAttribute('aria-selected'); 8877 } 8878 } 8879 } 8880 8881 if (!keepActive && !activeElementIsSet && selected && this.prevActiveElement !== undefined) { 8882 prevActive = this.prevActiveElement; 8883 8884 this.defocusItem(prevActive); 8885 } 8886 }, 8887 8888 /** 8889 * @param {number} index - the index of the option that is being disabled 8890 * @param {boolean} disabled - true if the option is being disabled, false if being enabled 8891 */ 8892 setDisabled: function (liData) { 8893 var disabled = liData.disabled, 8894 li = liData.element, 8895 a; 8896 8897 if (!li) return; 8898 8899 a = li.firstChild; 8900 8901 li.classList.toggle(classNames.DISABLED, disabled); 8902 8903 if (a) { 8904 if (version.major >= '4') a.classList.toggle(classNames.DISABLED, disabled); 8905 8906 if (disabled) { 8907 a.setAttribute('aria-disabled', disabled); 8908 a.setAttribute('tabindex', -1); 8909 } else { 8910 a.removeAttribute('aria-disabled'); 8911 a.setAttribute('tabindex', 0); 8912 } 8913 } 8914 }, 8915 8916 isDisabled: function () { 8917 return this.$element[0].disabled; 8918 }, 8919 8920 checkDisabled: function () { 8921 if (this.isDisabled()) { 8922 this.$newElement[0].classList.add(classNames.DISABLED); 8923 this.$button.addClass(classNames.DISABLED).attr('aria-disabled', true); 8924 } else { 8925 if (this.$button[0].classList.contains(classNames.DISABLED)) { 8926 this.$newElement[0].classList.remove(classNames.DISABLED); 8927 this.$button.removeClass(classNames.DISABLED).attr('aria-disabled', false); 8928 } 8929 } 8930 }, 8931 8932 clickListener: function () { 8933 var that = this, 8934 $document = $(document); 8935 8936 $document.data('spaceSelect', false); 8937 8938 this.$button.on('keyup', function (e) { 8939 if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) { 8940 e.preventDefault(); 8941 $document.data('spaceSelect', false); 8942 } 8943 }); 8944 8945 this.$newElement.on('show.bs.dropdown', function () { 8946 if (!that.dropdown && version.major === '4') { 8947 that.dropdown = that.$button.data('bs.dropdown'); 8948 that.dropdown._menu = that.$menu[0]; 8949 } 8950 }); 8951 8952 function clearSelection (e) { 8953 if (that.multiple) { 8954 that.deselectAll(); 8955 } else { 8956 var element = that.$element[0], 8957 prevValue = element.value, 8958 prevIndex = element.selectedIndex, 8959 prevOption = element.options[prevIndex], 8960 prevData = prevOption ? that.selectpicker.main.data[prevOption.liIndex] : false; 8961 8962 if (prevData) { 8963 that.setSelected(prevData, false); 8964 } 8965 8966 element.selectedIndex = 0; 8967 8968 changedArguments = [prevIndex, false, prevValue]; 8969 that.$element.triggerNative('change'); 8970 } 8971 8972 // remove selected styling if menu is open 8973 if (that.$newElement.hasClass(classNames.SHOW)) { 8974 if (that.options.liveSearch) { 8975 that.$searchbox.trigger('focus'); 8976 } 8977 8978 that.createView(false); 8979 } 8980 } 8981 8982 this.$button.on('click.bs.dropdown.data-api', function (e) { 8983 if (that.options.allowClear) { 8984 var target = e.target, 8985 clearButton = that.$clearButton[0]; 8986 8987 // IE doesn't support event listeners on child elements of buttons 8988 if (/MSIE|Trident/.test(window.navigator.userAgent)) { 8989 target = document.elementFromPoint(e.clientX, e.clientY); 8990 } 8991 8992 if (target === clearButton || target.parentElement === clearButton) { 8993 e.stopImmediatePropagation(); 8994 clearSelection(e); 8995 } 8996 } 8997 8998 if (!that.$newElement.hasClass(classNames.SHOW)) { 8999 that.setSize(); 9000 } 9001 }); 9002 9003 function setFocus () { 9004 if (that.options.liveSearch) { 9005 that.$searchbox.trigger('focus'); 9006 } else { 9007 that.$menuInner.trigger('focus'); 9008 } 9009 } 9010 9011 function checkPopperExists () { 9012 if (that.dropdown && that.dropdown._popper && that.dropdown._popper.state) { 9013 setFocus(); 9014 } else { 9015 requestAnimationFrame(checkPopperExists); 9016 } 9017 } 9018 9019 this.$element.on('shown' + EVENT_KEY, function () {
9020 if (that.$menuInner[0].scrollTop !== that.selectpicker.view.scrollTop) { 9021 that.$menuInner[0].scrollTop = that.selectpicker.view.scrollTop; 9022 } 9023 9024 if (version.major > 3) { 9025 requestAnimationFrame(checkPopperExists); 9026 } else { 9027 setFocus(); 9028 } 9029 }); 9030 9031 // ensure posinset and setsize are correct before selecting an option via a click 9032 this.$menuInner.on('mouseenter', 'li a', function (e) { 9033 var hoverLi = this.parentElement, 9034 position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, 9035 index = Array.prototype.indexOf.call(hoverLi.parentElement.children, hoverLi), 9036 hoverData = that.selectpicker.current.data[index + position0]; 9037 9038 that.focusItem(hoverLi, hoverData, true); 9039 }); 9040 9041 this.$menuInner.on('click', 'li a', function (e, retainActive) { 9042 var $this = $(this), 9043 element = that.$element[0], 9044 position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, 9045 clickedData = that.selectpicker.current.data[$this.parent().index() + position0], 9046 clickedElement = clickedData.element, 9047 prevValue = getSelectValues.call(that), 9048 prevIndex = element.selectedIndex, 9049 prevOption = element.options[prevIndex], 9050 prevData = prevOption ? that.selectpicker.main.data[prevOption.liIndex] : false, 9051 triggerChange = true; 9052 9053 // Don't close on multi choice menu 9054 if (that.multiple && that.options.maxOptions !== 1) { 9055 e.stopPropagation(); 9056 } 9057 9058 e.preventDefault(); 9059 9060 // Don't run if the select is disabled 9061 if (!that.isDisabled() && !$this.parent().hasClass(classNames.DISABLED)) { 9062 var option = clickedData.option, 9063 $option = $(option), 9064 state = option.selected, 9065 optgroupData = that.selectpicker.current.data.find(function (datum) { 9066 return datum.optID === clickedData.optID && datum.type === 'optgroup-label'; 9067 }), 9068 optgroup = optgroupData ? optgroupData.optgroup : undefined, 9069 dataGetter = optgroup instanceof Element ? getOptionData.fromOption : getOptionData.fromDataSource, 9070 optgroupOptions = optgroup && optgroup.children, 9071 maxOptions = parseInt(that.options.maxOptions), 9072 maxOptionsGrp = optgroup && parseInt(dataGetter(optgroup, 'maxOptions')) || false; 9073 9074 if (clickedElement === that.activeElement) retainActive = true; 9075 9076 if (!retainActive) { 9077 that.prevActiveElement = that.activeElement; 9078 that.activeElement = undefined; 9079 } 9080 9081 if (!that.multiple || maxOptions === 1) { // Deselect previous option if not multi select 9082 if (prevData) that.setSelected(prevData, false); 9083 that.setSelected(clickedData, true); 9084 } else { // Toggle the clicked option if multi select. 9085 that.setSelected(clickedData, !state); 9086 that.focusedParent.focus(); 9087 9088 if (maxOptions !== false || maxOptionsGrp !== false) { 9089 var maxReached = maxOptions < getSelectedOptions.call(that).length, 9090 selectedGroupOptions = 0; 9091 9092 if (optgroup && optgroup.children) { 9093 for (var i = 0; i < optgroup.children.length; i++) { 9094 if (optgroup.children[i].selected) selectedGroupOptions++; 9095 } 9096 } 9097 9098 var maxReachedGrp = maxOptionsGrp < selectedGroupOptions; 9099 9100 if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) { 9101 if (maxOptions && maxOptions === 1) { 9102 element.selectedIndex = -1; 9103 that.setOptionStatus(true); 9104 } else if (maxOptionsGrp && maxOptionsGrp === 1) { 9105 for (var i = 0; i < optgroupOptions.length; i++) { 9106 var _option = optgroupOptions[i]; 9107 that.setSelected(that.selectpicker.current.data[_option.liIndex], false); 9108 } 9109 9110 that.setSelected(clickedData, true); 9111 } else { 9112 var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText, 9113 maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText, 9114 maxTxt = maxOptionsArr[0].replace('{n}', maxOptions), 9115 maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp), 9116 $notify = $('<div class="notify"></div>'); 9117 // If {var} is set in array, replace it 9118 /** @deprecated */ 9119 if (maxOptionsArr[2]) { 9120 maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]); 9121 maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]); 9122 } 9123 9124 that.$menu.append($notify); 9125 9126 if (maxOptions && maxReached) { 9127 $notify.append($('<div>' + maxTxt + '</div>')); 9128 triggerChange = false;
vendor: 6,803 bytes, lines 9129-9317
9129 that.$element.trigger('maxReached' + EVENT_KEY); 9130 } 9131 9132 if (maxOptionsGrp && maxReachedGrp) { 9133 $notify.append($('<div>' + maxTxtGrp + '</div>')); 9134 triggerChange = false; 9135 that.$element.trigger('maxReachedGrp' + EVENT_KEY); 9136 } 9137 9138 setTimeout(function () { 9139 that.setSelected(clickedData, false); 9140 }, 10); 9141 9142 $notify[0].classList.add('fadeOut'); 9143 9144 setTimeout(function () { 9145 $notify.remove(); 9146 }, 1050); 9147 } 9148 } 9149 } 9150 } 9151 9152 if (that.options.source.data) that.$element[0].appendChild(that.selectpicker.main.optionQueue); 9153 9154 if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) { 9155 that.$button.trigger('focus'); 9156 } else if (that.options.liveSearch) { 9157 that.$searchbox.trigger('focus'); 9158 } 9159 9160 // Trigger select 'change' 9161 if (triggerChange) { 9162 if (that.multiple || prevIndex !== element.selectedIndex) { 9163 // $option.prop('selected') is current option state (selected/unselected). prevValue is the value of the select prior to being changed. 9164 changedArguments = [option.index, $option.prop('selected'), prevValue]; 9165 that.$element 9166 .triggerNative('change'); 9167 } 9168 } 9169 } 9170 }); 9171 9172 this.$menu.on('click', 'li.' + classNames.DISABLED + ' a, .' + classNames.POPOVERHEADER + ', .' + classNames.POPOVERHEADER + ' :not(.close)', function (e) { 9173 if (e.currentTarget == this) { 9174 e.preventDefault(); 9175 e.stopPropagation(); 9176 if (that.options.liveSearch && !$(e.target).hasClass('close')) { 9177 that.$searchbox.trigger('focus'); 9178 } else { 9179 that.$button.trigger('focus'); 9180 } 9181 } 9182 }); 9183 9184 this.$menuInner.on('click', '.divider, .dropdown-header', function (e) { 9185 e.preventDefault(); 9186 e.stopPropagation(); 9187 if (that.options.liveSearch) { 9188 that.$searchbox.trigger('focus'); 9189 } else { 9190 that.$button.trigger('focus'); 9191 } 9192 }); 9193 9194 this.$menu.on('click', '.' + classNames.POPOVERHEADER + ' .close', function () { 9195 that.$button.trigger('click'); 9196 }); 9197 9198 this.$searchbox.on('click', function (e) { 9199 e.stopPropagation(); 9200 }); 9201 9202 this.$menu.on('click', '.actions-btn', function (e) { 9203 if (that.options.liveSearch) { 9204 that.$searchbox.trigger('focus'); 9205 } else { 9206 that.$button.trigger('focus'); 9207 } 9208 9209 e.preventDefault(); 9210 e.stopPropagation(); 9211 9212 if ($(this).hasClass('bs-select-all')) { 9213 that.selectAll(); 9214 } else { 9215 that.deselectAll(); 9216 } 9217 }); 9218 9219 this.$button 9220 .on('focus' + EVENT_KEY, function (e) { 9221 var tabindex = that.$element[0].getAttribute('tabindex'); 9222 9223 // only change when button is actually focused 9224 if (tabindex !== undefined && e.originalEvent && e.originalEvent.isTrusted) { 9225 // apply select element's tabindex to ensure correct order is followed when tabbing to the next element 9226 this.setAttribute('tabindex', tabindex); 9227 // set element's tabindex to -1 to allow for reverse tabbing 9228 that.$element[0].setAttribute('tabindex', -1); 9229 that.selectpicker.view.tabindex = tabindex; 9230 } 9231 }) 9232 .on('blur' + EVENT_KEY, function (e) { 9233 // revert everything to original tabindex 9234 if (that.selectpicker.view.tabindex !== undefined && e.originalEvent && e.originalEvent.isTrusted) { 9235 that.$element[0].setAttribute('tabindex', that.selectpicker.view.tabindex); 9236 this.setAttribute('tabindex', -1); 9237 that.selectpicker.view.tabindex = undefined; 9238 } 9239 }); 9240 9241 this.$element 9242 .on('change' + EVENT_KEY, function () { 9243 that.render(); 9244 that.$element.trigger('changed' + EVENT_KEY, changedArguments); 9245 changedArguments = null; 9246 }) 9247 .on('focus' + EVENT_KEY, function () { 9248 if (!that.options.mobile) that.$button[0].focus(); 9249 }); 9250 }, 9251 9252 liveSearchListener: function () { 9253 var that = this; 9254 9255 this.$button.on('click.bs.dropdown.data-api', function () { 9256 if (!!that.$searchbox.val()) { 9257 that.$searchbox.val(''); 9258 that.selectpicker.search.previousValue = undefined; 9259 } 9260 }); 9261 9262 this.$searchbox.on('click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api', function (e) { 9263 e.stopPropagation(); 9264 }); 9265 9266 this.$searchbox.on('input propertychange', function () { 9267 var searchValue = that.$searchbox[0].value; 9268 9269 that.selectpicker.search.elements = []; 9270 that.selectpicker.search.data = []; 9271 9272 if (searchValue) { 9273 that.selectpicker.search.previousValue = searchValue; 9274 9275 if (that.options.source.search) { 9276 that.fetchData(function (builtData) { 9277 that.render(); 9278 that.buildList(undefined, true); 9279 that.noScroll = true; 9280 that.$menuInner.scrollTop(0); 9281 that.createView(true); 9282 showNoResults.call(that, builtData, searchValue); 9283 }, 'search', 0, searchValue); 9284 } else { 9285 var i, 9286 searchMatch = [], 9287 q = searchValue.toUpperCase(), 9288 cache = {}, 9289 cacheArr = [], 9290 searchStyle = that._searchStyle(), 9291 normalizeSearch = that.options.liveSearchNormalize; 9292 9293 if (normalizeSearch) q = normalizeToBase(q); 9294 9295 for (var i = 0; i < that.selectpicker.main.data.length; i++) { 9296 var li = that.selectpicker.main.data[i]; 9297 9298 if (!cache[i]) { 9299 cache[i] = stringSearch(li, q, searchStyle, normalizeSearch); 9300 } 9301 9302 if (cache[i] && li.headerIndex !== undefined && cacheArr.indexOf(li.headerIndex) === -1) { 9303 if (li.headerIndex > 0) { 9304 cache[li.headerIndex - 1] = true; 9305 cacheArr.push(li.headerIndex - 1); 9306 } 9307 9308 cache[li.headerIndex] = true; 9309 cacheArr.push(li.headerIndex); 9310 9311 cache[li.lastIndex + 1] = true; 9312 } 9313 9314 if (cache[i] && li.type !== 'optgroup-label') cacheArr.push(i); 9315 } 9316 9317 for (var i = 0, cacheLen = cacheArr.length; i < cacheLen; i++) {
9318 var index = cacheArr[i], 9319 prevIndex = cacheArr[i - 1], 9320 li = that.selectpicker.main.data[index], 9321 liPrev = that.selectpicker.main.data[prevIndex]; 9322 9323 if (li.type !== 'divider' || (li.type === 'divider' && liPrev && liPrev.type !== 'divider' && cacheLen - 1 !== i)) { 9324 that.selectpicker.search.data.push(li); 9325 searchMatch.push(that.selectpicker.main.elements[index]); 9326 } 9327 } 9328 9329 that.activeElement = undefined; 9330 that.noScroll = true; 9331 that.$menuInner.scrollTop(0); 9332 that.selectpicker.search.elements = searchMatch; 9333 that.createView(true); 9334 showNoResults.call(that, searchMatch, searchValue); 9335 } 9336 } else if (that.selectpicker.search.previousValue) { // for IE11 (#2402) 9337 that.$menuInner.scrollTop(0); 9338 that.createView(false); 9339 } 9340 }); 9341 }, 9342 9343 _searchStyle: function () { 9344 return this.options.liveSearchStyle || 'contains'; 9345 }, 9346 9347 val: function (value) { 9348 var element = this.$element[0]; 9349 9350 if (typeof value !== 'undefined') { 9351 var selectedOptions = getSelectedOptions.call(this), 9352 prevValue = getSelectValues.call(this, selectedOptions); 9353 9354 changedArguments = [null, null, prevValue]; 9355 9356 if (!Array.isArray(value)) value = [ value ]; 9357 9358 value.map(String); 9359 9360 for (var i = 0; i < selectedOptions.length; i++) { 9361 var item = selectedOptions[i]; 9362 9363 if (item && value.indexOf(String(item.value)) === -1) { 9364 this.setSelected(item, false); 9365 } 9366 } 9367 9368 // only update selected value if it matches an existing option 9369 this.selectpicker.main.data.filter(function (item) { 9370 if (value.indexOf(String(item.value)) !== -1) { 9371 this.setSelected(item, true); 9372 return true; 9373 } 9374 9375 return false; 9376 }, this); 9377 9378 if (this.options.source.data) element.appendChild(this.selectpicker.main.optionQueue); 9379 9380 this.$element.trigger('changed' + EVENT_KEY, changedArguments); 9381 9382 if (this.$newElement.hasClass(classNames.SHOW)) { 9383 if (this.multiple) { 9384 this.setOptionStatus(true); 9385 } else { 9386 var liSelectedIndex = (element.options[element.selectedIndex] || {}).liIndex; 9387 9388 if (typeof liSelectedIndex === 'number') { 9389 this.setSelected(this.selectpicker.current.data[liSelectedIndex], true); 9390 } 9391 } 9392 } 9393 9394 this.render(); 9395 9396 changedArguments = null; 9397 9398 return this.$element; 9399 } else { 9400 return this.$element.val(); 9401 } 9402 }, 9403 9404 changeAll: function (status) { 9405 if (!this.multiple) return; 9406 if (typeof status === 'undefined') status = true; 9407 9408 var element = this.$element[0], 9409 previousSelected = 0, 9410 currentSelected = 0, 9411 prevValue = getSelectValues.call(this); 9412 9413 element.classList.add('bs-select-hidden'); 9414 9415 for (var i = 0, data = this.selectpicker.current.data, len = data.length; i < len; i++) { 9416 var liData = data[i], 9417 option = liData.option; 9418 9419 if (option && !liData.disabled && liData.type !== 'divider') { 9420 if (liData.selected) previousSelected++; 9421 option.selected = status; 9422 liData.selected = status; 9423 if (status === true) currentSelected++; 9424 } 9425 } 9426 9427 element.classList.remove('bs-select-hidden'); 9428 9429 if (previousSelected === currentSelected) return; 9430 9431 this.setOptionStatus(); 9432 9433 changedArguments = [null, null, prevValue]; 9434 9435 this.$element 9436 .triggerNative('change'); 9437 }, 9438 9439 selectAll: function () { 9440 return this.changeAll(true); 9441 }, 9442 9443 deselectAll: function () { 9444 return this.changeAll(false); 9445 }, 9446 9447 toggle: function (e, state) { 9448 var isActive, 9449 triggerClick = state === undefined; 9450 9451 e = e || window.event; 9452 9453 if (e) e.stopPropagation(); 9454 9455 if (triggerClick === false) { 9456 isActive = this.$newElement[0].classList.contains(classNames.SHOW); 9457 triggerClick = state === true && isActive === false || state === false && isActive === true; 9458 } 9459 9460 if (triggerClick) this.$button.trigger('click.bs.dropdown.data-api'); 9461 }, 9462 9463 open: function (e) { 9464 this.toggle(e, true); 9465 }, 9466 9467 close: function (e) { 9468 this.toggle(e, false); 9469 }, 9470 9471 keydown: function (e) { 9472 var $this = $(this), 9473 isToggle = $this.hasClass('dropdown-toggle'), 9474 $parent = isToggle ? $this.closest('.dropdown') : $this.closest(Selector.MENU), 9475 that = $parent.data('this'), 9476 $items = that.findLis(), 9477 index, 9478 isActive, 9479 liActive, 9480 activeLi, 9481 offset, 9482 updateScroll = false, 9483 downOnTab = e.which === keyCodes.TAB && !isToggle && !that.options.selectOnTab, 9484 isArrowKey = REGEXP_ARROW.test(e.which) || downOnTab, 9485 scrollTop = that.$menuInner[0].scrollTop, 9486 isVirtual = that.isVirtual(), 9487 position0 = isVirtual === true ? that.selectpicker.view.position0 : 0; 9488 9489 // do nothing if a function key is pressed 9490 if (e.which >= 112 && e.which <= 123) return; 9491 9492 isActive = that.$menu.hasClass(classNames.SHOW); 9493 9494 if ( 9495 !isActive && 9496 ( 9497 isArrowKey || 9498 (e.which >= 48 && e.which <= 57) || 9499 (e.which >= 96 && e.which <= 105) || 9500 (e.which >= 65 && e.which <= 90) 9501 ) 9502 ) { 9503 that.$button.trigger('click.bs.dropdown.data-api'); 9504 9505 if (that.options.liveSearch) { 9506 that.$searchbox.trigger('focus'); 9507 return; 9508 } 9509 } 9510 9511 if (e.which === keyCodes.ESCAPE && isActive) { 9512 e.preventDefault(); 9513 that.$button.trigger('click.bs.dropdown.data-api').trigger('focus'); 9514 } 9515 9516 if (isArrowKey) { // if up or down 9517 if (!$items.length) return; 9518 9519 liActive = that.activeElement; 9520 index = liActive ? Array.prototype.indexOf.call(liActive.parentElement.children, liActive) : -1; 9521 9522 if (index !== -1) { 9523 that.defocusItem(liActive); 9524 } 9525 9526 if (e.which === keyCodes.ARROW_UP) { // up 9527 if (index !== -1) index--; 9528 if (index + position0 < 0) index += $items.length; 9529 9530 if (!that.selectpicker.view.canHighlight[index + position0]) { 9531 index = that.selectpicker.view.canHighlight.slice(0, index + position0).lastIndexOf(true) - position0; 9532 if (index === -1) index = $items.length - 1; 9533 } 9534 } else if (e.which === keyCodes.ARROW_DOWN || downOnTab) { // down 9535 index++; 9536 if (index + position0 >
vendor: 4,978 bytes, lines 9536-9677
9536= that.selectpicker.view.canHighlight.length) index = that.selectpicker.view.firstHighlightIndex; 9537 9538 if (!that.selectpicker.view.canHighlight[index + position0]) { 9539 index = index + 1 + that.selectpicker.view.canHighlight.slice(index + position0 + 1).indexOf(true); 9540 } 9541 } 9542 9543 e.preventDefault(); 9544 9545 var liActiveIndex = position0 + index; 9546 9547 if (e.which === keyCodes.ARROW_UP) { // up 9548 // scroll to bottom and highlight last option 9549 if (position0 === 0 && index === $items.length - 1) { 9550 that.$menuInner[0].scrollTop = that.$menuInner[0].scrollHeight; 9551 9552 liActiveIndex = that.selectpicker.current.elements.length - 1; 9553 } else { 9554 activeLi = that.selectpicker.current.data[liActiveIndex]; 9555 9556 // could be undefined if no results exist 9557 if (activeLi) { 9558 offset = activeLi.position - activeLi.height; 9559 9560 updateScroll = offset < scrollTop; 9561 } 9562 } 9563 } else if (e.which === keyCodes.ARROW_DOWN || downOnTab) { // down 9564 // scroll to top and highlight first option 9565 if (index === that.selectpicker.view.firstHighlightIndex) { 9566 that.$menuInner[0].scrollTop = 0; 9567 9568 liActiveIndex = that.selectpicker.view.firstHighlightIndex; 9569 } else { 9570 activeLi = that.selectpicker.current.data[liActiveIndex]; 9571 9572 // could be undefined if no results exist 9573 if (activeLi) { 9574 offset = activeLi.position - that.sizeInfo.menuInnerHeight; 9575 9576 updateScroll = offset > scrollTop; 9577 } 9578 } 9579 } 9580 9581 liActive = that.selectpicker.current.elements[liActiveIndex]; 9582 9583 that.activeElement = (that.selectpicker.current.data[liActiveIndex] || {}).element; 9584 9585 that.focusItem(liActive); 9586 9587 that.selectpicker.view.currentActive = liActive; 9588 9589 if (updateScroll) that.$menuInner[0].scrollTop = offset; 9590 9591 if (that.options.liveSearch) { 9592 that.$searchbox.trigger('focus'); 9593 } else { 9594 $this.trigger('focus'); 9595 } 9596 } else if ( 9597 (!$this.is('input') && !REGEXP_TAB_OR_ESCAPE.test(e.which)) || 9598 (e.which === keyCodes.SPACE && that.selectpicker.keydown.keyHistory) 9599 ) { 9600 var searchMatch, 9601 matches = [], 9602 keyHistory; 9603 9604 e.preventDefault(); 9605 9606 that.selectpicker.keydown.keyHistory += keyCodeMap[e.which]; 9607 9608 if (that.selectpicker.keydown.resetKeyHistory.cancel) clearTimeout(that.selectpicker.keydown.resetKeyHistory.cancel); 9609 that.selectpicker.keydown.resetKeyHistory.cancel = that.selectpicker.keydown.resetKeyHistory.start(); 9610 9611 keyHistory = that.selectpicker.keydown.keyHistory; 9612 9613 // if all letters are the same, set keyHistory to just the first character when searching 9614 if (/^(.)\1+$/.test(keyHistory)) { 9615 keyHistory = keyHistory.charAt(0); 9616 } 9617 9618 // find matches 9619 for (var i = 0; i < that.selectpicker.current.data.length; i++) { 9620 var li = that.selectpicker.current.data[i], 9621 hasMatch; 9622 9623 hasMatch = stringSearch(li, keyHistory, 'startsWith', true); 9624 9625 if (hasMatch && that.selectpicker.view.canHighlight[i]) { 9626 matches.push(li.element); 9627 } 9628 } 9629 9630 if (matches.length) { 9631 var matchIndex = 0; 9632 9633 $items.removeClass('active').find('a').removeClass('active'); 9634 9635 // either only one key has been pressed or they are all the same key 9636 if (keyHistory.length === 1) { 9637 matchIndex = matches.indexOf(that.activeElement); 9638 9639 if (matchIndex === -1 || matchIndex === matches.length - 1) { 9640 matchIndex = 0; 9641 } else { 9642 matchIndex++; 9643 } 9644 } 9645 9646 searchMatch = matches[matchIndex]; 9647 9648 activeLi = that.selectpicker.main.data[searchMatch]; 9649 9650 if (scrollTop - activeLi.position > 0) { 9651 offset = activeLi.position - activeLi.height; 9652 updateScroll = true; 9653 } else { 9654 offset = activeLi.position - that.sizeInfo.menuInnerHeight; 9655 // if the option is already visible at the current scroll position, just keep it the same 9656 updateScroll = activeLi.position > scrollTop + that.sizeInfo.menuInnerHeight; 9657 } 9658 9659 liActive = that.selectpicker.main.elements[searchMatch]; 9660 9661 that.activeElement = liActive; 9662 9663 that.focusItem(liActive); 9664 9665 if (liActive) liActive.firstChild.focus(); 9666 9667 if (updateScroll) that.$menuInner[0].scrollTop = offset; 9668 9669 $this.trigger('focus'); 9670 } 9671 } 9672 9673 // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu. 9674 if ( 9675 isActive && 9676 ( 9677 (e.which === keyCodes.SPACE && !that.selectpicker.keydown.keyHistory) ||
9678 e.which === keyCodes.ENTER || 9679 (e.which === keyCodes.TAB && that.options.selectOnTab) 9680 ) 9681 ) { 9682 if (e.which !== keyCodes.SPACE) e.preventDefault(); 9683 9684 if (!that.options.liveSearch || e.which !== keyCodes.SPACE) { 9685 that.$menuInner.find('.active a').trigger('click', true); // retain active class 9686 $this.trigger('focus'); 9687 9688 if (!that.options.liveSearch) { 9689 // Prevent screen from scrolling if the user hits the spacebar 9690 e.preventDefault(); 9691 // Fixes spacebar selection of dropdown items in FF & IE 9692 $(document).data('spaceSelect', true); 9693 } 9694 } 9695 } 9696 }, 9697 9698 mobile: function () { 9699 // ensure mobile is set to true if mobile function is called after init 9700 this.options.mobile = true; 9701 this.$element[0].classList.add('mobile-device'); 9702 }, 9703 9704 refresh: function () { 9705 var that = this; 9706 // update options if data attributes have been changed 9707 var config = $.extend({}, this.options, getAttributesObject(this.$element), this.$element.data()); // in this order on refresh, as user may change attributes on select, and options object is not passed on refresh 9708 this.options = config; 9709 9710 if (this.options.source.data) { 9711 this.render(); 9712 this.buildList(); 9713 } else { 9714 this.fetchData(function () { 9715 that.render(); 9716 that.buildList(); 9717 }); 9718 } 9719 9720 this.checkDisabled(); 9721 this.setStyle(); 9722 this.setWidth(); 9723 9724 this.setSize(true); 9725 9726 this.$element.trigger('refreshed' + EVENT_KEY); 9727 }, 9728 9729 hide: function () { 9730 this.$newElement.hide(); 9731 }, 9732 9733 show: function () { 9734 this.$newElement.show(); 9735 }, 9736 9737 remove: function () { 9738 this.$newElement.remove(); 9739 this.$element.remove(); 9740 }, 9741 9742 destroy: function () { 9743 this.$newElement.before(this.$element).remove(); 9744 9745 if (this.$bsContainer) { 9746 this.$bsContainer.remove(); 9747 } else { 9748 this.$menu.remove(); 9749 } 9750 9751 if (this.selectpicker.view.titleOption && this.selectpicker.view.titleOption.parentNode) { 9752 this.selectpicker.view.titleOption.parentNode.removeChild(this.selectpicker.view.titleOption); 9753 } 9754 9755 this.$element 9756 .off(EVENT_KEY) 9757 .removeData('selectpicker') 9758 .removeClass('bs-select-hidden selectpicker mobile-device'); 9759 9760 $(window).off(EVENT_KEY + '.' + this.selectId); 9761 } 9762 }; 9763 9764 // SELECTPICKER PLUGIN DEFINITION 9765 // ============================== 9766 function Plugin (option) { 9767 // get the args of the outer function.. 9768 var args = arguments; 9769 // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them 9770 // to get lost/corrupted in android 2.3 and IE9 #715 #775 9771 var _option = option; 9772 9773 [].shift.apply(args); 9774 9775 // if the version was not set successfully 9776 if (!version.success) { 9777 // try to retreive it again 9778 try { 9779 version.full = (getVersion() || '').split(' ')[0].split('.'); 9780 } catch (err) { 9781 // fall back to use BootstrapVersion if set 9782 if (Selectpicker.BootstrapVersion) { 9783 version.full = Selectpicker.BootstrapVersion.split(' ')[0].split('.'); 9784 } else { 9785 version.full = [version.major, '0', '0']; 9786 9787 console.warn( 9788 'There was an issue retrieving Bootstrap\'s version. ' + 9789 'Ensure Bootstrap is being loaded before bootstrap-select and there is no namespace collision. ' + 9790 'If loading Bootstrap asynchronously, the version may need to be manually specified via $.fn.selectpicker.Constructor.BootstrapVersion.', 9791 err 9792 ); 9793 } 9794 } 9795 9796 version.major = version.full[0]; 9797 version.success = true; 9798 } 9799 9800 if (version.major >= '4') { 9801 // some defaults need to be changed if using Bootstrap 4 9802 // check to see if they have already been manually changed before forcing them to update 9803 var toUpdate = []; 9804 9805 if (Selectpicker.DEFAULTS.style === classNames.BUTTONCLASS) toUpdate.push({ name: 'style', className: 'BUTTONCLASS' }); 9806 if (Selectpicker.DEFAULTS.iconBase === classNames.ICONBASE) toUpdate.push({ name: 'iconBase', className: 'ICONBASE' }); 9807 if (Selectpicker.DEFAULTS.tickIcon === classNames.TICKICON) toUpdate.push({ name: 'tickIcon', className: 'TICKICON' }); 9808 9809 classNames.DIVIDER = 'dropdown-divider'; 9810 classNames.SHOW = 'show'; 9811 classNames.BUTTONCLASS = 'btn-light';
9812 classNames.POPOVERHEADER = 'popover-header'; 9813 classNames.ICONBASE = ''; 9814 classNames.TICKICON = 'bs-ok-default'; 9815 9816 for (var i = 0; i < toUpdate.length; i++) { 9817 var option = toUpdate[i]; 9818 Selectpicker.DEFAULTS[option.name] = classNames[option.className]; 9819 } 9820 } 9821 9822 if (version.major > '4') { 9823 Selector.DATA_TOGGLE = 'data-bs-toggle="dropdown"'; 9824 } 9825 9826 var value; 9827 var chain = this.each(function () { 9828 var $this = $(this); 9829 if ($this.is('select')) { 9830 var data = $this.data('selectpicker'), 9831 options = typeof _option == 'object' && _option; 9832 9833 // for backwards compatibility 9834 // (using title as placeholder is deprecated - remove in v2.0.0) 9835 if (options.title) options.placeholder = options.title; 9836 9837 if (!data) { 9838 var dataAttributes = $this.data(); 9839 9840 for (var dataAttr in dataAttributes) { 9841 if (Object.prototype.hasOwnProperty.call(dataAttributes, dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) { 9842 delete dataAttributes[dataAttr]; 9843 } 9844 } 9845 9846 var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, getAttributesObject($this), dataAttributes, options); // this is correct order on initial render 9847 config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), dataAttributes.template, options.template); 9848 config.source = $.extend({}, Selectpicker.DEFAULTS.source, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.source : {}), options.source); 9849 $this.data('selectpicker', (data = new Selectpicker(this, config))); 9850 } else if (options) { 9851 for (var i in options) { 9852 if (Object.prototype.hasOwnProperty.call(options, i)) { 9853 data.options[i] = options[i]; 9854 } 9855 } 9856 } 9857 9858 if (typeof _option == 'string') { 9859 if (data[_option] instanceof Function) { 9860 value = data[_option].apply(data, args); 9861 } else { 9862 value = data.options[_option]; 9863 } 9864 } 9865 } 9866 }); 9867 9868 if (typeof value !== 'undefined') { 9869 // noinspection JSUnusedAssignment 9870 return value; 9871 } else { 9872 return chain; 9873 } 9874 } 9875 9876 var old = $.fn.selectpicker; 9877 $.fn.selectpicker = Plugin; 9878 $.fn.selectpicker.Constructor = Selectpicker; 9879 9880 // SELECTPICKER NO CONFLICT 9881 // ======================== 9882 $.fn.selectpicker.noConflict = function () { 9883 $.fn.selectpicker = old; 9884 return this; 9885 }; 9886 9887 // get Bootstrap's keydown event handler for either Bootstrap 4 or Bootstrap 3 9888 function keydownHandler () { 9889 if (version.major < 5) { 9890 if ($.fn.dropdown) { 9891 // wait to define until function is called in case Bootstrap isn't loaded yet 9892 var bootstrapKeydown = $.fn.dropdown.Constructor._dataApiKeydownHandler || $.fn.dropdown.Constructor.prototype.keydown; 9893 return bootstrapKeydown.apply(this, arguments); 9894 } 9895 } else { 9896 return Dropdown.dataApiKeydownHandler; 9897 } 9898 } 9899 9900 $(document) 9901 .off('keydown.bs.dropdown.data-api') 9902 .on('keydown.bs.dropdown.data-api', ':not(.bootstrap-select) > [' + Selector.DATA_TOGGLE + ']', keydownHandler) 9903 .on('keydown.bs.dropdown.data-api', ':not(.bootstrap-select) > .dropdown-menu', keydownHandler) 9904 .on('keydown' + EVENT_KEY, '.bootstrap-select [' + Selector.DATA_TOGGLE + '], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input', Selectpicker.prototype.keydown) 9905 .on('focusin.modal', '.bootstrap-select [' + Selector.DATA_TOGGLE + '], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input', function (e) { 9906 e.stopPropagation(); 9907 }); 9908 9909 // SELECTPICKER DATA-API 9910 // ===================== 9911 document.addEventListener('DOMContentLoaded', function () { 9912 $('.selectpicker').each(function () { 9913 var $selectpicker = $(this); 9914 Plugin.call($selectpicker, $selectpicker.data()); 9915 }); 9916 }); 9917})(jQuery); 9918; 9919(function( $ ){ 9920 9921 var createdElements = []; 9922 9923 var defaults = { 9924 options: { 9925 prependExistingHelpBlock: false, 9926 sniffHtml: true, // sniff for 'required', 'maxlength', etc 9927 preventSubmit: true, // stop the form submit event from firing if validation fails
9928 submitError: function( $oForm , e, oErrors) 9929 { 9930 $oForm.find( 'input[name="' + Object.keys( oErrors )[ 0 ] + '"]').focus(); 9931 }, // function called if there is an error when trying to submit 9932 submitSuccess: false, // function called just before a successful submit event is sent to the server 9933 semanticallyStrict: false, // set to true to tidy up generated HTML output 9934 autoAdd: 9935 { 9936 helpBlocks: true 9937 }, 9938 filter: function () 9939 { 9940 return $(this).is(":visible"); // only validate elements you can see 9941 //return true; // validate everything 9942 } 9943 }, 9944 methods: { 9945 init : function( options ) { 9946 9947 var settings = $.extend(true, {}, defaults); 9948 9949 settings.options = $.extend(true, settings.options, options); 9950 9951 var $siblingElements = this; 9952 9953 var uniqueForms = $.unique( 9954 $siblingElements.map( function () { 9955 return $(this).parents("form")[0]; 9956 }).toArray() 9957 ); 9958 9959 $(uniqueForms).bind("submit", function (e) { 9960 var $form = $(this); 9961 var warningsFound = 0; 9962 var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); 9963 $inputs.trigger("submit.validation").trigger("validationLostFocus.validation"); 9964 9965 $inputs.each(function (i, el) { 9966 var $this = $(el), 9967 $controlGroup = $this.parents(".form-group").first(); 9968 if ( 9969 $controlGroup.hasClass("text-warning") 9970 ) { 9971 $controlGroup.removeClass("text-warning").addClass("text-danger"); 9972 warningsFound++; 9973 } 9974 }); 9975 9976 $inputs.trigger("validationLostFocus.validation"); 9977 9978 if (warningsFound) { 9979 if (settings.options.preventSubmit) { 9980 e.preventDefault(); 9981 } 9982 //$form.addClass("text-danger"); 9983 if ($.isFunction(settings.options.submitError)) { 9984 settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true)); 9985 } 9986 } else { 9987 //$form.removeClass("text-danger"); 9988 if ($.isFunction(settings.options.submitSuccess)) { 9989 settings.options.submitSuccess($form, e); 9990 } 9991 } 9992 }); 9993 9994 return this.each(function(){ 9995 9996 // Get references to everything we're interested in 9997 var $this = $(this), 9998 $controlGroup = $this.parents(".form-group").first(), 9999 $helpBlock = $controlGroup.find(".help-block").first(), 10000 $form = $this.parents("form").first(), 10001 validatorNames = []; 10002 10003 // create message container if not exists 10004 if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) { 10005 $helpBlock = $('<div class="help-block" />'); 10006 $controlGroup.find('.controls').append($helpBlock); 10007 createdElements.push($helpBlock[0]); 10008 } 10009 10010 // ============================================================= 10011 // SNIFF HTML FOR VALIDATORS 10012 // ============================================================= 10013 10014 // *snort sniff snuffle* 10015 10016 if (settings.options.sniffHtml) { 10017 var message = ""; 10018 // --------------------------------------------------------- 10019 // PATTERN 10020 // --------------------------------------------------------- 10021 if ($this.attr("pattern") !== undefined) { 10022 message = "Not in the expected format<!-- data-validation-pattern-message to override -->"; 10023 if ($this.data("validationPatternMessage")) { 10024 message = $this.data("validationPatternMessage"); 10025 } 10026 $this.data("validationPatternMessage", message); 10027 $this.data("validationPatternRegex", $this.attr("pattern")); 10028 } 10029 // --------------------------------------------------------- 10030 // MAX 10031 // --------------------------------------------------------- 10032 if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) { 10033 var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax")); 10034 message = "Too high: Maximum of '" + max + "'<!-- data-validation-max-message to override -->"; 10035 if ($this.data("validationMaxMessage")) { 10036 message = $this.data("validationMaxMessage"); 10037 } 10038 $this.data("validationMaxMessage", message); 10039 $this.data("validationMaxMax", max); 10040 } 10041 // --------------------------------------------------------- 10042 // MIN 10043 // --------------------------------------------------------- 10044 if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) { 10045 var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin")); 10046 message = "Too low: Minimum of '" + min + "'<!-- data-validation-min-message to override -->"; 10047 if ($this.data("validationMinMessage")) { 10048 message = $this.data("validationMinMessage"); 10049 } 10050 $this.data("validationMinMessage", message); 10051 $this.data("validationMinMin", min); 10052 } 10053 // --------------------------------------------------------- 10054 // MAXLENGTH 10055 // --------------------------------------------------------- 10056 if ($this.attr("maxlength") !== undefined) { 10057 message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters<!-- data-validation-maxlength-message to override -->"; 10058 if ($this.data("validationMaxlengthMessage")) { 10059 message = $this.data("validationMaxlengthMessage"); 10060 } 10061 $this.data("validationMaxlengthMessage", message); 10062 $this.data("validationMaxlengthMaxlength", $this.attr("maxlength")); 10063 } 10064 // --------------------------------------------------------- 10065 // MINLENGTH 10066 // --------------------------------------------------------- 10067 if ($this.attr("minlength") !== undefined) { 10068 message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters<!-- data-validation-minlength-message to override -->"; 10069 if ($this.data("validationMinlengthMessage")) { 10070 message = $this.data("validationMinlengthMessage"); 10071 } 10072 $this.data("validationMinlengthMessage", message); 10073 $this.data("validationMinlengthMinlength", $this.attr("minlength")); 10074 } 10075 // --------------------------------------------------------- 10076 // REQUIRED 10077 // --------------------------------------------------------- 10078 if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) { 10079 message = settings.builtInValidators.required.message; 10080 if ($this.data("validationRequiredMessage")) { 10081 message = $this.data("validationRequiredMessage"); 10082 } 10083 $this.data("validationRequiredMessage", message); 10084 } 10085 // --------------------------------------------------------- 10086 // NUMBER 10087 // --------------------------------------------------------- 10088 if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") { 10089 message = settings.builtInValidators.number.message; 10090 if ($this.data("validationNumberMessage")) { 10091 message = $this.data("validationNumberMessage"); 10092 } 10093 $this.data("validationNumberMessage", message); 10094 } 10095 // --------------------------------------------------------- 10096 // EMAIL 10097 // --------------------------------------------------------- 10098 if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") { 10099 message = oFlow.i18n.DD_FORM_VALIDATION_VALIDEMAIL; 10100 if ($this.data("validationValidemailMessage")) { 10101 message = $this.data("validationValidemailMessage"); 10102 } else if ($this.data("validationEmailMessage")) { 10103 message = $this.data("validationEmailMessage"); 10104 } 10105 $this.data("validationValidemailMessage", message); 10106 } 10107 // --------------------------------------------------------- 10108 // MINCHECKED 10109 // --------------------------------------------------------- 10110 if ($this.attr("minchecked") !== undefined) { 10111 message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required<!-- data-validation-minchecked-message to override -->"; 10112 if ($this.data("validationMincheckedMessage")) { 10113 message = $this.data("validationMincheckedMessage"); 10114 } 10115 $this.data("validationMincheckedMessage", message); 10116 $this.data("validationMincheckedMinchecked", $this.attr("minchecked")); 10117 } 10118 // --------------------------------------------------------- 10119 // MAXCHECKED 10120 // --------------------------------------------------------- 10121 if ($this.attr("maxchecked") !== undefined) { 10122 message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required<!-- data-validation-maxchecked-message to override -->";
10123 if ($this.data("validationMaxcheckedMessage")) { 10124 message = $this.data("validationMaxcheckedMessage"); 10125 } 10126 $this.data("validationMaxcheckedMessage", message); 10127 $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked")); 10128 } 10129 } 10130 10131 // ============================================================= 10132 // COLLECT VALIDATOR NAMES 10133 // ============================================================= 10134 10135 // Get named validators 10136 if ($this.data("validation") !== undefined) { 10137 validatorNames = $this.data("validation").split(","); 10138 } 10139 10140 // Get extra ones defined on the element's data attributes 10141 $.each($this.data(), function (i, el) { 10142 var parts = i.replace(/([A-Z])/g, ",$1").split(","); 10143 if (parts[0] === "validation" && parts[1]) { 10144 validatorNames.push(parts[1]); 10145 } 10146 }); 10147 10148 // ============================================================= 10149 // NORMALISE VALIDATOR NAMES 10150 // ============================================================= 10151 10152 var validatorNamesToInspect = validatorNames; 10153 var newValidatorNamesToInspect = []; 10154 10155 do // repeatedly expand 'shortcut' validators into their real validators 10156 { 10157 // Uppercase only the first letter of each name 10158 $.each(validatorNames, function (i, el) { 10159 validatorNames[i] = formatValidatorName(el); 10160 }); 10161 10162 // Remove duplicate validator names 10163 validatorNames = $.unique(validatorNames); 10164 10165 // Pull out the new validator names from each shortcut 10166 newValidatorNamesToInspect = []; 10167 $.each(validatorNamesToInspect, function(i, el) { 10168 if ($this.data("validation" + el + "Shortcut") !== undefined) { 10169 // Are these custom validators? 10170 // Pull them out! 10171 $.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) { 10172 newValidatorNamesToInspect.push(el2); 10173 }); 10174 } else if (settings.builtInValidators[el.toLowerCase()]) { 10175 // Is this a recognised built-in? 10176 // Pull it out! 10177 var validator = settings.builtInValidators[el.toLowerCase()]; 10178 if (validator.type.toLowerCase() === "shortcut") { 10179 $.each(validator.shortcut.split(","), function (i, el) { 10180 el = formatValidatorName(el); 10181 newValidatorNamesToInspect.push(el); 10182 validatorNames.push(el); 10183 }); 10184 } 10185 } 10186 }); 10187 10188 validatorNamesToInspect = newValidatorNamesToInspect; 10189 10190 } while (validatorNamesToInspect.length > 0) 10191 10192 // ============================================================= 10193 // SET UP VALIDATOR ARRAYS 10194 // ============================================================= 10195 10196 var validators = {}; 10197 10198 $.each(validatorNames, function (i, el) { 10199 // Set up the 'override' message 10200 var message = $this.data("validation" + el + "Message"); 10201 var hasOverrideMessage = (message !== undefined); 10202 var foundValidator = false; 10203 message = 10204 ( 10205 message 10206 ? message 10207 : "'" + el + "' validation failed <!-- Add attribute 'data-validation-" + el.toLowerCase() + "-message' to input to change this message -->" 10208 ) 10209 ; 10210 10211 $.each( 10212 settings.validatorTypes, 10213 function (validatorType, validatorTemplate) { 10214 if (validators[validatorType] === undefined) { 10215 validators[validatorType] = []; 10216 } 10217 if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) { 10218 validators[validatorType].push( 10219 $.extend( 10220 true, 10221 { 10222 name: formatValidatorName(validatorTemplate.name), 10223 message: message 10224 }, 10225 validatorTemplate.init($this, el) 10226 ) 10227 ); 10228 foundValidator = true; 10229 } 10230 } 10231 ); 10232 10233 if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) { 10234
10235 var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]); 10236 if (hasOverrideMessage) { 10237 validator.message = message; 10238 } 10239 var validatorType = validator.type.toLowerCase(); 10240 10241 if (validatorType === "shortcut") { 10242 foundValidator = true; 10243 } else { 10244 $.each( 10245 settings.validatorTypes, 10246 function (validatorTemplateType, validatorTemplate) { 10247 if (validators[validatorTemplateType] === undefined) { 10248 validators[validatorTemplateType] = []; 10249 } 10250 if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) { 10251 $this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]); 10252 validators[validatorType].push( 10253 $.extend( 10254 validator, 10255 validatorTemplate.init($this, el) 10256 ) 10257 ); 10258 foundValidator = true; 10259 } 10260 } 10261 ); 10262 } 10263 } 10264 10265 if (! foundValidator) { 10266 $.error("Cannot find validation info for '" + el + "'"); 10267 } 10268 }); 10269 10270 // ============================================================= 10271 // STORE FALLBACK VALUES 10272 // ============================================================= 10273 10274 $helpBlock.data( 10275 "original-contents", 10276 ( 10277 $helpBlock.data("original-contents") 10278 ? $helpBlock.data("original-contents") 10279 : $helpBlock.html() 10280 ) 10281 ); 10282 10283 $helpBlock.data( 10284 "original-role", 10285 ( 10286 $helpBlock.data("original-role") 10287 ? $helpBlock.data("original-role") 10288 : $helpBlock.attr("role") 10289 ) 10290 ); 10291 10292 $controlGroup.data( 10293 "original-classes", 10294 ( 10295 $controlGroup.data("original-clases") 10296 ? $controlGroup.data("original-classes") 10297 : $controlGroup.attr("class") 10298 ) 10299 ); 10300 10301 $this.data( 10302 "original-aria-invalid", 10303 ( 10304 $this.data("original-aria-invalid") 10305 ? $this.data("original-aria-invalid") 10306 : $this.attr("aria-invalid") 10307 ) 10308 ); 10309 10310 // ============================================================= 10311 // VALIDATION 10312 // ============================================================= 10313 10314 $this.bind( 10315 "validation.validation", 10316 function (event, params) { 10317 10318 var value = getValue($this); 10319 10320 // Get a list of the errors to apply 10321 var errorsFound = []; 10322 10323 $.each(validators, function (validatorType, validatorTypeArray) { 10324 if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) { 10325 $.each(validatorTypeArray, function (i, validator) { 10326 if (settings.validatorTypes[validatorType].validate($this, value, validator)) { 10327 errorsFound.push(validator.message); 10328 } 10329 }); 10330 } 10331 }); 10332 10333 return errorsFound; 10334 } 10335 ); 10336 10337 $this.bind( 10338 "getValidators.validation", 10339 function () { 10340 return validators; 10341 } 10342 ); 10343 10344 // ============================================================= 10345 // WATCH FOR CHANGES 10346 // ============================================================= 10347 $this.bind( 10348 "submit.validation", 10349 function () { 10350 return $this.triggerHandler("change.validation", {submitting: true}); 10351 } 10352 ); 10353 $this.bind( 10354 [ 10355 "keyup", 10356 "focus", 10357 "blur", 10358 "click", 10359 "keydown", 10360 "keypress", 10361 "change" 10362 ].join(".validation ") + ".validation", 10363 function (e, params) { 10364 10365 var value = getValue($this); 10366 10367 var errorsFound = []; 10368 10369 $controlGroup.find("input,textarea,select").each(function (i, el) { 10370 var oldCount = errorsFound.length; 10371 $.each($(el).triggerHandler("validation.validation", params), function (j, message) { 10372 errorsFound.push(message); 10373 }); 10374 if (errorsFound.length > oldCount) { 10375 $(el).attr("aria-invalid", "true"); 10376 } else { 10377 var original = $this.data("original-aria-invalid"); 10378 $(el).attr("aria-invalid", (original !== undefined ? original : false)); 10379 } 10380 }); 10381 10382 $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation"); 10383 10384 errorsFound = $.unique(errorsFound.sort()); 10385 10386 // Were there any errors? 10387 if (errorsFound.length) { 10388 // Better flag it up as a warning. 10389 $controlGroup.removeClass("text-success text-danger").addClass("text-warning"); 10390 10391 // How many errors did we find? 10392 if (settings.options.semanticallyStrict && errorsFound.length === 1) { 10393 // Only one? Being strict? Just output it. 10394 $helpBlock.html(errorsFound[0] + 10395 ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); 10396 } else { 10397 var extraClass = $this.data("extra-class"); 10398 10399 if (typeof extraClass !== "undefined") { 10400 $helpBlock.addClass(extraClass); 10401 } 10402 // Multiple? Being sloppy? Glue them together into an UL. 10403 $helpBlock.html("<ul class=\"list-unstyled text-danger\" role=\"alert\"><li>" + errorsFound.join("</li><li>") + "</li></ul>" + 10404 ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); 10405 } 10406 } else { 10407 $controlGroup.removeClass("text-warning text-danger text-success"); 10408 if (value.length > 0) { 10409 $controlGroup.addClass("text-success"); 10410 } 10411 $helpBlock.html($helpBlock.data("original-contents")); 10412 } 10413 10414 if (e.type === "blur") { 10415 $controlGroup.removeClass("text-success"); 10416 } 10417 } 10418 ); 10419 $this.bind("validationLostFocus.validation", function () { 10420 $controlGroup.removeClass("text-success"); 10421 }); 10422 }); 10423 }, 10424 destroy : function( ) { 10425 10426 return this.each( 10427 function() { 10428 10429 var 10430 $this = $(this), 10431 $controlGroup = $this.parents(".form-group").first(), 10432 $helpBlock = $controlGroup.find(".help-block").first(); 10433 10434 // remove our events 10435 $this.unbind('.validation'); // events are namespaced. 10436 // reset help text 10437 $helpBlock.html($helpBlock.data("original-contents")); 10438 // reset classes 10439 $controlGroup.attr("class", $controlGroup.data("original-classes")); 10440 // reset aria 10441 $this.attr("aria-invalid", $this.data("original-aria-invalid")); 10442 // reset role 10443 $helpBlock.attr("role", $this.data("original-role")); 10444 // remove all elements we created 10445 if (createdElements.indexOf($helpBlock[0]) > -1) { 10446 $helpBlock.remove(); 10447 } 10448 10449 } 10450 ); 10451 10452 }, 10453 collectErrors : function(includeEmpty) { 10454 10455 var errorMessages = {}; 10456 this.each(function (i, el) { 10457 var $el = $(el); 10458 var name = $el.attr("name"); 10459 var errors = $el.triggerHandler("validation.validation", {includeEmpty: true}); 10460 errorMessages[name] = $.extend(true, errors, errorMessages[name]); 10461 }); 10462 10463 $.each(errorMessages, function (i, el) { 10464 if (el.length === 0) { 10465 delete errorMessages[i]; 10466 } 10467 }); 10468 10469 return errorMessages; 10470 10471 }, 10472 hasErrors: function() { 10473 10474 var errorMessages = []; 10475 10476 this.each(function (i, el) { 10477 errorMessages = errorMessages.concat( 10478 $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : [] 10479 ); 10480 }); 10481 10482 return (errorMessages.length > 0); 10483 }, 10484 override : function (newDefaults) { 10485 defaults = $.extend(true, defaults, newDefaults); 10486 } 10487 }, 10488 validatorTypes: { 10489 callback: { 10490 name: "callback", 10491 init: function ($this, name) { 10492 return { 10493 validatorName: name, 10494 callback: $this.data("validation" + name + "Callback"),
10495 lastValue: $this.val(), 10496 lastValid: true, 10497 lastFinished: true 10498 }; 10499 }, 10500 validate: function ($this, value, validator) { 10501 if (validator.lastValue === value && validator.lastFinished) { 10502 return !validator.lastValid; 10503 } 10504 10505 if (validator.lastFinished === true) 10506 { 10507 validator.lastValue = value; 10508 validator.lastValid = true; 10509 validator.lastFinished = false; 10510 10511 var rrjqbvValidator = validator; 10512 var rrjqbvThis = $this; 10513 executeFunctionByName( 10514 validator.callback, 10515 window, 10516 $this, 10517 value, 10518 function (data) { 10519 if (rrjqbvValidator.lastValue === data.value) { 10520 rrjqbvValidator.lastValid = data.valid; 10521 if (data.message) { 10522 rrjqbvValidator.message = data.message; 10523 } 10524 rrjqbvValidator.lastFinished = true; 10525 rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message); 10526 // Timeout is set to avoid problems with the events being considered 'already fired' 10527 setTimeout(function () { 10528 rrjqbvThis.trigger("change.validation"); 10529 }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst 10530 } 10531 } 10532 ); 10533 } 10534 10535 return false; 10536 10537 } 10538 }, 10539 ajax: { 10540 name: "ajax", 10541 init: function ($this, name) { 10542 return { 10543 validatorName: name, 10544 url: $this.data("validation" + name + "Ajax"), 10545 lastValue: $this.val(), 10546 lastValid: true, 10547 lastFinished: true 10548 }; 10549 }, 10550 validate: function ($this, value, validator) { 10551 if (""+validator.lastValue === ""+value && validator.lastFinished === true) { 10552 return validator.lastValid === false; 10553 } 10554 10555 if (validator.lastFinished === true) 10556 { 10557 validator.lastValue = value; 10558 validator.lastValid = true; 10559 validator.lastFinished = false; 10560 $.ajax({ 10561 url: validator.url, 10562 data: "value=" + value + "&field=" + $this.attr("name"), 10563 dataType: "json", 10564 success: function (data) { 10565 if (""+validator.lastValue === ""+data.value) { 10566 validator.lastValid = !!(data.valid); 10567 if (data.message) { 10568 validator.message = data.message; 10569 } 10570 validator.lastFinished = true; 10571 $this.data("validation" + validator.validatorName + "Message", validator.message); 10572 // Timeout is set to avoid problems with the events being considered 'already fired' 10573 setTimeout(function () { 10574 $this.trigger("change.validation"); 10575 }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst 10576 } 10577 }, 10578 failure: function () { 10579 validator.lastValid = true; 10580 validator.message = "ajax call failed"; 10581 validator.lastFinished = true; 10582 $this.data("validation" + validator.validatorName + "Message", validator.message); 10583 // Timeout is set to avoid problems with the events being considered 'already fired' 10584 setTimeout(function () { 10585 $this.trigger("change.validation"); 10586 }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst 10587 } 10588 }); 10589 } 10590 10591 return false; 10592 10593 } 10594 }, 10595 regex: { 10596 name: "regex", 10597 init: function ($this, name) { 10598 return {regex: regexFromString($this.data("validation" + name + "Regex"))}; 10599 }, 10600 validate: function ($this, value, validator) { 10601 return (!validator.regex.test(value) && ! validator.negative) 10602 || (validator.regex.test(value) && validator.negative); 10603 } 10604 }, 10605 required: { 10606 name: "required", 10607 init: function ($this, name) { 10608 return {}; 10609 }, 10610 validate: function ($this, value, validator) { 10611 return !!(value.length === 0 && ! validator.negative) 10612 || !!(value.length > 0 && validator.negative); 10613 }, 10614 blockSubmit: true 10615 }, 10616 match: { 10617 name: "match", 10618 init: function ($this, name) { 10619 var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first(); 10620 element.bind("validation.validation", function () { 10621 $this.trigger("change.validation", {submitting: true}); 10622 }); 10623 return {"element": element}; 10624 }, 10625 validate: function ($this, value, validator) { 10626 return (value !== validator.element.val() && ! validator.negative) 10627 || (value === validator.element.val() && validator.negative); 10628 }, 10629 blockSubmit: true 10630 }, 10631 max: { 10632 name: "max", 10633 init: function ($this, name) { 10634 return {max: $this.data("validation" + name + "Max")}; 10635 }, 10636 validate: function ($this, value, validator) { 10637 return (parseFloat(value, 10) > parseFloat(validator.max, 10) && ! validator.negative) 10638 || (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative); 10639 } 10640 }, 10641 min: { 10642 name: "min", 10643 init: function ($this, name) { 10644 return {min: $this.data("validation" + name + "Min")}; 10645 }, 10646 validate: function ($this, value, validator) { 10647 return (parseFloat(value) < parseFloat(validator.min) && ! validator.negative) 10648 || (parseFloat(value) >= parseFloat(validator.min) && validator.negative); 10649 } 10650 }, 10651 maxlength: { 10652 name: "maxlength", 10653 init: function ($this, name) { 10654 return {maxlength: $this.data("validation" + name + "Maxlength")}; 10655 }, 10656 validate: function ($this, value, validator) { 10657 return ((value.length > validator.maxlength) && ! validator.negative) 10658 || ((value.length <= validator.maxlength) && validator.negative); 10659 } 10660 }, 10661 minlength: { 10662 name: "minlength", 10663 init: function ($this, name) { 10664 return {minlength: $this.data("validation" + name + "Minlength")}; 10665 }, 10666 validate: function ($this, value, validator) { 10667 return ((value.length < validator.minlength) && ! validator.negative) 10668 || ((value.length >= validator.minlength) && validator.negative); 10669 } 10670 }, 10671 maxchecked: { 10672 name: "maxchecked", 10673 init: function ($this, name) { 10674 var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); 10675 elements.bind("click.validation", function () { 10676 $this.trigger("change.validation", {includeEmpty: true}); 10677 }); 10678 return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements}; 10679 }, 10680 validate: function ($this, value, validator) { 10681 return (validator.elements.filter(":checked").length > validator.maxchecked && ! validator.negative) 10682 || (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative); 10683 }, 10684 blockSubmit: true 10685 }, 10686 minchecked: { 10687 name: "minchecked", 10688 init: function ($this, name) { 10689 var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); 10690 elements.bind("click.validation", function () { 10691 $this.trigger("change.validation", {includeEmpty: true}); 10692 }); 10693 return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements}; 10694 }, 10695 validate: function ($this, value, validator) { 10696 return (validator.elements.filter(":checked").length < validator.minchecked && ! validator.negative) 10697 || (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative); 10698 }, 10699 blockSubmit: true 10700 } 10701 }, 10702 builtInValidators: { 10703 email: { 10704 name: "Email", 10705 type: "shortcut", 10706 shortcut: "validemail" 10707 }, 10708 validemail: { 10709 name: "Validemail", 10710 type: "regex", 10711 regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{1,63}", 10712 message: oFlow.i18n.DD_FORM_VALIDATION_VALIDEMAIL 10713 }, 10714 passwordagain: { 10715 name: "Passwordagain", 10716 type: "match", 10717 match: "password", 10718 message: oFlow.i18n.DD_FORM_VALIDATION_PASSWORDAGAIN 10719 }, 10720 positive: { 10721 name: "Positive", 10722 type: "shortcut", 10723 shortcut: "number,positivenumber" 10724 }, 10725 negative: { 10726 name: "Negative", 10727 type: "shortcut", 10728 shortcut: "number,negativenumber" 10729 }, 10730 number: { 10731 name: "Number", 10732 type: "regex", 10733 regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?", 10734 message: oFlow.i18n.DD_FORM_VALIDATION_NUMBER 10735 }, 10736 integer: { 10737 name: "Integer", 10738 type: "regex", 10739 regex: "[+-]?\\\d+", 10740 message: oFlow.i18n.DD_FORM_VALIDATION_INTEGER 10741 }, 10742 positivenumber: { 10743 name: "Positivenumber", 10744 type: "min", 10745 min: 0, 10746 message: oFlow.i18n.DD_FORM_VALIDATION_POSITIVENUMBER 10747 }, 10748 negativenumber: { 10749 name: "Negativenumber", 10750 type: "max", 10751 max: 0, 10752 message: oFlow.i18n.DD_FORM_VALIDATION_NEGATIVENUMBER 10753 }, 10754 required: { 10755 name: "Required", 10756 type: "required", 10757 message: oFlow.i18n.DD_FORM_VALIDATION_REQUIRED 10758 }, 10759 checkone: { 10760 name: "Checkone", 10761 type: "minchecked", 10762 minchecked: 1, 10763 message: oFlow.i18n.DD_FORM_VALIDATION_CHECKONE 10764 } 10765 } 10766 }; 10767 10768 var formatValidatorName = function (name) { 10769 return name 10770 .toLowerCase() 10771 .replace( 10772 /(^|\s)([a-z])/g , 10773 function(m,p1,p2) { 10774 return p1+p2.toUpperCase(); 10775 } 10776 ) 10777 ; 10778 }; 10779 10780 var getValue = function ($this) { 10781 // Extract the value we're talking about 10782 var value = $this.val(); 10783 var type = $this.attr("type"); 10784 if (type === "checkbox") { 10785 value = ($this.is(":checked") ? value : ""); 10786 } 10787 if (type === "radio") { 10788 value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : ""); 10789 } 10790 return value; 10791 }; 10792 10793 function regexFromString(inputstring) {
10794 return new RegExp("^" + inputstring + "$"); 10795 } 10796 10797 /** 10798 * Thanks to Jason Bunting via StackOverflow.com 10799 * 10800 * http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910 10801 * Short link: http://tinyurl.com/executeFunctionByName 10802 **/ 10803 function executeFunctionByName(functionName, context /*, args*/) { 10804 var args = Array.prototype.slice.call(arguments).splice(2); 10805 var namespaces = functionName.split("."); 10806 var func = namespaces.pop(); 10807 for(var i = 0; i < namespaces.length; i++) { 10808 context = context[namespaces[i]]; 10809 } 10810 return context[func].apply(this, args); 10811 } 10812 10813 $.fn.jqBootstrapValidation = function( method ) { 10814 10815 if ( defaults.methods[method] ) { 10816 return defaults.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); 10817 } else if ( typeof method === 'object' || ! method ) { 10818 return defaults.methods.init.apply( this, arguments ); 10819 } else { 10820 $.error( 'Method ' + method + ' does not exist on jQuery.jqBootstrapValidation' ); 10821 return null; 10822 } 10823 10824 }; 10825 10826 $.jqBootstrapValidation = function (options) { 10827 $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments); 10828 }; 10829 10830})( jQuery ); 10831 10832; 10833;(function($) { 10834 10835 $.fn.unveil = function(threshold, callback) { 10836 10837 var $w = $(window), 10838 th = threshold || 0, 10839 retina = window.devicePixelRatio > 1, 10840 attrib = retina? "data-src-retina" : "data-src", 10841 images = this, 10842 loaded; 10843 10844 this.one("unveil", function() { 10845 var source = this.getAttribute(attrib); 10846 source = source || this.getAttribute("data-src"); 10847 if (source) { 10848 this.setAttribute("src", source); 10849 if (typeof callback === "function") callback.call(this); 10850 } 10851 }); 10852 10853 function unveil() { 10854 var inview = images.filter(function() { 10855 var $e = $(this); 10856 if ($e.is(":hidden")) return; 10857 10858 var wt = $w.scrollTop(), 10859 wb = wt + $w.height(), 10860 et = $e.offset().top, 10861 eb = et + $e.height(); 10862 10863 return eb >= wt - th && et <= wb + th; 10864 }); 10865 10866 loaded = inview.trigger("unveil"); 10867 images = images.not(loaded); 10868 } 10869 10870 $w.on("scroll.unveil resize.unveil lookup.unveil", unveil); 10871 10872 unveil(); 10873 10874 return this; 10875 10876 }; 10877 10878})(window.jQuery || window.Zepto); 10879; 10880(function (window, document, $, undefined) { 10881 "use strict"; 10882 10883 var H = $("html"), 10884 W = $(window), 10885 D = $(document), 10886 F = $.fancybox = function () { 10887 F.open.apply( this, arguments ); 10888 }, 10889 IE = navigator.userAgent.match(/msie/i), 10890 didUpdate = null, 10891 isTouch = document.createTouch !== undefined, 10892 10893 isQuery = function(obj) { 10894 return obj && obj.hasOwnProperty && obj instanceof $; 10895 }, 10896 isString = function(str) { 10897 return str && $.type(str) === "string"; 10898 }, 10899 isPercentage = function(str) { 10900 return isString(str) && str.indexOf('%') > 0; 10901 }, 10902 isScrollable = function(el) { 10903 return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight))); 10904 }, 10905 getScalar = function(orig, dim) { 10906 var value = parseInt(orig, 10) || 0; 10907 10908 if (dim && isPercentage(orig)) { 10909 value = F.getViewport()[ dim ] / 100 * value; 10910 } 10911 10912 return Math.ceil(value); 10913 }, 10914 getValue = function(value, dim) { 10915 return getScalar(value, dim) + 'px'; 10916 }; 10917 10918 $.extend(F, { 10919 // The current version of fancyBox 10920 version: '2.1.5', 10921 10922 defaults: { 10923 padding : 15, 10924 margin : 20, 10925 10926 width : 800, 10927 height : 600, 10928 minWidth : 100, 10929 minHeight : 100, 10930 maxWidth : 9999, 10931 maxHeight : 9999, 10932 pixelRatio: 1, // Set to 2 for retina display support 10933 10934 autoSize : true, 10935 autoHeight : false, 10936 autoWidth : false, 10937 10938 autoResize : true, 10939 autoCenter : !isTouch, 10940 fitToView : true, 10941 aspectRatio : false, 10942 topRatio : 0.5, 10943 leftRatio : 0.5, 10944 10945 scrolling : 'auto', // 'auto', 'yes' or 'no' 10946 wrapCSS : '', 10947 10948 arrows : true, 10949 closeBtn : true, 10950 closeClick : false, 10951 nextClick : false, 10952 mouseWheel : true, 10953 autoPlay : false, 10954 playSpeed : 3000, 10955 preload : 3, 10956 modal : false, 10957 loop : true, 10958 10959 ajax : { 10960 dataType : 'html', 10961 headers : { 'X-fancyBox': true } 10962 }, 10963 iframe : { 10964 scrolling : 'auto', 10965 preload : true 10966 }, 10967 swf : { 10968 wmode: 'transparent', 10969 allowfullscreen : 'true', 10970 allowscriptaccess : 'always' 10971 }, 10972 10973 keys : { 10974 next : { 10975 13 : 'left', // enter 10976 34 : 'up', // page down 10977 39 : 'left', // right arrow 10978 40 : 'up' // down arrow 10979 }, 10980 prev : { 10981 8 : 'right', // backspace 10982 33 : 'down', // page up 10983 37 : 'right', // left arrow 10984 38 : 'down' // up arrow 10985 }, 10986 close : [27], // escape key 10987 play : [32], // space - start/stop slideshow 10988 toggle : [70] // letter "f" - toggle fullscreen 10989 }, 10990 10991 direction : { 10992 next : 'left', 10993 prev : 'right' 10994 }, 10995 10996 scrollOutside : true, 10997 10998 // Override some properties 10999 index : 0, 11000 type : null, 11001 href : null, 11002 content : null, 11003 title : null, 11004 11005 // HTML templates 11006 tpl: { 11007 wrap : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>', 11008 image : '<img class="fancybox-image" src="{href}" alt="" />', 11009 iframe : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>', 11010 error : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>', 11011 closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>', 11012 next : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>', 11013 prev : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>' 11014 }, 11015 11016 // Properties for each animation type 11017 // Opening fancyBox 11018 openEffect : 'fade', // 'elastic', 'fade' or 'none' 11019 openSpeed : 250, 11020 openEasing : 'swing', 11021 openOpacity : true, 11022 openMethod : 'zoomIn', 11023 11024 // Closing fancyBox 11025 closeEffect : 'fade', // 'elastic', 'fade' or 'none' 11026 closeSpeed : 250, 11027 closeEasing : 'swing', 11028 closeOpacity : true, 11029 closeMethod : 'zoomOut', 11030 11031 // Changing next gallery item 11032 nextEffect : 'elastic', // 'elastic', 'fade' or 'none' 11033 nextSpeed : 250, 11034 nextEasing : 'swing', 11035 nextMethod : 'changeIn', 11036 11037 // Changing previous gallery item 11038 prevEffect : 'elastic', // 'elastic', 'fade' or 'none' 11039 prevSpeed : 250, 11040 prevEasing : 'swing', 11041 prevMethod : 'changeOut', 11042 11043 // Enable default helpers 11044 helpers : { 11045 overlay : true, 11046 title : true 11047 }, 11048 11049 // Callbacks 11050 onCancel : $.noop, // If canceling 11051 beforeLoad : $.noop, // Before loading 11052 afterLoad : $.noop, // After loading 11053 beforeShow : $.noop, // Before changing in current item 11054 afterShow : $.noop, // After opening 11055 beforeChange : $.noop, // Before changing gallery item 11056 beforeClose : $.noop, // Before closing 11057 afterClose : $.noop // After closing 11058 }, 11059 11060 //Current state 11061 group : {}, // Selected group 11062 opts : {}, // Group options 11063 previous : null, // Previous element 11064 coming : null, // Element being loaded 11065 current : null, // Currently loaded element 11066 isActive : false, // Is activated 11067 isOpen : false, // Is currently open 11068 isOpened : false, // Have been fully opened at least once 11069 11070 wrap : null, 11071 skin : null, 11072 outer : null, 11073 inner : null, 11074 11075 player : { 11076 timer : null, 11077 isActive : false 11078 }, 11079 11080 // Loaders
vendor: 12,016 bytes, lines 11081-11628
11081 ajaxLoad : null, 11082 imgPreload : null, 11083 11084 // Some collections 11085 transitions : {}, 11086 helpers : {}, 11087 11088 /* 11089 * Static methods 11090 */ 11091 11092 open: function (group, opts) { 11093 if (!group) { 11094 return; 11095 } 11096 11097 if (!$.isPlainObject(opts)) { 11098 opts = {}; 11099 } 11100 11101 // Close if already active 11102 if (false === F.close(true)) { 11103 return; 11104 } 11105 11106 // Normalize group 11107 if (!$.isArray(group)) { 11108 group = isQuery(group) ? $(group).get() : [group]; 11109 } 11110 11111 // Recheck if the type of each element is `object` and set content type (image, ajax, etc) 11112 $.each(group, function(i, element) { 11113 var obj = {}, 11114 href, 11115 title, 11116 content, 11117 type, 11118 rez, 11119 hrefParts, 11120 selector; 11121 11122 if ($.type(element) === "object") { 11123 // Check if is DOM element 11124 if (element.nodeType) { 11125 element = $(element); 11126 } 11127 11128 if (isQuery(element)) { 11129 obj = { 11130 href : element.data('fancybox-href') || element.attr('href'), 11131 title : element.data('fancybox-title') || element.attr('title'), 11132 isDom : true, 11133 element : element 11134 }; 11135 11136 if ($.metadata) { 11137 $.extend(true, obj, element.metadata()); 11138 } 11139 11140 } else { 11141 obj = element; 11142 } 11143 } 11144 11145 href = opts.href || obj.href || (isString(element) ? element : null); 11146 title = opts.title !== undefined ? opts.title : obj.title || ''; 11147 11148 content = opts.content || obj.content; 11149 type = content ? 'html' : (opts.type || obj.type); 11150 11151 if (!type && obj.isDom) { 11152 type = element.data('fancybox-type'); 11153 11154 if (!type) { 11155 rez = element.prop('class').match(/fancybox\.(\w+)/); 11156 type = rez ? rez[1] : null; 11157 } 11158 } 11159 11160 if (isString(href)) { 11161 // Try to guess the content type 11162 if (!type) { 11163 if (F.isImage(href)) { 11164 type = 'image'; 11165 11166 } else if (F.isSWF(href)) { 11167 type = 'swf'; 11168 11169 } else if (href.charAt(0) === '#') { 11170 type = 'inline'; 11171 11172 } else if (isString(element)) { 11173 type = 'html'; 11174 content = element; 11175 } 11176 } 11177 11178 // Split url into two pieces with source url and content selector, e.g, 11179 // "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id" 11180 if (type === 'ajax') { 11181 hrefParts = href.split(/\s+/, 2); 11182 href = hrefParts.shift(); 11183 selector = hrefParts.shift(); 11184 } 11185 } 11186 11187 if (!content) { 11188 if (type === 'inline') { 11189 if (href) { 11190 content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7 11191 11192 } else if (obj.isDom) { 11193 content = element; 11194 } 11195 11196 } else if (type === 'html') { 11197 content = href; 11198 11199 } else if (!type && !href && obj.isDom) { 11200 type = 'inline'; 11201 content = element; 11202 } 11203 } 11204 11205 $.extend(obj, { 11206 href : href, 11207 type : type, 11208 content : content, 11209 title : title, 11210 selector : selector 11211 }); 11212 11213 group[ i ] = obj; 11214 }); 11215 11216 // Extend the defaults 11217 F.opts = $.extend(true, {}, F.defaults, opts); 11218 11219 // All options are merged recursive except keys 11220 if (opts.keys !== undefined) { 11221 F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false; 11222 } 11223 11224 F.group = group; 11225 11226 return F._start(F.opts.index); 11227 }, 11228 11229 // Cancel image loading or abort ajax request 11230 cancel: function () { 11231 var coming = F.coming; 11232 11233 if (!coming || false === F.trigger('onCancel')) { 11234 return; 11235 } 11236 11237 F.hideLoading(); 11238 11239 if (F.ajaxLoad) { 11240 F.ajaxLoad.abort(); 11241 } 11242 11243 F.ajaxLoad = null; 11244 11245 if (F.imgPreload) { 11246 F.imgPreload.onload = F.imgPreload.onerror = null; 11247 } 11248 11249 if (coming.wrap) { 11250 coming.wrap.stop(true, true).trigger('onReset').remove(); 11251 } 11252 11253 F.coming = null; 11254 11255 // If the first item has been canceled, then clear everything 11256 if (!F.current) { 11257 F._afterZoomOut( coming ); 11258 } 11259 }, 11260 11261 // Start closing animation if is open; remove immediately if opening/closing 11262 close: function (event) { 11263 F.cancel(); 11264 11265 if (false === F.trigger('beforeClose')) { 11266 return; 11267 } 11268 11269 F.unbindEvents(); 11270 11271 if (!F.isActive) { 11272 return; 11273 } 11274 11275 if (!F.isOpen || event === true) { 11276 $('.fancybox-wrap').stop(true).trigger('onReset').remove(); 11277 11278 F._afterZoomOut(); 11279 11280 } else { 11281 F.isOpen = F.isOpened = false; 11282 F.isClosing = true; 11283 11284 $('.fancybox-item, .fancybox-nav').remove(); 11285 11286 F.wrap.stop(true, true).removeClass('fancybox-opened'); 11287 11288 F.transitions[ F.current.closeMethod ](); 11289 } 11290 }, 11291 11292 // Manage slideshow: 11293 // $.fancybox.play(); - toggle slideshow 11294 // $.fancybox.play( true ); - start 11295 // $.fancybox.play( false ); - stop 11296 play: function ( action ) { 11297 var clear = function () { 11298 clearTimeout(F.player.timer); 11299 }, 11300 set = function () { 11301 clear(); 11302 11303 if (F.current && F.player.isActive) { 11304 F.player.timer = setTimeout(F.next, F.current.playSpeed); 11305 } 11306 }, 11307 stop = function () { 11308 clear(); 11309 11310 D.unbind('.player'); 11311 11312 F.player.isActive = false; 11313 11314 F.trigger('onPlayEnd'); 11315 }, 11316 start = function () { 11317 if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) { 11318 F.player.isActive = true; 11319 11320 D.bind({ 11321 'onCancel.player beforeClose.player' : stop, 11322 'onUpdate.player' : set, 11323 'beforeLoad.player' : clear 11324 }); 11325 11326 set(); 11327 11328 F.trigger('onPlayStart'); 11329 } 11330 }; 11331 11332 if (action === true || (!F.player.isActive && action !== false)) { 11333 start(); 11334 } else { 11335 stop(); 11336 } 11337 }, 11338 11339 // Navigate to next gallery item 11340 next: function ( direction ) { 11341 var current = F.current; 11342 11343 if (current) { 11344 if (!isString(direction)) { 11345 direction = current.direction.next; 11346 } 11347 11348 F.jumpto(current.index + 1, direction, 'next'); 11349 } 11350 }, 11351 11352 // Navigate to previous gallery item 11353 prev: function ( direction ) { 11354 var current = F.current; 11355 11356 if (current) { 11357 if (!isString(direction)) { 11358 direction = current.direction.prev; 11359 } 11360 11361 F.jumpto(current.index - 1, direction, 'prev'); 11362 } 11363 }, 11364 11365 // Navigate to gallery item by index 11366 jumpto: function ( index, direction, router ) { 11367 var current = F.current; 11368 11369 if (!current) { 11370 return; 11371 } 11372 11373 index = getScalar(index); 11374 11375 F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ]; 11376 F.router = router || 'jumpto'; 11377 11378 if (current.loop) { 11379 if (index < 0) { 11380 index = current.group.length + (index % current.group.length); 11381 } 11382 11383 index = index % current.group.length; 11384 } 11385 11386 if (current.group[ index ] !== undefined) { 11387 F.cancel(); 11388 11389 F._start(index); 11390 } 11391 }, 11392 11393 // Center inside viewport and toggle position type to fixed or absolute if needed 11394 reposition: function (e, onlyAbsolute) { 11395 var current = F.current, 11396 wrap = current ? current.wrap : null, 11397 pos; 11398 11399 if (wrap) { 11400 pos = F._getPosition(onlyAbsolute); 11401 11402 if (e && e.type === 'scroll') { 11403 delete pos.position; 11404 11405 wrap.stop(true, true).animate(pos, 200); 11406 11407 } else { 11408 wrap.css(pos); 11409 11410 current.pos = $.extend({}, current.dim, pos); 11411 } 11412 } 11413 }, 11414 11415 update: function (e) { 11416 var type = (e && e.type), 11417 anyway = !type || type === 'orientationchange'; 11418 11419 if (anyway) { 11420 clearTimeout(didUpdate); 11421 11422 didUpdate = null; 11423 } 11424 11425 if (!F.isOpen || didUpdate) { 11426 return; 11427 } 11428 11429 didUpdate = setTimeout(function() { 11430 var current = F.current; 11431 11432 if (!current || F.isClosing) { 11433 return; 11434 } 11435 11436 F.wrap.removeClass('fancybox-tmp'); 11437 11438 if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) { 11439 F._setDimension(); 11440 } 11441 11442 if (!(type === 'scroll' && current.canShrink)) { 11443 F.reposition(e); 11444 } 11445 11446 F.trigger('onUpdate'); 11447 11448 didUpdate = null; 11449 11450 }, (anyway && !isTouch ? 0 : 300)); 11451 }, 11452 11453 // Shrink content to fit inside viewport or restore if resized 11454 toggle: function ( action ) { 11455 if (F.isOpen) { 11456 F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView; 11457 11458 // Help browser to restore document dimensions 11459 if (isTouch) { 11460 F.wrap.removeAttr('style').addClass('fancybox-tmp'); 11461 11462 F.trigger('onUpdate'); 11463 } 11464 11465 F.update(); 11466 } 11467 }, 11468 11469 hideLoading: function () { 11470 D.unbind('.loading'); 11471 11472 $('#fancybox-loading').remove(); 11473 }, 11474 11475 showLoading: function () { 11476 var el, viewport; 11477 11478 F.hideLoading(); 11479 11480 el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body'); 11481 11482 // If user will press the escape-button, the request will be canceled 11483 D.bind('keydown.loading', function(e) { 11484 if ((e.which || e.keyCode) === 27) { 11485 e.preventDefault(); 11486 11487 F.cancel(); 11488 } 11489 }); 11490 11491 if (!F.defaults.fixed) { 11492 viewport = F.getViewport(); 11493 11494 el.css({ 11495 position : 'absolute', 11496 top : (viewport.h * 0.5) + viewport.y, 11497 left : (viewport.w * 0.5) + viewport.x 11498 }); 11499 } 11500 }, 11501 11502 getViewport: function () { 11503 var locked = (F.current && F.current.locked) || false, 11504 rez = { 11505 x: W.scrollLeft(), 11506 y: W.scrollTop() 11507 }; 11508 11509 if (locked) { 11510 rez.w = locked[0].clientWidth; 11511 rez.h = locked[0].clientHeight; 11512 11513 } else { 11514 // See http://bugs.jquery.com/ticket/6724 11515 rez.w = isTouch && window.innerWidth ? window.innerWidth : W.width(); 11516 rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height(); 11517 } 11518 11519 return rez; 11520 }, 11521 11522 // Unbind the keyboard / clicking actions 11523 unbindEvents: function () { 11524 if (F.wrap && isQuery(F.wrap)) { 11525 F.wrap.unbind('.fb'); 11526 } 11527 11528 D.unbind('.fb'); 11529 W.unbind('.fb'); 11530 }, 11531 11532 bindEvents: function () { 11533 var current = F.current, 11534 keys; 11535 11536 if (!current) { 11537 return; 11538 } 11539 11540 // Changing document height on iOS devices triggers a 'resize' event, 11541 // that can change document height... repeating infinitely 11542 W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update); 11543 11544 keys = current.keys; 11545 11546 if (keys) { 11547 D.bind('keydown.fb', function (e) { 11548 var code = e.which || e.keyCode, 11549 target = e.target || e.srcElement; 11550 11551 // Skip esc key if loading, because showLoading will cancel preloading 11552 if (code === 27 && F.coming) { 11553 return false; 11554 } 11555 11556 // Ignore key combinations and key events within form elements 11557 if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) { 11558 $.each(keys, function(i, val) { 11559 if (current.group.length > 1 && val[ code ] !== undefined) { 11560 F[ i ]( val[ code ] ); 11561 11562 e.preventDefault(); 11563 return false; 11564 } 11565 11566 if ($.inArray(code, val) > -1) { 11567 F[ i ] (); 11568 11569 e.preventDefault(); 11570 return false; 11571 } 11572 }); 11573 } 11574 }); 11575 } 11576 11577 if ($.fn.mousewheel && current.mouseWheel) { 11578 F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) { 11579 var target = e.target || null, 11580 parent = $(target), 11581 canScroll = false; 11582 11583 while (parent.length) { 11584 if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) { 11585 break; 11586 } 11587 11588 canScroll = isScrollable( parent[0] ); 11589 parent = $(parent).parent(); 11590 } 11591 11592 if (delta !== 0 && !canScroll) { 11593 if (F.group.length > 1 && !current.canShrink) { 11594 if (deltaY > 0 || deltaX > 0) { 11595 F.prev( deltaY > 0 ? 'down' : 'left' ); 11596 11597 } else if (deltaY < 0 || deltaX < 0) { 11598 F.next( deltaY < 0 ? 'up' : 'right' ); 11599 } 11600 11601 e.preventDefault(); 11602 } 11603 } 11604 }); 11605 } 11606 }, 11607 11608 trigger: function (event, o) { 11609 var ret, obj = o || F.coming || F.current; 11610 11611 if (!obj) { 11612 return; 11613 } 11614 11615 if ($.isFunction( obj[event] )) { 11616 ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1)); 11617 } 11618 11619 if (ret === false) { 11620 return false; 11621 } 11622 11623 if (obj.helpers) { 11624 $.each(obj.helpers, function (helper, opts) { 11625 if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) { 11626 F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj); 11627 } 11628 });
vendor: 8,050 bytes, lines 11628-11987
11628 11629 } 11630 11631 D.trigger(event); 11632 }, 11633 11634 isImage: function (str) { 11635 return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i); 11636 }, 11637 11638 isSWF: function (str) { 11639 return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i); 11640 }, 11641 11642 _start: function (index) { 11643 var coming = {}, 11644 obj, 11645 href, 11646 type, 11647 margin, 11648 padding; 11649 11650 index = getScalar( index ); 11651 obj = F.group[ index ] || null; 11652 11653 if (!obj) { 11654 return false; 11655 } 11656 11657 coming = $.extend(true, {}, F.opts, obj); 11658 11659 // Convert margin and padding properties to array - top, right, bottom, left 11660 margin = coming.margin; 11661 padding = coming.padding; 11662 11663 if ($.type(margin) === 'number') { 11664 coming.margin = [margin, margin, margin, margin]; 11665 } 11666 11667 if ($.type(padding) === 'number') { 11668 coming.padding = [padding, padding, padding, padding]; 11669 } 11670 11671 // 'modal' propery is just a shortcut 11672 if (coming.modal) { 11673 $.extend(true, coming, { 11674 closeBtn : false, 11675 closeClick : false, 11676 nextClick : false, 11677 arrows : false, 11678 mouseWheel : false, 11679 keys : null, 11680 helpers: { 11681 overlay : { 11682 closeClick : false 11683 } 11684 } 11685 }); 11686 } 11687 11688 // 'autoSize' property is a shortcut, too 11689 if (coming.autoSize) { 11690 coming.autoWidth = coming.autoHeight = true; 11691 } 11692 11693 if (coming.width === 'auto') { 11694 coming.autoWidth = true; 11695 } 11696 11697 if (coming.height === 'auto') { 11698 coming.autoHeight = true; 11699 } 11700 11701 /* 11702 * Add reference to the group, so it`s possible to access from callbacks, example: 11703 * afterLoad : function() { 11704 * this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : ''); 11705 * } 11706 */ 11707 11708 coming.group = F.group; 11709 coming.index = index; 11710 11711 // Give a chance for callback or helpers to update coming item (type, title, etc) 11712 F.coming = coming; 11713 11714 if (false === F.trigger('beforeLoad')) { 11715 F.coming = null; 11716 11717 return; 11718 } 11719 11720 type = coming.type; 11721 href = coming.href; 11722 11723 if (!type) { 11724 F.coming = null; 11725 11726 //If we can not determine content type then drop silently or display next/prev item if looping through gallery 11727 if (F.current && F.router && F.router !== 'jumpto') { 11728 F.current.index = index; 11729 11730 return F[ F.router ]( F.direction ); 11731 } 11732 11733 return false; 11734 } 11735 11736 F.isActive = true; 11737 11738 if (type === 'image' || type === 'swf') { 11739 coming.autoHeight = coming.autoWidth = false; 11740 coming.scrolling = 'visible'; 11741 } 11742 11743 if (type === 'image') { 11744 coming.aspectRatio = true; 11745 } 11746 11747 if (type === 'iframe' && isTouch) { 11748 coming.scrolling = 'scroll'; 11749 } 11750 11751 // Build the neccessary markup 11752 coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' ); 11753 11754 $.extend(coming, { 11755 skin : $('.fancybox-skin', coming.wrap), 11756 outer : $('.fancybox-outer', coming.wrap), 11757 inner : $('.fancybox-inner', coming.wrap) 11758 }); 11759 11760 $.each(["Top", "Right", "Bottom", "Left"], function(i, v) { 11761 coming.skin.css('padding' + v, getValue(coming.padding[ i ])); 11762 }); 11763 11764 F.trigger('onReady'); 11765 11766 // Check before try to load; 'inline' and 'html' types need content, others - href 11767 if (type === 'inline' || type === 'html') { 11768 if (!coming.content || !coming.content.length) { 11769 return F._error( 'content' ); 11770 } 11771 11772 } else if (!href) { 11773 return F._error( 'href' ); 11774 } 11775 11776 if (type === 'image') { 11777 F._loadImage(); 11778 11779 } else if (type === 'ajax') { 11780 F._loadAjax(); 11781 11782 } else if (type === 'iframe') { 11783 F._loadIframe(); 11784 11785 } else { 11786 F._afterLoad(); 11787 } 11788 }, 11789 11790 _error: function ( type ) { 11791 $.extend(F.coming, { 11792 type : 'html', 11793 autoWidth : true, 11794 autoHeight : true, 11795 minWidth : 0, 11796 minHeight : 0, 11797 scrolling : 'no', 11798 hasError : type, 11799 content : F.coming.tpl.error 11800 }); 11801 11802 F._afterLoad(); 11803 }, 11804 11805 _loadImage: function () { 11806 // Reset preload image so it is later possible to check "complete" property 11807 var img = F.imgPreload = new Image(); 11808 11809 img.onload = function () { 11810 this.onload = this.onerror = null; 11811 11812 F.coming.width = this.width / F.opts.pixelRatio; 11813 F.coming.height = this.height / F.opts.pixelRatio; 11814 11815 F._afterLoad(); 11816 }; 11817 11818 img.onerror = function () { 11819 this.onload = this.onerror = null; 11820 11821 F._error( 'image' ); 11822 }; 11823 11824 img.src = F.coming.href; 11825 11826 if (img.complete !== true) { 11827 F.showLoading(); 11828 } 11829 }, 11830 11831 _loadAjax: function () { 11832 var coming = F.coming; 11833 11834 F.showLoading(); 11835 11836 F.ajaxLoad = $.ajax($.extend({}, coming.ajax, { 11837 url: coming.href, 11838 error: function (jqXHR, textStatus) { 11839 if (F.coming && textStatus !== 'abort') { 11840 F._error( 'ajax', jqXHR ); 11841 11842 } else { 11843 F.hideLoading(); 11844 } 11845 }, 11846 success: function (data, textStatus) { 11847 if (textStatus === 'success') { 11848 coming.content = data; 11849 11850 F._afterLoad(); 11851 } 11852 } 11853 })); 11854 }, 11855 11856 _loadIframe: function() { 11857 var coming = F.coming, 11858 iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime())) 11859 .attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling) 11860 .attr('src', coming.href); 11861 11862 // This helps IE 11863 $(coming.wrap).bind('onReset', function () { 11864 try { 11865 $(this).find('iframe').hide().attr('src', '//about:blank').end().empty(); 11866 } catch (e) {} 11867 }); 11868 11869 if (coming.iframe.preload) { 11870 F.showLoading(); 11871 11872 iframe.one('load', function() { 11873 $(this).data('ready', 1); 11874 11875 // iOS will lose scrolling if we resize 11876 if (!isTouch) { 11877 $(this).bind('load.fb', F.update); 11878 } 11879 11880 // Without this trick: 11881 // - iframe won't scroll on iOS devices 11882 // - IE7 sometimes displays empty iframe 11883 $(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show(); 11884 11885 F._afterLoad(); 11886 }); 11887 } 11888 11889 coming.content = iframe.appendTo( coming.inner ); 11890 11891 if (!coming.iframe.preload) { 11892 F._afterLoad(); 11893 } 11894 }, 11895 11896 _preloadImages: function() { 11897 var group = F.group, 11898 current = F.current, 11899 len = group.length, 11900 cnt = current.preload ? Math.min(current.preload, len - 1) : 0, 11901 item, 11902 i; 11903 11904 for (i = 1; i <= cnt; i += 1) { 11905 item = group[ (current.index + i ) % len ]; 11906 11907 if (item.type === 'image' && item.href) { 11908 new Image().src = item.href; 11909 } 11910 } 11911 }, 11912 11913 _afterLoad: function () { 11914 var coming = F.coming, 11915 previous = F.current, 11916 placeholder = 'fancybox-placeholder', 11917 current, 11918 content, 11919 type, 11920 scrolling, 11921 href, 11922 embed; 11923 11924 F.hideLoading(); 11925 11926 if (!coming || F.isActive === false) { 11927 return; 11928 } 11929 11930 if (false === F.trigger('afterLoad', coming, previous)) { 11931 coming.wrap.stop(true).trigger('onReset').remove(); 11932 11933 F.coming = null; 11934 11935 return; 11936 } 11937 11938 if (previous) { 11939 F.trigger('beforeChange', previous); 11940 11941 previous.wrap.stop(true).removeClass('fancybox-opened') 11942 .find('.fancybox-item, .fancybox-nav') 11943 .remove(); 11944 } 11945 11946 F.unbindEvents(); 11947 11948 current = coming; 11949 content = coming.content; 11950 type = coming.type; 11951 scrolling = coming.scrolling; 11952 11953 $.extend(F, { 11954 wrap : current.wrap, 11955 skin : current.skin, 11956 outer : current.outer, 11957 inner : current.inner, 11958 current : current, 11959 previous : previous 11960 }); 11961 11962 href = current.href; 11963 11964 switch (type) { 11965 case 'inline': 11966 case 'ajax': 11967 case 'html': 11968 if (current.selector) { 11969 content = $('<div>').html(content).find(current.selector); 11970 11971 } else if (isQuery(content)) { 11972 if (!content.data(placeholder)) { 11973 content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() ); 11974 } 11975 11976 content = content.show().detach(); 11977 11978 current.wrap.bind('onReset', function () { 11979 if ($(this).find(content).length) { 11980 content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false); 11981 } 11982 }); 11983 } 11984 break; 11985 11986 case 'image': 11987 content = current.tpl.image.replace(
vendor: 14,919 bytes, lines 11987-12556
11987'{href}', href); 11988 break; 11989 11990 case 'swf': 11991 content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>'; 11992 embed = ''; 11993 11994 $.each(current.swf, function(name, val) { 11995 content += '<param name="' + name + '" value="' + val + '"></param>'; 11996 embed += ' ' + name + '="' + val + '"'; 11997 }); 11998 11999 content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>'; 12000 break; 12001 } 12002 12003 if (!(isQuery(content) && content.parent().is(current.inner))) { 12004 current.inner.append( content ); 12005 } 12006 12007 // Give a chance for helpers or callbacks to update elements 12008 F.trigger('beforeShow'); 12009 12010 // Set scrolling before calculating dimensions 12011 current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling)); 12012 12013 // Set initial dimensions and start position 12014 F._setDimension(); 12015 12016 F.reposition(); 12017 12018 F.isOpen = false; 12019 F.coming = null; 12020 12021 F.bindEvents(); 12022 12023 if (!F.isOpened) { 12024 $('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove(); 12025 12026 } else if (previous.prevMethod) { 12027 F.transitions[ previous.prevMethod ](); 12028 } 12029 12030 F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ](); 12031 12032 F._preloadImages(); 12033 }, 12034 12035 _setDimension: function () { 12036 var viewport = F.getViewport(), 12037 steps = 0, 12038 canShrink = false, 12039 canExpand = false, 12040 wrap = F.wrap, 12041 skin = F.skin, 12042 inner = F.inner, 12043 current = F.current, 12044 width = current.width, 12045 height = current.height, 12046 minWidth = current.minWidth, 12047 minHeight = current.minHeight, 12048 maxWidth = current.maxWidth, 12049 maxHeight = current.maxHeight, 12050 scrolling = current.scrolling, 12051 scrollOut = current.scrollOutside ? current.scrollbarWidth : 0, 12052 margin = current.margin, 12053 wMargin = getScalar(margin[1] + margin[3]), 12054 hMargin = getScalar(margin[0] + margin[2]), 12055 wPadding, 12056 hPadding, 12057 wSpace, 12058 hSpace, 12059 origWidth, 12060 origHeight, 12061 origMaxWidth, 12062 origMaxHeight, 12063 ratio, 12064 width_, 12065 height_, 12066 maxWidth_, 12067 maxHeight_, 12068 iframe, 12069 body; 12070 12071 // Reset dimensions so we could re-check actual size 12072 wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp'); 12073 12074 wPadding = getScalar(skin.outerWidth(true) - skin.width()); 12075 hPadding = getScalar(skin.outerHeight(true) - skin.height()); 12076 12077 // Any space between content and viewport (margin, padding, border, title) 12078 wSpace = wMargin + wPadding; 12079 hSpace = hMargin + hPadding; 12080 12081 origWidth = isPercentage(width) ? (viewport.w - wSpace) * getScalar(width) / 100 : width; 12082 origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height; 12083 12084 if (current.type === 'iframe') { 12085 iframe = current.content; 12086 12087 if (current.autoHeight && iframe.data('ready') === 1) { 12088 try { 12089 if (iframe[0].contentWindow.document.location) { 12090 inner.width( origWidth ).height(9999); 12091 12092 body = iframe.contents().find('body'); 12093 12094 if (scrollOut) { 12095 body.css('overflow-x', 'hidden'); 12096 } 12097 12098 origHeight = body.outerHeight(true); 12099 } 12100 12101 } catch (e) {} 12102 } 12103 12104 } else if (current.autoWidth || current.autoHeight) { 12105 inner.addClass( 'fancybox-tmp' ); 12106 12107 // Set width or height in case we need to calculate only one dimension 12108 if (!current.autoWidth) { 12109 inner.width( origWidth ); 12110 } 12111 12112 if (!current.autoHeight) { 12113 inner.height( origHeight ); 12114 } 12115 12116 if (current.autoWidth) { 12117 origWidth = inner.width(); 12118 } 12119 12120 if (current.autoHeight) { 12121 origHeight = inner.height(); 12122 } 12123 12124 inner.removeClass( 'fancybox-tmp' ); 12125 } 12126 12127 width = getScalar( origWidth ); 12128 height = getScalar( origHeight ); 12129 12130 ratio = origWidth / origHeight; 12131 12132 // Calculations for the content 12133 minWidth = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth); 12134 maxWidth = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth); 12135 12136 minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight); 12137 maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight); 12138 12139 // These will be used to determine if wrap can fit in the viewport 12140 origMaxWidth = maxWidth; 12141 origMaxHeight = maxHeight; 12142 12143 if (current.fitToView) { 12144 maxWidth = Math.min(viewport.w - wSpace, maxWidth); 12145 maxHeight = Math.min(viewport.h - hSpace, maxHeight); 12146 } 12147 12148 maxWidth_ = viewport.w - wMargin; 12149 maxHeight_ = viewport.h - hMargin; 12150 12151 if (current.aspectRatio) { 12152 if (width > maxWidth) { 12153 width = maxWidth; 12154 height = getScalar(width / ratio); 12155 } 12156 12157 if (height > maxHeight) { 12158 height = maxHeight; 12159 width = getScalar(height * ratio); 12160 } 12161 12162 if (width < minWidth) { 12163 width = minWidth; 12164 height = getScalar(width / ratio); 12165 } 12166 12167 if (height < minHeight) { 12168 height = minHeight; 12169 width = getScalar(height * ratio); 12170 } 12171 12172 } else { 12173 width = Math.max(minWidth, Math.min(width, maxWidth)); 12174 12175 if (current.autoHeight && current.type !== 'iframe') { 12176 inner.width( width ); 12177 12178 height = inner.height(); 12179 } 12180 12181 height = Math.max(minHeight, Math.min(height, maxHeight)); 12182 } 12183 12184 // Try to fit inside viewport (including the title) 12185 if (current.fitToView) { 12186 inner.width( width ).height( height ); 12187 12188 wrap.width( width + wPadding ); 12189 12190 // Real wrap dimensions 12191 width_ = wrap.width(); 12192 height_ = wrap.height(); 12193 12194 if (current.aspectRatio) { 12195 while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) { 12196 if (steps++ > 19) { 12197 break; 12198 } 12199 12200 height = Math.max(minHeight, Math.min(maxHeight, height - 10)); 12201 width = getScalar(height * ratio); 12202 12203 if (width < minWidth) { 12204 width = minWidth; 12205 height = getScalar(width / ratio); 12206 } 12207 12208 if (width > maxWidth) { 12209 width = maxWidth; 12210 height = getScalar(width / ratio); 12211 } 12212 12213 inner.width( width ).height( height ); 12214 12215 wrap.width( width + wPadding ); 12216 12217 width_ = wrap.width(); 12218 height_ = wrap.height(); 12219 } 12220 12221 } else { 12222 width = Math.max(minWidth, Math.min(width, width - (width_ - maxWidth_))); 12223 height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_))); 12224 } 12225 } 12226 12227 if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) { 12228 width += scrollOut; 12229 } 12230 12231 inner.width( width ).height( height ); 12232 12233 wrap.width( width + wPadding ); 12234 12235 width_ = wrap.width(); 12236 height_ = wrap.height(); 12237 12238 canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight; 12239 canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight)); 12240 12241 $.extend(current, { 12242 dim : { 12243 width : getValue( width_ ), 12244 height : getValue( height_ ) 12245 }, 12246 origWidth : origWidth, 12247 origHeight : origHeight, 12248 canShrink : canShrink, 12249 canExpand : canExpand, 12250 wPadding : wPadding, 12251 hPadding : hPadding, 12252 wrapSpace : height_ - skin.outerHeight(true), 12253 skinSpace : skin.height() - height 12254 }); 12255 12256 if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) { 12257 inner.height('auto'); 12258 } 12259 }, 12260 12261 _getPosition: function (onlyAbsolute) { 12262 var current = F.current, 12263 viewport = F.getViewport(), 12264 margin = current.margin, 12265 width = F.wrap.width() + margin[1] + margin[3], 12266 height = F.wrap.height() + margin[0] + margin[2], 12267 rez = { 12268 position: 'absolute', 12269 top : margin[0], 12270 left : margin[3] 12271 }; 12272 12273 if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) { 12274 rez.position = 'fixed'; 12275 12276 } else if (!current.locked) { 12277 rez.top += viewport.y; 12278 rez.left += viewport.x; 12279 } 12280 12281 rez.top = getValue(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio))); 12282 rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width) * current.leftRatio))); 12283 12284 return rez; 12285 }, 12286 12287 _afterZoomIn: function () { 12288 var current = F.current; 12289 12290 if (!current) { 12291 return; 12292 } 12293 12294 F.isOpen = F.isOpened = true; 12295 12296 F.wrap.css('overflow', 'visible').addClass('fancybox-opened'); 12297 12298 F.update(); 12299 12300 // Assign a click event 12301 if ( current.closeClick || (current.nextClick && F.group.length > 1) ) { 12302 F.inner.css('cursor', 'pointer').bind('click.fb', function(e) { 12303 if (!$(e.target).is('a') && !$(e.target).parent().is('a')) { 12304 e.preventDefault(); 12305 12306 F[ current.closeClick ? 'close' : 'next' ](); 12307 } 12308 }); 12309 } 12310 12311 // Create a close button 12312 if (current.closeBtn) { 12313 $(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) { 12314 e.preventDefault(); 12315 12316 F.close(); 12317 }); 12318 } 12319 12320 // Create navigation arrows 12321 if (current.arrows && F.group.length > 1) { 12322 if (current.loop || current.index > 0) { 12323 $(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev); 12324 } 12325 12326 if (current.loop || current.index < F.group.length - 1) { 12327 $(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next); 12328 } 12329 } 12330 12331 F.trigger('afterShow'); 12332 12333 // Stop the slideshow if this is the last item 12334 if (!current.loop && current.index === current.group.length - 1) { 12335 F.play( false ); 12336 12337 } else if (F.opts.autoPlay && !F.player.isActive) { 12338 F.opts.autoPlay = false; 12339 12340 F.play(); 12341 } 12342 }, 12343 12344 _afterZoomOut: function ( obj ) { 12345 obj = obj || F.current; 12346 12347 $('.fancybox-wrap').trigger('onReset').remove(); 12348 12349 $.extend(F, { 12350 group : {}, 12351 opts : {}, 12352 router : false, 12353 current : null, 12354 isActive : false, 12355 isOpened : false, 12356 isOpen : false, 12357 isClosing : false, 12358 wrap : null, 12359 skin : null, 12360 outer : null, 12361 inner : null 12362 }); 12363 12364 F.trigger('afterClose', obj); 12365 } 12366 }); 12367 12368 /* 12369 * Default transitions 12370 */ 12371 12372 F.transitions = { 12373 getOrigPosition: function () { 12374 var current = F.current, 12375 element = current.element, 12376 orig = current.orig, 12377 pos = {}, 12378 width = 50, 12379 height = 50, 12380 hPadding = current.hPadding, 12381 wPadding = current.wPadding, 12382 viewport = F.getViewport(); 12383 12384 if (!orig && current.isDom && element.is(':visible')) { 12385 orig = element.find('img:first'); 12386 12387 if (!orig.length) { 12388 orig = element; 12389 } 12390 } 12391 12392 if (isQuery(orig)) { 12393 pos = orig.offset(); 12394 12395 if (orig.is('img')) { 12396 width = orig.outerWidth(); 12397 height = orig.outerHeight(); 12398 } 12399 12400 } else { 12401 pos.top = viewport.y + (viewport.h - height) * current.topRatio; 12402 pos.left = viewport.x + (viewport.w - width) * current.leftRatio; 12403 } 12404 12405 if (F.wrap.css('position') === 'fixed' || current.locked) { 12406 pos.top -= viewport.y; 12407 pos.left -= viewport.x; 12408 } 12409 12410 pos = { 12411 top : getValue(pos.top - hPadding * current.topRatio), 12412 left : getValue(pos.left - wPadding * current.leftRatio), 12413 width : getValue(width + wPadding), 12414 height : getValue(height + hPadding) 12415 }; 12416 12417 return pos; 12418 }, 12419 12420 step: function (now, fx) { 12421 var ratio, 12422 padding, 12423 value, 12424 prop = fx.prop, 12425 current = F.current, 12426 wrapSpace = current.wrapSpace, 12427 skinSpace = current.skinSpace; 12428 12429 if (prop === 'width' || prop === 'height') { 12430 ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start); 12431 12432 if (F.isClosing) { 12433 ratio = 1 - ratio; 12434 } 12435 12436 padding = prop === 'width' ? current.wPadding : current.hPadding; 12437 value = now - padding; 12438 12439 F.skin[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) ) ); 12440 F.inner[ prop ]( getScalar( prop === 'width' ? value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) ); 12441 } 12442 }, 12443 12444 zoomIn: function () { 12445 var current = F.current, 12446 startPos = current.pos, 12447 effect = current.openEffect, 12448 elastic = effect === 'elastic', 12449 endPos = $.extend({opacity : 1}, startPos); 12450 12451 // Remove "position" property that breaks older IE 12452 delete endPos.position; 12453 12454 if (elastic) { 12455 startPos = this.getOrigPosition(); 12456 12457 if (current.openOpacity) { 12458 startPos.opacity = 0.1; 12459 } 12460 12461 } else if (effect === 'fade') { 12462 startPos.opacity = 0.1; 12463 } 12464 12465 F.wrap.css(startPos).animate(endPos, { 12466 duration : effect === 'none' ? 0 : current.openSpeed, 12467 easing : current.openEasing, 12468 step : elastic ? this.step : null, 12469 complete : F._afterZoomIn 12470 }); 12471 }, 12472 12473 zoomOut: function () { 12474 var current = F.current, 12475 effect = current.closeEffect, 12476 elastic = effect === 'elastic', 12477 endPos = {opacity : 0.1}; 12478 12479 if (elastic) { 12480 endPos = this.getOrigPosition(); 12481 12482 if (current.closeOpacity) { 12483 endPos.opacity = 0.1; 12484 } 12485 } 12486 12487 F.wrap.animate(endPos, { 12488 duration : effect === 'none' ? 0 : current.closeSpeed, 12489 easing : current.closeEasing, 12490 step : elastic ? this.step : null, 12491 complete : F._afterZoomOut 12492 }); 12493 }, 12494 12495 changeIn: function () { 12496 var current = F.current, 12497 effect = current.nextEffect, 12498 startPos = current.pos, 12499 endPos = { opacity : 1 }, 12500 direction = F.direction, 12501 distance = 200, 12502 field; 12503 12504 startPos.opacity = 0.1; 12505 12506 if (effect === 'elastic') { 12507 field = direction === 'down' || direction === 'up' ? 'top' : 'left'; 12508 12509 if (direction === 'down' || direction === 'right') { 12510 startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance); 12511 endPos[ field ] = '+=' + distance + 'px'; 12512 12513 } else { 12514 startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance); 12515 endPos[ field ] = '-=' + distance + 'px'; 12516 } 12517 } 12518 12519 // Workaround for http://bugs.jquery.com/ticket/12273 12520 if (effect === 'none') { 12521 F._afterZoomIn(); 12522 12523 } else { 12524 F.wrap.css(startPos).animate(endPos, { 12525 duration : current.nextSpeed, 12526 easing : current.nextEasing, 12527 complete : F._afterZoomIn 12528 }); 12529 } 12530 }, 12531 12532 changeOut: function () { 12533 var previous = F.previous, 12534 effect = previous.prevEffect, 12535 endPos = { opacity : 0.1 }, 12536 direction = F.direction, 12537 distance = 200; 12538 12539 if (effect === 'elastic') { 12540 endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px'; 12541 } 12542 12543 previous.wrap.animate(endPos, { 12544 duration : effect === 'none' ? 0 : previous.prevSpeed, 12545 easing : previous.prevEasing, 12546 complete : function () { 12547 $(this).trigger('onReset').remove(); 12548 } 12549 }); 12550 } 12551 }; 12552 12553 /* 12554 * Overlay helper 12555 */ 12556
12557 F.helpers.overlay = { 12558 defaults : { 12559 closeClick : true, // if true, fancyBox will be closed when user clicks on the overlay 12560 speedOut : 200, // duration of fadeOut animation 12561 showEarly : true, // indicates if should be opened immediately or wait until the content is ready 12562 css : {}, // custom CSS properties 12563 locked : !isTouch, // if true, the content will be locked into overlay 12564 fixed : true // if false, the overlay CSS position property will not be set to "fixed" 12565 }, 12566 12567 overlay : null, // current handle 12568 fixed : false, // indicates if the overlay has position "fixed" 12569 el : $('html'), // element that contains "the lock" 12570 12571 // Public methods 12572 create : function(opts) { 12573 opts = $.extend({}, this.defaults, opts); 12574 12575 if (this.overlay) { 12576 this.close(); 12577 } 12578 12579 this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( F.coming ? F.coming.parent : opts.parent ); 12580 this.fixed = false; 12581 12582 if (opts.fixed && F.defaults.fixed) { 12583 this.overlay.addClass('fancybox-overlay-fixed'); 12584 12585 this.fixed = true; 12586 } 12587 }, 12588 12589 open : function(opts) { 12590 var that = this; 12591 12592 opts = $.extend({}, this.defaults, opts); 12593 12594 if (this.overlay) { 12595 this.overlay.unbind('.overlay').width('auto').height('auto'); 12596 12597 } else { 12598 this.create(opts); 12599 } 12600 12601 if (!this.fixed) { 12602 W.bind('resize.overlay', $.proxy( this.update, this) ); 12603 12604 this.update(); 12605 } 12606 12607 if (opts.closeClick) { 12608 this.overlay.bind('click.overlay', function(e) { 12609 if ($(e.target).hasClass('fancybox-overlay')) { 12610 if (F.isActive) { 12611 F.close(); 12612 } else { 12613 that.close(); 12614 } 12615 12616 return false; 12617 } 12618 }); 12619 } 12620 12621 this.overlay.css( opts.css ).show(); 12622 }, 12623 12624 close : function() { 12625 var scrollV, scrollH; 12626 12627 W.unbind('resize.overlay'); 12628 12629 if (this.el.hasClass('fancybox-lock')) { 12630 $('.fancybox-margin').removeClass('fancybox-margin'); 12631 12632 scrollV = W.scrollTop(); 12633 scrollH = W.scrollLeft(); 12634 12635 this.el.removeClass('fancybox-lock'); 12636 12637 W.scrollTop( scrollV ).scrollLeft( scrollH ); 12638 } 12639 12640 $('.fancybox-overlay').remove().hide(); 12641 12642 $.extend(this, { 12643 overlay : null, 12644 fixed : false 12645 }); 12646 }, 12647 12648 // Private, callbacks 12649 12650 update : function () { 12651 var width = '100%', offsetWidth; 12652 12653 // Reset width/height so it will not mess 12654 this.overlay.width(width).height('100%'); 12655 12656 // jQuery does not return reliable result for IE 12657 if (IE) { 12658 offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth); 12659 12660 if (D.width() > offsetWidth) { 12661 width = D.width(); 12662 } 12663 12664 } else if (D.width() > W.width()) { 12665 width = D.width(); 12666 } 12667 12668 this.overlay.width(width).height(D.height()); 12669 }, 12670 12671 // This is where we can manipulate DOM, because later it would cause iframes to reload 12672 onReady : function (opts, obj) { 12673 var overlay = this.overlay; 12674 12675 $('.fancybox-overlay').stop(true, true); 12676 12677 if (!overlay) { 12678 this.create(opts); 12679 } 12680 12681 if (opts.locked && this.fixed && obj.fixed) { 12682 if (!overlay) { 12683 this.margin = D.height() > W.height() ? $('html').css('margin-right').replace("px", "") : false; 12684 } 12685 12686 obj.locked = this.overlay.append( obj.wrap ); 12687 obj.fixed = false; 12688 } 12689 12690 if (opts.showEarly === true) { 12691 this.beforeShow.apply(this, arguments); 12692 } 12693 }, 12694 12695 beforeShow : function(opts, obj) { 12696 var scrollV, scrollH; 12697 12698 if (obj.locked) { 12699 if (this.margin !== false) { 12700 $('*').filter(function(){ 12701 return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") ); 12702 }).addClass('fancybox-margin'); 12703 12704 this.el.addClass('fancybox-margin'); 12705 } 12706 12707 scrollV = W.scrollTop(); 12708 scrollH = W.scrollLeft(); 12709 12710 this.el.addClass('fancybox-lock'); 12711 12712 W.scrollTop( scrollV ).scrollLeft( scrollH ); 12713 } 12714 12715 this.open(opts); 12716 }, 12717 12718 onUpdate : function() { 12719 if (!this.fixed) { 12720 this.update(); 12721 } 12722 }, 12723 12724 afterClose: function (opts) { 12725 // Remove overlay if exists and fancyBox is not opening 12726 // (e.g., it is not being open using afterClose callback) 12727 //if (this.overlay && !F.isActive) { 12728 if (this.overlay && !F.coming) { 12729 this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this )); 12730 } 12731 } 12732 }; 12733 12734 /* 12735 * Title helper 12736 */ 12737 12738 F.helpers.title = { 12739 defaults : { 12740 type : 'float', // 'float', 'inside', 'outside' or 'over', 12741 position : 'bottom' // 'top' or 'bottom' 12742 }, 12743 12744 beforeShow: function (opts) { 12745 var current = F.current, 12746 text = current.title, 12747 type = opts.type, 12748 title, 12749 target; 12750 12751 if ($.isFunction(text)) { 12752 text = text.call(current.element, current); 12753 } 12754 12755 if (!isString(text) || $.trim(text) === '') { 12756 return; 12757 } 12758 12759 title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">
12759' + text + '</div>'); 12760 12761 switch (type) { 12762 case 'inside': 12763 target = F.skin; 12764 break; 12765 12766 case 'outside': 12767 target = F.wrap; 12768 break; 12769 12770 case 'over': 12771 target = F.inner; 12772 break; 12773 12774 default: // 'float' 12775 target = F.skin; 12776 12777 title.appendTo('body'); 12778 12779 if (IE) { 12780 title.width( title.width() ); 12781 } 12782 12783 title.wrapInner('<span class="child"></span>'); 12784 12785 //Increase bottom margin so this title will also fit into viewport 12786 F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) ); 12787 break; 12788 } 12789 12790 title[ (opts.position === 'top' ? 'prependTo' : 'appendTo') ](target); 12791 } 12792 }; 12793 12794 // jQuery plugin initialization 12795 $.fn.fancybox = function (options) { 12796 var index, 12797 that = $(this), 12798 selector = this.selector || '', 12799 run = function(e) { 12800 var what = $(this).blur(), idx = index, relType, relVal; 12801 12802 if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) { 12803 relType = options.groupAttr || 'data-fancybox-group'; 12804 relVal = what.attr(relType); 12805 12806 if (!relVal) { 12807 relType = 'rel'; 12808 relVal = what.get(0)[ relType ]; 12809 } 12810 12811 if (relVal && relVal !== '' && relVal !== 'nofollow') { 12812 what = selector.length ? $(selector) : that; 12813 what = what.filter('[' + relType + '="' + relVal + '"]'); 12814 idx = what.index(this); 12815 } 12816 12817 options.index = idx; 12818 12819 // Stop an event from bubbling if everything is fine 12820 if (F.open(what, options) !== false) { 12821 e.preventDefault(); 12822 } 12823 } 12824 }; 12825 12826 options = options || {}; 12827 index = options.index || 0; 12828 12829 if (!selector || options.live === false) { 12830 that.unbind('click.fb-start').bind('click.fb-start', run); 12831 12832 } else { 12833 D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run); 12834 } 12835 12836 this.filter('[data-fancybox-start=1]').trigger('click'); 12837 12838 return this; 12839 }; 12840 12841 // Tests that need a body at doc ready 12842 D.ready(function() { 12843 var w1, w2; 12844 12845 if ( $.scrollbarWidth === undefined ) { 12846 // http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth 12847 $.scrollbarWidth = function() { 12848 var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'), 12849 child = parent.children(), 12850 width = child.innerWidth() - child.height( 99 ).innerWidth(); 12851 12852 parent.remove(); 12853 12854 return width; 12855 }; 12856 } 12857 12858 if ( $.support.fixedPosition === undefined ) { 12859 $.support.fixedPosition = (function() { 12860 var elem = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'), 12861 fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 ); 12862 12863 elem.remove(); 12864 12865 return fixed; 12866 }()); 12867 } 12868 12869 $.extend(F.defaults, { 12870 scrollbarWidth : $.scrollbarWidth(), 12871 fixed : $.support.fixedPosition, 12872 parent : $('body') 12873 }); 12874 12875 //Get real width of page scroll-bar 12876 w1 = $(window).width(); 12877 12878 H.addClass('fancybox-lock-test'); 12879 12880 w2 = $(window).width(); 12881 12882 H.removeClass('fancybox-lock-test'); 12883 12884 $("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head"); 12885 }); 12886 12887}(window, document, jQuery)); 12888; 12889; 12890(function($, window, document, undefined) { 12891 12892 // Create the defaults once 12893 var pluginName = "sliphover", 12894 defaults = { 12895 target: 'img', //the element that the overlay will attach to 12896 caption: 'title', //the caption that will display when hover 12897 duration: 'fast', //specify how long the animation will lasts in milliseconds 12898 fontColor: '#fff', 12899 textAlign: 'center', //display the caption left, center or right 12900 verticalMiddle: true, //display the caption vertical middle or not 12901 backgroundColor: 'rgba(0,0,0,.7)', //specify the background color and opacity using rgba 12902 backgroundColorAttr: null, //specify the attribute with background color value and opacity using rgba 12903 reverse: false, //reverse the direction 12904 height: '100%', //specify the height of the overlay 12905 withLink: true //if image is wraped with a link the overlay will be clickable, set false to disable click 12906 }; 12907 12908 function SlipHover(element, options) { 12909 this.element = element; 12910 this.settings = $.extend({}, defaults, options); 12911 this._defaults = defaults; 12912 this._name = pluginName; 12913 this.version = 'v2.0.5'; 12914 this.init(); 12915 } 12916 12917 SlipHover.prototype = { 12918 init: function() { 12919 12920 //disable on touch devices 12921 if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) { 12922 return; 12923 } 12924 12925 var that = this, 12926 target = this.settings.target; 12927 12928 //create the overlay container each time the mouse enters 12929 $(this.element).off('mouseenter.sliphover', target).on('mouseenter.sliphover', target, function(event) { 12930 //fix #9 https://github.com/wayou/SlipHover/issues/9 12931 //use this instead of event.target for sometimes the event.target is not retriving the right target we want 12932 //http://stackoverflow.com/questions/9838137/event-target-jquery-on-mousedown-up-is-not-giving-the-dom-specified-by-selecto 12933 var $element = $(this), 12934 $overlayContainer = that.createContainer($element); 12935 12936 $overlayContainer.off('mouseenter.sliphover mouseleave.
12936sliphover').on('mouseenter.sliphover mouseleave.sliphover', function(event) { 12937 //if (!$overlayContainer) return; 12938 var direction = that.getDirection($(this), event); 12939 12940 //check if reverse option is on 12941 direction = that.settings.reverse ? direction = (direction + 2) % 4 : direction; 12942 12943 if (event.type === 'mouseenter') { 12944 //check if the previous overlay still exists before we create it 12945 var $overlay = $overlayContainer.find('.sliphover-overlay'); 12946 if (!$overlay.length) { 12947 $overlay = that.createOverlay(that, direction, $element); 12948 //put the overlay into the container 12949 $(this).html($overlay); 12950 } 12951 that.slideIn(that, $overlay); 12952 } else { 12953 //slide out based on the direction 12954 that.removeOverlay(that, $(this), direction); 12955 } 12956 }); 12957 }); 12958 }, 12959 createContainer: function($element) { 12960 //get the properties of the target 12961 var top = $element.offset().top, 12962 left = $element.offset().left, 12963 //border = parseFloat($element.css("border-left-width")), 12964 width = $element.outerWidth(), 12965 height = $element.outerHeight(); 12966 zIndex = $element.css("z-index");
12967 var $overlayContainer = $('<div>', { 12968 class: 'sliphover-container' 12969 }).css({ 12970 width: width, 12971 height: height, 12972 position: 'absolute', 12973 overflow: 'hidden', 12974 top: top, 12975 left: left, 12976 borderRadius: $element.css('border-radius'), //in case the target has a round border, this will make the overlay more nicer 12977 zIndex: zIndex == +zIndex ? (zIndex + 1) : 999 // if the z-index of the target is not number then use 999 12978 }); 12979 12980 $('body').append($overlayContainer); 12981 12982 return $overlayContainer; 12983 }, 12984 createOverlay: function(instance, direction, $element) { 12985 12986 var bottom, left, $overlay, $overlayColor, content, $targetAParent; 12987 12988 switch (direction) { 12989 case 0: 12990 //from top 12991 left = 0; 12992 bottom = '100%'; 12993 break; 12994 case 1: 12995 //from right 12996 left = '100%'; 12997 bottom = 0; 12998 break; 12999 case 2: 13000 //from bottom 13001 left = 0; 13002 bottom = '-100%'; 13003 break; 13004 case 3: 13005 //from left 13006 left = '-100%'; 13007 bottom = 0; 13008 break; 13009 default: 13010 window.console.error('error when get direction of the mouse'); 13011 }; 13012 13013 //if we want to display content vertical middle, we need to wrap the content into a div and set the style with display table-cell 13014 if (instance.settings.verticalMiddle) { 13015 content = $('<div>').css({ 13016 display: 'table-cell', 13017 verticalAlign: 'middle' 13018 }).html($element.attr(instance.settings.caption)); 13019 } else { 13020 content = $element.attr(instance.settings.caption); 13021 } 13022 $targetAParent = $element.parent('a'); 13023 if ($targetAParent.length && instance.settings.withLink) { 13024 var url = $targetAParent.attr('href'), 13025 target=$targetAParent.attr('target');//fix issue#17 13026 $overlay = $('<a>', { 13027 class: 'sliphover-overlay', 13028 href: url || '#', 13029 target: target||'_self' 13030 }).css({ 13031 textDecoration: 'none' 13032 }); 13033 } else { 13034 $overlay = $('<div>', { 13035 class: 'sliphover-overlay' 13036 }); 13037 } 13038 13039 $overlayColor = instance.settings.backgroundColorAttr ? 13040 $element.attr(instance.settings.backgroundColorAttr) : instance.settings.backgroundColor; 13041 13042 $overlay.css({ 13043 width: '100%', 13044 height: instance.settings.height, 13045 position: 'absolute', 13046 left: left, 13047 bottom: bottom, 13048 display: instance.settings.verticalMiddle ? 'table' : 'inline', 13049 textAlign: instance.settings.textAlign, 13050 color: instance.settings.fontColor, 13051 backgroundColor: $overlayColor 13052 }) 13053 .html(content); 13054 return $overlay; 13055 }, 13056 slideIn: function(instance, $overlay) { 13057 $overlay.stop().animate({ 13058 left: 0, 13059 bottom: 0 13060 }, instance.settings.duration); 13061 }, 13062 removeOverlay: function(instance, $overlayContainer, direction) { 13063 var finalState, 13064 $overlay = $overlayContainer.find('.sliphover-overlay'); 13065 13066 switch (direction) { 13067 case 0: //to top 13068 finalState = { 13069 bottom: '100%', 13070 left: 0 13071 }; 13072 break; 13073 case 1: //to right 13074 finalState = { 13075 bottom: 0, 13076 left: '100%' 13077 }; 13078 break; 13079 case 2: //to bottom 13080 finalState = { 13081 bottom: '-100%', 13082 left: 0 13083 }; 13084 break; 13085 case 3: //to left 13086 finalState = { 13087 bottom: 0, 13088 left: '-100%' 13089 }; 13090 break; 13091 default: 13092 window.console.error('error when get direction of the mouse'); 13093 }; 13094 13095 //slide out 13096 $overlay.stop().animate(finalState, instance.settings.duration, function() { 13097 $overlayContainer.remove(); 13098 }); 13099 }, 13100 getDirection: function($target, event) { 13101 //reference: http://stackoverflow.com/questions/3627042/jquery-animation-for-a-hover-with-mouse-direction 13102 var w = $target.width(), 13103 h = $target.height(), 13104 x = (event.pageX - $target.offset().left - (w / 2)) * (w > h ? (h / w) : 1), 13105 y = (event.pageY - $target.offset().top - (h / 2)) * (h > w ? (w / h) : 1), 13106 direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4; 13107 return direction; 13108 } 13109 }; 13110 13111 $.fn[pluginName] = function(options) { 13112 this.each(function() { 13113 if (!$.data(this, "plugin_" + pluginName)) { 13114 $.data(this, "plugin_" + pluginName, new SlipHover(this, options)); 13115 } 13116 }); 13117 13118 // chain jQuery functions 13119 return this; 13120 }; 13121 13122})(jQuery, window, document); 13123; 13124(function($) { 13125 13126 'use strict'; 13127 13128 // Define the jscroll namespace and default settings 13129 $.jscroll = { 13130 defaults: { 13131 debug: false, 13132 autoTrigger: true, 13133 autoTriggerUntil: false, 13134 loadingHtml: '<small>Loading...</small>', 13135 loadingFunction: false, 13136 padding: 0, 13137 nextSelector: 'a:last', 13138 contentSelector: '', 13139 pagingSelector: '', 13140 callback: false 13141 } 13142 }; 13143 13144 // Constructor 13145 var jScroll = function($e, options) { 13146 13147 // Private vars and methods 13148 var _data = $e.data('jscroll'), 13149 _userOptions = (typeof options === 'function') ? { callback: options } : options, 13150 _options = $.extend({}, $.jscroll.defaults, _userOptions, _data || {}), 13151 _isWindow = ($e.css('overflow-y') === 'visible'), 13152 _$next = $e.find(_options.nextSelector).first(), 13153 _$window = $(window), 13154 _$body = $('body'), 13155 _$scroll = _isWindow ? _$window : $e, 13156 _nextHref = $.trim(_$next.attr('href') + ' ' + _options.contentSelector), 13157 13158 // Check if a loading image is defined and preload 13159 _preloadImage = function() { 13160 var src = $(_options.loadingHtml).filter('img').attr('src'); 13161 if (src) { 13162 var image = new Image(); 13163 image.src = src; 13164 } 13165 }, 13166 13167 // Wrap inner content, if it isn't already 13168 _wrapInnerContent = function() { 13169 if (!$e.find('.jscroll-inner').length) { 13170 $e.contents().wrapAll('<div class="jscroll-inner" />'); 13171 } 13172 }, 13173 13174 // Find the next link's parent, or add one, and hide it 13175 _nextWrap = function($next) { 13176 var $parent; 13177 13178 if (_options.pagingSelector) { 13179 $next.closest(_options.pagingSelector).hide(); 13180 } else { 13181 $parent = $next.parent().not('.jscroll-inner,.jscroll-added').addClass('jscroll-next-parent').hide(); 13182 if (!$parent.length) { 13183 $next.wrap('<div class="jscroll-next-parent" />').parent().hide(); 13184 } 13185 } 13186 }, 13187 13188 // Remove the jscroll behavior and data from an element 13189 _destroy = function() { 13190 return _$scroll.unbind('.jscroll') 13191 .removeData('jscroll') 13192 .find('.jscroll-inner').children().unwrap() 13193 .filter('.jscroll-added').children().unwrap(); 13194 }, 13195 13196 // Observe the scroll event for when to trigger the next load 13197 _observe = function() { 13198 if ($e.is(':visible')) { 13199 _wrapInnerContent(); 13200 var $inner = $e.find('div.jscroll-inner').first(), 13201 data = $e.data('jscroll'), 13202 borderTopWidth = parseInt($e.css('borderTopWidth'), 10), 13203 borderTopWidthInt = isNaN(borderTopWidth) ? 0 : borderTopWidth, 13204 iContainerTop = parseInt($e.css('paddingTop'), 10) + borderTopWidthInt, 13205 iTopHeight = _isWindow ? _$scroll.scrollTop() : $e.offset().top, 13206 innerTop = $inner.length ? $inner.offset().top : 0,
vendor: 6,810 bytes, lines 13207-13366
13207 iTotalHeight = Math.ceil(iTopHeight - innerTop + _$scroll.height() + iContainerTop); 13208 13209 if (!data.waiting && iTotalHeight + _options.padding >= $inner.outerHeight()) { 13210 //data.nextHref = $.trim(data.nextHref + ' ' + _options.contentSelector); 13211 _debug('info', 'jScroll:', $inner.outerHeight() - iTotalHeight, 'from bottom. Loading next request...'); 13212 return _load(); 13213 } 13214 } 13215 }, 13216 13217 // Check if the href for the next set of content has been set 13218 _checkNextHref = function(data) { 13219 data = data || $e.data('jscroll'); 13220 if (!data || !data.nextHref) { 13221 _debug('warn', 'jScroll: nextSelector not found - destroying'); 13222 _destroy(); 13223 return false; 13224 } else { 13225 _setBindings(); 13226 return true; 13227 } 13228 }, 13229 13230 _setBindings = function() { 13231 var $next = $e.find(_options.nextSelector).first(); 13232 13233 if (!$next.length) { 13234 return; 13235 } 13236 if (_options.autoTrigger && (_options.autoTriggerUntil === false || _options.autoTriggerUntil > 0)) { 13237 _nextWrap($next); 13238 var scrollingBodyHeight = _$body.height() - $e.offset().top, 13239 scrollingHeight = ($e.height() < scrollingBodyHeight) ? $e.height() : scrollingBodyHeight, 13240 windowHeight = ($e.offset().top - _$window.scrollTop() > 0) ? _$window.height() - ($e.offset().top - $(window).scrollTop()) : _$window.height(); 13241 if (scrollingHeight <= windowHeight) { 13242 _observe(); 13243 } 13244 _$scroll.unbind('.jscroll').bind('scroll.jscroll', function() { 13245 return _observe(); 13246 }); 13247 if (_options.autoTriggerUntil > 0) { 13248 _options.autoTriggerUntil--; 13249 } 13250 } else { 13251 _$scroll.unbind('.jscroll'); 13252 $next.bind('click.jscroll', function() { 13253 _nextWrap($next); 13254 _load(); 13255 return false; 13256 }); 13257 } 13258 }, 13259 13260 // Load the next set of content, if available 13261 _load = function() { 13262 var $inner = $e.find('div.jscroll-inner').first(), 13263 data = $e.data('jscroll'); 13264 13265 data.waiting = true; 13266 $inner.append('<div class="jscroll-added" />') 13267 .children('.jscroll-added').last() 13268 .html('<div class="jscroll-loading" id="jscroll-loading">' + _options.loadingHtml + '</div>') 13269 .promise() 13270 .done(function(){ 13271 if (_options.loadingFunction) { 13272 _options.loadingFunction(); 13273 } 13274 }); 13275 13276 return $e.animate({scrollTop: $inner.outerHeight()}, 0, function() { 13277 $inner.find('div.jscroll-added').last().load(data.nextHref, function(r, status) { 13278 if (status === 'error') { 13279 return _destroy(); 13280 } 13281 var $next = $(this).find(_options.nextSelector).first(); 13282 data.waiting = false; 13283 data.nextHref = $next.attr('href') ? $.trim($next.attr('href') + ' ' + _options.contentSelector) : false; 13284 $('.jscroll-next-parent', $e).remove(); // Remove the previous next link now that we have a new one 13285 _checkNextHref(); 13286 if (_options.callback) { 13287 _options.callback.call(this); 13288 } 13289 _debug('dir', data); 13290 }); 13291 }); 13292 }, 13293 13294 // Safe console debug - http://klauzinski.com/javascript/safe-firebug-console-in-javascript 13295 _debug = function(m) { 13296 if (_options.debug && typeof console === 'object' && (typeof m === 'object' || typeof console[m] === 'function')) { 13297 if (typeof m === 'object') { 13298 var args = []; 13299 for (var sMethod in m) { 13300 if (typeof console[sMethod] === 'function') { 13301 args = (m[sMethod].length) ? m[sMethod] : [m[sMethod]]; 13302 console[sMethod].apply(console, args); 13303 } else { 13304 console.log.apply(console, args); 13305 } 13306 } 13307 } else { 13308 console[m].apply(console, Array.prototype.slice.call(arguments, 1)); 13309 } 13310 } 13311 }; 13312 13313 // Initialization 13314 $e.data('jscroll', $.extend({}, _data, {initialized: true, waiting: false, nextHref: _nextHref})); 13315 _wrapInnerContent(); 13316 _preloadImage(); 13317 _setBindings(); 13318 13319 // Expose API methods via the jQuery.jscroll namespace, e.g. $('sel').jscroll.method() 13320 $.extend($e.jscroll, { 13321 destroy: _destroy 13322 }); 13323 return $e; 13324 }; 13325 13326 // Define the jscroll plugin method and loop 13327 $.fn.jscroll = function(m) { 13328 return this.each(function() { 13329 var $this = $(this), 13330 data = $this.data('jscroll'), jscroll; 13331 13332 // Instantiate jScroll on this element if it hasn't been already 13333 if (data && data.initialized) { 13334 return; 13335 } 13336 jscroll = new jScroll($this, m); 13337 }); 13338 }; 13339 13340})(jQuery); 13341 13342; 13343;(function($){ 13344/*******************************************************************************************/ 13345// jquery.pajinate.js - version 0.4 13346// A jQuery plugin for paginating through any number of DOM elements 13347// 13348// Copyright (c) 2010, Wes Nolte (http://wesnolte.com) 13349// Licensed under the MIT License (MIT-LICENSE.txt) 13350// http://www.opensource.org/licenses/mit-license.php 13351// Created: 2010-04-16 | Updated: 2010-04-26 13352// 13353/*******************************************************************************************/ 13354 13355 $.fn.pajinate = function(options){ 13356 // Set some state information 13357 var current_page = 'current_page'; 13358 var items_per_page = 'items_per_page'; 13359 13360 var meta; 13361 13362 // Setup default option values 13363 var defaults = { 13364 item_container_id : '.content', 13365 items_per_page : 10, 13366 nav_panel_id : '.page_navigation',
13367 nav_info_id : '.info_text', 13368 num_page_links_to_display : 20, 13369 start_page : 0, 13370 wrap_around : false, 13371 nav_label_first : 'First', 13372 nav_label_prev : 'Prev', 13373 nav_label_next : 'Next', 13374 nav_label_last : 'Last', 13375 nav_order : ["first", "prev", "num", "next", "last"], 13376 nav_label_info : 'Showing {0}-{1} of {2} results', 13377 show_first_last: true, 13378 abort_on_small_lists: false, 13379 jquery_ui: false, 13380 jquery_ui_active: "ui-state-highlight", 13381 jquery_ui_default: "ui-state-default", 13382 jquery_ui_disabled: "ui-state-disabled" 13383 }; 13384 var options = $.extend(defaults,options); 13385 var $item_container; 13386 var $page_container; 13387 var $items; 13388 var $nav_panels; 13389 var total_page_no_links; 13390 var jquery_ui_default_class = options.jquery_ui ? options.jquery_ui_default : ''; 13391 var jquery_ui_active_class = options.jquery_ui ? options.jquery_ui_active : ''; 13392 var jquery_ui_disabled_class = options.jquery_ui ? options.jquery_ui_disabled : ''; 13393 13394 return this.each(function(){ 13395 $page_container = $(this); 13396 $item_container = $(this).find(options.item_container_id); 13397 $items = $page_container.find(options.item_container_id).children(); 13398 13399 if (options.abort_on_small_lists && options.items_per_page >= $items.size()) 13400 return $page_container; 13401 13402 meta = $page_container; 13403 13404 // Initialize meta data 13405 meta.data(current_page,0); 13406 meta.data(items_per_page, options.items_per_page); 13407 13408 // Get the total number of items 13409 var total_items = $item_container.children().size(); 13410 13411 // Calculate the number of pages needed 13412 var number_of_pages = Math.ceil(total_items/options.items_per_page); 13413 13414 // Construct the nav bar 13415 var more = '<span class="ellipse more">...</span>'; 13416 var less = '<span class="ellipse less">...</span>'; 13417 var first = !options.show_first_last ? '' : '<a class="first_link '+ jquery_ui_default_class +'" href="">'+ options.nav_label_first +'</a>'; 13418 var last = !options.show_first_last ? '' : '<a class="last_link '+ jquery_ui_default_class +'" href="">'+ options.nav_label_last +'</a>'; 13419 13420 var navigation_html = ""; 13421 13422 for(var i = 0; i < options.nav_order.length; i++) { 13423 switch (options.nav_order[i]) { 13424 case "first": 13425 navigation_html += first; 13426 break; 13427 case "last": 13428 navigation_html += last; 13429 break; 13430 case "next": 13431 navigation_html += '<a class="next_link '+ jquery_ui_default_class +'" href="">'+ options.nav_label_next +'</a>'; 13432 break; 13433 case "prev": 13434 navigation_html += '<a class="previous_link '+ jquery_ui_default_class +'" href="">'+ options.nav_label_prev +'</a>'; 13435 break; 13436 case "num": 13437 navigation_html += less; 13438 var current_link = 0; 13439 while(number_of_pages > current_link){ 13440 navigation_html += '<a class="page_link '+ jquery_ui_default_class +'" href="" longdesc="' + current_link +'">'+ (current_link + 1) +'</a>'; 13441 current_link++; 13442 } 13443 navigation_html += more; 13444 break; 13445 default: 13446 break; 13447 } 13448 13449 } 13450 13451 // And add it to the appropriate area of the DOM 13452 $nav_panels = $page_container.find(options.nav_panel_id); 13453 $nav_panels.html(navigation_html).each(function(){ 13454 13455 $(this).find('.page_link:first').addClass('first'); 13456 $(this).find('.page_link:last').addClass('last'); 13457 13458 }); 13459 13460 // Hide the more/less indicators 13461 $nav_panels.children('.ellipse').hide(); 13462 13463 // Set the active page link styling 13464 $nav_panels.find('.previous_link').next().next().addClass('active_page '+ jquery_ui_active_class); 13465 13466 /* Setup Page Display */ 13467 // And hide all pages 13468 $items.hide(); 13469 // Show the first page 13470 $items.slice(0, meta.data(items_per_page)).show(); 13471 13472 /* Setup Nav Menu Display */ 13473 // Page number slices 13474 13475 total_page_no_links = $page_container.children(options.nav_panel_id+':first').children('.page_link').size(); 13476 options.num_page_links_to_display = Math.min(options.num_page_links_to_display,total_page_no_links); 13477 13478 $nav_panels.children('.page_link').hide(); // Hide all the page links 13479 13480 // And only show the number we should be seeing 13481 $nav_panels.each(function(){ 13482 $(this).children('.page_link').slice(0, options.num_page_links_to_display).show(); 13483 }); 13484 13485 /* Bind the actions to their respective links */ 13486 13487 // Event handler for 'First' link 13488 $page_container.find('.first_link').click(function(e){ 13489 e.preventDefault(); 13490
13491 movePageNumbersRight($(this),0); 13492 gotopage(0); 13493 }); 13494 13495 // Event handler for 'Last' link 13496 $page_container.find('.last_link').click(function(e){ 13497 e.preventDefault(); 13498 var lastPage = total_page_no_links - 1; 13499 movePageNumbersLeft($(this),lastPage); 13500 gotopage(lastPage); 13501 }); 13502 13503 // Event handler for 'Prev' link 13504 $page_container.find('.previous_link').click(function(e){ 13505 e.preventDefault(); 13506 showPrevPage($(this)); 13507 }); 13508 13509 13510 // Event handler for 'Next' link 13511 $page_container.find('.next_link').click(function(e){ 13512 e.preventDefault(); 13513 showNextPage($(this)); 13514 }); 13515 13516 // Event handler for each 'Page' link 13517 $page_container.find('.page_link').click(function(e){ 13518 e.preventDefault(); 13519 gotopage($(this).attr('longdesc')); 13520 }); 13521 13522 // Goto the required page 13523 gotopage(parseInt(options.start_page)); 13524 toggleMoreLess(); 13525 if(!options.wrap_around) 13526 tagNextPrev(); 13527 }); 13528 13529 function showPrevPage(e){ 13530 new_page = parseInt(meta.data(current_page)) - 1; 13531 13532 // Check that we aren't on a boundary link 13533 if($(e).siblings('.active_page').prev('.page_link').length==true){ 13534 movePageNumbersRight(e,new_page); 13535 gotopage(new_page); 13536 }else if(options.wrap_around){ 13537 gotopage(total_page_no_links-1); 13538 } 13539 13540 }; 13541 13542 function showNextPage(e){ 13543 new_page = parseInt(meta.data(current_page)) + 1; 13544 13545 // Check that we aren't on a boundary link 13546 if($(e).siblings('.active_page').next('.page_link').length==true){ 13547 movePageNumbersLeft(e,new_page); 13548 gotopage(new_page); 13549 } else if (options.wrap_around) { 13550 gotopage(0); 13551 } 13552 13553 }; 13554 13555 function gotopage(page_num){ 13556 13557 var ipp = parseInt(meta.data(items_per_page)); 13558 13559 var isLastPage = false; 13560 13561 // Find the start of the next slice 13562 start_from = page_num * ipp; 13563 13564 // Find the end of the next slice
13565 end_on = start_from + ipp; 13566 // Hide the current page 13567 var items = $items.hide().slice(start_from, end_on); 13568 13569 items.show(); 13570 13571 // Reassign the active class 13572 $page_container.find(options.nav_panel_id).children('.page_link[longdesc=' + page_num +']').addClass('active_page '+ jquery_ui_active_class) 13573 .siblings('.active_page') 13574 .removeClass('active_page ' + jquery_ui_active_class); 13575 13576 // Set the current page meta data 13577 meta.data(current_page,page_num); 13578 13579 $page_container.find(options.nav_info_id).html(options.nav_label_info.replace("{0}",start_from+1). 13580 replace("{1}",start_from + items.length).replace("{2}",$items.length)); 13581 13582 // Hide the more and/or less indicators 13583 toggleMoreLess(); 13584 13585 // Add a class to the next or prev links if there are no more pages next or previous to the active page 13586 tagNextPrev(); 13587 }; 13588 13589 // Methods to shift the diplayed index of page numbers to the left or right 13590 function movePageNumbersLeft(e, new_p){ 13591 var new_page = new_p; 13592 13593 var $current_active_link = $(e).siblings('.active_page'); 13594 13595 if($current_active_link.siblings('.page_link[longdesc=' + new_page +']').css('display') == 'none'){ 13596 13597 $nav_panels.each(function(){ 13598 $(this).children('.page_link') 13599 .hide() // Hide all the page links 13600 .slice(parseInt(new_page - options.num_page_links_to_display + 1) , new_page + 1) 13601 .show(); 13602 }); 13603 } 13604 13605 } 13606 13607 function movePageNumbersRight(e, new_p){ 13608 var new_page = new_p; 13609 13610 var $current_active_link = $(e).siblings('.active_page'); 13611 13612 if($current_active_link.siblings('.page_link[longdesc=' + new_page +']').css('display') == 'none'){ 13613 13614 $nav_panels.each(function(){ 13615 $(this).children('.page_link') 13616 .hide() // Hide all the page links 13617 .slice( new_page , new_page + parseInt(options.num_page_links_to_display)) 13618 .show(); 13619 }); 13620 } 13621 } 13622 13623 // Show or remove the ellipses that indicate that more page numbers exist in the page index than are currently shown 13624 function toggleMoreLess(){ 13625 13626 if(!$nav_panels.children('.page_link:visible').hasClass('last')){ 13627 $nav_panels.children('.more').show(); 13628 }else { 13629 $nav_panels.children('.more').hide(); 13630 } 13631 13632 if(!$nav_panels.children('.page_link:visible').hasClass('first')){ 13633 $nav_panels.children('.less').show(); 13634 }else { 13635 $nav_panels.children('.less').hide(); 13636 } 13637 } 13638 13639 /* Add the style class ".no_more" to the first/prev and last/next links to allow custom styling */ 13640 function tagNextPrev() { 13641 if($nav_panels.children('.last').hasClass('active_page')){ 13642 $nav_panels.children('.next_link').add('.last_link').addClass('no_more ' + jquery_ui_disabled_class); 13643 } else { 13644 $nav_panels.children('.next_link').add('.last_link').removeClass('no_more ' + jquery_ui_disabled_class); 13645 } 13646 13647 if($nav_panels.children('.first').hasClass('active_page')){ 13648 $nav_panels.children('.previous_link').add('.first_link').addClass('no_more ' + jquery_ui_disabled_class); 13649 } else { 13650 $nav_panels.children('.previous_link').add('.first_link').removeClass('no_more ' + jquery_ui_disabled_class); 13651 } 13652 } 13653 13654 }; 13655 13656})(jQuery); 13657; 13658(function(factory) { 13659 if (typeof define === 'function' && define.amd) { 13660 // AMD 13661 define(['jquery'], factory); 13662 } else if (typeof module === 'object' && module.exports) { 13663 factory(require('jquery')); 13664 } else { 13665 // Browser globals 13666 factory(jQuery); 13667 } 13668}(function($) { 13669 13670 /**** 13671 * Allows plugin behavior simulation in modern browsers for easier debugging. 13672 * When setting to true, use attribute "placeholder-x" rather than the usual "placeholder" in your inputs/textareas 13673 * i.e. <input type="text" placeholder-x="my placeholder text" /> 13674 */ 13675 var debugMode = false; 13676 13677 // Opera Mini v7 doesn't support placeholder although its DOM seems to indicate so 13678 var isOperaMini = Object.prototype.toString.call(window.operamini) === '[object OperaMini]'; 13679 var isInputSupported = 'placeholder' in document.createElement('input') && !isOperaMini && !debugMode; 13680 var isTextareaSupported = 'placeholder' in document.createElement('textarea') && !isOperaMini && !debugMode; 13681 var valHooks = $.valHooks; 13682 var propHooks = $.propHooks; 13683 var hooks; 13684 var placeholder; 13685 var settings = {}; 13686 13687 if (isInputSupported && isTextareaSupported) { 13688 13689 placeholder = $.fn.placeholder = function() { 13690 return this; 13691 }; 13692 13693 placeholder.input = true; 13694 placeholder.textarea = true; 13695 13696 } else { 13697 13698 placeholder = $.fn.placeholder = function(options) { 13699 13700 var defaults = {customClass: 'placeholder'}; 13701 settings = $.extend({}, defaults, options); 13702 13703 return this.filter((isInputSupported ? 'textarea' : ':input') + '[' + (debugMode ? 'placeholder-x' : 'placeholder') + ']') 13704 .not('.'+settings.customClass) 13705 .not(':radio, :checkbox, [type=hidden]') 13706 .bind({
vendor: 5,558 bytes, lines 13707-13872
13707 'focus.placeholder': clearPlaceholder, 13708 'blur.placeholder': setPlaceholder 13709 }) 13710 .data('placeholder-enabled', true) 13711 .trigger('blur.placeholder'); 13712 }; 13713 13714 placeholder.input = isInputSupported; 13715 placeholder.textarea = isTextareaSupported; 13716 13717 hooks = { 13718 'get': function(element) { 13719 13720 var $element = $(element); 13721 var $passwordInput = $element.data('placeholder-password'); 13722 13723 if ($passwordInput) { 13724 return $passwordInput[0].value; 13725 } 13726 13727 return $element.data('placeholder-enabled') && $element.hasClass(settings.customClass) ? '' : element.value; 13728 }, 13729 'set': function(element, value) { 13730 13731 var $element = $(element); 13732 var $replacement; 13733 var $passwordInput; 13734 13735 if (value !== '') { 13736 13737 $replacement = $element.data('placeholder-textinput'); 13738 $passwordInput = $element.data('placeholder-password'); 13739 13740 if ($replacement) { 13741 clearPlaceholder.call($replacement[0], true, value) || (element.value = value); 13742 $replacement[0].value = value; 13743 13744 } else if ($passwordInput) { 13745 clearPlaceholder.call(element, true, value) || ($passwordInput[0].value = value); 13746 element.value = value; 13747 } 13748 } 13749 13750 if (!$element.data('placeholder-enabled')) { 13751 element.value = value; 13752 return $element; 13753 } 13754 13755 if (value === '') { 13756 13757 element.value = value; 13758 13759 // Setting the placeholder causes problems if the element continues to have focus. 13760 if (element != safeActiveElement()) { 13761 // We can't use `triggerHandler` here because of dummy text/password inputs :( 13762 setPlaceholder.call(element); 13763 } 13764 13765 } else { 13766 13767 if ($element.hasClass(settings.customClass)) { 13768 clearPlaceholder.call(element); 13769 } 13770 13771 element.value = value; 13772 } 13773 // `set` can not return `undefined`; see http://jsapi.info/jquery/1.7.1/val#L2363 13774 return $element; 13775 } 13776 }; 13777 13778 if (!isInputSupported) { 13779 valHooks.input = hooks; 13780 propHooks.value = hooks; 13781 } 13782 13783 if (!isTextareaSupported) { 13784 valHooks.textarea = hooks; 13785 propHooks.value = hooks; 13786 } 13787 13788 $(function() { 13789 // Look for forms 13790 $(document).delegate('form', 'submit.placeholder', function() { 13791 13792 // Clear the placeholder values so they don't get submitted 13793 var $inputs = $('.'+settings.customClass, this).each(function() { 13794 clearPlaceholder.call(this, true, ''); 13795 }); 13796 13797 setTimeout(function() { 13798 $inputs.each(setPlaceholder); 13799 }, 10); 13800 }); 13801 }); 13802 13803 // Clear placeholder values upon page reload 13804 $(window).bind('beforeunload.placeholder', function() { 13805 13806 var clearPlaceholders = true; 13807 13808 try { 13809 // Prevent IE javascript:void(0) anchors from causing cleared values 13810 if (document.activeElement.toString() === 'javascript:void(0)') { 13811 clearPlaceholders = false; 13812 } 13813 } catch (exception) { } 13814 13815 if (clearPlaceholders) { 13816 $('.'+settings.customClass).each(function() { 13817 this.value = ''; 13818 }); 13819 } 13820 }); 13821 } 13822 13823 function args(elem) { 13824 // Return an object of element attributes 13825 var newAttrs = {}; 13826 var rinlinejQuery = /^jQuery\d+$/; 13827 13828 $.each(elem.attributes, function(i, attr) { 13829 if (attr.specified && !rinlinejQuery.test(attr.name)) { 13830 newAttrs[attr.name] = attr.value; 13831 } 13832 }); 13833 13834 return newAttrs; 13835 } 13836 13837 function clearPlaceholder(event, value) { 13838 13839 var input = this; 13840 var $input = $(this); 13841 13842 if (input.value === $input.attr((debugMode ? 'placeholder-x' : 'placeholder')) && $input.hasClass(settings.customClass)) { 13843 13844 input.value = ''; 13845 $input.removeClass(settings.customClass); 13846 13847 if ($input.data('placeholder-password')) { 13848 13849 $input = $input.hide().nextAll('input[type="password"]:first').show().attr('id', $input.removeAttr('id').data('placeholder-id')); 13850 13851 // If `clearPlaceholder` was called from `$.valHooks.input.set` 13852 if (event === true) { 13853 $input[0].value = value; 13854 13855 return value; 13856 } 13857 13858 $input.focus(); 13859 13860 } else { 13861 input == safeActiveElement() && input.select(); 13862 } 13863 } 13864 } 13865 13866 function setPlaceholder(event) { 13867 var $replacement; 13868 var input = this; 13869 var $input = $(this); 13870 var id = input.id; 13871 13872 // If the placeholder is activated, triggering blur event (`$input.trigger('blur')`) should do n
13872othing. 13873 if (event && event.type === 'blur' && $input.hasClass(settings.customClass)) { 13874 return; 13875 } 13876 13877 if (input.value === '') { 13878 if (input.type === 'password') { 13879 if (!$input.data('placeholder-textinput')) { 13880 13881 try { 13882 $replacement = $input.clone().prop({ 'type': 'text' }); 13883 } catch(e) { 13884 $replacement = $('<input>').attr($.extend(args(this), { 'type': 'text' })); 13885 } 13886 13887 $replacement 13888 .removeAttr('name') 13889 .data({ 13890 'placeholder-enabled': true, 13891 'placeholder-password': $input, 13892 'placeholder-id': id 13893 }) 13894 .bind('focus.placeholder', clearPlaceholder); 13895 13896 $input 13897 .data({ 13898 'placeholder-textinput': $replacement, 13899 'placeholder-id': id 13900 }) 13901 .before($replacement); 13902 } 13903 13904 input.value = ''; 13905 $input = $input.removeAttr('id').hide().prevAll('input[type="text"]:first').attr('id', $input.data('placeholder-id')).show(); 13906 13907 } else { 13908 13909 var $passwordInput = $input.data('placeholder-password'); 13910 13911 if ($passwordInput) { 13912 $passwordInput[0].value = ''; 13913 $input.attr('id', $input.data('placeholder-id')).show().nextAll('input[type="password"]:last').hide().removeAttr('id'); 13914 } 13915 } 13916 13917 $input.addClass(settings.customClass); 13918 $input[0].value = $input.attr((debugMode ? 'placeholder-x' : 'placeholder')); 13919 13920 } else { 13921 $input.removeClass(settings.customClass); 13922 } 13923 } 13924 13925 function safeActiveElement() { 13926 // Avoid IE9 `document.activeElement` of death 13927 try { 13928 return document.activeElement; 13929 } catch (exception) {} 13930 } 13931})); 13932 13933; 13934/* global window, document, define, jQuery, setInterval, clearInterval */ 13935;(function(factory) { 13936 'use strict'; 13937 if (typeof define === 'function' && define.amd) { 13938 define(['jquery'], factory); 13939 } else if (typeof exports !== 'undefined') { 13940 module.exports = factory(require('jquery')); 13941 } else { 13942 factory(jQuery); 13943 } 13944 13945}(function($) { 13946 'use strict';
vendor: 31,932 bytes, lines 13946-15009
13946 13947 var Slick = window.Slick || {}; 13948 13949 Slick = (function() { 13950 13951 var instanceUid = 0; 13952 13953 function Slick(element, settings) { 13954 13955 var _ = this, dataSettings; 13956 13957 _.defaults = { 13958 accessibility: true, 13959 adaptiveHeight: false, 13960 appendArrows: $(element), 13961 appendDots: $(element), 13962 arrows: true, 13963 asNavFor: null, 13964 prevArrow: '<button class="slick-prev" aria-label="Previous" type="button">Previous</button>', 13965 nextArrow: '<button class="slick-next" aria-label="Next" type="button">Next</button>', 13966 autoplay: false, 13967 autoplaySpeed: 3000, 13968 centerMode: false, 13969 centerPadding: '50px', 13970 cssEase: 'ease', 13971 customPaging: function(slider, i) { 13972 return $('<button type="button" />').text(i + 1); 13973 }, 13974 dots: false, 13975 dotsClass: 'slick-dots', 13976 draggable: true, 13977 easing: 'linear', 13978 edgeFriction: 0.35, 13979 fade: false, 13980 focusOnSelect: false, 13981 focusOnChange: false, 13982 infinite: true, 13983 initialSlide: 0, 13984 lazyLoad: 'ondemand', 13985 mobileFirst: false, 13986 pauseOnHover: true, 13987 pauseOnFocus: true, 13988 pauseOnDotsHover: false, 13989 respondTo: 'window', 13990 responsive: null, 13991 rows: 1, 13992 rtl: false, 13993 slide: '', 13994 slidesPerRow: 1, 13995 slidesToShow: 1, 13996 slidesToScroll: 1, 13997 speed: 500, 13998 swipe: true, 13999 swipeToSlide: false, 14000 touchMove: true, 14001 touchThreshold: 5, 14002 useCSS: true, 14003 useTransform: true, 14004 variableWidth: false, 14005 vertical: false, 14006 verticalSwiping: false, 14007 waitForAnimate: true, 14008 zIndex: 1000 14009 }; 14010 14011 _.initials = { 14012 animating: false, 14013 dragging: false, 14014 autoPlayTimer: null, 14015 currentDirection: 0, 14016 currentLeft: null, 14017 currentSlide: 0, 14018 direction: 1, 14019 $dots: null, 14020 listWidth: null, 14021 listHeight: null, 14022 loadIndex: 0, 14023 $nextArrow: null, 14024 $prevArrow: null, 14025 scrolling: false, 14026 slideCount: null, 14027 slideWidth: null, 14028 $slideTrack: null, 14029 $slides: null, 14030 sliding: false, 14031 slideOffset: 0, 14032 swipeLeft: null, 14033 swiping: false, 14034 $list: null, 14035 touchObject: {}, 14036 transformsEnabled: false, 14037 unslicked: false 14038 }; 14039 14040 $.extend(_, _.initials); 14041 14042 _.activeBreakpoint = null; 14043 _.animType = null; 14044 _.animProp = null; 14045 _.breakpoints = []; 14046 _.breakpointSettings = []; 14047 _.cssTransitions = false; 14048 _.focussed = false; 14049 _.interrupted = false; 14050 _.hidden = 'hidden'; 14051 _.paused = true; 14052 _.positionProp = null; 14053 _.respondTo = null; 14054 _.rowCount = 1; 14055 _.shouldClick = true; 14056 _.$slider = $(element); 14057 _.$slidesCache = null; 14058 _.transformType = null; 14059 _.transitionType = null; 14060 _.visibilityChange = 'visibilitychange'; 14061 _.windowWidth = 0; 14062 _.windowTimer = null; 14063 14064 dataSettings = $(element).data('slick') || {}; 14065 14066 _.options = $.extend({}, _.defaults, settings, dataSettings); 14067 14068 _.currentSlide = _.options.initialSlide; 14069 14070 _.originalSettings = _.options; 14071 14072 if (typeof document.mozHidden !== 'undefined') { 14073 _.hidden = 'mozHidden'; 14074 _.visibilityChange = 'mozvisibilitychange'; 14075 } else if (typeof document.webkitHidden !== 'undefined') { 14076 _.hidden = 'webkitHidden'; 14077 _.visibilityChange = 'webkitvisibilitychange'; 14078 } 14079 14080 _.autoPlay = $.proxy(_.autoPlay, _); 14081 _.autoPlayClear = $.proxy(_.autoPlayClear, _); 14082 _.autoPlayIterator = $.proxy(_.autoPlayIterator, _); 14083 _.changeSlide = $.proxy(_.changeSlide, _); 14084 _.clickHandler = $.proxy(_.clickHandler, _); 14085 _.selectHandler = $.proxy(_.selectHandler, _); 14086 _.setPosition = $.proxy(_.setPosition, _); 14087 _.swipeHandler = $.proxy(_.swipeHandler, _); 14088 _.dragHandler = $.proxy(_.dragHandler, _); 14089 _.keyHandler = $.proxy(_.keyHandler, _); 14090 14091 _.instanceUid = instanceUid++; 14092 14093 // A simple way to check for HTML strings 14094 // Strict HTML recognition (must start with <) 14095 // Extracted from jQuery v1.11 source 14096 _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/; 14097 14098 14099 _.registerBreakpoints(); 14100 _.init(true); 14101 14102 } 14103 14104 return Slick; 14105 14106 }()); 14107 14108 Slick.prototype.activateADA = function() { 14109 var _ = this; 14110 14111 _.$slideTrack.find('.slick-active').attr({ 14112 'aria-hidden': 'false' 14113 }).find('a, input, button, select').attr({ 14114 'tabindex': '0' 14115 }); 14116 14117 }; 14118 14119 Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) { 14120 14121 var _ = this; 14122 14123 if (typeof(index) === 'boolean') { 14124 addBefore = index; 14125 index = null; 14126 } else if (index < 0 || (index >= _.slideCount)) { 14127 return false; 14128 } 14129 14130 _.unload(); 14131 14132 if (typeof(index) === 'number') { 14133 if (index === 0 && _.$slides.length === 0) { 14134 $(markup).appendTo(_.$slideTrack); 14135 } else if (addBefore) { 14136 $(markup).insertBefore(_.$slides.eq(index)); 14137 } else { 14138 $(markup).insertAfter(_.$slides.eq(index)); 14139 } 14140 } else { 14141 if (addBefore === true) { 14142 $(markup).prependTo(_.$slideTrack); 14143 } else { 14144 $(markup).appendTo(_.$slideTrack); 14145 } 14146 } 14147 14148 _.$slides = _.$slideTrack.children(this.options.slide); 14149 14150 _.$slideTrack.children(this.options.slide).detach(); 14151 14152 _.$slideTrack.append(_.$slides); 14153 14154 _.$slides.each(function(index, element) { 14155 $(element).attr('data-slick-index', index); 14156 }); 14157 14158 _.$slidesCache = _.$slides; 14159 14160 _.reinit(); 14161 14162 }; 14163 14164 Slick.prototype.animateHeight = function() { 14165 var _ = this; 14166 if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) { 14167 var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true); 14168 _.$list.animate({ 14169 height: targetHeight 14170 }, _.options.speed); 14171 } 14172 }; 14173 14174 Slick.prototype.animateSlide = function(targetLeft, callback) { 14175 14176 var animProps = {}, 14177 _ = this; 14178 14179 _.animateHeight(); 14180 14181 if (_.options.rtl === true && _.options.vertical === false) { 14182 targetLeft = -targetLeft; 14183 } 14184 if (_.transformsEnabled === false) { 14185 if (_.options.vertical === false) { 14186 _.$slideTrack.animate({ 14187 left: targetLeft 14188 }, _.options.speed, _.options.easing, callback); 14189 } else { 14190 _.$slideTrack.animate({ 14191 top: targetLeft 14192 }, _.options.speed, _.options.easing, callback); 14193 } 14194 14195 } else { 14196 14197 if (_.cssTransitions === false) { 14198 if (_.options.rtl === true) { 14199 _.currentLeft = -(_.currentLeft); 14200 } 14201 $({ 14202 animStart: _.currentLeft 14203 }).animate({ 14204 animStart: targetLeft 14205 }, { 14206 duration: _.options.speed, 14207 easing: _.options.easing, 14208 step: function(now) { 14209 now = Math.ceil(now); 14210 if (_.options.vertical === false) { 14211 animProps[_.animType] = 'translate(' + 14212 now + 'px, 0px)'; 14213 _.$slideTrack.css(animProps); 14214 } else { 14215 animProps[_.animType] = 'translate(0px,' + 14216 now + 'px)'; 14217 _.$slideTrack.css(animProps); 14218 } 14219 }, 14220 complete: function() { 14221 if (callback) { 14222 callback.call(); 14223 } 14224 } 14225 }); 14226 14227 } else { 14228 14229 _.applyTransition(); 14230 targetLeft = Math.ceil(targetLeft); 14231 14232 if (_.options.vertical === false) { 14233 animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)'; 14234 } else { 14235 animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)'; 14236 } 14237 _.$slideTrack.css(animProps); 14238 14239 if (callback) { 14240 setTimeout(function() { 14241 14242 _.disableTransition(); 14243 14244 callback.call(); 14245 }, _.options.speed); 14246 } 14247 14248 } 14249 14250 } 14251 14252 }; 14253 14254 Slick.prototype.getNavTarget = function() { 14255 14256 var _ = this, 14257 asNavFor = _.options.asNavFor; 14258 14259 if ( asNavFor && asNavFor !== null ) { 14260 asNavFor = $(asNavFor).not(_.$slider); 14261 } 14262 14263 return asNavFor; 14264 14265 }; 14266 14267 Slick.prototype.asNavFor = function(index) { 14268 14269 var _ = this, 14270 asNavFor = _.getNavTarget(); 14271 14272 if ( asNavFor !== null && typeof asNavFor === 'object' ) { 14273 asNavFor.each(function() { 14274 var target = $(this).slick('getSlick'); 14275 if(!target.unslicked) { 14276 target.slideHandler(index, true); 14277 } 14278 }); 14279 } 14280 14281 }; 14282 14283 Slick.prototype.applyTransition = function(slide) { 14284 14285 var _ = this, 14286 transition = {}; 14287 14288 if (_.options.fade === false) { 14289 transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase; 14290 } else { 14291 transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase; 14292 } 14293 14294 if (_.options.fade === false) { 14295 _.$slideTrack.css(transition); 14296 } else { 14297 _.$slides.eq(slide).css(transition); 14298 } 14299 14300 }; 14301 14302 Slick.prototype.autoPlay = function() { 14303 14304 var _ = this; 14305 14306 _.autoPlayClear(); 14307 14308 if ( _.slideCount > _.options.slidesToShow ) { 14309 _.autoPlayTimer = setInterval( _.autoPlayIterator, _.options.autoplaySpeed ); 14310 } 14311 14312 }; 14313 14314 Slick.prototype.autoPlayClear = function() { 14315 14316 var _ = this; 14317 14318 if (_.autoPlayTimer) { 14319 clearInterval(_.autoPlayTimer); 14320 } 14321 14322 }; 14323 14324 Slick.prototype.autoPlayIterator = function() { 14325 14326 var _ = this, 14327 slideTo = _.currentSlide + _.options.slidesToScroll; 14328 14329 if ( !_.paused && !_.interrupted && !_.focussed ) { 14330 14331 if ( _.options.infinite === false ) { 14332 14333 if ( _.direction === 1 && ( _.currentSlide + 1 ) === ( _.slideCount - 1 )) { 14334 _.direction = 0; 14335 } 14336 14337 else if ( _.direction === 0 ) { 14338 14339 slideTo = _.currentSlide - _.options.slidesToScroll; 14340 14341 if ( _.currentSlide - 1 === 0 ) { 14342 _.direction = 1; 14343 } 14344 14345 } 14346 14347 } 14348 14349 _.slideHandler( slideTo ); 14350 14351 } 14352 14353 }; 14354 14355 Slick.prototype.buildArrows = function() { 14356 14357 var _ = this; 14358 14359 if (_.options.arrows === true ) { 14360 14361 _.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow'); 14362 _.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow'); 14363 14364 if( _.slideCount > _.options.slidesToShow ) { 14365 14366 _.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex'); 14367 _.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex'); 14368 14369 if (_.htmlExpr.test(_.options.prevArrow)) { 14370 _.$prevArrow.prependTo(_.options.appendArrows); 14371 } 14372 14373 if (_.htmlExpr.test(_.options.nextArrow)) { 14374 _.$nextArrow.appendTo(_.options.appendArrows); 14375 } 14376 14377 if (_.options.infinite !== true) { 14378 _.$prevArrow 14379 .addClass('slick-disabled') 14380 .attr('aria-disabled', 'true'); 14381 } 14382 14383 } else { 14384 14385 _.$prevArrow.add( _.$nextArrow ) 14386 14387 .addClass('slick-hidden') 14388 .attr({ 14389 'aria-disabled': 'true', 14390 'tabindex': '-1' 14391 }); 14392 14393 } 14394 14395 } 14396 14397 }; 14398 14399 Slick.prototype.buildDots = function() { 14400 14401 var _ = this, 14402 i, dot; 14403 14404 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 14405 14406 _.$slider.addClass('slick-dotted'); 14407 14408 dot = $('<ul />').addClass(_.options.dotsClass); 14409 14410 for (i = 0; i <= _.getDotCount(); i += 1) { 14411 dot.append($('<li />').append(_.options.customPaging.call(this, _, i))); 14412 } 14413 14414 _.$dots = dot.appendTo(_.options.appendDots); 14415 14416 _.$dots.find('li').first().addClass('slick-active'); 14417 14418 } 14419 14420 }; 14421 14422 Slick.prototype.buildOut = function() { 14423 14424 var _ = this; 14425 14426 _.$slides = 14427 _.$slider 14428 .children( _.options.slide + ':not(.slick-cloned)') 14429 .addClass('slick-slide'); 14430 14431 _.slideCount = _.$slides.length; 14432 14433 _.$slides.each(function(index, element) { 14434 $(element) 14435 .attr('data-slick-index', index) 14436 .data('originalStyling', $(element).attr('style') || ''); 14437 }); 14438 14439 _.$slider.addClass('slick-slider'); 14440 14441 _.$slideTrack = (_.slideCount === 0) ? 14442 $('<div class="slick-track"/>').appendTo(_.$slider) : 14443 _.$slides.wrapAll('<div class="slick-track"/>').parent(); 14444 14445 _.$list = _.$slideTrack.wrap( 14446 '<div class="slick-list"/>').parent(); 14447 _.$slideTrack.css('opacity', 0); 14448 14449 if (_.options.centerMode === true || _.options.swipeToSlide === true) { 14450 _.options.slidesToScroll = 1; 14451 } 14452 14453 $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading'); 14454 14455 _.setupInfinite(); 14456 14457 _.buildArrows(); 14458 14459 _.buildDots(); 14460 14461 _.updateDots(); 14462 14463 14464 _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0); 14465 14466 if (_.options.draggable === true) { 14467 _.$list.addClass('draggable'); 14468 } 14469 14470 }; 14471 14472 Slick.prototype.buildRows = function() { 14473 14474 var _ = this, a, b, c, newSlides, numOfSlides, originalSlides,slidesPerSection; 14475 14476 newSlides = document.createDocumentFragment(); 14477 originalSlides = _.$slider.children(); 14478 14479 if(_.options.rows > 0) { 14480 14481 slidesPerSection = _.options.slidesPerRow * _.options.rows; 14482 numOfSlides = Math.ceil( 14483 originalSlides.length / slidesPerSection 14484 ); 14485 14486 for(a = 0; a < numOfSlides; a++){ 14487 var slide = document.createElement('div'); 14488 for(b = 0; b < _.options.rows; b++) { 14489 var row = document.createElement('div'); 14490 for(c = 0; c < _.options.slidesPerRow; c++) { 14491 var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c)); 14492 if (originalSlides.get(target)) { 14493 row.appendChild(originalSlides.get(target)); 14494 } 14495 } 14496 slide.appendChild(row); 14497 } 14498 newSlides.appendChild(slide); 14499 } 14500 14501 _.$slider.empty().append(newSlides); 14502 _.$slider.children().children().children() 14503 .css({ 14504 'width':(100 / _.options.slidesPerRow) + '%', 14505 'display': 'inline-block' 14506 }); 14507 14508 } 14509 14510 }; 14511 14512 Slick.prototype.checkResponsive = function(initial, forceUpdate) { 14513 14514 var _ = this, 14515 breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false; 14516 var sliderWidth = _.$slider.width(); 14517 var windowWidth = window.innerWidth || $(window).width(); 14518 14519 if (_.respondTo === 'window') { 14520 respondToWidth = windowWidth; 14521 } else if (_.respondTo === 'slider') { 14522 respondToWidth = sliderWidth; 14523 } else if (_.respondTo === 'min') { 14524 respondToWidth = Math.min(windowWidth, sliderWidth); 14525 } 14526 14527 if ( _.options.responsive && 14528 _.options.responsive.length && 14529 _.options.responsive !== null) { 14530 14531 targetBreakpoint = null; 14532 14533 for (breakpoint in _.breakpoints) { 14534 if (_.breakpoints.hasOwnProperty(breakpoint)) { 14535 if (_.originalSettings.mobileFirst === false) { 14536 if (respondToWidth < _.breakpoints[breakpoint]) { 14537 targetBreakpoint = _.breakpoints[breakpoint]; 14538 } 14539 } else { 14540 if (respondToWidth > _.breakpoints[breakpoint]) { 14541 targetBreakpoint = _.breakpoints[breakpoint]; 14542 } 14543 } 14544 } 14545 } 14546 14547 if (targetBreakpoint !== null) { 14548 if (_.activeBreakpoint !== null) { 14549 if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) { 14550 _.activeBreakpoint = 14551 targetBreakpoint; 14552 if (_.breakpointSettings[targetBreakpoint] === 'unslick') { 14553 _.unslick(targetBreakpoint); 14554 } else { 14555 _.options = $.extend({}, _.originalSettings, 14556 _.breakpointSettings[ 14557 targetBreakpoint]); 14558 if (initial === true) { 14559 _.currentSlide = _.options.initialSlide; 14560 } 14561 _.refresh(initial); 14562 } 14563 triggerBreakpoint = targetBreakpoint; 14564 } 14565 } else { 14566 _.activeBreakpoint = targetBreakpoint; 14567 if (_.breakpointSettings[targetBreakpoint] === 'unslick') { 14568 _.unslick(targetBreakpoint); 14569 } else { 14570 _.options = $.extend({}, _.originalSettings, 14571 _.breakpointSettings[ 14572 targetBreakpoint]); 14573 if (initial === true) { 14574 _.currentSlide = _.options.initialSlide; 14575 } 14576 _.refresh(initial); 14577 } 14578 triggerBreakpoint = targetBreakpoint; 14579 } 14580 } else { 14581 if (_.activeBreakpoint !== null) { 14582 _.activeBreakpoint = null; 14583 _.options = _.originalSettings; 14584 if (initial === true) { 14585 _.currentSlide = _.options.initialSlide; 14586 } 14587 _.refresh(initial); 14588 triggerBreakpoint = targetBreakpoint; 14589 } 14590 } 14591 14592 // only trigger breakpoints during an actual break. not on initialize. 14593 if( !initial && triggerBreakpoint !== false ) { 14594 _.$slider.trigger('breakpoint', [_, triggerBreakpoint]); 14595 } 14596 } 14597 14598 }; 14599 14600 Slick.prototype.changeSlide = function(event, dontAnimate) { 14601 14602 var _ = this, 14603 $target = $(event.currentTarget), 14604 indexOffset, slideOffset, unevenOffset; 14605 14606 // If target is a link, prevent default action. 14607 if($target.is('a')) { 14608 event.preventDefault(); 14609 } 14610 14611 // If target is not the <li> element (ie: a child), find the <li>. 14612 if(!$target.is('li')) { 14613 $target = $target.closest('li'); 14614 } 14615 14616 unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0); 14617 indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll; 14618 14619 switch (event.data.message) { 14620 14621 case 'previous': 14622 slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset; 14623 if (_.slideCount > _.options.slidesToShow) { 14624 _.slideHandler(_.currentSlide - slideOffset, false, dontAnimate); 14625 } 14626 break; 14627 14628 case 'next': 14629 slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset; 14630 if (_.slideCount > _.options.slidesToShow) { 14631 _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate); 14632 } 14633 break; 14634 14635 case 'index': 14636 var index = event.data.index === 0 ? 0 : 14637 event.data.index || $target.index() * _.options.slidesToScroll; 14638 14639 _.slideHandler(_.checkNavigable(index), false, dontAnimate); 14640 $target.children().trigger('focus'); 14641 break; 14642 14643 default: 14644 return; 14645 } 14646 14647 }; 14648 14649 Slick.prototype.checkNavigable = function(index) { 14650 14651 var _ = this, 14652 navigables, prevNavigable; 14653 14654 navigables = _.getNavigableIndexes(); 14655 prevNavigable = 0; 14656 if (index > navigables[navigables.length - 1]) { 14657 index = navigables[navigables.length - 1]; 14658 } else { 14659 for (var n in navigables) { 14660 if (index < navigables[n]) { 14661 index = prevNavigable; 14662 break; 14663 } 14664 prevNavigable = navigables[n]; 14665 } 14666 } 14667 14668 return index; 14669 }; 14670 14671 Slick.prototype.cleanUpEvents = function() { 14672 14673 var _ = this; 14674 14675 if (_.options.dots && _.$dots !== null) { 14676 14677 $('li', _.$dots) 14678 .off('click.slick', _.changeSlide) 14679 .off('mouseenter.slick', $.proxy(_.interrupt, _, true)) 14680 .off('mouseleave.slick', $.proxy(_.interrupt, _, false)); 14681 14682 if (_.options.accessibility === true) { 14683 _.$dots.off('keydown.slick', _.keyHandler); 14684 } 14685 } 14686 14687 _.$slider.off('focus.slick blur.slick'); 14688 14689 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 14690 _.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide); 14691 _.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide); 14692 14693 if (_.options.accessibility === true) { 14694 _.$prevArrow && _.$prevArrow.off('keydown.slick', _.keyHandler); 14695 _.$nextArrow && _.$nextArrow.off('keydown.slick', _.keyHandler); 14696 } 14697 } 14698 14699 _.$list.off('touchstart.slick mousedown.slick', _.swipeHandler); 14700 _.$list.off('touchmove.slick mousemove.slick', _.swipeHandler); 14701 _.$list.off('touchend.slick mouseup.slick', _.swipeHandler); 14702 _.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler); 14703 14704 _.$list.off('click.slick', _.clickHandler); 14705 14706 $(document).off(_.visibilityChange, _.visibility); 14707 14708 _.cleanUpSlideEvents(); 14709 14710 if (_.options.accessibility === true) { 14711 _.$list.off('keydown.slick', _.keyHandler); 14712 } 14713 14714 if (_.options.focusOnSelect === true) { 14715 $(_.$slideTrack).children().off('click.slick', _.selectHandler); 14716 } 14717 14718 $(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange); 14719 14720 $(window).off('resize.slick.slick-' + _.instanceUid, _.resize); 14721 14722 $('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault); 14723 14724 $(window).off('load.slick.slick-' + _.instanceUid, _.setPosition); 14725 14726 }; 14727 14728 Slick.prototype.cleanUpSlideEvents = function() { 14729 14730 var _ = this; 14731 14732 _.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true)); 14733 _.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false)); 14734 14735 }; 14736 14737 Slick.prototype.cleanUpRows = function() { 14738 14739 var _ = this, originalSlides; 14740 14741 if(_.options.rows > 0) { 14742 originalSlides = _.$slides.children().children(); 14743 originalSlides.removeAttr('style'); 14744 _.$slider.empty().append(originalSlides); 14745 } 14746 14747 }; 14748 14749 Slick.prototype.clickHandler = function(event) { 14750 14751 var _ = this; 14752 14753 if (_.shouldClick === false) { 14754 event.stopImmediatePropagation(); 14755 event.stopPropagation(); 14756 event.preventDefault(); 14757 } 14758 14759 }; 14760 14761 Slick.prototype.destroy = function(refresh) { 14762 14763 var _ = this; 14764 14765 _.autoPlayClear(); 14766 14767 _.touchObject = {}; 14768 14769 _.cleanUpEvents(); 14770 14771 $('.slick-cloned', _.$slider).detach(); 14772 14773 if (_.$dots) { 14774 _.$dots.remove(); 14775 } 14776 14777 if ( _.$prevArrow && _.$prevArrow.length ) { 14778 14779 _.$prevArrow 14780 .removeClass('slick-disabled slick-arrow slick-hidden') 14781 .removeAttr('aria-hidden aria-disabled tabindex') 14782 .css('display',''); 14783 14784 if ( _.htmlExpr.test( _.options.prevArrow )) { 14785 _.$prevArrow.remove(); 14786 } 14787 } 14788 14789 if ( _.$nextArrow && _.$nextArrow.length ) { 14790 14791 _.$nextArrow 14792 .removeClass('slick-disabled slick-arrow slick-hidden') 14793 .removeAttr('aria-hidden aria-disabled tabindex') 14794 .css('display',''); 14795 14796 if ( _.htmlExpr.test( _.options.nextArrow )) { 14797 _.$nextArrow.remove(); 14798 } 14799 } 14800 14801 14802 if (_.$slides) { 14803 14804 _.$slides 14805 .removeClass('slick-slide slick-active slick-center slick-visible slick-current') 14806 .removeAttr('aria-hidden') 14807 .removeAttr('data-slick-index') 14808 .each(function(){ 14809 $(this).attr('style', $(this).data('originalStyling')); 14810 }); 14811 14812 _.$slideTrack.children(this.options.slide).detach(); 14813 14814 _.$slideTrack.detach(); 14815 14816 _.$list.detach(); 14817 14818 _.$slider.append(_.$slides); 14819 } 14820 14821 _.cleanUpRows(); 14822 14823 _.$slider.removeClass('slick-slider'); 14824 _.$slider.removeClass('slick-initialized'); 14825 _.$slider.removeClass('slick-dotted'); 14826 14827 _.unslicked = true; 14828 14829 if(!refresh) { 14830 _.$slider.trigger('destroy', [_]); 14831 } 14832 14833 }; 14834 14835 Slick.prototype.disableTransition = function(slide) { 14836 14837 var _ = this, 14838 transition = {}; 14839 14840 transition[_.transitionType] = ''; 14841 14842 if (_.options.fade === false) { 14843 _.$slideTrack.css(transition); 14844 } else { 14845 _.$slides.eq(slide).css(transition); 14846 } 14847 14848 }; 14849 14850 Slick.prototype.fadeSlide = function(slideIndex, callback) { 14851 14852 var _ = this; 14853 14854 if (_.cssTransitions === false) { 14855 14856 _.$slides.eq(slideIndex).css({ 14857 zIndex: _.options.zIndex 14858 }); 14859 14860 _.$slides.eq(slideIndex).animate({ 14861 opacity: 1 14862 }, _.options.speed, _.options.easing, callback); 14863 14864 } else { 14865 14866 _.applyTransition(slideIndex); 14867 14868 _.$slides.eq(slideIndex).css({ 14869 opacity: 1, 14870 zIndex: _.options.zIndex 14871 }); 14872 14873 if (callback) { 14874 setTimeout(function() { 14875 14876 _.disableTransition(slideIndex); 14877 14878 callback.call(); 14879 }, _.options.speed); 14880 } 14881 14882 } 14883 14884 }; 14885 14886 Slick.prototype.fadeSlideOut = function(slideIndex) { 14887 14888 var _ = this; 14889 14890 if (_.cssTransitions === false) { 14891 14892 _.$slides.eq(slideIndex).animate({ 14893 opacity: 0, 14894 zIndex: _.options.zIndex - 2 14895 }, _.options.speed, _.options.easing); 14896 14897 } else { 14898 14899 _.applyTransition(slideIndex); 14900 14901 _.$slides.eq(slideIndex).css({ 14902 opacity: 0, 14903 zIndex: _.options.zIndex - 2 14904 }); 14905 14906 } 14907 14908 }; 14909 14910 Slick.prototype.filterSlides = Slick.prototype.slickFilter = function(filter) { 14911 14912 var _ = this; 14913 14914 if (filter !== null) { 14915 14916 _.$slidesCache = _.$slides; 14917 14918 _.unload(); 14919 14920 _.$slideTrack.children(this.options.slide).detach(); 14921 14922 _.$slidesCache.filter(filter).appendTo(_.$slideTrack); 14923 14924 _.reinit(); 14925 14926 } 14927 14928 }; 14929 14930 Slick.prototype.focusHandler = function() { 14931 14932 var _ = this; 14933 14934 _.$slider 14935 .off('focus.slick blur.slick') 14936 .on('focus.slick blur.slick', '*', function(event) { 14937 14938 event.stopImmediatePropagation(); 14939 var $sf = $(this); 14940 14941 setTimeout(function() { 14942 14943 if( _.options.pauseOnFocus ) { 14944 _.focussed = $sf.is(':focus'); 14945 _.autoPlay(); 14946 } 14947 14948 }, 0); 14949 14950 }); 14951 }; 14952 14953 Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function() { 14954 14955 var _ = this; 14956 return _.currentSlide; 14957 14958 }; 14959 14960 Slick.prototype.getDotCount = function() { 14961 14962 var _ = this; 14963 14964 var breakPoint = 0; 14965 var counter = 0; 14966 var pagerQty = 0; 14967 14968 if (_.options.infinite === true) { 14969 if (_.slideCount <= _.options.slidesToShow) { 14970 ++pagerQty; 14971 } else { 14972 while (breakPoint < _.slideCount) { 14973 ++pagerQty; 14974 breakPoint = counter + _.options.slidesToScroll; 14975 counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow; 14976 } 14977 } 14978 } else if (_.options.centerMode === true) { 14979 pagerQty = _.slideCount; 14980 } else if(!_.options.asNavFor) { 14981 pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll); 14982 }else { 14983 while (breakPoint < _.slideCount) { 14984 ++pagerQty; 14985 breakPoint = counter + _.options.slidesToScroll; 14986 counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow; 14987 } 14988 } 14989 14990 return pagerQty - 1; 14991 14992 }; 14993 14994 Slick.prototype.getLeft = function(slideIndex) { 14995 14996 var _ = this, 14997 targetLeft, 14998 verticalHeight, 14999 verticalOffset = 0, 15000 targetSlide, 15001 coef; 15002 15003 _.slideOffset = 0; 15004 verticalHeight = _.$slides.first().outerHeight(true); 15005 15006 if (_.options.infinite === true) { 15007 if (_.slideCount > _.options.slidesToShow) { 15008 _.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1; 15009 coef = -1
15009 15010 15011 if (_.options.vertical === true && _.options.centerMode === true) { 15012 if (_.options.slidesToShow === 2) { 15013 coef = -1.5; 15014 } else if (_.options.slidesToShow === 1) { 15015 coef = -2
vendor: 47,517 bytes, lines 15015-16618
15015 15016 } 15017 } 15018 verticalOffset = (verticalHeight * _.options.slidesToShow) * coef; 15019 } 15020 if (_.slideCount % _.options.slidesToScroll !== 0) { 15021 if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) { 15022 if (slideIndex > _.slideCount) { 15023 _.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1; 15024 verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1; 15025 } else { 15026 _.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1; 15027 verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1; 15028 } 15029 } 15030 } 15031 } else { 15032 if (slideIndex + _.options.slidesToShow > _.slideCount) { 15033 _.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth; 15034 verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight; 15035 } 15036 } 15037 15038 if (_.slideCount <= _.options.slidesToShow) { 15039 _.slideOffset = 0; 15040 verticalOffset = 0; 15041 } 15042 15043 if (_.options.centerMode === true && _.slideCount <= _.options.slidesToShow) { 15044 _.slideOffset = ((_.slideWidth * Math.floor(_.options.slidesToShow)) / 2) - ((_.slideWidth * _.slideCount) / 2); 15045 } else if (_.options.centerMode === true && _.options.infinite === true) { 15046 _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth; 15047 } else if (_.options.centerMode === true) { 15048 _.slideOffset = 0; 15049 _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2); 15050 } 15051 15052 if (_.options.vertical === false) { 15053 targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset; 15054 } else { 15055 targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset; 15056 } 15057 15058 if (_.options.variableWidth === true) { 15059 15060 if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) { 15061 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex); 15062 } else { 15063 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow); 15064 } 15065 15066 if (_.options.rtl === true) { 15067 if (targetSlide[0]) { 15068 targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1; 15069 } else { 15070 targetLeft = 0; 15071 } 15072 } else { 15073 targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0; 15074 } 15075 15076 if (_.options.centerMode === true) { 15077 if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) { 15078 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex); 15079 } else { 15080 targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1); 15081 } 15082 15083 if (_.options.rtl === true) { 15084 if (targetSlide[0]) { 15085 targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1; 15086 } else { 15087 targetLeft = 0; 15088 } 15089 } else { 15090 targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0; 15091 } 15092 15093 targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2; 15094 } 15095 } 15096 15097 return targetLeft; 15098 15099 }; 15100 15101 Slick.prototype.getOption = Slick.prototype.slickGetOption = function(option) { 15102 15103 var _ = this; 15104 15105 return _.options[option]; 15106 15107 }; 15108 15109 Slick.prototype.getNavigableIndexes = function() { 15110 15111 var _ = this, 15112 breakPoint = 0, 15113 counter = 0, 15114 indexes = [], 15115 max; 15116 15117 if (_.options.infinite === false) { 15118 max = _.slideCount; 15119 } else { 15120 breakPoint = _.options.slidesToScroll * -1; 15121 counter = _.options.slidesToScroll * -1; 15122 max = _.slideCount * 2; 15123 } 15124 15125 while (breakPoint < max) { 15126 indexes.push(breakPoint); 15127 breakPoint = counter + _.options.slidesToScroll; 15128 counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow; 15129 } 15130 15131 return indexes; 15132 15133 }; 15134 15135 Slick.prototype.getSlick = function() { 15136 15137 return this; 15138 15139 }; 15140 15141 Slick.prototype.getSlideCount = function() { 15142 15143 var _ = this, 15144 slidesTraversed, swipedSlide, centerOffset; 15145 15146 centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0; 15147 15148 if (_.options.swipeToSlide === true) { 15149 _.$slideTrack.find('.slick-slide').each(function(index, slide) { 15150 if (slide.offsetLeft - centerOffset + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) { 15151 swipedSlide = slide; 15152 return false; 15153 } 15154 }); 15155 15156 slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1; 15157 15158 return slidesTraversed; 15159 15160 } else { 15161 return _.options.slidesToScroll; 15162 } 15163 15164 }; 15165 15166 Slick.prototype.goTo = Slick.prototype.slickGoTo = function(slide, dontAnimate) { 15167 15168 var _ = this; 15169 15170 _.changeSlide({ 15171 data: { 15172 message: 'index', 15173 index: parseInt(slide) 15174 } 15175 }, dontAnimate); 15176 15177 }; 15178 15179 Slick.prototype.init = function(creation) { 15180 15181 var _ = this; 15182 15183 if (!$(_.$slider).hasClass('slick-initialized')) { 15184 15185 $(_.$slider).addClass('slick-initialized'); 15186 15187 _.buildRows(); 15188 _.buildOut(); 15189 _.setProps(); 15190 _.startLoad(); 15191 _.loadSlider(); 15192 _.initializeEvents(); 15193 _.updateArrows(); 15194 _.updateDots(); 15195 _.checkResponsive(true); 15196 _.focusHandler(); 15197 15198 } 15199 15200 if (creation) { 15201 _.$slider.trigger('init', [_]); 15202 } 15203 15204 if (_.options.accessibility === true) { 15205 _.initADA(); 15206 } 15207 15208 if ( _.options.autoplay ) { 15209 15210 _.paused = false; 15211 _.autoPlay(); 15212 15213 } 15214 15215 }; 15216 15217 Slick.prototype.initADA = function() { 15218 var _ = this, 15219 numDotGroups = Math.ceil(_.slideCount / _.options.slidesToShow), 15220 tabControlIndexes = _.getNavigableIndexes().filter(function(val) { 15221 return (val >= 0) && (val < _.slideCount); 15222 }); 15223 15224 _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({ 15225 'aria-hidden': 'true', 15226 'tabindex': '-1' 15227 }).find('a, input, button, select').attr({ 15228 'tabindex': '-1' 15229 }); 15230 15231 if (_.$dots !== null) { 15232 _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) { 15233 var slideControlIndex = tabControlIndexes.indexOf(i); 15234 15235 $(this).attr({ 15236 'role': 'tabpanel', 15237 'id': 'slick-slide' + _.instanceUid + i, 15238 'tabindex': -1 15239 }); 15240 15241 if (slideControlIndex !== -1) { 15242 var ariaButtonControl = 'slick-slide-control' + _.instanceUid + slideControlIndex 15243 if ($('#' + ariaButtonControl).length) { 15244 $(this).attr({ 15245 'aria-describedby': ariaButtonControl 15246 }); 15247 } 15248 } 15249 }); 15250 15251 _.$dots.attr('role', 'tablist').find('li').each(function(i) { 15252 var mappedSlideIndex = tabControlIndexes[i]; 15253 15254 $(this).attr({ 15255 'role': 'presentation' 15256 }); 15257 15258 $(this).find('button').first().attr({ 15259 'role': 'tab', 15260 'id': 'slick-slide-control' + _.instanceUid + i, 15261 'aria-controls': 'slick-slide' + _.instanceUid + mappedSlideIndex, 15262 'aria-label': (i + 1) + ' of ' + numDotGroups, 15263 'aria-selected': null, 15264 'tabindex': '-1' 15265 }); 15266 15267 }).eq(_.currentSlide).find('button').attr({ 15268 'aria-selected': 'true', 15269 'tabindex': '0' 15270 }).end(); 15271 } 15272 15273 for (var i=_.currentSlide, max=i+_.options.slidesToShow; i < max; i++) { 15274 if (_.options.focusOnChange) { 15275 _.$slides.eq(i).attr({'tabindex': '0'}); 15276 } else { 15277 _.$slides.eq(i).removeAttr('tabindex'); 15278 } 15279 } 15280 15281 _.activateADA(); 15282 15283 }; 15284 15285 Slick.prototype.initArrowEvents = function() { 15286 15287 var _ = this; 15288 15289 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 15290 _.$prevArrow 15291 .off('click.slick') 15292 .on('click.slick', { 15293 message: 'previous' 15294 }, _.changeSlide); 15295 _.$nextArrow 15296 .off('click.slick') 15297 .on('click.slick', { 15298 message: 'next' 15299 }, _.changeSlide); 15300 15301 if (_.options.accessibility === true) { 15302 _.$prevArrow.on('keydown.slick', _.keyHandler); 15303 _.$nextArrow.on('keydown.slick', _.keyHandler); 15304 } 15305 } 15306 15307 }; 15308 15309 Slick.prototype.initDotEvents = function() { 15310 15311 var _ = this; 15312 15313 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 15314 $('li', _.$dots).on('click.slick', { 15315 message: 'index' 15316 }, _.changeSlide); 15317 15318 if (_.options.accessibility === true) { 15319 _.$dots.on('keydown.slick', _.keyHandler); 15320 } 15321 } 15322 15323 if (_.options.dots === true && _.options.pauseOnDotsHover === true && _.slideCount > _.options.slidesToShow) { 15324 15325 $('li', _.$dots) 15326 .on('mouseenter.slick', $.proxy(_.interrupt, _, true)) 15327 .on('mouseleave.slick', $.proxy(_.interrupt, _, false)); 15328 15329 } 15330 15331 }; 15332 15333 Slick.prototype.initSlideEvents = function() { 15334 15335 var _ = this; 15336 15337 if ( _.options.pauseOnHover ) { 15338 15339 _.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true)); 15340 _.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false)); 15341 15342 } 15343 15344 }; 15345 15346 Slick.prototype.initializeEvents = function() { 15347 15348 var _ = this; 15349 15350 _.initArrowEvents(); 15351 15352 _.initDotEvents(); 15353 _.initSlideEvents(); 15354 15355 _.$list.on('touchstart.slick mousedown.slick', { 15356 action: 'start' 15357 }, _.swipeHandler); 15358 _.$list.on('touchmove.slick mousemove.slick', { 15359 action: 'move' 15360 }, _.swipeHandler); 15361 _.$list.on('touchend.slick mouseup.slick', { 15362 action: 'end' 15363 }, _.swipeHandler); 15364 _.$list.on('touchcancel.slick mouseleave.slick', { 15365 action: 'end' 15366 }, _.swipeHandler); 15367 15368 _.$list.on('click.slick', _.clickHandler); 15369 15370 $(document).on(_.visibilityChange, $.proxy(_.visibility, _)); 15371 15372 if (_.options.accessibility === true) { 15373 _.$list.on('keydown.slick', _.keyHandler); 15374 } 15375 15376 if (_.options.focusOnSelect === true) { 15377 $(_.$slideTrack).children().on('click.slick', _.selectHandler); 15378 } 15379 15380 $(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _)); 15381 15382 $(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _)); 15383 15384 $('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault); 15385 15386 $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition); 15387 $(_.setPosition); 15388 15389 }; 15390 15391 Slick.prototype.initUI = function() { 15392 15393 var _ = this; 15394 15395 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 15396 15397 _.$prevArrow.show(); 15398 _.$nextArrow.show(); 15399 15400 } 15401 15402 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 15403 15404 _.$dots.show(); 15405 15406 } 15407 15408 }; 15409 15410 Slick.prototype.keyHandler = function(event) { 15411 15412 var _ = this; 15413 //Dont slide if the cursor is inside the form fields and arrow keys are pressed 15414 if(!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) { 15415 if (event.keyCode === 37 && _.options.accessibility === true) { 15416 _.changeSlide({ 15417 data: { 15418 message: _.options.rtl === true ? 'next' : 'previous' 15419 } 15420 }); 15421 } else if (event.keyCode === 39 && _.options.accessibility === true) { 15422 _.changeSlide({ 15423 data: { 15424 message: _.options.rtl === true ? 'previous' : 'next' 15425 } 15426 }); 15427 } 15428 } 15429 15430 }; 15431 15432 Slick.prototype.lazyLoad = function() { 15433 15434 var _ = this, 15435 loadRange, cloneRange, rangeStart, rangeEnd; 15436 15437 function loadImages(imagesScope) { 15438 15439 $('img[data-lazy]', imagesScope).each(function() { 15440 15441 var image = $(this), 15442 imageSource = $(this).attr('data-lazy'), 15443 imageSrcSet = $(this).attr('data-srcset'), 15444 imageSizes = $(this).attr('data-sizes') || _.$slider.attr('data-sizes'), 15445 imageToLoad = document.createElement('img'); 15446 15447 imageToLoad.onload = function() { 15448 15449 image 15450 .animate({ opacity: 0 }, 100, function() { 15451 15452 if (imageSrcSet) { 15453 image 15454 .attr('srcset', imageSrcSet ); 15455 15456 if (imageSizes) { 15457 image 15458 .attr('sizes', imageSizes ); 15459 } 15460 } 15461 15462 image 15463 .attr('src', imageSource) 15464 .animate({ opacity: 1 }, 200, function() { 15465 image 15466 .removeAttr('data-lazy data-srcset data-sizes') 15467 .removeClass('slick-loading'); 15468 }); 15469 _.$slider.trigger('lazyLoaded', [_, image, imageSource]); 15470 }); 15471 15472 }; 15473 15474 imageToLoad.onerror = function() { 15475 15476 image 15477 .removeAttr( 'data-lazy' ) 15478 .removeClass( 'slick-loading' ) 15479 .addClass( 'slick-lazyload-error' ); 15480 15481 _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]); 15482 15483 }; 15484 15485 imageToLoad.src = imageSource; 15486 15487 }); 15488 15489 } 15490 15491 if (_.options.centerMode === true) { 15492 if (_.options.infinite === true) { 15493 rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1); 15494 rangeEnd = rangeStart + _.options.slidesToShow + 2; 15495 } else { 15496 rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1)); 15497 rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide; 15498 } 15499 } else { 15500 rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide; 15501 rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow); 15502 if (_.options.fade === true) { 15503 if (rangeStart > 0) rangeStart--; 15504 if (rangeEnd <= _.slideCount) rangeEnd++; 15505 } 15506 } 15507 15508 loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd); 15509 15510 if (_.options.lazyLoad === 'anticipated') { 15511 var prevSlide = rangeStart - 1, 15512 nextSlide = rangeEnd, 15513 $slides = _.$slider.find('.slick-slide'); 15514 15515 for (var i = 0; i < _.options.slidesToScroll; i++) { 15516 if (prevSlide < 0) prevSlide = _.slideCount - 1; 15517 loadRange = loadRange.add($slides.eq(prevSlide)); 15518 loadRange = loadRange.add($slides.eq(nextSlide)); 15519 prevSlide--; 15520 nextSlide++; 15521 } 15522 } 15523 15524 loadImages(loadRange); 15525 15526 if (_.slideCount <= _.options.slidesToShow) { 15527 cloneRange = _.$slider.find('.slick-slide'); 15528 loadImages(cloneRange); 15529 } else 15530 if (_.currentSlide >= _.slideCount - _.options.slidesToShow) { 15531 cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow); 15532 loadImages(cloneRange); 15533 } else if (_.currentSlide === 0) { 15534 cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1); 15535 loadImages(cloneRange); 15536 } 15537 15538 }; 15539 15540 Slick.prototype.loadSlider = function() { 15541 15542 var _ = this; 15543 15544 _.setPosition(); 15545 15546 _.$slideTrack.css({ 15547 opacity: 1 15548 }); 15549 15550 _.$slider.removeClass('slick-loading'); 15551 15552 _.initUI(); 15553 15554 if (_.options.lazyLoad === 'progressive') { 15555 _.progressiveLazyLoad(); 15556 } 15557 15558 }; 15559 15560 Slick.prototype.next = Slick.prototype.slickNext = function() { 15561 15562 var _ = this; 15563 15564 _.changeSlide({ 15565 data: { 15566 message: 'next' 15567 } 15568 }); 15569 15570 }; 15571 15572 Slick.prototype.orientationChange = function() { 15573 15574 var _ = this; 15575 15576 _.checkResponsive(); 15577 _.setPosition(); 15578 15579 }; 15580 15581 Slick.prototype.pause = Slick.prototype.slickPause = function() { 15582 15583 var _ = this; 15584 15585 _.autoPlayClear(); 15586 _.paused = true; 15587 15588 }; 15589 15590 Slick.prototype.play = Slick.prototype.slickPlay = function() { 15591 15592 var _ = this; 15593 15594 _.autoPlay(); 15595 _.options.autoplay = true; 15596 _.paused = false; 15597 _.focussed = false; 15598 _.interrupted = false; 15599 15600 }; 15601 15602 Slick.prototype.postSlide = function(index) { 15603 15604 var _ = this; 15605 15606 if( !_.unslicked ) { 15607 15608 _.$slider.trigger('afterChange', [_, index]); 15609 15610 _.animating = false; 15611 15612 if (_.slideCount > _.options.slidesToShow) { 15613 _.setPosition(); 15614 } 15615 15616 _.swipeLeft = null; 15617 15618 if ( _.options.autoplay ) { 15619 _.autoPlay(); 15620 } 15621 15622 if (_.options.accessibility === true) { 15623 _.initADA(); 15624 15625 if (_.options.focusOnChange) { 15626 var $currentSlide = $(_.$slides.get(_.currentSlide)); 15627 $currentSlide.attr('tabindex', 0).focus(); 15628 } 15629 } 15630 15631 } 15632 15633 }; 15634 15635 Slick.prototype.prev = Slick.prototype.slickPrev = function() { 15636 15637 var _ = this; 15638 15639 _.changeSlide({ 15640 data: { 15641 message: 'previous' 15642 } 15643 }); 15644 15645 }; 15646 15647 Slick.prototype.preventDefault = function(event) { 15648 15649 event.preventDefault(); 15650 15651 }; 15652 15653 Slick.prototype.progressiveLazyLoad = function( tryCount ) { 15654 15655 tryCount = tryCount || 1; 15656 15657 var _ = this, 15658 $imgsToLoad = $( 'img[data-lazy]', _.$slider ), 15659 image, 15660 imageSource, 15661 imageSrcSet, 15662 imageSizes, 15663 imageToLoad; 15664 15665 if ( $imgsToLoad.length ) { 15666 15667 image = $imgsToLoad.first(); 15668 imageSource = image.attr('data-lazy'); 15669 imageSrcSet = image.attr('data-srcset'); 15670 imageSizes = image.attr('data-sizes') || _.$slider.attr('data-sizes'); 15671 imageToLoad = document.createElement('img'); 15672 15673 imageToLoad.onload = function() { 15674 15675 if (imageSrcSet) { 15676 image 15677 .attr('srcset', imageSrcSet ); 15678 15679 if (imageSizes) { 15680 image 15681 .attr('sizes', imageSizes ); 15682 } 15683 } 15684 15685 image 15686 .attr( 'src', imageSource ) 15687 .removeAttr('data-lazy data-srcset data-sizes') 15688 .removeClass('slick-loading'); 15689 15690 if ( _.options.adaptiveHeight === true ) { 15691 _.setPosition(); 15692 } 15693 15694 _.$slider.trigger('lazyLoaded', [ _, image, imageSource ]); 15695 _.progressiveLazyLoad(); 15696 15697 }; 15698 15699 imageToLoad.onerror = function() { 15700 15701 if ( tryCount < 3 ) { 15702 15703 /** 15704 * try to load the image 3 times, 15705 * leave a slight delay so we don't get 15706 * servers blocking the request. 15707 */ 15708 setTimeout( function() { 15709 _.progressiveLazyLoad( tryCount + 1 ); 15710 }, 500 ); 15711 15712 } else { 15713 15714 image 15715 .removeAttr( 'data-lazy' ) 15716 .removeClass( 'slick-loading' ) 15717 .addClass( 'slick-lazyload-error' ); 15718 15719 _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]); 15720 15721 _.progressiveLazyLoad(); 15722 15723 } 15724 15725 }; 15726 15727 imageToLoad.src = imageSource; 15728 15729 } else { 15730 15731 _.$slider.trigger('allImagesLoaded', [ _ ]); 15732 15733 } 15734 15735 }; 15736 15737 Slick.prototype.refresh = function( initializing ) { 15738 15739 var _ = this, currentSlide, lastVisibleIndex; 15740 15741 lastVisibleIndex = _.slideCount - _.options.slidesToShow; 15742 15743 // in non-infinite sliders, we don't want to go past the 15744 // last visible index. 15745 if( !_.options.infinite && ( _.currentSlide > lastVisibleIndex )) { 15746 _.currentSlide = lastVisibleIndex; 15747 } 15748 15749 // if less slides than to show, go to start. 15750 if ( _.slideCount <= _.options.slidesToShow ) { 15751 _.currentSlide = 0; 15752 15753 } 15754 15755 currentSlide = _.currentSlide; 15756 15757 _.destroy(true); 15758 15759 $.extend(_, _.initials, { currentSlide: currentSlide }); 15760 15761 _.init(); 15762 15763 if( !initializing ) { 15764 15765 _.changeSlide({ 15766 data: { 15767 message: 'index', 15768 index: currentSlide 15769 } 15770 }, false); 15771 15772 } 15773 15774 }; 15775 15776 Slick.prototype.registerBreakpoints = function() { 15777 15778 var _ = this, breakpoint, currentBreakpoint, l, 15779 responsiveSettings = _.options.responsive || null; 15780 15781 if ( $.type(responsiveSettings) === 'array' && responsiveSettings.length ) { 15782 15783 _.respondTo = _.options.respondTo || 'window'; 15784 15785 for ( breakpoint in responsiveSettings ) { 15786 15787 l = _.breakpoints.length-1; 15788 15789 if (responsiveSettings.hasOwnProperty(breakpoint)) { 15790 currentBreakpoint = responsiveSettings[breakpoint].breakpoint; 15791 15792 // loop through the breakpoints and cut out any existing 15793 // ones with the same breakpoint number, we don't want dupes. 15794 while( l >= 0 ) { 15795 if( _.breakpoints[l] && _.breakpoints[l] === currentBreakpoint ) { 15796 _.breakpoints.splice(l,1); 15797 } 15798 l--; 15799 } 15800 15801 _.breakpoints.push(currentBreakpoint); 15802 _.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings; 15803 15804 } 15805 15806 } 15807 15808 _.breakpoints.sort(function(a, b) { 15809 return ( _.options.mobileFirst ) ? a-b : b-a; 15810 }); 15811 15812 } 15813 15814 }; 15815 15816 Slick.prototype.reinit = function() { 15817 15818 var _ = this; 15819 15820 _.$slides = 15821 _.$slideTrack 15822 .children(_.options.slide) 15823 .addClass('slick-slide'); 15824 15825 _.slideCount = _.$slides.length; 15826 15827 if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) { 15828 _.currentSlide = _.currentSlide - _.options.slidesToScroll; 15829 } 15830 15831 if (_.slideCount <= _.options.slidesToShow) { 15832 _.currentSlide = 0; 15833 } 15834 15835 _.registerBreakpoints(); 15836 15837 _.setProps(); 15838 _.setupInfinite(); 15839 _.buildArrows(); 15840 _.updateArrows(); 15841 _.initArrowEvents(); 15842 _.buildDots(); 15843 _.updateDots(); 15844 _.initDotEvents(); 15845 _.cleanUpSlideEvents(); 15846 _.initSlideEvents(); 15847 15848 _.checkResponsive(false, true); 15849 15850 if (_.options.focusOnSelect === true) { 15851 $(_.$slideTrack).children().on('click.slick', _.selectHandler); 15852 } 15853 15854 _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0); 15855 15856 _.setPosition(); 15857 _.focusHandler(); 15858 15859 _.paused = !_.options.autoplay; 15860 _.autoPlay(); 15861 15862 _.$slider.trigger('reInit', [_]); 15863 15864 }; 15865 15866 Slick.prototype.resize = function() { 15867 15868 var _ = this; 15869 15870 if ($(window).width() !== _.windowWidth) { 15871 clearTimeout(_.windowDelay); 15872 _.windowDelay = window.setTimeout(function() { 15873 _.windowWidth = $(window).width(); 15874 _.checkResponsive(); 15875 if( !_.unslicked ) { _.setPosition(); } 15876 }, 50); 15877 } 15878 }; 15879 15880 Slick.prototype.removeSlide = Slick.prototype.slickRemove = function(index, removeBefore, removeAll) { 15881 15882 var _ = this; 15883 15884 if (typeof(index) === 'boolean') { 15885 removeBefore = index; 15886 index = removeBefore === true ? 0 : _.slideCount - 1; 15887 } else { 15888 index = removeBefore === true ? --index : index; 15889 } 15890 15891 if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) { 15892 return false; 15893 } 15894 15895 _.unload(); 15896 15897 if (removeAll === true) { 15898 _.$slideTrack.children().remove(); 15899 } else { 15900 _.$slideTrack.children(this.options.slide).eq(index).remove(); 15901 } 15902 15903 _.$slides = _.$slideTrack.children(this.options.slide); 15904 15905 _.$slideTrack.children(this.options.slide).detach(); 15906 15907 _.$slideTrack.append(_.$slides); 15908 15909 _.$slidesCache = _.$slides; 15910 15911 _.reinit(); 15912 15913 }; 15914 15915 Slick.prototype.setCSS = function(position) { 15916 15917 var _ = this, 15918 positionProps = {}, 15919 x, y; 15920 15921 if (_.options.rtl === true) { 15922 position = -position; 15923 } 15924 x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px'; 15925 y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px'; 15926 15927 positionProps[_.positionProp] = position; 15928 15929 if (_.transformsEnabled === false) { 15930 _.$slideTrack.css(positionProps); 15931 } else { 15932 positionProps = {}; 15933 if (_.cssTransitions === false) { 15934 positionProps[_.animType] = 'translate(' + x + ', ' + y + ')'; 15935 _.$slideTrack.css(positionProps); 15936 } else { 15937 positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)'; 15938 _.$slideTrack.css(positionProps); 15939 } 15940 } 15941 15942 }; 15943 15944 Slick.prototype.setDimensions = function() { 15945 15946 var _ = this; 15947 15948 if (_.options.vertical === false) { 15949 if (_.options.centerMode === true) { 15950 _.$list.css({ 15951 padding: ('0px ' + _.options.centerPadding) 15952 }); 15953 } 15954 } else { 15955 _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow); 15956 if (_.options.centerMode === true) { 15957 _.$list.css({ 15958 padding: (_.options.centerPadding + ' 0px') 15959 }); 15960 } 15961 } 15962 15963 _.listWidth = _.$list.width(); 15964 _.listHeight = _.$list.height(); 15965 15966 15967 if (_.options.vertical === false && _.options.variableWidth === false) { 15968 _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow); 15969 _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length))); 15970 15971 } else if (_.options.variableWidth === true) { 15972 _.$slideTrack.width(5000 * _.slideCount); 15973 } else { 15974 _.slideWidth = Math.ceil(_.listWidth); 15975 _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length))); 15976 } 15977 15978 var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width(); 15979 if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset); 15980 15981 }; 15982 15983 Slick.prototype.setFade = function() { 15984 15985 var _ = this, 15986 targetLeft; 15987 15988 _.$slides.each(function(index, element) { 15989 targetLeft = (_.slideWidth * index) * -1; 15990 if (_.options.rtl === true) { 15991 $(element).css({ 15992 position: 'relative', 15993 right: targetLeft, 15994 top: 0, 15995 zIndex: _.options.zIndex - 2, 15996 opacity: 0 15997 }); 15998 } else { 15999 $(element).css({ 16000 position: 'relative', 16001 left: targetLeft, 16002 top: 0, 16003 zIndex: _.options.zIndex - 2, 16004 opacity: 0 16005 }); 16006 } 16007 }); 16008 16009 _.$slides.eq(_.currentSlide).css({ 16010 zIndex: _.options.zIndex - 1, 16011 opacity: 1 16012 }); 16013 16014 }; 16015 16016 Slick.prototype.setHeight = function() { 16017 16018 var _ = this; 16019 16020 if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) { 16021 var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true); 16022 _.$list.css('height', targetHeight); 16023 } 16024 16025 }; 16026 16027 Slick.prototype.setOption = 16028 Slick.prototype.slickSetOption = function() { 16029 16030 /** 16031 * accepts arguments in format of: 16032 * 16033 * - for changing a single option's value: 16034 * .slick("setOption", option, value, refresh ) 16035 * 16036 * - for changing a set of responsive options: 16037 * .slick("setOption", 'responsive', [{}, ...], refresh ) 16038 * 16039 * - for updating multiple values at once (not responsive) 16040 * .slick("setOption", { 'option': value, ... }, refresh ) 16041 */ 16042 16043 var _ = this, l, item, option, value, refresh = false, type; 16044 16045 if( $.type( arguments[0] ) === 'object' ) { 16046 16047 option = arguments[0]; 16048 refresh = arguments[1]; 16049 type = 'multiple'; 16050 16051 } else if ( $.type( arguments[0] ) === 'string' ) { 16052 16053 option = arguments[0]; 16054 value = arguments[1]; 16055 refresh = arguments[2]; 16056 16057 if ( arguments[0] === 'responsive' && $.type( arguments[1] ) === 'array' ) { 16058 16059 type = 'responsive'; 16060 16061 } else if ( typeof arguments[1] !== 'undefined' ) { 16062 16063 type = 'single'; 16064 16065 } 16066 16067 } 16068 16069 if ( type === 'single' ) { 16070 16071 _.options[option] = value; 16072 16073 16074 } else if ( type === 'multiple' ) { 16075 16076 $.each( option , function( opt, val ) { 16077 16078 _.options[opt] = val; 16079 16080 }); 16081 16082 16083 } else if ( type === 'responsive' ) { 16084 16085 for ( item in value ) { 16086 16087 if( $.type( _.options.responsive ) !== 'array' ) { 16088 16089 _.options.responsive = [ value[item] ]; 16090 16091 } else { 16092 16093 l = _.options.responsive.length-1; 16094 16095 // loop through the responsive object and splice out duplicates. 16096 while( l >= 0 ) { 16097 16098 if( _.options.responsive[l].breakpoint === value[item].breakpoint ) { 16099 16100 _.options.responsive.splice(l,1); 16101 16102 } 16103 16104 l--; 16105 16106 } 16107 16108 _.options.responsive.push( value[item] ); 16109 16110 } 16111 16112 } 16113 16114 } 16115 16116 if ( refresh ) { 16117 16118 _.unload(); 16119 _.reinit(); 16120 16121 } 16122 16123 }; 16124 16125 Slick.prototype.setPosition = function() { 16126 16127 var _ = this; 16128 16129 _.setDimensions(); 16130 16131 _.setHeight(); 16132 16133 if (_.options.fade === false) { 16134 _.setCSS(_.getLeft(_.currentSlide)); 16135 } else { 16136 _.setFade(); 16137 } 16138 16139 _.$slider.trigger('setPosition', [_]); 16140 16141 }; 16142 16143 Slick.prototype.setProps = function() { 16144 16145 var _ = this, 16146 bodyStyle = document.body.style; 16147 16148 _.positionProp = _.options.vertical === true ? 'top' : 'left'; 16149 16150 if (_.positionProp === 'top') { 16151 _.$slider.addClass('slick-vertical'); 16152 } else { 16153 _.$slider.removeClass('slick-vertical'); 16154 } 16155 16156 if (bodyStyle.WebkitTransition !== undefined || 16157 bodyStyle.MozTransition !== undefined || 16158 bodyStyle.msTransition !== undefined) { 16159 if (_.options.useCSS === true) { 16160 _.cssTransitions = true; 16161 } 16162 } 16163 16164 if ( _.options.fade ) { 16165 if ( typeof _.options.zIndex === 'number' ) { 16166 if( _.options.zIndex < 3 ) { 16167 _.options.zIndex = 3; 16168 } 16169 } else { 16170 _.options.zIndex = _.defaults.zIndex; 16171 } 16172 } 16173 16174 if (bodyStyle.OTransform !== undefined) { 16175 _.animType = 'OTransform'; 16176 _.transformType = '-o-transform'; 16177 _.transitionType = 'OTransition'; 16178 if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false; 16179 } 16180 if (bodyStyle.MozTransform !== undefined) { 16181 _.animType = 'MozTransform'; 16182 _.transformType = '-moz-transform'; 16183 _.transitionType = 'MozTransition'; 16184 if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false; 16185 } 16186 if (bodyStyle.webkitTransform !== undefined) { 16187 _.animType = 'webkitTransform'; 16188 _.transformType = '-webkit-transform'; 16189 _.transitionType = 'webkitTransition'; 16190 if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false; 16191 } 16192 if (bodyStyle.msTransform !== undefined) { 16193 _.animType = 'msTransform'; 16194 _.transformType = '-ms-transform'; 16195 _.transitionType = 'msTransition'; 16196 if (bodyStyle.msTransform === undefined) _.animType = false; 16197 } 16198 if (bodyStyle.transform !== undefined && _.animType !== false) { 16199 _.animType = 'transform'; 16200 _.transformType = 'transform'; 16201 _.transitionType = 'transition'; 16202 } 16203 _.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false); 16204 }; 16205 16206 16207 Slick.prototype.setSlideClasses = function(index) { 16208 16209 var _ = this, 16210 centerOffset, allSlides, indexOffset, remainder; 16211 16212 allSlides = _.$slider 16213 .find('.slick-slide') 16214 .removeClass('slick-active slick-center slick-current') 16215 .attr('aria-hidden', 'true'); 16216 16217 _.$slides 16218 .eq(index) 16219 .addClass('slick-current'); 16220 16221 if (_.options.centerMode === true) { 16222 16223 var evenCoef = _.options.slidesToShow % 2 === 0 ? 1 : 0; 16224 16225 centerOffset = Math.floor(_.options.slidesToShow / 2); 16226 16227 if (_.options.infinite === true) { 16228 16229 if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) { 16230 _.$slides 16231 .slice(index - centerOffset + evenCoef, index + centerOffset + 1) 16232 .addClass('slick-active') 16233 .attr('aria-hidden', 'false'); 16234 16235 } else { 16236 16237 indexOffset = _.options.slidesToShow + index; 16238 allSlides 16239 .slice(indexOffset - centerOffset + 1 + evenCoef, indexOffset + centerOffset + 2) 16240 .addClass('slick-active') 16241 .attr('aria-hidden', 'false'); 16242 16243 } 16244 16245 if (index === 0) { 16246 16247 allSlides 16248 .eq(allSlides.length - 1 - _.options.slidesToShow) 16249 .addClass('slick-center'); 16250 16251 } else if (index === _.slideCount - 1) { 16252 16253 allSlides 16254 .eq(_.options.slidesToShow) 16255 .addClass('slick-center'); 16256 16257 } 16258 16259 } 16260 16261 _.$slides 16262 .eq(index) 16263 .addClass('slick-center'); 16264 16265 } else { 16266 16267 if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) { 16268 16269 _.$slides 16270 .slice(index, index + _.options.slidesToShow) 16271 .addClass('slick-active') 16272 .attr('aria-hidden', 'false'); 16273 16274 } else if (allSlides.length <= _.options.slidesToShow) { 16275 16276 allSlides 16277 .addClass('slick-active') 16278 .attr('aria-hidden', 'false'); 16279 16280 } else { 16281 16282 remainder = _.slideCount % _.options.slidesToShow; 16283 indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index; 16284 16285 if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) { 16286 16287 allSlides 16288 .slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder) 16289 .addClass('slick-active') 16290 .attr('aria-hidden', 'false'); 16291 16292 } else { 16293 16294 allSlides 16295 .slice(indexOffset, indexOffset + _.options.slidesToShow) 16296 .addClass('slick-active') 16297 .attr('aria-hidden', 'false'); 16298 16299 } 16300 16301 } 16302 16303 } 16304 16305 if (_.options.lazyLoad === 'ondemand' || _.options.lazyLoad === 'anticipated') { 16306 _.lazyLoad(); 16307 } 16308 }; 16309 16310 Slick.prototype.setupInfinite = function() { 16311 16312 var _ = this, 16313 i, slideIndex, infiniteCount; 16314 16315 if (_.options.fade === true) { 16316 _.options.centerMode = false; 16317 } 16318 16319 if (_.options.infinite === true && _.options.fade === false) { 16320 16321 slideIndex = null; 16322 16323 if (_.slideCount > _.options.slidesToShow) { 16324 16325 if (_.options.centerMode === true) { 16326 infiniteCount = _.options.slidesToShow + 1; 16327 } else { 16328 infiniteCount = _.options.slidesToShow; 16329 } 16330 16331 for (i = _.slideCount; i > (_.slideCount - 16332 infiniteCount); i -= 1) { 16333 slideIndex = i - 1; 16334 $(_.$slides[slideIndex]).clone(true).attr('id', '') 16335 .attr('data-slick-index', slideIndex - _.slideCount) 16336 .prependTo(_.$slideTrack).addClass('slick-cloned'); 16337 } 16338 for (i = 0; i < infiniteCount + _.slideCount; i += 1) { 16339 slideIndex = i; 16340 $(_.$slides[slideIndex]).clone(true).attr('id', '') 16341 .attr('data-slick-index', slideIndex + _.slideCount) 16342 .appendTo(_.$slideTrack).addClass('slick-cloned'); 16343 } 16344 _.$slideTrack.find('.slick-cloned').find('[id]').each(function() { 16345 $(this).attr('id', ''); 16346 }); 16347 16348 } 16349 16350 } 16351 16352 }; 16353 16354 Slick.prototype.interrupt = function( toggle ) { 16355 16356 var _ = this; 16357 16358 if( !toggle ) { 16359 _.autoPlay(); 16360 } 16361 _.interrupted = toggle; 16362 16363 }; 16364 16365 Slick.prototype.selectHandler = function(event) { 16366 16367 var _ = this; 16368 16369 var targetElement = 16370 $(event.target).is('.slick-slide') ? 16371 $(event.target) : 16372 $(event.target).parents('.slick-slide'); 16373 16374 var index = parseInt(targetElement.attr('data-slick-index')); 16375 16376 if (!index) index = 0; 16377 16378 if (_.slideCount <= _.options.slidesToShow) { 16379 16380 _.slideHandler(index, false, true); 16381 return; 16382 16383 } 16384 16385 _.slideHandler(index); 16386 16387 }; 16388 16389 Slick.prototype.slideHandler = function(index, sync, dontAnimate) { 16390 16391 var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null, 16392 _ = this, navTarget; 16393 16394 sync = sync || false; 16395 16396 if (_.animating === true && _.options.waitForAnimate === true) { 16397 return; 16398 } 16399 16400 if (_.options.fade === true && _.currentSlide === index) { 16401 return; 16402 } 16403 16404 if (sync === false) { 16405 _.asNavFor(index); 16406 } 16407 16408 targetSlide = index; 16409 targetLeft = _.getLeft(targetSlide); 16410 slideLeft = _.getLeft(_.currentSlide); 16411 16412 _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft; 16413 16414 if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) { 16415 if (_.options.fade === false) { 16416 targetSlide = _.currentSlide; 16417 if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) { 16418 _.animateSlide(slideLeft, function() { 16419 _.postSlide(targetSlide); 16420 }); 16421 } else { 16422 _.postSlide(targetSlide); 16423 } 16424 } 16425 return; 16426 } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) { 16427 if (_.options.fade === false) { 16428 targetSlide = _.currentSlide; 16429 if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) { 16430 _.animateSlide(slideLeft, function() { 16431 _.postSlide(targetSlide); 16432 }); 16433 } else { 16434 _.postSlide(targetSlide); 16435 } 16436 } 16437 return; 16438 } 16439 16440 if ( _.options.autoplay ) { 16441 clearInterval(_.autoPlayTimer); 16442 } 16443 16444 if (targetSlide < 0) { 16445 if (_.slideCount % _.options.slidesToScroll !== 0) { 16446 animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll); 16447 } else { 16448 animSlide = _.slideCount + targetSlide; 16449 } 16450 } else if (targetSlide >= _.slideCount) { 16451 if (_.slideCount % _.options.slidesToScroll !== 0) { 16452 animSlide = 0; 16453 } else { 16454 animSlide = targetSlide - _.slideCount; 16455 } 16456 } else { 16457 animSlide = targetSlide; 16458 } 16459 16460 _.animating = true; 16461 16462 _.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]); 16463 16464 oldSlide = _.currentSlide; 16465 _.currentSlide = animSlide; 16466 16467 _.setSlideClasses(_.currentSlide); 16468 16469 if ( _.options.asNavFor ) { 16470 16471 navTarget = _.getNavTarget(); 16472 navTarget = navTarget.slick('getSlick'); 16473 16474 if ( navTarget.slideCount <= navTarget.options.slidesToShow ) { 16475 navTarget.setSlideClasses(_.currentSlide); 16476 } 16477 16478 } 16479 16480 _.updateDots(); 16481 _.updateArrows(); 16482 16483 if (_.options.fade === true) { 16484 if (dontAnimate !== true) { 16485 16486 _.fadeSlideOut(oldSlide); 16487 16488 _.fadeSlide(animSlide, function() { 16489 _.postSlide(animSlide); 16490 }); 16491 16492 } else { 16493 _.postSlide(animSlide); 16494 } 16495 _.animateHeight(); 16496 return; 16497 } 16498 16499 if (dontAnimate !== true && _.slideCount > _.options.slidesToShow) { 16500 _.animateSlide(targetLeft, function() { 16501 _.postSlide(animSlide); 16502 }); 16503 } else { 16504 _.postSlide(animSlide); 16505 } 16506 16507 }; 16508 16509 Slick.prototype.startLoad = function() { 16510 16511 var _ = this; 16512 16513 if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) { 16514 16515 _.$prevArrow.hide(); 16516 _.$nextArrow.hide(); 16517 16518 } 16519 16520 if (_.options.dots === true && _.slideCount > _.options.slidesToShow) { 16521 16522 _.$dots.hide(); 16523 16524 } 16525 16526 _.$slider.addClass('slick-loading'); 16527 16528 }; 16529 16530 Slick.prototype.swipeDirection = function() { 16531 16532 var xDist, yDist, r, swipeAngle, _ = this; 16533 16534 xDist = _.touchObject.startX - _.touchObject.curX; 16535 yDist = _.touchObject.startY - _.touchObject.curY; 16536 r = Math.atan2(yDist, xDist); 16537 16538 swipeAngle = Math.round(r * 180 / Math.PI); 16539 if (swipeAngle < 0) { 16540 swipeAngle = 360 - Math.abs(swipeAngle); 16541 } 16542 16543 if ((swipeAngle <= 45) && (swipeAngle >= 0)) { 16544 return (_.options.rtl === false ? 'left' : 'right'); 16545 } 16546 if ((swipeAngle <= 360) && (swipeAngle >= 315)) { 16547 return (_.options.rtl === false ? 'left' : 'right'); 16548 } 16549 if ((swipeAngle >= 135) && (swipeAngle <= 225)) { 16550 return (_.options.rtl === false ? 'right' : 'left'); 16551 } 16552 if (_.options.verticalSwiping === true) { 16553 if ((swipeAngle >= 35) && (swipeAngle <= 135)) { 16554 return 'down'; 16555 } else { 16556 return 'up'; 16557 } 16558 } 16559 16560 return 'vertical'; 16561 16562 }; 16563 16564 Slick.prototype.swipeEnd = function(event) { 16565 16566 var _ = this, 16567 slideCount, 16568 direction; 16569 16570 _.dragging = false; 16571 _.swiping = false; 16572 16573 if (_.scrolling) { 16574 _.scrolling = false; 16575 return false; 16576 } 16577 16578 _.interrupted = false; 16579 _.shouldClick = ( _.touchObject.swipeLength > 10 ) ? false : true; 16580 16581 if ( _.touchObject.curX === undefined ) { 16582 return false; 16583 } 16584 16585 if ( _.touchObject.edgeHit === true ) { 16586 _.$slider.trigger('edge', [_, _.swipeDirection() ]); 16587 } 16588 16589 if ( _.touchObject.swipeLength >= _.touchObject.minSwipe ) { 16590 16591 direction = _.swipeDirection(); 16592 16593 switch ( direction ) { 16594 16595 case 'left': 16596 case 'down': 16597 16598 slideCount = 16599 _.options.swipeToSlide ? 16600 _.checkNavigable( _.currentSlide + _.getSlideCount() ) : 16601 _.currentSlide + _.getSlideCount(); 16602 16603 _.currentDirection = 0; 16604 16605 break; 16606 16607 case 'right': 16608 case 'up': 16609 16610 slideCount = 16611 _.options.swipeToSlide ? 16612 _.checkNavigable( _.currentSlide - _.getSlideCount() ) : 16613 _.currentSlide - _.getSlideCount(); 16614 16615 _.currentDirection = 1; 16616 16617 break; 16618
vendor: 9,201 bytes, lines 16619-16952
16619 default: 16620 16621 16622 } 16623 16624 if( direction != 'vertical' ) { 16625 16626 _.slideHandler( slideCount ); 16627 _.touchObject = {}; 16628 _.$slider.trigger('swipe', [_, direction ]); 16629 16630 } 16631 16632 } else { 16633 16634 if ( _.touchObject.startX !== _.touchObject.curX ) { 16635 16636 _.slideHandler( _.currentSlide ); 16637 _.touchObject = {}; 16638 16639 } 16640 16641 } 16642 16643 }; 16644 16645 Slick.prototype.swipeHandler = function(event) { 16646 16647 var _ = this; 16648 16649 if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) { 16650 return; 16651 } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) { 16652 return; 16653 } 16654 16655 _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ? 16656 event.originalEvent.touches.length : 1; 16657 16658 _.touchObject.minSwipe = _.listWidth / _.options 16659 .touchThreshold; 16660 16661 if (_.options.verticalSwiping === true) { 16662 _.touchObject.minSwipe = _.listHeight / _.options 16663 .touchThreshold; 16664 } 16665 16666 switch (event.data.action) { 16667 16668 case 'start': 16669 _.swipeStart(event); 16670 break; 16671 16672 case 'move': 16673 _.swipeMove(event); 16674 break; 16675 16676 case 'end': 16677 _.swipeEnd(event); 16678 break; 16679 16680 } 16681 16682 }; 16683 16684 Slick.prototype.swipeMove = function(event) { 16685 16686 var _ = this, 16687 edgeWasHit = false, 16688 curLeft, swipeDirection, swipeLength, positionOffset, touches, verticalSwipeLength; 16689 16690 touches = event.originalEvent !== undefined ? event.originalEvent.touches : null; 16691 16692 if (!_.dragging || _.scrolling || touches && touches.length !== 1) { 16693 return false; 16694 } 16695 16696 curLeft = _.getLeft(_.currentSlide); 16697 16698 _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX; 16699 _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY; 16700 16701 _.touchObject.swipeLength = Math.round(Math.sqrt( 16702 Math.pow(_.touchObject.curX - _.touchObject.startX, 2))); 16703 16704 verticalSwipeLength = Math.round(Math.sqrt( 16705 Math.pow(_.touchObject.curY - _.touchObject.startY, 2))); 16706 16707 if (!_.options.verticalSwiping && !_.swiping && verticalSwipeLength > 4) { 16708 _.scrolling = true; 16709 return false; 16710 } 16711 16712 if (_.options.verticalSwiping === true) { 16713 _.touchObject.swipeLength = verticalSwipeLength; 16714 } 16715 16716 swipeDirection = _.swipeDirection(); 16717 16718 if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) { 16719 _.swiping = true; 16720 event.preventDefault(); 16721 } 16722 16723 positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1); 16724 if (_.options.verticalSwiping === true) { 16725 positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1; 16726 } 16727 16728 16729 swipeLength = _.touchObject.swipeLength; 16730 16731 _.touchObject.edgeHit = false; 16732 16733 if (_.options.infinite === false) { 16734 if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) { 16735 swipeLength = _.touchObject.swipeLength * _.options.edgeFriction; 16736 _.touchObject.edgeHit = true; 16737 } 16738 } 16739 16740 if (_.options.vertical === false) { 16741 _.swipeLeft = curLeft + swipeLength * positionOffset; 16742 } else { 16743 _.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset; 16744 } 16745 if (_.options.verticalSwiping === true) { 16746 _.swipeLeft = curLeft + swipeLength * positionOffset; 16747 } 16748 16749 if (_.options.fade === true || _.options.touchMove === false) { 16750 return false; 16751 } 16752 16753 if (_.animating === true) { 16754 _.swipeLeft = null; 16755 return false; 16756 } 16757 16758 _.setCSS(_.swipeLeft); 16759 16760 }; 16761 16762 Slick.prototype.swipeStart = function(event) { 16763 16764 var _ = this, 16765 touches; 16766 16767 _.interrupted = true; 16768 16769 if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) { 16770 _.touchObject = {}; 16771 return false; 16772 } 16773 16774 if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) { 16775 touches = event.originalEvent.touches[0]; 16776 } 16777 16778 _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX; 16779 _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY; 16780 16781 _.dragging = true; 16782 16783 }; 16784 16785 Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function() { 16786 16787 var _ = this; 16788 16789 if (_.$slidesCache !== null) { 16790 16791 _.unload(); 16792 16793 _.$slideTrack.children(this.options.slide).detach(); 16794 16795 _.$slidesCache.appendTo(_.$slideTrack); 16796 16797 _.reinit(); 16798 16799 } 16800 16801 }; 16802 16803 Slick.prototype.unload = function() { 16804 16805 var _ = this; 16806 16807 $('.slick-cloned', _.$slider).remove(); 16808 16809 if (_.$dots) { 16810 _.$dots.remove(); 16811 } 16812 16813 if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) { 16814 _.$prevArrow.remove(); 16815 } 16816 16817 if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) { 16818 _.$nextArrow.remove(); 16819 } 16820 16821 _.$slides 16822 .removeClass('slick-slide slick-active slick-visible slick-current') 16823 .attr('aria-hidden', 'true') 16824 .css('width', ''); 16825 16826 }; 16827 16828 Slick.prototype.unslick = function(fromBreakpoint) { 16829 16830 var _ = this; 16831 _.$slider.trigger('unslick', [_, fromBreakpoint]); 16832 _.destroy(); 16833 16834 }; 16835 16836 Slick.prototype.updateArrows = function() { 16837 16838 var _ = this, 16839 centerOffset; 16840 16841 centerOffset = Math.floor(_.options.slidesToShow / 2); 16842 16843 if ( _.options.arrows === true && 16844 _.slideCount > _.options.slidesToShow && 16845 !_.options.infinite ) { 16846 16847 _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 16848 _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 16849 16850 if (_.currentSlide === 0) { 16851 16852 _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true'); 16853 _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 16854 16855 } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) { 16856 16857 _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true'); 16858 _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 16859 16860 } else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) { 16861 16862 _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true'); 16863 _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false'); 16864 16865 } 16866 16867 } 16868 16869 }; 16870 16871 Slick.prototype.updateDots = function() { 16872 16873 var _ = this; 16874 16875 if (_.$dots !== null) { 16876 16877 _.$dots 16878 .find('li') 16879 .removeClass('slick-active') 16880 .end(); 16881 16882 _.$dots 16883 .find('li') 16884 .eq(Math.floor(_.currentSlide / _.options.slidesToScroll)) 16885 .addClass('slick-active'); 16886 16887 } 16888 16889 }; 16890 16891 Slick.prototype.visibility = function() { 16892 16893 var _ = this; 16894 16895 if ( _.options.autoplay ) { 16896 16897 if ( document[_.hidden] ) { 16898 16899 _.interrupted = true; 16900 16901 } else { 16902 16903 _.interrupted = false; 16904 16905 } 16906 16907 } 16908 16909 }; 16910 16911 $.fn.slick = function() { 16912 var _ = this, 16913 opt = arguments[0], 16914 args = Array.prototype.slice.call(arguments, 1), 16915 l = _.length, 16916 i, 16917 ret; 16918 for (i = 0; i < l; i++) { 16919 if (typeof opt == 'object' || typeof opt == 'undefined') 16920 _[i].slick = new Slick(_[i], opt); 16921 else 16922 ret = _[i].slick[opt].apply(_[i].slick, args); 16923 if (typeof ret != 'undefined') return ret; 16924 } 16925 return _; 16926 }; 16927 16928})); 16929 16930; 16931/* Windows Phone viewport fix */ 16932(function() { 16933 if ("-ms-user-select" in document.documentElement.style && navigator.userAgent.match(/IEMobile\/10\.0/)) { 16934 var msViewportStyle = document.createElement("style"); 16935 msViewportStyle.appendChild( 16936 document.createTextNode("@-ms-viewport{width:auto!important}") 16937 ); 16938 document.getElementsByTagName("head")[0].appendChild(msViewportStyle); 16939 } 16940})(); 16941 16942Flow = {}; 16943 16944// Short-Handle for document.ready 16945$(function() { 16946 var $window = $(window), 16947 $oBody = $('body'), 16948 $oHeader = $('#header'), 16949 $oBasketList = $('#basket_list'), 16950 $oToTop = $('#jumptotop'), 16951 $oRecommendations = $('#econdaRecommendations'), 16952 $oChangeEmail = $('input.oxValidate_enterPass'),
16953 $oSearchInput = $('#searchParam'), 16954 iHeaderWrapperHeight = parseInt($oHeader.height()), 16955 blIsCheckout = $oBody.hasClass('is-checkout'); 16956 16957 // Mobile detection 16958 window.isMobileDevice = function() { 16959 var check = false; 16960 (function(a) { 16961 if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) { 16962 check = true; 16963 } 16964 })(navigator.userAgent || navigator.vendor || window.opera); 16965 return check; 16966 }; 16967 16968 // Search Toggle 16969 $('.search-toggle').click(function(e) { 16970 e.preventDefault(); 16971 16972 $('html, body').animate( 16973 { 16974 scrollTop: ( $oSearchInput.position().top - 10 || 0 ) 16975 }, 16976 300, 16977 function() { 16978 $oSearchInput.focus(); 16979 } 16980 ); 16981 16982 } 16983 ); 16984 16985 // Global popover init 16986 var elements = document.querySelectorAll('[data-bs-toggle="popover"]'); 16987 Array.prototype.forEach.call(elements, function (el) { 16988 new bootstrap.Popover(el); 16989 }); 16990 16991 // Unveil beim Wechsel eines Tabs durchführen 16992 $('a[data-toggle="tab"]').on('shown.bs.tab', function(e) { 16993 $(this.getAttribute('href')).find('img').unveil(); 16994 } 16995 ); 16996 16997 $oToTop.click(function() { 16998 $('html, body').animate( 16999 { 17000 scrollTop: 0 17001 }, 17002 300 17003 ); 17004 } 17005 ); 17006 17007 // Fix um Eingabefelder in Bootstrap Dropdown-Menüs fokussieren zu können. 17008 $('#header .dropdown-menu input, #header .dropdown-menu label, #header .dropdown-menu button, #header .dropdown-menu').click(function(e) { 17009 e.stopPropagation(); 17010 } 17011 ); 17012 17013 $('.nav').on('mouseenter', 'li.dropdown', function(e) { 17014 if ($window.width() >= 760) { 17015 $(this).addClass('open'); 17016 } 17017 } 17018 ).on('mouseleave', 'li.dropdown', function(e) { 17019 if ($window.width() >= 760) { 17020 $(this).removeClass('open'); 17021 } 17022 } 17023 ).on('click', 'li.dropdown', function(e) { 17024 e.stopPropagation(); 17025 } 17026 ); 17027 17028 $oHeader.find('.menu-dropdowns button[data-href]').click(function(e) { 17029 var $this = $(this); 17030 17031 if ($(window).width() <= 767) { 17032 e.stopPropagation(); 17033 document.location.href = $this.attr('data-href'); 17034 } 17035 } 17036 ); 17037 17038 17039 if ($oRecommendations.length) { 17040 $.get(window.sBaseUrl + 'cl=tpl&tpl=ajax_econda_recommendations.tpl&actcl=' + sActCl + '', function(o
17040Data, sStatus, oXhr) { 17041 $oRecommendations.html(oData); 17042 $oRecommendations.find('img').unveil(); 17043 } 17044 ); 17045 } 17046 17047 /* ********************************* 17048 * List filter 17049 * *********************************/ 17050 var $oFilterList = $('#filterList'); 17051 17052 if ($oFilterList.length) { 17053 $oFilterList.find('.dropdown-menu li').click(function() { 17054 var $this = $(this); 17055 $this.parent().prev().val($this.children().first().data('selection-id')); 17056 $this.closest('form').submit(); 17057 } 17058 ); 17059 } 17060 17061 var $oSidebar = $('#sidebar'), 17062 $oCategoryBox = $oSidebar.find('.box.categorytree'); 17063 if ($oCategoryBox.length) { 17064 $oCategoryBox.find('.toggleTree').on('click touch', function() { 17065 var $this = $(this), 17066 $oCategoryTreeBox = $this.parents('.categorytree').find('.categoryBox'); 17067 17068 if ($this.hasClass('fa-caret-down')) { 17069 $this.removeClass('fa-caret-down'); 17070 $this.attr('class', 'fa-caret-up ' + $this.attr('class')); 17071 $oCategoryTreeBox.attr('style', 'display:block!important'); 17072 } 17073 else { 17074 $this.removeClass('fs-caret-up'); 17075 $this.attr('class', 'fs-caret-down ' + $this.attr('class')); 17076 $oCategoryTreeBox.removeAttr('style'); 17077 } 17078 } 17079 ); 17080 } 17081 17082 /* ********************************* 17083 * Variant selection in lists 17084 * *********************************/ 17085 var $oSelectionLists = $('.selectorsBox'); 17086 17087 if ($oSelectionLists.length) { 17088 $oSelectionLists.find('.dropdown-menu li').click(function(e) { 17089 e.preventDefault(); 17090 var $this = $(this); 17091 $this.parent().prev().val($this.children().first().data('selection-id')); 17092 $this.closest('form').submit(); 17093 } 17094 ); 17095 } 17096 17097 17098 /* ********************************* 17099 * Details page 17100 * *********************************/ 17101 Flow.initEvents = function() { 17102 // Lazy Loading für Bilder 17103 $("img").unveil(); 17104 var scrollTimeout = null; 17105 $(window).scroll(function() { 17106 if(scrollTimeout !== null) { 17107 clearTimeout(scrollTimeout); 17108 } 17109 scrollTimeout = setTimeout(function() { 17110 $("img").unveil(); 17111 }, 250); 17112 }); 17113 17114 $(".selectpicker").selectpicker(); 17115 17116 // Globale Tooltip-Klasse 17117 $('.hasTooltip').tooltip(); 17118 }; 17119 Flow.initEvents(); 17120 17121 function reRenderMainNav () { 17122 var $oMainNav = $('#mainnav').find('.navbar-collapse'), 17123 $oNavList = $('#navigation'), 17124 $oMoreLinks = $oNavList.find('.moreLinks'); 17125 17126 // Abbrechen, wenn Fensterbreite <= 767 17127 if ($window.width() <= 755) { 17128 $oMoreLinks.before($oMoreLinks.find('> ul > li')); 17129 $oMoreLinks.remove(); 17130 return; 17131 } 17132 17133 if ($oMoreLinks.length) { 17134 $oMoreLinks.before($oMoreLinks.find('> ul > li')); 17135 } 17136 else { 17137 var oMoreLinkElem = document.createElement('li'), 17138 oMoreLinkAElem = document.createElement('a'), 17139 oMoreLinkUlElem = document.createElement('ul'); 17140 17141 oMoreLinkElem.className = 'dropdown moreLinks'; 17142 17143 oMoreLinkAElem.className = 'dropdown-toggle'; 17144 oMoreLinkAElem.innerHTML = 'Mehr <span class="caret"></span>'; 17145 oMoreLinkAElem.setAttribute('data-toggle', 'dropdown'); 17146 17147 oMoreLinkUlElem.className = 'dropdown-menu'; 17148 oMoreLinkUlElem.setAttribute('role', 'menu'); 17149 17150 oMoreLinkElem.appendChild(oMoreLinkAElem); 17151 oMoreLinkElem.appendChild(oMoreLinkUlElem); 17152 17153 $oNavList.append(oMoreLinkElem); 17154 $oMoreLinks = $(oMoreLinkElem); 17155 } 17156 17157 var iMainNavWidth = $oMainNav.width(), 17158 $oNavItems = $oNavList.find('> li').not('.moreLinks'), 17159 iNavItemsWidth = 0, 17160 aMoreLinkElems = []; 17161 17162 iMainNavWidth -= $oMoreLinks.width(); 17163 17164 $oNavItems.each(function() { 17165 var $this = $(this); 17166 iNavItemsWidth += $this.outerWidth(); 17167 17168 if (iNavItemsWidth >
17168 iMainNavWidth) { 17169 aMoreLinkElems.push($this); 17170 } 17171 } 17172 ); 17173 17174 if (aMoreLinkElems.length) { 17175 $oMoreLinks.find('> ul').append(aMoreLinkElems); 17176 } 17177 else { 17178 $oMoreLinks.remove(); 17179 } 17180 } 17181 17182 reRenderMainNav(); 17183 $window.resize(function() { 17184 reRenderMainNav(); 17185 }); 17186 17187 /* ********************************* 17188 * Warenkorb 17189 * *********************************/ 17190 if ($oBasketList.length) { 17191 $('#basket_form').on('submit', function(e) { 17192 var $this = $(this), 17193 $oHiddenXs = $this.find('.hidden-xs'), 17194 $oVisibleXs = $this.find('.visible-xs'); 17195 17196 if ($oHiddenXs.is(':hidden')) { 17197 $oHiddenXs.remove(); 17198 } 17199 17200 if ($oVisibleXs.is(':hidden')) { 17201 $oVisibleXs.remove(); 17202 } 17203 17204 //e.target.submit(); 17205 } 17206 ); 17207 17208 $oBasketList.find('.toggle-actions').click(function(e) { 17209 e.preventDefault(); 17210 var $this = $(this), 17211 $oToggable = $this.parents('li').first().find('.row.toggable'); 17212 17213 $oToggable.slideToggle(150, function() { 17214 $this.find('i').attr('class', ( $oToggable.is(':visible') ? 'fa fa-chevron-up' : 'fa fa-chevron-down' )); 17215 } 17216 ); 17217 } 17218 ); 17219 } 17220 17221 /* ********************************* 17222 * Mein Konto 17223 * *********************************/ 17224 if ($oChangeEmail.length) { 17225 var sOldMail = $oChangeEmail.val(), 17226 $oPasswordElem = $('.oxValidate_pwd'); 17227 $oChangeEmail.keyup(function(e) { 17228 if ($oPasswordElem.length) { 17229 if (sOldMail != e.target.value) { 17230 $oPasswordElem.slideDown('fast'); 17231 } 17232 else { 17233 if ($oPasswordElem.is(':visible')) { 17234 $oPasswordElem.slideUp('fast'); 17235 } 17236 } 17237 } 17238 } 17239 ); 17240 } 17241 17242 /* ********************************* 17243 * Private Sales Login 17244 * *********************************/ 17245 $('#private-sales-login input.agb-check').click(function() { 17246 if ((this).checked) { 17247 $('#private-sales-login button.submitButton').removeAttr('disabled'); 17248 } else { 17249 $('#private-sales-login button.submitButton').attr("disabled", "disabled"); 17250 } 17251 }); 17252 17253 $('input, textarea').placeholder(); 17254 17255 /* BOF EUTO-222 - Suche Übersicht */ 17256 /* don't submit form if searchparam is empty */ 17257 $('form[name="search"]').submit(function(){if($(this).find('input[name="searchparam"]').val().length === 0){return false;}}); 17258 /* EOF EUTO-222 */ 17259 } 17260); 17261 17262$(window).on('load', function() { 17263 // Bugfix für das Nachladen von Bildern, wenn man die 17264 // Seite aktualisiert und dadurch nicht auf scrollTop 0 ist. 17265 window.setTimeout(function() { 17266 $("img").unveil(); 17267 }, 500); 17268 } 17269); 17270 17271/* BOF best it: secret 17272$(function(){if("onhashchange"in window){window.onhashchange=function(){if(location.hash==="#shake"){(function(){function c(){var e=document.createElement("link");e.setAttribute("type","text/css");e.setAttribute("rel","stylesheet");e.setAttribute("href",f);e.setAttribute("class",l);document.body.appendChild(e);}function h(){var e=document.getElementsByClassName(l);for(var t=0;t<e.length;t++){document.body.removeChild(e[t]);}}function p(){var e=document.createElement("div");e.setAttribute("class",a);document.body.appendChild(e);setTimeout(function(){document.body.removeChild(e);},100);}function d(e){return{height:e.offsetHeight,width:e.offsetWidth};}function v(i){var s=d(i);return s.height>e&&s.height<n&&s.width>t&&s.width<r;}function m(e){var t=e;var n=0;while(!!t){n+=t.offsetTop;t=t.offsetParent;}return n;}function g(){var e=document.documentElement;if(!!window.innerWidth){return window.innerHeight;}else if(e&&!isNaN(e.clientHeight)){return e.clientHeight;}return 0;}function y(){if(window.pageYOffset){return window.pageYOffset;}return Math.max(document.documentElement.scrollTop,document.body.scrollTop);}function E(e){var t=m(e);return t>=w&&t<=b+w;}function S(){var e=document.createElement("audio");e.setAttribute("class",l);e.src=i;e.loop=false;e.addEventListener("canplay",function(){setTimeout(function(){x(k);},500);setTimeout(function(){N();p();for(var e=0;e<O.length;e++){T(O[e]);}},15500);},true);e.addEventListener("ended",function(){N();h();},true);e.innerHTML=" <p>If you are reading this, it is because your browser does not support the audio element. We recommend that you get a new browser.</p> <p>";document.body.appendChild(e);e.play();}function x(e){e.className+=" "+s+" "+o;}function T(e){e.className+=" "+s+" "+u[Math.floor(Math.random()*u.length)];}function N(){var e=document.getElementsByClassName(s);var t=new RegExp("\\b"+s+"\\b");for(var n=0;n<e.length;){e[n].className=e[n].className.replace(t,"");}}var e=30;var t=30;var n=600;var r=600;var i="//s3.amazonaws.com/moovweb-marketing/playground/harlem-shake.mp3";var s="mw-harlem_shake_me";var o="im_first";var u=["im_drunk","im_baked","im_trippin","im_blown"];var a="mw-strobe_light";var f="//s3.amazonaws.com/moovweb-marketing/playground/harlem-shake-style.css";var l="mw_added_css";var b=g();var w=y();var C=document.getElementsByTagName("*");var k=null;for(var LL=0;LL<C.length;LL++){var AA=C[LL];if(v(AA)){if(E(AA)){k=AA;break;}}}c();S();var O=[];for(var LLL=0;LLL<C.length;
17272LLL++){var AAA=C[LLL];if(v(AAA)){O.push(AAA);}}})();}};}if(location.hash==="#shake"){window.onhashchange();}}); 17273/* EOF best it: secret */ 17274 17275/** 17276 * Eurotops JS 17277 * */ 17278//Function to the css rule 17279function getBreakpoint() { 17280 var $responsiveState = $('#responsive-state'); 17281 var lastState = $responsiveState.data('last-state'); 17282 var state = $responsiveState.css('content').replace(/"/g, ''); 17283 var width = $(window).width(); 17284 17285 /* Fallback if css content isn't working */ 17286 if (state !== 'xs' && state !== 'sm' && state !== 'md' && state !== 'lg') { 17287 state = 'xs'; 17288 17289 if (width >= 768) { 17290 state = 'sm'; 17291 } 17292 if (width >= 1024) { 17293 state = 'md'; 17294 } 17295 if (width >= 1430) { 17296 state = 'lg'; 17297 } 17298 } 17299 17300 if (lastState !== state) { 17301 $responsiveState.data('last-state', state); 17302 $(window).trigger('responsiveEvent', [state, lastState]); 17303 } 17304 17305 return [state, lastState]; 17306} 17307 17308function initSlider(className) { 17309 className = (typeof className !== 'undefined') ? className : '.product-slider__slider'; 17310 17311 //Product sliders, get existing swiper instance 17312 var $productSliders = $(className); 17313 17314 if ($productSliders.length > 0) { 17315 $.each($productSliders, function (index, item) { 17316 var $slider = $(item); 17317 var mdCount = (typeof $(item).data('mdcount') !== 'undefined') ? parseInt($(item).data('mdcount')) : 6; 17318 var smCount = (typeof $(item).data('smcount') !== 'undefined') ? parseInt($(item).data('smcount')) : 4; 17319 var xsCount = (typeof $(item).data('xscount') !== 'undefined') ? parseInt($(item).data('xscount')) : 2; 17320 var mdScroll = (typeof $(item).data('mdscroll') !== 'undefined') ? parseInt($(item).data('mdscroll')) : mdCount; 17321 var smScroll = (typeof $(item).data('smscroll') !== 'undefined') ? parseInt($(item).data('smscroll')) : smCount; 17322 var xsScroll = (typeof $(item).data('xsscroll') !== 'undefined') ? parseInt($(item).data('xsscroll')) : xsCount; 17323 var autoplay = (typeof $(item).data('autoplay') !== 'undefined') ? parseInt($(item).data('autoplay')) : 0; 17324 var autoplaySpeed = (typeof $(item).data('autoplayspeed') !== 'undefined') ? parseInt($(item).data('autoplayspeed')) : 0; 17325 var dots = (typeof $(item).data('dots') !== 'undefined') ? parseInt($(item).data('dots')) : 0; 17326 var infinite = (typeof $(item).data('infinite') !== 'undefined') ? parseInt($(item).data('infinite')) : 1; 17327 var speed = (typeof $(item).data('speed') !== 'undefined') ? parseInt($(item).data('speed')) : 300; 17328 17329 if ($slider.hasClass('slick-initialized')) { 17330 $slider.slick('unslick'); 17331 } 17332 17333 $slider.slick({ 17334 dots: !!dots, 17335 autoplay: !!autoplay, 17336 autoplaySpeed: autoplaySpeed, 17337 infinite: !!infinite, 17338 speed: speed, 17339 slidesToShow: mdCount, 17340 slidesToScroll: mdScroll, 17341 prevArrow: '<div class="slick-prev product-slider__btn product-slider__btn--prev"><i class="icon--icomoon-slider-left"></i></div>', 17342 nextArrow: '<div class="slick-next product-slider__btn product-slider__btn--next"><i class="icon--icomoon-slider-right"></i></div>', 17343 responsive: [ 17344 { 17345 breakpoint: 768, 17346 settings: { 17347 slidesToShow: xsCount, 17348 slidesToScroll: xsScroll, 17349 } 17350 }, { 17351 breakpoint: 992, 17352 settings: { 17353 slidesToShow: smCount, 17354 slidesToScroll: smScroll, 17355 } 17356 } 17357 ] 17358 }); 17359 }); 17360 } 17361} 17362 17363function initAjaxProductSlider($productlist) { 17364 if (!$productlist.data('initiated')) { 17365 var econdaArpParameter = {}; 17366 17367 if (typeof econda !== 'undefined' && econda.hasOwnProperty('recengine')) {
17368 var econdaRequest = new econda.recengine.Request(); 17369 econdaArpParameter = econdaRequest.getRecommendationServiceParameters(); 17370 } 17371 17372 jQuery.post('/index.php', { 17373 cl: 'foun10AjaxProductListWidget', 17374 title: $productlist.data('title'), 17375 title_css: $productlist.data('title_css'), 17376 type: $productlist.data('type'), 17377 typeid: $productlist.data('typeid'), 17378 sourceProducts: $productlist.data('sourceproducts'), 17379 mdCount: $productlist.data('mdcount'), 17380 shp: $productlist.data('shopid'), 17381 econdaArp: JSON.stringify(econdaArpParameter) 17382 }).done(function(data) { 17383 $productlist.html(data); 17384 17385 initSlider('.product-slider__slider'); 17386 17387 $productlist.find('img').unveil(); 17388 jQuery(window).trigger('scroll'); 17389 }); 17390 $productlist.data('initiated', true); 17391 } 17392} 17393 17394$(function () { 17395 var $body = $('body'); 17396 17397 // run test on initial page load 17398 getBreakpoint(); 17399 17400 // run test on resize of the window 17401 $(window).resize(getBreakpoint); 17402 17403 /* MENU TOGGLE - FOR MOBILE */ 17404 $(".menu--js").click(function(event) { 17405 event.preventDefault(); 17406 $('.subMenuTarget--js').slideUp(); 17407 $(this).next('ul').slideToggle(400, function() { 17408 if ($(this).is(":visible")) { 17409 $('.sticky-header:not(.sticky-header--checkout)').css('position', 'absolute'); 17410 $('html, body').animate({scrollTop: 0}, 0); 17411 } else { 17412 $('.sticky-header:not(.sticky-header--checkout)').css('position', 'fixed'); 17413 } 17414 }); 17415 }); 17416 17417 $(".selection .toggleSubMenu--js").click(function(event) { 17418 event.preventDefault(); 17419 $('.subMenuTarget--js').not($(this).next()).slideUp(); 17420 $(this).next('.subMenuTarget--js').stop(true, true).slideToggle(); 17421 }); 17422 17423 $(".headericons--basket-icon").click(function(event) { 17424 $('.headericons--basket-flyout').slideDown(); 17425 event.preventDefault(); 17426 }); 17427 $('.headericons--basket').mouseleave(function() { 17428 $('.headericons--basket-flyout').slideUp(); 17429 }); 17430 17431 // Click anywhere on the document 17432 $(document).click(function(event) { 17433 if (!$(event.target).closest(".selection").length) { 17434 $('.subMenuTarget--js').slideUp(); 17435 } 17436 }); 17437 17438 // Fancybox - for tab only 17439 $(".tabFancybox").fancybox({ 17440 autoSize: true, 17441 height: 'auto', 17442 width: 'auto', 17443 maxWidth: '224px', 17444 }); 17445 17446 // browser window scroll (in pixels) after which the "back to top" link is shown 17447 var offset = 300, 17448 //browser window scroll (in pixels) after which the "back to top" link opacity is reduced 17449 offset_opacity = 1200, 17450 //duration of the top scrolling animation (in ms) 17451 scroll_top_duration = 700, 17452 //grab the "back to top" link 17453 $back_to_top = $('.cd-top'); 17454 17455 //hide or show the "back to top" link 17456 $(window).scroll(function() { 17457 if ($(this).scrollTop() > offset) { 17458 $back_to_top.addClass('cd-is-visible'); 17459 } else { 17460 $back_to_top.removeClass('cd-is-visible cd-fade-out'); 17461 } 17462 17463 if ($(this).scrollTop() > offset_opacity) { 17464 $back_to_top.addClass('cd-fade-out'); 17465 } 17466 }); 17467 17468 //smooth scroll to top 17469 $back_to_top.on('click', function(event) { 17470 event.preventDefault(); 17471 $('body,html').animate({ 17472 scrollTop: 0, 17473 }, scroll_top_duration 17474 ); 17475 }); 17476 17477 /*Newsletter Modal */ 17478 $body.on('click', '.newsletter-modal__confirm', function() { 17479 $.fancybox.close(); 17480 }); 17481 17482 /* Content Navigation*/ 17483 $('#cms-navigation a').on('touchstart click', function(event) { 17484 var target = $(this).attr('href'); 17485 17486 if (!target || target.charAt(0) !== '#') { 17487 return; 17488 } 17489 17490 var $targetEl = $(target); 17491 var $container = $('body, html'); 17492 var offset = 0; 17493 17494 event.preventDefault(); 17495 17496 if (!$targetEl.length) { 17497 return; 17498 } 17499 17500 var position = $targetEl.offset().top + ~~(offset); 17501 17502 $container.animate({ 17503 scrollTop: position, 17504 }, 500); 17505 17506 }); 17507 17508 /* Show Password */ 17509 $('.js__show-password').on('click', function (event) { 17510 event.preventDefault(); 17511 17512 var $showPassword = $(this); 17513 var passwordId = $showPassword.data('password'); 17514 var passwordConfirmId = $showPassword.data('password-confirm'); 17515 var htmlText = $showPassword.html(); 17516 var dataText = $showPassword.data('switch-text'); 17517 var $password = $(passwordId); 17518 var $passwordConfirm = $(passwordConfirmId); 17519 var $passwordModified; 17520 var $passwordConfirmModified; 17521 17522 //Clone inputs and toggle type between text and password 17523 if ($password.attr('type') === 'password' && ($passwordConfirm.length === 0 || $passwordConfirm.attr('type') === 'password')) { 17524 $passwordModified = $password.clone().attr('type', 'text'); 17525 $passwordConfirmModified = $passwordConfirm.clone().attr('type', 'text'); 17526 17527 } else if ($password.attr('type') === 'text' && ($passwordConfirm.length === 0 || $passwordConfirm.attr('type') === 'text')) { 17528 $passwordModified = $password.clone().attr('type', 'password'); 17529 $passwordConfirmModified = $passwordConfirm.clone().attr('type', 'password'); 17530 } 17531 17532 if(typeof $passwordModified !== "undefined" && ($passwordConfirm.length === 0 || typeof $passwordConfirmModified !== "undefined")) { 17533 //Replace inputs with modified type 17534 $password.replaceWith($passwordModified); 17535 $passwordConfirm.replaceWith($passwordConfirmModified); 17536 17537 //Switch text on button 17538 $showPassword.html(dataText); 17539 $showPassword.attr('data-switch-text', htmlText).data('switch-text', htmlText); 17540 } 17541 }); 17542 17543 // BOF EUTO-830 Prevent change off birthday or name 17544 var $addressForm = $('#addressForm'); 17545 var $firstName = $addressForm.find('input[name="invadr[oxuser__oxfname]"]'); 17546 var $birthDateBlock = $addressForm.find('.oxDate'); 17547 var $submitButton = $('#accUserSaveTop'); 17548 17549 // Show hints in change form 17550 $addressForm.find('.account--register-hint').removeClass('hidden'); 17551 17552 $submitButton.on('click', function(){ 17553 if ($firstName.has('disabled')) { 17554 $firstName.removeAttr('disabled'); 17555 } 17556 17557 $birthDateBlock.find(':input').each(function() { 17558 this.removeAttribute('disabled'); 17559 }); 17560 }); 17561 17562 if ($firstName.val() !== undefined) { 17563 $firstName.attr('disabled', true); 17564 } 17565 17566 $birthDateBlock.find(':input').each(function() { 17567 if ($(this).val() !== '') { 17568 this.setAttribute('disabled', true); 17569 } 17570 }); 17571 // EOF EUTO-830 17572 17573 // BOF EUTO-814 Set default country select 17574 var $registerForm = $('.user-account--register'); 17575 var $shopId = $registerForm.data("shop-id"); 17576 var $delZip = $registerForm.find('input[name="deladr[oxuser__oxzip]"]'); 17577 var $billingZip = $registerForm.find('input[name="invadr[oxuser__oxzip]"]'); 17578 17579 var $delCountry = $('#delCountrySelect'); 17580 var $billCountry = $('#invCountrySelect'); 17581 17582 var germanyId = 'a7c40f631fc920687.20179984'; 17583 var austriaId = 'a7c40f6320aeb2ec2.72885259'; 17584
17585 if ($shopId === 2) { 17586 var applyCountryByZip = function ($zipField, $countrySelect) { 17587 $zipField.on('blur', function () { 17588 var len = this.value.length; 17589 17590 if (len === 4) { 17591 $countrySelect.selectpicker('val', austriaId); 17592 } 17593 17594 if (len === 5) { 17595 $countrySelect.selectpicker('val', germanyId); 17596 } 17597 17598 // Note: no selectpicker('refresh') here — 'val' already updates the 17599 // rendered button; refreshing again duplicates the country text. 17600 $countrySelect.trigger('change'); 17601 }); 17602 }; 17603 17604 applyCountryByZip($billingZip, $billCountry); 17605 applyCountryByZip($delZip, $delCountry); 17606 } 17607 17608 // EOF EUTO-814 Set default country select 17609 17610 // EUTO-2826 reCAPTCHA inside the ajax modals (recall form). 17611 // jQuery silently drops the cross origin api.js include when it injects the 17612 // ajax response - same origin includes in the same response still run - so the 17613 // widget never gets created. Load the api ourselves on the first modal that 17614 // needs it and render explicitly: the automatic render only scans the document 17615 // once, while api.js is loading, so a modal opened later is never picked up. 17616 var recaptchaApiRequested = false; 17617 17618 function renderModalRecaptchas() { 17619 var $pending = $('.fancybox-inner .g-recaptcha').filter(function () { 17620 return $(this).children().length === 0; 17621 }); 17622 17623 if (!$pending.length) { 17624 return; 17625 } 17626 17627 if (window.grecaptcha && window.grecaptcha.render) { 17628 $pending.each(function () { 17629 window.grecaptcha.render(this, { 17630 sitekey: $(this).attr('data-sitekey'), 17631 size: $(this).attr('data-size') || 'normal' 17632 }); 17633 }); 17634 17635 return; 17636 } 17637 17638 if (recaptchaApiRequested) { 17639 return; 17640 } 17641 17642 recaptchaApiRequested = true; 17643 window.initialiseModalRecaptcha = renderModalRecaptchas; 17644 17645 // Plain DOM on purpose - appending it with jQuery would hit the very bug 17646 // this works around. 17647 var recaptchaApi = document.createElement('script'); 17648 recaptchaApi.src = 'https://www.google.com/recaptcha/api.js?render=explicit&onload=initialiseModalRecaptcha'; 17649 document.head.appendChild(recaptchaApi); 17650 } 17651 17652 //Register modals 17653 $('.js__modal').fancybox({ 17654 type: 'ajax', 17655 wrapCSS: 'eurotops', 17656 beforeLoad : function() { 17657 if (this.element.data('fancybox-css')) { 17658 this.wrapCSS = this.element.data('fancybox-css'); 17659 } 17660 }, 17661 afterShow: function() { 17662 $(".selectpicker").selectpicker(); 17663 renderModalRecaptchas(); 17664 var anchor = this.element.data('go-to-anchor'); 17665 if(anchor) { 17666 setTimeout(function(){ 17667 $(".fancybox-inner").find(anchor)[0].scrollIntoView(); 17668 }, 1000); 17669 } 17670 } 17671 }); 17672 17673 // Images inside a modal carry data-src instead of src so they stay out of the 17674 // initial page load - swap it in the first time the modal is opened. 17675 $body.on('show.bs.modal', '.modal', function () { 17676 $(this).find('img[data-src]').each(function () { 17677 this.src = this.getAttribute('data-src'); 17678 this.removeAttribute('data-src'); 17679 }); 17680 }); 17681 17682 // Payment popover 17683 var $checkoutPayment = $('.checkout-payment, .checkout-voucher__text'); 17684 var $checkoutPaymentPopover = $checkoutPayment.find('[data-toggle="popover"]'); 17685 17686 if ($checkoutPaymentPopover.length) { 17687 $checkoutPaymentPopover.on('click', function (event) { 17688 event.preventDefault(); 17689 }); 17690 17691 $body.on('click', '.popover', function (event) { 17692 $checkoutPaymentPopover.popover('hide'); 17693 }); 17694 17695 $checkoutPaymentPopover.popover({ 17696 trigger: 'focus', 17697 }); 17698 } 17699 17700 17701 $('dl dt input[type=radio]', '.payment-list').on('click', function (event) { 17702 var $dl = $(this).parents("dl"); 17703 var $dd = $dl.children("dd"); 17704 $('dd', '.payment-list').hide(); 17705 $('dl', '.payment-list').removeClass('active'); 17706 17707 if ($dd.length > 0) { 17708 $dd.toggle(); 17709 17710 if ($dd.is(':visible')) { 17711 $dl.addClass('active'); 17712 } 17713 } 17714 }); 17715 17716 //Article review page 17717 var $starSelect = $('.star-select__stars'); 17718 var starHoverTimeout = 0; 17719 17720 $starSelect.on('click', '.js__star', function (event) { 17721 var $clickedStar = $(event.currentTarget); 17722 var starValue = $clickedStar.index() + 1; 17723 var $votingArticle = $clickedStar.closest('.voting-article'); 17724 var $standardHint = $clickedStar.closest('.star-select__wrapper').find('.star-select__hint'); 17725 17726 $votingArticle.find('.js__star-input').val(starValue); 17727 $votingArticle.find('.voting-article__review').addClass('voting-article__review--active'); 17728 $votingArticle.find('.js__review-input').attr('required', 'required'); 17729 17730 $clickedStar.closest('.star-select__stars').find('.js__star') 17731 .removeClass('icon--icomoon-stern rating-star-filled') 17732 .addClass('icon--icomoon-stern_leer rating-star-empty'); 17733 17734 $clickedStar 17735 .removeClass('icon--icomoon-stern_leer rating-star-empty') 17736 .addClass('icon--icomoon-stern rating-star-filled'); 17737 17738 $clickedStar.prevAll().removeClass('icon--icomoon-stern_leer rating-star-empty') 17739 .addClass('icon--icomoon-stern rating-star-filled'); 17740 17741 $standardHint.addClass('star-select__hint--hidden'); 17742 }); 17743 17744 $starSelect.on('mouseenter mouseleave', '.js__star', function (event) { 17745 var $hoveredStar = $(event.currentTarget); 17746 var hoveredIndex = $hoveredStar.index() + 1; 17747 var $standardHint = $hoveredStar.closest('.star-select__wrapper').find('.star-select__hint'); 17748 var $starHint = $hoveredStar.closest('.star-select__wrapper').find('.star-select__star--' + hoveredIndex); 17749 var $votingArticle = $hoveredStar.closest('.voting-article'); 17750 var selectedStarValue = $votingArticle.find('.js__star-input').val(); 17751 17752 if (event.type === 'mouseenter') { 17753 clearTimeout(starHoverTimeout); 17754 17755 starHoverTimeout = setTimeout(function () { 17756 $starHint.addClass('star-select__star--active'); 17757 $standardHint.addClass('star-select__hint--hidden'); 17758 }, 500); 17759 } 17760 17761 if (event.type === 'mouseleave') { 17762 clearTimeout(starHoverTimeout); 17763 $starHint.removeClass('star-select__star--active'); 17764 17765 if (selectedStarValue === '0') { 17766 $standardHint.removeClass('star-select__hint--hidden'); 17767 } 17768 } 17769 }); 17770 17771 //Quantity select 17772 $body.on('change', '.js__quantiy-select', function() { 17773 var $me = $(this); 17774 17775 $me.closest('form').submit(); 17776 }); 17777 17778 //Account order pagination 17779 var $orderTable = $('.js__order-list'); 17780 17781 if ($orderTable.length > 0) { 17782 $orderTable.pajinate({ 17783 items_per_page : 6, 17784 num_page_links_to_display: 3, 17785 nav_order : ['prev', 'num', 'next'],
17786 nav_label_next: '<i class="icon--icomoon-slider-right"></i>', 17787 nav_label_prev: '<i class="icon--icomoon-slider-left"></i>', 17788 jquery_ui: true, 17789 jquery_ui_default: 'btn btn-gray', 17790 jquery_ui_disabled: 'disabled' 17791 }); 17792 } 17793 17794 /* Add additional address fields for registration */ 17795 var $additionalInfoGroups = $('.addinfo-group'); 17796 17797 $additionalInfoGroups.each(function () { 17798 var $additionalInfoGroup = $(this); 17799 var $addInfo = $('.add-addinfo', $additionalInfoGroup); 17800 17801 $addInfo.on('click', function(e) { 17802 e.preventDefault(); 17803 var $collapsedContent = $addInfo.closest('.addinfo-group').find('.collapse:not(.in)'); 17804 $collapsedContent.first().collapse('show'); 17805 $addInfo.addClass('hide'); 17806 17807 if ($collapsedContent.length >= 1) { 17808 $('.remove-addinfo', $additionalInfoGroup).addClass('is--active'); 17809 } 17810 }); 17811 17812 $('.remove-addinfo', $additionalInfoGroup).on('click', function(e) { 17813 e.preventDefault(); 17814 var $openContent = $(this).closest('.addinfo-group').find('.collapse.in'); 17815 $openContent.last().collapse('hide'); 17816 17817 if ($openContent.length === 1) { 17818 $(this).removeClass('is--active'); 17819 $addInfo.removeClass('hide'); 17820 } 17821 }); 17822 17823 var $doorField = $('[name="door"]', $additionalInfoGroup); 17824 var doorFieldPrefix = $doorField.data('field-name') + ' '; 17825 var $staircaseField = $('[name="staircase"]', $additionalInfoGroup); 17826 var staircaseFieldPrefix = $staircaseField.data('field-name') + ' '; 17827 var $targetField = $('[data-add-info-field]', $additionalInfoGroup); 17828 var value = $targetField.val(); 17829 17830 (value ? value : '').split('/').forEach(function (value) { 17831 if (value.startsWith(doorFieldPrefix)) { 17832 $doorField.val(value.replace(doorFieldPrefix, '')); 17833 } else if (value.startsWith(staircaseFieldPrefix)) { 17834 $staircaseField.val(value.replace(staircaseFieldPrefix, '')); 17835 } 17836 }); 17837 17838 var addChangeEvent = function (target) { 17839 target.on('change', function () { 17840 var data = []; 17841 data.push($doorField.val() !== '' ? doorFieldPrefix + $doorField.val() : null); 17842 data.push($staircaseField.val() !== '' ? staircaseFieldPrefix + $staircaseField.val() : null); 17843 17844 $targetField.val( 17845 data 17846 .filter(function (element) { 17847 return element !== null; 17848 }) 17849 .join('/') 17850 ); 17851 }); 17852 }; 17853 17854 addChangeEvent($doorField); 17855 addChangeEvent($staircaseField); 17856 }); 17857 17858 // Remove PayPal Express button on details page if basket is not empty - use JS to keep caching performance 17859 if ($('.cart-items small').length === 0) { 17860 $('#paypalExpressCheckoutDetailsBox').show(); 17861 } 17862 17863 // Init wishlist triggers/markers 17864 if (typeof bestitWishlistTrigger !== "undefined") { 17865 bestitWishlistTrigger.init(); 17866 $('#linkToWishList, .wishlist-product__remove-button').click(function(){ 17867 bestitWishlistTrigger.clearWishlistItemStorage(); 17868 }); 17869 } 17870 17871 initSlider('.product-slider__slider'); 17872 initSlider('.category-header__slider'); 17873 17874 /* BOF EUTO-1498 */ 17875 var $tablePreview = jQuery('.table-preview'); 17876 17877 $tablePreview.each(function() { 17878 var $table = $(this); 17879 var tableHeight = $table.data('previewheight') || 200; 17880 var showMoreInfo = $table.data('showmoreinfo'); 17881 var showMoreBackground = $table.data('showmorebackground') || '#ececec'; 17882 17883 if ($table.height() > tableHeight) { 17884 var $tableWrapper = $('<div>').addClass('table-preview__wrapper'); 17885 $tableWrapper.height(tableHeight); 17886 17887 $table.wrap($tableWrapper); 17888 17889 $tableWrapper = $table.closest('.table-preview__wrapper'); 17890 17891 var $showMoreButton = $('<div>') 17892 .addClass('table-preview__show-button') 17893 .css('background', 'linear-gradient(to top, ' + showMoreBackground + ', transparent)') 17894 .html(showMoreInfo) 17895 .click(function(){ 17896 $(this).hide(); 17897 $tableWrapper.addClass('table-preview__wrapper---opened'); 17898 }); 17899 $tableWrapper.append($showMoreButton); 17900 } 17901 }); 17902 /* EOF EUTO-1498 */ 17903 17904 /* BOF EUTO-1556 */ 17905 $('.checkout-voucher__expand').click(function(){ 17906 $(this).hide(); 17907 $('.checkout-voucher__form-input').show(); 17908 }); 17909 /* EOF EUTO-1556 */ 17910 17911 var $campaignAdvisor = $('.campaignAdvisor'); 17912 17913 $('.close' , $campaignAdvisor).on('click', function (e) { 17914 $(this).toggleClass('collapsed'); 17915 $('.advisorContent', $campaignAdvisor).toggleClass('hidden'); 17916 e.preventDefault(); 17917 }); 17918 17919 $('.cms-blog-navigation-button').on('click', function (e) { 17920 $('~.cms-blog-navigation', this).toggle(); 17921 e.preventDefault(); 17922 }); 17923 17924 var getRowGroups = function(groupSize) { 17925 var $cmsRows = $('.cms-element__blog-article') 17926 .parentsUntil('.dd-ve-container', '.row') 17927 .toArray() 17928 .reverse(); 17929 var groups = [[]]; 17930 17931 $cmsRows.forEach(function (row) { 17932 if (groups[groups.length - 1].length >= groupSize) { 17933 groups.push([]); 17934 } 17935 17936 groups[groups.length - 1].push(row); 17937 }); 17938 17939 return groups; 17940 }; 17941 17942 var groups = getRowGroups(3); 17943 groups.shift(); 17944 var loadButton = $('.cms-blog-load-more'); 17945 17946 if (groups.length > 0) { 17947 loadButton.show(); 17948 17949 groups.forEach(function (group) { 17950 group.forEach(function (row) { 17951 $(row).hide(); 17952 }); 17953 }); 17954 17955 loadButton.on('click', function (e) {
17956 groups.shift().forEach(function (row) { 17957 $(row).show(); 17958 }); 17959 17960 if (groups.length <= 0) { 17961 $(this).hide(); 17962 } 17963 }); 17964 } else { 17965 loadButton.hide(); 17966 } 17967}); 17968 17969 17970$(window).on('responsiveEvent', function (event, state, lastState) { 17971 /* SUBMENU TOGGLE */ 17972 var $submenuToggle = $('.menu-bar.menu-bar--js .has-sub-menu--js>a'); 17973 var $submenus = $('.menu-bar .sub-menu--js'); 17974 17975 $submenus.removeClass('is--active'); 17976 17977 if (state === 'xs') { 17978 $submenuToggle.off('click').on('click', function(e) { 17979 var submenuHidden = $(this).siblings('.sub-menu--js').is(':hidden'); 17980 17981 if (submenuHidden) { 17982 e.preventDefault(); 17983 17984 /* Close other open submenus */ 17985 $(this).closest('.sub-menu--js').find('.sub-menu--js').not(':hidden').stop(true, true).slideUp(); 17986 17987 /* Open clicked submenus */ 17988 $(this).siblings('.sub-menu--js').stop(true, true).slideToggle(); 17989 } 17990 17991 if ($(e.target).hasClass('sub-menu__trigger')) { 17992 if (!submenuHidden) { 17993 $(this).siblings('.sub-menu--js').stop(true, true).slideToggle(); 17994 } 17995 17996 e.preventDefault(); 17997 } 17998 }); 17999 } else if (state === 'md' || state === 'sm') { 18000 $submenuToggle.off('click').on('click', function(e) { 18001 var $submenu = $(this).siblings('.sub-menu--js'); 18002 var href = $(this).attr('href'); 18003 var $otherSubmenus = $(this).parent('.has-sub-menu--js').siblings('.has-sub-menu--js'); 18004 18005 e.preventDefault(); 18006 18007 $otherSubmenus.find('.sub-menu--js').removeClass('is--active'); 18008 18009 if ($submenu.hasClass('is--active') && href !== '#') { 18010 window.location = href; 18011 } 18012 18013 $submenu.addClass('is--active'); 18014 }); 18015 } else { 18016 $submenuToggle.off('click').on('click', function(e) { 18017 var href = $(this).attr('href'); 18018 18019 if (href !== '#') { 18020 window.location = href; 18021 } 18022 }); 18023 } 18024 18025 var $categorySubmenuToggle = $('.category-menu-bar.menu-bar--js .has-sub-menu--js>a'); 18026 var $categorySubmenus = $('.category-menu-bar .sub-menu--js'); 18027 18028 $categorySubmenus.removeClass('is--active'); 18029 18030 if (state === 'xs' || state === 'sm' || state === 'md') { 18031 $categorySubmenuToggle.off('click').on('click', function(e) { 18032 var $submenu = $(this).siblings('.sub-menu--js'); 18033 var href = $(this).attr('href'); 18034 var $otherSubmenus = $(this).parent('.has-sub-menu--js').siblings('.has-sub-menu--js'); 18035 18036 e.preventDefault(); 18037 18038 $otherSubmenus.find('.sub-menu--js').removeClass('is--active'); 18039 18040 if ($submenu.hasClass('is--active') && href !== '#') { 18041 window.location = href; 18042 } 18043 18044 $submenu.addClass('is--active'); 18045 }); 18046 } else { 18047 $categorySubmenuToggle.off('click').on('click', function(e) { 18048 var href = $(this).attr('href'); 18049 18050 if (href !== '#') { 18051 window.location = href; 18052 } 18053 }); 18054 } 18055 18056 /* submit button on checkout fix (IE problem) */ 18057 /* see EUTO-199 - Logo Zahlarten ideal - Bestellseite */ 18058 $('#submitOrderButtonTop').click(function(){ 18059 if ($(this)[0].form === null) { 18060 // browser does not support form attribute 18061 $('form#'+$(this).attr('form')).submit(); 18062 } 18063 }); 18064 18065 /* BOF EUTO-425 - Sticky Navigation */ 18066 /* BOF EUTO-527 - Additional sticky navigation for categories */ 18067 /* BOF EUTO-666 - Optimize Sticky header */ 18068 /** 18069 * Sticky header 18070 */ 18071 var header = document.getElementById("sticky-header"); 18072 if (header !== null) { 18073 var sticky = header.offsetTop; 18074 18075 $(window).on('scroll', function() { 18076 if (window.pageYOffset > sticky) { 18077 header.classList.add("sticky-header--stuck"); 18078 } else { 18079 header.classList.remove("sticky-header--stuck"); 18080 } 18081 }); 18082 } 18083 18084 /* EOF EUTO-425 - Sticky Navigation */ 18085 /* EOF EUTO-666 - Optimize Sticky header */ 18086 18087 /* BOF EUTO-558 - FactFinder Filter */ 18088 $('.asnGroup .page-header').off('click').click(function (){ 18089 var $this = $(this), 18090 $parentContainer = $this.parent('.asnGroup'), 18091 activeClass = 'asnGroup--active'; 18092 18093 $parentContainer.toggleClass(activeClass); 18094 }); 18095 18096 $('.asnHeader__toggle').off('click').click(function () { 18097 var $this = $(this), 18098 $filterContainer = $this.closest('.asn').find('.asnGroupBox'), 18099 $toggleLabel = $this.find('span'); 18100
18101 $filterContainer.toggle(); 18102 $toggleLabel.toggle(); 18103 }); 18104 18105 $('select.asnFilterInput').on('change', function (event) { 18106 var $this = $(this); 18107 var value = $this.val(); 18108 18109 if (value.charAt(0) === '/' || value.startsWith('http')) { 18110 window.location.href = $this.val(); 18111 } 18112 }); 18113 /* EOF EUTO-558 - FactFinder Filter */ 18114 18115 /* BOF EUTO-892 - econda markers */ 18116 $('.econda__marker').on('click', function () { 18117 var $this = $(this); 18118 18119 if (typeof $this.data('econdamarker') !== 'undefined' && typeof window.emos3 !== 'undefined') { 18120 window.emos3.send({ 18121 marker: $this.data('econdamarker'), 18122 type: 'event' 18123 }); 18124 } 18125 }); 18126 /* EOF EUTO-892 */ 18127 18128 /* BOF EUTO-1046 - ajax product lists */ 18129 if (jQuery('.foun10ajaxproductlist').length > 0) { 18130 jQuery('.foun10ajaxproductlist').each(function(index) { 18131 var $productlist = jQuery(this); 18132 initAjaxProductSlider($productlist); 18133 }); 18134 } 18135 /* EOF EUTO-1046 */ 18136 18137 /* BOF SANPU-88 - back to top button */ 18138 if (jQuery('.backToTop').length > 0) { 18139 var $backToTop = jQuery('.backToTop'); 18140 var scrollTrigger = 100; 18141 var backToTop = function () { 18142 var scrollTop = jQuery(window).scrollTop(); 18143 if (scrollTop > scrollTrigger) { 18144 $backToTop.addClass('show'); 18145 } else { 18146 $backToTop.removeClass('show'); 18147 } 18148 }; 18149 18150 backToTop(); 18151 18152 jQuery(window).on('scroll', function () { 18153 backToTop(); 18154 }); 18155 18156 $backToTop.on('click', function (e) { 18157 e.preventDefault(); 18158 18159 jQuery('html,body').animate({ 18160 scrollTop: 0 18161 }, 700, function(){ 18162 backToTop(); 18163 }); 18164 }); 18165 } 18166 /* EOF SANPU-88 */ 18167 18168 /* BOF EUTO-1496 */ 18169 $('a[href*="#"]') 18170 .not('[href="#"]') 18171 .not('[href="#0"]') 18172 .click(function(event) { 18173 // Check for on-page links 18174 if (location.pathname.replace(/^\//, '') === this.pathname.replace(/^\//, '') && location.hostname === this.hostname) { 18175 var target = $(this.hash); 18176 target = target.length ? target : $('[name=' + this.hash.slice(1) + ']'); 18177 18178 if (target.length) { 18179 event.preventDefault(); 18180 18181 var scrollToTarget = function(target) { 18182 $('html, body').animate({ 18183 scrollTop: target.offset().top - $('.usp-bar').outerHeight() - $('.sticky-header').outerHeight() 18184 }, 1000, function() { 18185 var $target = $(target); 18186 $target.focus(); 18187 if ($target.is(":focus")) { 18188 return false; 18189 } else { 18190 $target.attr('tabindex','-1'); 18191 $target.focus(); 18192 } 18193 }); 18194 }; 18195 18196 if ($(window).scrollTop() === 0) { 18197 // Scroll a bit down to show sticky header 18198 $("html, body").animate({ scrollTop: $(window).scrollTop() + 100 }, 500, function() { 18199 scrollToTarget(target); 18200 }); 18201 } else { 18202 scrollToTarget(target); 18203 } 18204 } 18205 } 18206 }); 18207 /* EOF EUTO-1496 */ 18208 18209 /* BOF EUTO-1498 */ 18210 $('.read-more').each(function() { 18211 var $readMore = $(this); 18212 var $readMoreButton = $readMore.siblings('.read-more__button').first(); 18213 18214 if ($readMore.siblings('.read-more__button').length === 0) { 18215 $readMoreButton = $('<span>').addClass('read-more__button').html($readMore.data('readmore')); 18216 18217 $readMoreButton.click(function() { 18218 if ($readMore.is(':visible')) { 18219 $readMore.addClass('read-more--hidden'); 18220 $(this).html($readMore.data('readmore')); 18221 } else { 18222 $readMore.removeClass('read-more--hidden'); 18223 $(this).html($readMore.data('readless')); 18224 } 18225 18226 if (typeof $readMore.data('readless') === 'undefined' || $readMore.data('readless') === '') { 18227 $readMoreButton.hide(); 18228 } 18229 }); 18230 } 18231 18232 if ($readMore.hasClass('read-more--hide-' + state)) { 18233 $readMore.addClass('read-more--hidden'); 18234 $readMoreButton.html($readMore.data('readmore')); 18235 $readMoreButton.appendTo($readMore.parent()); 18236 } else { 18237 $readMoreButton.html($readMore.data('readless')); 18238 $readMore.removeClass('read-more--hidden'); 18239 $readMoreButton.remove(); 18240 } 18241 }); 18242 /* EOF EUTO-1498 */ 18243 18244 /* BOF EUTO-1549 - add logics to change placeholder on devices */ 18245 var $searchField = $('input#searchParam'); 18246 18247 if (state === 'xs') { 18248 $searchField.data('placeholder-default', $searchField.attr('placeholder')); 18249 $searchField.attr('placeholder', $searchField.data('placeholder-xs')); 18250 } else { 18251 if (typeof $searchField.data('placeholder-default') !== 'undefined') { 18252 $searchField.attr('placeholder', $searchField.data('placeholder-default')); 18253 } 18254 } 18255 /* EOF EUTO-1549 */ 18256 18257 $('.product-pictures__big-pictures').slick({ 18258 slidesToShow: 1, 18259 slidesToScroll: 1, 18260 fade: true, 18261 infinite: false, 18262 asNavFor: '.product-pictures__navigation-pictures', 18263 prevArrow: '<div class="slick-prev product-slider__btn product-slider__btn--prev"><i class="icon--icomoon-slider-left"></i></div>', 18264 nextArrow: '<div class="slick-next product-slider__btn product-slider__btn--next"><i class="icon--icomoon-slider-right"></i></div>', 18265 responsive: [ 18266 { 18267 breakpoint: 768, 18268 settings: { 18269 dots: true 18270 } 18271 }, { 18272 breakpoint: 992, 18273 settings: { 18274 } 18275 } 18276 ] 18277 }); 18278 18279 $('.product-pictures__navigation-pictures').slick({ 18280 slidesToShow: 8, 18281 slidesToScroll: 1, 18282 asNavFor: '.product-pictures__big-pictures', 18283 infinite: false, 18284 dots: false,
18285 arrows: false, 18286 focusOnSelect: true, 18287 responsive: [ 18288 { 18289 breakpoint: 768, 18290 settings: { 18291 } 18292 }, { 18293 breakpoint: 992, 18294 settings: { 18295 } 18296 } 18297 ] 18298 }); 18299 18300 $('.slick-slide .img-responsive').on('click', function () { 18301 var $sliderImage = $(this); 18302 var src = $sliderImage.data('zoom'); 18303 18304 if (src === '') { 18305 src = $sliderImage.attr('src'); 18306 } 18307 18308 var alt = $sliderImage.attr('alt'); 18309 var html = "<img src=\"" + src + "\" alt=\"" + alt + "\" />"; 18310 $.fancybox(html); 18311 }); 18312 18313 $('.toggleStickyMenu, .toggleStickyMenu >').on('click', function (event) { 18314 event.preventDefault(); 18315 $('.sticky-header').removeClass('sticky-header--stuck'); 18316 }); 18317}); 18318 18319; 18320var bestitWishlistTrigger = { 18321 isUserLoggedIn: !!$('.headericons--account .account-status').length, 18322 loadedFromUser: false, 18323 wishlistItems: null, 18324 browserStorage: localStorage, 18325 shopId: 1, 18326 langId: 0, 18327 tooltipString: null, 18328 18329 init: function() { 18330 var self = this; 18331 18332 // Remove items from storage after logout 18333 if (window.location.href.indexOf('fnc=logout') !== -1) { 18334 self.clearWishlistItemStorage(); 18335 } 18336 18337 self.setShopId(); 18338 self.setLangId(); 18339 self.setTooltipString(); 18340 self.initTooltips(); 18341 self.initWishlistItems(); 18342 self.initClickEvent(); 18343 }, 18344 initTooltips: function() { 18345 var self = this; 18346 $('body').on('DOMNodeInserted', '.sliphover-container', function () { 18347 var $sliphoverContainer = $(this); 18348 18349 $sliphoverContainer.ready(function() { 18350 self.setTooltipOnMarker($sliphoverContainer.find('.wishlist-marker')); 18351 }); 18352 }); 18353 $('.product__info').on('DOMNodeInserted', '.wishlist-marker', function () { 18354 var $wishlistMarker = $(this); 18355 18356 $wishlistMarker.ready(function() { 18357 self.setTooltipOnMarker($wishlistMarker); 18358 }); 18359 }); 18360 }, 18361 setShopId: function() { 18362 var self = this; 18363 18364 // Try to get shop id 18365 var $shopIdInputFields = $('input[name="shp"]'); 18366 if ($shopIdInputFields.length > 0) { 18367 // From first form on page 18368 self.shopId = $($shopIdInputFields[0]).val(); 18369 } else if (typeof $aMyConfig === 'object' && typeof $aMyConfig.shopid !== 'undefined') { 18370 // From "deprecated" nexus JS code 18371 self.shopId = $aMyConfig.shopid.toString(); 18372 } 18373 }, 18374 setLangId: function() { 18375 var self = this; 18376 18377 // Try to get lang id 18378 var $langIdInputFields = $('input[name="lang"]'); 18379 if ($langIdInputFields.length > 0) { 18380 // From first form on page 18381 self.langId = $($langIdInputFields[0]).val(); 18382 } else if (typeof $aMyConfig === 'object' && typeof $aMyConfig.langid !== 'undefined') { 18383 // From "deprecated" nexus JS code 18384 self.langId = $aMyConfig.langid.toString(); 18385 } 18386 }, 18387 setTooltipString: function() { 18388 var self = this; 18389 18390 if (typeof(self.browserStorage) !== 'undefined' 18391 && typeof(self.browserStorage.tooltipString) !== 'undefined' 18392 ) { 18393 self.tooltipString = JSON.parse(self.browserStorage.tooltipString)[self.langId]; 18394 } else { 18395 $.ajax({ 18396 type: "POST", 18397 url: '/index.php', 18398 dataType: "json", 18399 data: { 18400 shp: self.shopId, 18401 lang: self.langId, 18402 cl: 'bestitWishlistEndpoint', 18403 fnc: 'getWishlistTooltip' 18404 }, 18405 success: function(data) { 18406 self.tooltipString = data['tooltip']; 18407 18408 // Store tooltip string to browser storage 18409 if (typeof(self.browserStorage) !== 'undefined') { 18410 var tooltipObject = {}; 18411 tooltipObject[self.langId] = self.tooltipString; 18412 18413 self.browserStorage.tooltipString = JSON.stringify(tooltipObject); 18414 } 18415 } 18416 }); 18417 } 18418 }, 18419 updateMarkers: function() { 18420 var self = this; 18421 18422 self.clearWishlistMarkers(); 18423 self.initWishlistItems(); 18424 }, 18425 updateWishlistCount: function(newAmount) { 18426 $('.header-account__wishlist-count').html(newAmount); 18427 }, 18428 clearWishlistMarkers: function() { 18429 $('.product .wishlist-marker').remove(); 18430 }, 18431 initWishlistItems: function() { 18432 var self = this; 18433 18434 if (!self.isUserLoggedIn) { 18435 self.wishlistItems = []; 18436 self.addWishlistMarker(); 18437 return; 18438 } 18439 18440 if (self.wishlistItems !== null && self.loadedFromUser === true) { 18441 self.addWishlistMarker(); 18442 self.updateWishlistCount(self.wishlistItems.length); 18443 return; 18444 } 18445 18446 // Try to get wishlist items from browser storage 18447 if (typeof(self.browserStorage) !== 'undefined' && typeof(self.browserStorage.wishlistItems) !== 'undefined') { 18448 self.wishlistItems = JSON.parse(self.browserStorage.wishlistItems); 18449 self.addWishlistMarker(); 18450 self.updateWishlistCount(self.wishlistItems.length); 18451 return; 18452 } 18453 18454 // Get wishlist items from shop 18455 self.updateWishlistItemsFromRemote(); 18456 }, 18457 updateWishlistItemsFromRemote: function() { 18458 var self = this; 18459 18460 $.getJSON('/index.php?cl=bestitWishlistEndpoint&fnc=getUserWishlistItems&shp='+self.shopId, function(data) { 18461 self.wishlistItems = data; 18462 }).done(function() { 18463 self.loadedFromUser = true; 18464 18465 self.storeWishlistItemsToStorage(); 18466 self.addWishlistMarker(); 18467 }); 18468 }, 18469 clearWishlistItemStorage: function() { 18470 var self = this; 18471 18472 if (typeof(self.browserStorage) !== 'undefined' && typeof(self.browserStorage.wishlistItems) !== 'undefined') { 18473 self.browserStorage.removeItem('wishlistItems'); 18474 } 18475 }, 18476 addWishlistMarker: function() { 18477 return; 18478 var self = this; 18479
18480 var $productContentList = $('.product .product__content, .productBox .product__content'); 18481 var $wishListMarkerRaw = $('<div class="product__wishlist-marker wishlist-marker"><i class="wishlist-marker__icon fa" aria-hidden="true"></i></div>'); 18482 18483 $productContentList.each(function(index){ 18484 var $productContent = $(this); 18485 var $wishListMarker = $wishListMarkerRaw.clone(true); 18486 $wishListMarker.attr('data-productid', $productContent.data('productid')); 18487 18488 // Set active state 18489 if ($.inArray($wishListMarker.data('productid'), self.wishlistItems) > -1) { 18490 self.changeMarker($wishListMarker, 'active'); 18491 } else { 18492 self.changeMarker($wishListMarker, 'inactive'); 18493 } 18494 18495 // Add marker to product widget 18496 $wishListMarker.clone(true).appendTo($productContent.find('.product__info')); 18497 18498 // Add Marker to sliphover container, too 18499 var $caption = $($productContent.data('caption')); 18500 $wishListMarker.clone(true).appendTo($caption); 18501 $productContent.attr('data-caption', $caption.prop('outerHTML')); 18502 }); 18503 }, 18504 setTooltipOnMarker: function($marker) { 18505 var self = this; 18506 18507 // Set up tooltip on hover 18508 if (self.tooltipString !== null) { 18509 $marker.tooltip({ 18510 title: self.tooltipString 18511 }); 18512 } 18513 }, 18514 changeMarker: function($marker, state) { 18515 if (state === 'active') { 18516 $($marker.addClass('wishlist-marker---active').find('.wishlist-marker__icon')).removeClass('fa-heart-o').addClass('fa-heart'); 18517 } else if (state === 'inactive') { 18518 $($marker.removeClass('wishlist-marker---active').find('.wishlist-marker__icon')).removeClass('fa-heart').addClass('fa-heart-o'); 18519 } 18520 }, 18521 initClickEvent: function() { 18522 var self = this; 18523 18524 $('body').on('click', '.wishlist-marker', function(event) { 18525 event.stopPropagation(); 18526 18527 var $this = $(this); 18528 18529 if (!self.isUserLoggedIn) { 18530 self.displayLoginInfo($this); 18531 return false; 18532 } else if ($this.hasClass('wishlist-marker---active')) { 18533 self.removeFromWishlist($this); 18534 } else { 18535 self.addToWishlist($this); 18536 } 18537 18538 self.updateMarkers(); 18539 18540 return false; 18541 }); 18542 }, 18543 displayLoginInfo: function($marker) { 18544 var self = this; 18545 var $loginModal = $('.login-to-wishlist-modal'); 18546 18547 if ($loginModal.length < 1) { 18548 // Get login flyout html from server 18549 if (typeof bestitNavigationParameterString === 'undefined') { 18550 bestitNavigationParameterString = ''; 18551 } 18552 18553 $.ajax({ 18554 type: "GET", 18555 url: '/index.php?'+bestitNavigationParameterString, 18556 data: { 18557 shp: self.shopId, 18558 lang: self.langId, 18559 cl: 'bestitWishlistEndpoint', 18560 fnc: 'getLoginModal', 18561 productid: $marker.data('productid') 18562 }, 18563 success: function(data) { 18564 $('body').append(data); 18565 18566 $loginModal = $('.login-to-wishlist-modal'); 18567 18568 if ($loginModal.length) { 18569 const modal = bootstrap.Modal.getOrCreateInstance($loginModal[0]); 18570 modal.show(); 18571 } 18572 } 18573 }); 18574 } else { 18575 if ($loginModal.length) { 18576 const modal = bootstrap.Modal.getOrCreateInstance($loginModal[0]); 18577 modal.show(); 18578 } 18579 } 18580 }, 18581 addToWishlist: function($marker) { 18582 var self = this; 18583 18584 self.wishlistItems.push($marker.data('productid')); 18585 self.storeWishlistItemsToStorage(); 18586 18587 $.ajax({ 18588 type: "POST", 18589 dataType: "json", 18590 url: '/index.php', 18591 data: { 18592 shp: self.shopId, 18593 cl: 'bestitWishlistEndpoint', 18594 fnc: 'addProductToWishlist', 18595 productid: $marker.data('productid') 18596 }, 18597 success: function(data) { 18598 self.updateWishlistCount(data); 18599 } 18600 }); 18601 18602 self.changeMarker($marker, 'active'); 18603 }, 18604 removeFromWishlist: function($marker) { 18605 var self = this; 18606 18607 self.wishlistItems.splice(self.wishlistItems.indexOf($marker.data('productid')), 1); 18608 self.storeWishlistItemsToStorage(); 18609 18610 $.ajax({ 18611 type: "POST", 18612 dataType: "json", 18613 url: '/index.php', 18614 data: { 18615 shp: self.shopId, 18616 cl: 'bestitWishlistEndpoint', 18617 fnc: 'removeProductFromWishlist', 18618 productid: $marker.data('productid') 18619 }, 18620 success: function(data) { 18621 self.updateWishlistCount(data); 18622 } 18623 }); 18624 18625 self.changeMarker($marker, 'inactive'); 18626 }, 18627 storeWishlistItemsToStorage: function() { 18628 var self = this; 18629 18630 // Store wishlist items to browser storage 18631 if (typeof(self.browserStorage) !== 'undefined') { 18632 self.browserStorage.wishlistItems = JSON.stringify(self.wishlistItems); 18633 } 18634 } 18635}; 18636 18637; 18638!function(a){oxEqualizer={equalHeight:function(b,c){var d=this,e=0,f=0,g=0;
18638c?b.height()<c.height()&&(f=c.height()-(b.innerHeight()-b.height())):f=d.getTallest(b),f&&b.each(function(){a(this).hasClass("oxEqualized")&&(a(this).css("height",""),a(this).removeClass("oxEqualized")),(g=a(this).outerHeight())<f&&(e=f-(g-a(this).height()),a(this).height(e).addClass("oxEqualized"))})},getTallest:function(b){var c=0;return b.each(function(){var b=a(this).outerHeight();!a(this).hasClass("oxEqualized")&&b>c&&(c=b)}),c}},a.widget("ui.oxEqualizer",oxEqualizer)}(jQuery); 18639; 18640var foun10RealtimeInformation = { 18641 shopId: 1, 18642 langId: 0, 18643 actionUrl: '/index.php', 18644 18645 init: function() { 18646 var self = this; 18647 18648 self.setShopId(); 18649 self.setLangId(); 18650 self.setActionUrl(); 18651 }, 18652 18653 setShopId: function() { 18654 var self = this; 18655 18656 // Try to get shop id 18657 var $shopIdInputFields = $('input[name="shp"]'); 18658 if ($shopIdInputFields.length > 0) { 18659 // From first form on page 18660 self.shopId = $($shopIdInputFields[0]).val(); 18661 } else if (typeof $aMyConfig === 'object' && typeof $aMyConfig.shopid !== 'undefined') { 18662 // From "deprecated" nexus JS code 18663 self.shopId = $aMyConfig.shopid.toString(); 18664 } 18665 }, 18666 setLangId: function() { 18667 var self = this; 18668 18669 // Try to get lang id 18670 var $langIdInputFields = $('input[name="lang"]'); 18671 if ($langIdInputFields.length > 0) { 18672 // From first form on page 18673 self.langId = $($langIdInputFields[0]).val(); 18674 } else if (typeof $aMyConfig === 'object' && typeof $aMyConfig.langid !== 'undefined') { 18675 // From "deprecated" nexus JS code 18676 self.langId = $aMyConfig.langid.toString(); 18677 } 18678 }, 18679 setActionUrl: function() { 18680 var self = this; 18681 18682 // Try to get shop url 18683 var $shopIdInputFields = $('input[name="shp"]'); 18684 if ($shopIdInputFields.length > 0) { 18685 // From first "shop" form on page 18686 self.actionUrl = $($shopIdInputFields[0]).closest('form').attr('action'); 18687 18688 if (self.actionUrl.indexOf('?') > 0) { 18689 self.actionUrl = self.actionUrl.substr(0, self.actionUrl.indexOf('?')); 18690 } 18691 } else if (typeof $aMyConfig === 'object' && typeof $aMyConfig.selflink !== 'undefined') { 18692 // From "deprecated" nexus JS code 18693 self.actionUrl = $aMyConfig.selflink.toString(); 18694 } 18695 }, 18696 push: function() { 18697 var self = this; 18698 var command = arguments[0]; 18699 var params = []; 18700 for (var j = 1; j < arguments.length; ++j) { 18701 params.push(arguments[j]); 18702 } 18703 if (self.hasOwnProperty(command)) { 18704 return self[command].apply(self, params); 18705 } 18706 }, 18707 track: function(action, objectid) { 18708 var self = this; 18709 self.request({fnc: 'trackAction', action: action, objectid: objectid}); 18710 }, 18711 display: function(objectid, foun10RealtimeDisplayCallback) { 18712 var self = this; 18713 self.request({fnc: 'getInformation', objectid: objectid}).done(function(data) { 18714 foun10RealtimeDisplayCallback(data); 18715 }); 18716 }, 18717 request: function(parameter) { 18718 var self = this; 18719 var response; 18720 var defaultParameter = { 18721 shp: self.shopId, 18722 cl: 'foun10RealtimeInformationEndpoint' 18723 }; 18724 18725 return $.ajax({ 18726 type: "POST", 18727 dataType: "json", 18728 url: self.actionUrl, 18729 data: Object.assign(defaultParameter, parameter) 18730 }); 18731 } 18732}; 18733 18734foun10RealtimeInformation.init();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.