PageSourceSearch

https://alexandraumlas.com/_static/??-eJydktFOBDEIRX/IDmPcZOOD8VNM…/z5WYJvpSvyd9stcf2W5/x0f3yc5+P8cDisn1YG+BM=

js alexandraumlas.com collected 2026-10-06 22:56:50 UTC 214,183 bytes, 5,864 lines download raw bytes

1(()=>{(function(){var Scroller,stats,type,text,totop,loading_text,isIE=-1!==navigator.userAgent.search("MSIE");if(isIE){var IEVersion=navigator.userAgent.match(/MSIE\s?(\d+)\.?\d*;/);IEVersion=parseInt(IEVersion[1])}function fullscreenState(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement?1:0}"https:"===document.location.protocol&&(infiniteScroll.settings.ajaxurl=infiniteScroll.settings.ajaxurl.replace("http://","https://")),Scroller=function(e){var t=this;this.id=e.id,this.body=document.body,this.window=window,this.element=document.getElementById(e.id),this.wrapperClass=e.wrapper_class,this.ready=!0,this.disabled=!1,this.page=1,this.offset=e.offset,this.currentday=e.currentday,this.order=e.order,this.throttle=!1,this.click_handle=e.click_handle,this.google_analytics=e.google_analytics,this.history=e.history,this.origURL=window.location.href,this.handle=document.createElement("div"),this.handle.setAttribute("id","infinite-handle");var n=document.createElement("span"),i=document.createElement("button");i.textContent=text,n.appendChild(i),this.handle.appendChild(n),this.footer={el:document.getElementById("infinite-footer"),wrap:e.footer},this.checkViewportOnLoadBound=t.checkViewportOnLoad.bind(this),this.wpMediaelement=null,"scroll"===type?(this.window.addEventListener("scroll",function(){t.throttle=!0}),t.gotop(),setInterval(function(){t.throttle&&(t.throttle=!1,t.thefooter(),t.refresh(),t.determineURL())},250),t.ensureFilledViewport(),this.body.addEventListener("is.post-load",t.checkViewportOnLoadBound)):"click"===type&&(this.click_handle&&this.element.appendChild(this.handle),this.handle.addEventListener("click",function(){t.click_handle&&t.handle.parentNode.removeChild(t.handle),t.refresh()})),this.body.addEventListener("is.post-load",t.initializeMejs)},Scroller.prototype.getScrollTop=function(){return window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0},Scroller.prototype.extend=function(e){e=e||{};for(var t=1;t<arguments.length;t++)if(arguments[t])for(var n in arguments[t])Object.hasOwn(arguments[t],n)&&(e[n]=arguments[t][n]);return e},Scroller.prototype.check=function(){return this.measure(this.element,[this.wrapperClass]).bottom<2*this.window.innerHeight},Scroller.prototype.render=function(e){var t=Array.prototype.slice.call(e.fragment.childNodes);for(this.body.classList.add("infinity-success");t.length>0;){var n=t.shift();this.element.appendChild(n)}this.trigger(this.body,"is.post-load",{jqueryEventName:"post-load",data:e}),this.ready=!0},Scroller.prototype.query=function(){return{page:this.page+this.offset,currentday:this.currentday,order:this.order,scripts:window.infiniteScroll.settings.scripts,styles:window.infiniteScroll.settings.styles,query_args:window.infiniteScroll.settings.query_args,query_before:window.infiniteScroll.settings.query_before,last_post_date:window.infiniteScroll.settings.last_post_date}},Scroller.prototype.animate=function(e,t){var n=performance.now();requestAnimationFrame(function i(o){var r=Math.min(1,(o-n)/t);e(r),r<1&&requestAnimationFrame(i)})},Scroller.prototype.gotop=function(){var e=document.getElementById("infinity-blog-title"),t=this;e&&(e.setAttribute("title",totop),e.addEventListener("click",function(e){var n=t.window.pageYOffset;e.preventDefault(),t.animate(function(e){var t=n-n*e;document.documentElement.scrollTop=document.body.scrollTop=t},200)}))},Scroller.prototype.thefooter=function(){var e,t,n,i,o=this;if(this.footer&&this.footer.el){if("string"==typeof this.footer.wrap){try{t=(t=document.getElementById(this.footer.wrap).getBoundingClientRect()).width}catch{t=0}t>479&&(e=this.footer.el.querySelector(".container"))&&(e.style.width=t+"px")}n=parseInt(o.footer.el.style.bottom||-50,10),i=this.window.pageYOffset>=350?0:-50,n!==i&&o.animate(function(e){var t=n+(i-n)*e;o.footer.el.style.bottom=t+"px",1===e&&(n=i)},200)}},Scroller.prototype.urlEncodeJSON=function(e,t){var n,i,o=[];for(var r in e)n=encodeURIComponent(r),i=t?t+"["+n+"]":n,"object"==typeof e[r]?!Array.isArray(e[r])||e[r].length>0?o.push(this.urlEncodeJSON(e[r],i)):o.push(i+"[]="):o.push(i+"="+encodeURIComponent(e[r]));return o.join("&")},Scroller.prototype.refresh=function(){var self=this,query,xhr,loader,customized;if(!this.disabled&&this.ready&&this.check())return this.ready=!1,this.click_handle&&(loader||(document.getElementById("infinite-aria").textContent=loading_text,loader=document.createElement("div"),loader.classList.add("infinite-loader"),loader.setAttribute("role","progress"),loader.innerHTML='<svg class="jetpack-spinner infinite-loader-spinner spinner" width="28" height="28" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><circle cx="50" cy="50" r="46" fill="none" stroke="#ddd" stroke-width="8"/><path d="M 50 4 A 46 46 0 0 1 96 50" fill="none" stroke="currentColor" stroke-width="8" stroke-linecap="round"><animateTransform attributeName="transform" type="rotate" dur="1.4s" from="0 50 50" to="360 50 50" repeatCount="indef
1inite"/></path></svg>'),this.element.appendChild(loader)),query=self.extend({action:"infinite_scroll"},this.query()),"undefined"!=typeof wp&&wp.customize&&wp.customize.settings.theme&&(customized={},query.wp_customize="on",query.theme=wp.customize.settings.theme.stylesheet,wp.customize.each(function(e){e._dirty&&(customized[e.id]=e())}),query.customized=JSON.stringify(customized),query.nonce=wp.customize.settings.nonce.preview),xhr=new XMLHttpRequest,xhr.open("POST",infiniteScroll.settings.ajaxurl,!0),xhr.setRequestHeader("X-Requested-With","XMLHttpRequest"),xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),xhr.send(self.urlEncodeJSON(query)),xhr.onerror=function(){self.click_handle&&loader.parentNode&&loader.parentNode.removeChild(loader),self.ready=!0},xhr.onload=function(){var response=JSON.parse(xhr.responseText),httpCheck=xhr.status>=200&&xhr.status<300,responseCheck=void 0!==response.html;if(response&&httpCheck&&responseCheck){if(self.click_handle&&loader.parentNode&&loader.parentNode.removeChild(loader),response.scripts&&Array.isArray(response.scripts)&&response.scripts.forEach(function(e){var t=e.footer?"body":"head";window.infiniteScroll.settings.scripts.push(e.handle),e.extra_data&&self.appendInlineScript(e.extra_data,t),e.before_handle&&self.appendInlineScript(e.before_handle,t);var n=document.createElement("script");n.type="text/javascript",n.src=e.src,n.id=e.handle,n.async=!1,e.after_handle&&(n.onload=function(){self.appendInlineScript(e.after_handle,t)}),"wp-mediaelement"===e.handle&&self.body.removeEventListener("is.post-load",self.initializeMejs),"wp-mediaelement"===e.handle&&"undefined"==typeof mejs?(self.wpMediaelement={},self.wpMediaelement.tag=n,self.wpMediaelement.element=t,setTimeout(self.maybeLoadMejs.bind(self),250)):document.getElementsByTagName(t)[0].appendChild(n)}),response.styles&&Array.isArray(response.styles)&&response.styles.forEach(function(item){window.infiniteScroll.settings.styles.push(item.handle);var style=document.createElement("link");style.rel="stylesheet",style.href=item.src,style.id=item.handle+"-css",!item.conditional||isIE&&eval(item.conditional.replace(/%ver/g,IEVersion))||(style=!1),style&&document.getElementsByTagName("head")[0].appendChild(style)}),response.fragment=document.createElement("div"),response.fragment.innerHTML=response.html,self.page++,stats&&((new Image).src=document.location.protocol+"//pixel.wp.com/g.gif?"+stats+"&post=0&baba="+Math.random()),"object"==typeof response.postflair&&"object"==typeof WPCOM_sharing_counts&&(WPCOM_sharing_counts=self.extend(WPCOM_sharing_counts,response.postflair)),self.render.call(self,response),"click"===type?(infiniteScroll.settings.wrapper&&document.querySelector("#infinite-view-"+(self.page+self.offset-1)+" a:first-of-type").focus({preventScroll:!0}),response.lastbatch?self.click_handle?(self.body.classList.add("infinity-end"),self.body.classList.remove("infinity-success")):self.trigger(this.body,"infinite-scroll-posts-end"):self.click_handle?self.element.appendChild(self.handle):self.trigger(this.body,"infinite-scroll-posts-more")):response.lastbatch&&(self.disabled=!0,self.body.classList.add("infinity-end"),self.body.classList.remove("infinity-success")),response.currentday&&(self.currentday=response.currentday),self.google_analytics){var ga_url=self.history.path.replace(/%d/,self.page);"object"==typeof _gaq&&_gaq.push(["_trackPageview",ga_url]),"function"==typeof ga&&ga("send","pageview",ga_url)}}else self.click_handle&&loader.parentNode&&loader.parentNode.removeChild(loader)},xhr},Scroller.prototype.appendInlineScript=function(e,t){var n=document.createElement("script"),i=document.createTextNode("//<![CDATA[ \n"+e+"\n//]]>");n.type="text/javascript",n.appendChild(i),document.getElementsByTagName(t)[0].appendChild(n)},Scroller.prototype.maybeLoadMejs=function(){null!==this.wpMediaelement&&("undefined"==typeof mejs?setTimeout(this.maybeLoadMejs.bind(this),250):(document.getElementsByTagName(this.wpMediaelement.element)[0].appendChild(this.wpMediaelement.tag),this.wpMediaelement=null,this.body.addEventListener("is.post-load",this.initializeMejs)))},Scroller.prototype.initializeMejs=function(e){if(e.detail&&e.detail.html&&(-1!==e.detail.html.indexOf("wp-audio-shortcode")||-1!==e.detail.html.indexOf("wp-video-shortcode"))&&"undefined"!=typeof mejs){var t,n={};"undefined"!=typeof _wpmejsSettings&&(n.pluginPath=_wpmejsSettings.pluginPath),n.success=function(e){var t=e.attributes.autoplay&&"false"!==e.attributes.autoplay;"flash"===e.pluginType&&t&&e.addEventListener("canplay",function(){e.play()},!1)},t=document.querySelectorAll(".wp-audio-shortcode, .wp-video-shortcode"),t=(t=Array.prototype.slice.call(t)).filter(function(e){for(;e.parentNode;){if(e.classList.contains("mejs-container"))return!1;e=e.parentNode}return!0});for(var i=0;i<t.length;i++)new MediaElementPlayer(t[i],n)}},Scroller.prototype.measure=function(e,t){t=t||[];for(var n,i,o,r=Array.prototype.slice.call(e.children),s=Number.MAX_VALUE,l=0;r.length>0;){for(n=r.shift(),o=0;o<t.length;o++)if(n.classList.contains(t[o])){r=r.concat(Array.prototype.slice.call(n.children));break}i=n.getBoundingClientRect(),s=Math.min(s,i.top),l=Math.max(l,i.bottom)}var a=Math.round(window.innerHeight/2),d=s<=a&&l>=a;return{top:s,bottom:l,height:l-s,factor:(Math.min(l,a)-Math.max(s,0))/a,isActive:d}},Scroller.prototype.ensureFilledViewport=function(){var e=this,t=e.window.innerHeight,n=e.measure(e.element,[e.wrapperClass]);e.body.removeEventListener("is.post-load",e.checkViewportOnLoadBound),0!==n.bottom&&n.bottom<t&&(e.ready=!0,e.refresh())},Scroller.prototype.checkViewportOnLoad=function(){this.ensureFilledViewport()};var previousFullScrenState=fullscreenState();Scroller.prototype.determineURL=function(){var e,t=this,n=-1,i=fullscreenState(),o=0;if(previousFullScrenState^i)previousFullScrenState=i;else{previousFullScrenState=i,e=document.querySelectorAll("."+t.wrapperClass);for(var r=0;r<e.length;r++){var s=t.measure(e[r]);if(s.isActive){n=parseInt(e[r].dataset.pageNum,10);break}s.factor>o&&(n=parseInt(e[r].dataset.pageNum,10),o=s.factor)}t.updateURL(n)}},Scroller.prototype.updateURL=function(e){if(window.history.pushState){var t=this,n=t.origURL;-1!==e&&(n=window.location.protocol+"//"+t.history.host+t.history.path.replace(/%d/,e)+t.history.parameters),window.location.href!==n&&history.pushState(null,null,n)}},Scroller.prototype.pause=function(){this.disabled=!0},Scroller.prototype.resume=function(){this.disabled=!1},Scroller.prototype.trigger=function(e,t,n){var i;(n=n||{}).jqueryEventName&&"undefined"!=typeof jQuery&&jQuery(e).trigger(n.jqueryEventName,n.data||null);try{i=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n.data||null})}catch{(i=document.createEvent("CustomEvent")).initCustomEvent(t,!0,!0,n.data||null)}e.dispatchEvent(i)};var jetpackInfinityModule=function(){if("object"==typeof infiniteScroll&&(infiniteScroll.
vendor: 23,687 bytes, lines 1-533
1settings.body_class.split(" ").forEach(function(e){e&&document.body.classList.add(e)}),stats=infiniteScroll.settings.stats,type=infiniteScroll.settings.type,text=infiniteScroll.settings.text,totop=infiniteScroll.settings.totop,loading_text=infiniteScroll.settings.loading_text,infiniteScroll.scroller=new Scroller(infiniteScroll.settings),"click"===type)){var e=null;window.addEventListener("scroll",function(){e||(e=setTimeout(function(){infiniteScroll.scroller.determineURL(),e=null},250))})}};"interactive"===document.readyState||"complete"===document.readyState?jetpackInfinityModule():document.addEventListener("DOMContentLoaded",jetpackInfinityModule)})()})();;
2/*
3 * jQuery FlexSlider v2.6.1
4 * Copyright 2012 WooThemes
5 * Contributing Author: Tyler Smith
6 */
7;
8(function ($) {
9
10  var focused = true;
11
12  //FlexSlider: Object Instance
13  $.flexslider = function(el, options) {
14    var slider = $(el);
15
16    // making variables public
17    slider.vars = $.extend({}, $.flexslider.defaults, options);
18
19    var namespace = slider.vars.namespace,
20        msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
21        touch = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch && document instanceof DocumentTouch) && slider.vars.touch,
22        // depricating this idea, as devices are being released with both of these events
23        eventType = "click touchend MSPointerUp keyup",
24        watchedEvent = "",
25        watchedEventClearTimer,
26        vertical = slider.vars.direction === "vertical",
27        reverse = slider.vars.reverse,
28        carousel = (slider.vars.itemWidth > 0),
29        fade = slider.vars.animation === "fade",
30        asNav = slider.vars.asNavFor !== "",
31        methods = {};
32
33    // Store a reference to the slider object
34    $.data(el, "flexslider", slider);
35
36    // Private slider methods
37    methods = {
38      init: function() {
39        slider.animating = false;
40        // Get current slide and make sure it is a number
41        slider.currentSlide = parseInt( ( slider.vars.startAt ? slider.vars.startAt : 0), 10 );
42        if ( isNaN( slider.currentSlide ) ) { slider.currentSlide = 0; }
43        slider.animatingTo = slider.currentSlide;
44        slider.atEnd = (slider.currentSlide === 0 || slider.currentSlide === slider.last);
45        slider.containerSelector = slider.vars.selector.substr(0,slider.vars.selector.search(' '));
46        slider.slides = $(slider.vars.selector, slider);
47        slider.container = $(slider.containerSelector, slider);
48        slider.count = slider.slides.length;
49        // SYNC:
50        slider.syncExists = $(slider.vars.sync).length > 0;
51        // SLIDE:
52        if (slider.vars.animation === "slide") { slider.vars.animation = "swing"; }
53        slider.prop = (vertical) ? "top" : "marginLeft";
54        slider.args = {};
55        // SLIDESHOW:
56        slider.manualPause = false;
57        slider.stopped = false;
58        //PAUSE WHEN INVISIBLE
59        slider.started = false;
60        slider.startTimeout = null;
61        // TOUCH/USECSS:
62        slider.transitions = !slider.vars.video && !fade && slider.vars.useCSS && (function() {
63          var obj = document.createElement('div'),
64              props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
65          for (var i in props) {
66            if ( obj.style[ props[i] ] !== undefined ) {
67              slider.pfx = props[i].replace('Perspective','').toLowerCase();
68              slider.prop = "-" + slider.pfx + "-transform";
69              return true;
70            }
71          }
72          return false;
73        }());
74        slider.ensureAnimationEnd = '';
75        // CONTROLSCONTAINER:
76        if (slider.vars.controlsContainer !== "") slider.controlsContainer = $(slider.vars.controlsContainer).length > 0 && $(slider.vars.controlsContainer);
77        // MANUAL:
78        if (slider.vars.manualControls !== "") slider.manualControls = $(slider.vars.manualControls).length > 0 && $(slider.vars.manualControls);
79
80        // CUSTOM DIRECTION NAV:
81        if (slider.vars.customDirectionNav !== "") slider.customDirectionNav = $(slider.vars.customDirectionNav).length === 2 && $(slider.vars.customDirectionNav);
82
83        // RANDOMIZE:
84        if (slider.vars.randomize) {
85          slider.slides.sort(function() { return (Math.round(Math.random())-0.5); });
86          slider.container.empty().append(slider.slides);
87        }
88
89        slider.doMath();
90
91        // INIT
92        slider.setup("init");
93
94        // CONTROLNAV:
95        if (slider.vars.controlNav) { methods.controlNav.setup(); }
96
97        // DIRECTIONNAV:
98        if (slider.vars.directionNav) { methods.directionNav.setup(); }
99
100        // KEYBOARD:
101        if (slider.vars.keyboard && ($(slider.containerSelector).length === 1 || slider.vars.multipleKeyboard)) {
102          $(document).bind('keyup', function(event) {
103            var keycode = event.keyCode;
104            if (!slider.animating && (keycode === 39 || keycode === 37)) {
105              var target = (keycode === 39) ? slider.getTarget('next') :
106                           (keycode === 37) ? slider.getTarget('prev') : false;
107              slider.flexAnimate(target, slider.vars.pauseOnAction);
108            }
109          });
110        }
111        // MOUSEWHEEL:
112        if (slider.vars.mousewheel) {
113          slider.bind('mousewheel', function(event, delta, deltaX, deltaY) {
114            event.preventDefault();
115            var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev');
116            slider.flexAnimate(target, slider.vars.pauseOnAction);
117          });
118        }
119
120        // PAUSEPLAY
121        if (slider.vars.pausePlay) { methods.pausePlay.setup(); }
122
123        //PAUSE WHEN INVISIBLE
124        if (slider.vars.slideshow && slider.vars.pauseInvisible) { methods.pauseInvisible.init(); }
125
126        // SLIDSESHOW
127        if (slider.vars.slideshow) {
128          if (slider.vars.pauseOnHover) {
129            slider.hover(function() {
130              if (!slider.manualPlay && !slider.manualPause) { slider.pause(); }
131            }, function() {
132              if (!slider.manualPause && !slider.manualPlay && !slider.stopped) { slider.play(); }
133            });
134          }
135          // initialize animation
136          //If we're visible, or we don't use PageVisibility API
137          if(!slider.vars.pauseInvisible || !methods.pauseInvisible.isHidden()) {
138            (slider.vars.initDelay > 0) ? slider.startTimeout = setTimeout(slider.play, slider.vars.initDelay) : slider.play();
139          }
140        }
141
142        // ASNAV:
143        if (asNav) { methods.asNav.setup(); }
144
145        // TOUCH
146        if (touch && slider.vars.touch) { methods.touch(); }
147
148        // FADE&&SMOOTHHEIGHT || SLIDE:
149        if (!fade || (fade && slider.vars.smoothHeight)) { $(window).bind("resize orientationchange focus", methods.resize); }
150
151        slider.find("img").attr("draggable", "false");
152
153        // API: start() Callback
154        setTimeout(function(){
155          slider.vars.start(slider);
156        }, 200);
157      },
158      asNav: {
159        setup: function() {
160          slider.asNav = true;
161          slider.animatingTo = Math.floor(slider.currentSlide/slider.move);
162          slider.currentItem = slider.currentSlide;
163          slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide");
164          if(!msGesture){
165              slider.slides.on(eventType, function(e){
166                e.preventDefault();
167                var $slide = $(this),
168                    target = $slide.index();
169                var posFromLeft = $slide.offset().left - $(slider).scrollLeft(); // Find position of slide relative to left of slider container
170                if( posFromLeft <= 0 && $slide.hasClass( namespace + 'active-slide' ) ) {
171                  slider.flexAnimate(slider.getTarget("prev"), true);
172                } else if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass(namespace + "active-slide")) {
173                  slider.direction = (slider.currentItem < target) ? "next" : "prev";
174                  slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true);
175                }
176              });
177          }else{
178              el._slider = slider;
179              slider.slides.each(function (){
180                  var that = this;
181                  that._gesture = new MSGesture();
182                  that._gesture.target = that;
183                  that.addEventListener("MSPointerDown", function (e){
184                      e.preventDefault();
185                      if(e.currentTarget._gesture) {
186                        e.currentTarget._gesture.addPointer(e.pointerId);
187                      }
188                  }, false);
189                  that.addEventListener("MSGestureTap", function (e){
190                      e.preventDefault();
191                      var $slide = $(this),
192                          target = $slide.index();
193                      if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass('active')) {
194                          slider.direction = (slider.currentItem < target) ? "next" : "prev";
195                          slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true);
196                      }
197                  });
198              });
199          }
200        }
201      },
202      controlNav: {
203        setup: function() {
204          if (!slider.manualControls) {
205            methods.controlNav.setupPaging();
206          } else { // MANUALCONTROLS:
207            methods.controlNav.setupManual();
208          }
209        },
210        setupPaging: function() {
211          var type = (slider.vars.controlNav === "thumbnails") ? 'control-thumbs' : 'control-paging',
212              j = 1,
213              item,
214              slide;
215
216          slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>');
217
218          if (slider.pagingCount > 1) {
219            for (var i = 0; i < slider.pagingCount; i++) {
220              slide = slider.slides.eq(i);
221
222              if ( undefined === slide.attr( 'data-thumb-alt' ) ) { 
223                slide.attr( 'data-thumb-alt', '' ); 
224              }
225              
226              item = $( '<a></a>' ).attr( 'href', '#' ).text( j );
227              if ( slider.vars.controlNav === "thumbnails" ) {
228                item = $( '<img/>' ).attr( 'src', slide.attr( 'data-thumb' ) );
229              }
230              
231              if ( '' !== slide.attr( 'data-thumb-alt' ) ) {
232                item.attr( 'alt', slide.attr( 'data-thumb-alt' ) );
233              }
234
235              if ( 'thumbnails' === slider.vars.controlNav && true === slider.vars.thumbCaptions ) {
236                var captn = slide.attr( 'data-thumbcaption' );
237                if ( '' !== captn && undefined !== captn ) { 
238                  var caption = $('<span></span>' ).addClass( namespace + 'caption' ).text( captn );
239                  item.append( caption );
240                }
241              }
242              
243              var liElement = $( '<li>' );
244              item.appendTo( liElement );
245              liElement.append( '</li>' );
246
247              slider.controlNavScaffold.append(liElement);
248              j++;
249            }
250          }
251
252          // CONTROLSCONTAINER:
253          (slider.controlsContainer) ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold);
254          methods.controlNav.set();
255
256          methods.controlNav.active();
257
258          slider.controlNavScaffold.delegate('a, img', eventType, function(event) {
259            event.preventDefault();
260
261            if (watchedEvent === "" || watchedEvent === event.type) {
262              var $this = $(this),
263                  target = slider.controlNav.index($this);
264
265              if (!$this.hasClass(namespace + 'active')) {
266                slider.direction = (target > slider.currentSlide) ? "next" : "prev";
267                slider.flexAnimate(target, slider.vars.pauseOnAction);
268              }
269            }
270
271            // setup flags to prevent event duplication
272            if (watchedEvent === "") {
273              watchedEvent = event.type;
274            }
275            methods.setToClearWatchedEvent();
276
277          });
278        },
279        setupManual: function() {
280          slider.controlNav = slider.manualControls;
281          methods.controlNav.active();
282
283          slider.controlNav.bind(eventType, function(event) {
284            event.preventDefault();
285
286            if (watchedEvent === "" || watchedEvent === event.type) {
287              var $this = $(this),
288                  target = slider.controlNav.index($this);
289
290              if (!$this.hasClass(namespace + 'active')) {
291                (target > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev";
292                slider.flexAnimate(target, slider.vars.pauseOnAction);
293              }
294            }
295
296            // setup flags to prevent event duplication
297            if (watchedEvent === "") {
298              watchedEvent = event.type;
299            }
300            methods.setToClearWatchedEvent();
301          });
302        },
303        set: function() {
304          var selector = (slider.vars.controlNav === "thumbnails") ? 'img' : 'a';
305          slider.controlNav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlsContainer) ? slider.controlsContainer : slider);
306        },
307        active: function() {
308          slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active");
309        },
310        update: function(action, pos) {
311          if (slider.pagingCount > 1 && action === "add") {
312            slider.controlNavScaffold.append($('<li><a href="#">' + slider.count + '</a></li>'));
313          } else if (slider.pagingCount === 1) {
314            slider.controlNavScaffold.find('li').remove();
315          } else {
316            slider.controlNav.eq(pos).closest('li').remove();
317          }
318          methods.controlNav.set();
319          (slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length) ? slider.update(pos, action) : methods.controlNav.active();
320        }
321      },
322      directionNav: {
323        setup: function() {
324          var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li class="' + namespace + 'nav-prev"><a class="' + namespace + 'prev" href="#">' + slider.vars.prevText + '</a></li><li class="' + namespace + 'nav-next"><a class="' + namespace + 'next" href="#">' + slider.vars.nextText + '</a></li></ul>');
325
326          // CUSTOM DIRECTION NAV:
327          if (slider.customDirectionNav) {
328            slider.directionNav = slider.customDirectionNav;
329          // CONTROLSCONTAINER:
330          } else if (slider.controlsContainer) {
331            $(slider.controlsContainer).append(directionNavScaffold);
332            slider.directionNav = $('.' + namespace + 'direction-nav li a', slider.controlsContainer);
333          } else {
334            slider.append(directionNavScaffold);
335            slider.directionNav = $('.' + namespace + 'direction-nav li a', slider);
336          }
337
338          methods.directionNav.update();
339
340          slider.directionNav.bind(eventType, function(event) {
341            event.preventDefault();
342            var target;
343
344            if (watchedEvent === "" || watchedEvent === event.type) {
345              target = ($(this).hasClass(namespace + 'next')) ? slider.getTarget('next') : slider.getTarget('prev');
346              slider.flexAnimate(target, slider.vars.pauseOnAction);
347            }
348
349            // setup flags to prevent event duplication
350            if (watchedEvent === "") {
351              watchedEvent = event.type;
352            }
353            methods.setToClearWatchedEvent();
354          });
355        },
356        update: function() {
357          var disabledClass = namespace + 'disabled';
358          if (slider.pagingCount === 1) {
359            slider.directionNav.addClass(disabledClass).attr('tabindex', '-1');
360          } else if (!slider.vars.animationLoop) {
361            if (slider.animatingTo === 0) {
362              slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "prev").addClass(disabledClass).attr('tabindex', '-1');
363            } else if (slider.animatingTo === slider.last) {
364              slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "next").addClass(disabledClass).attr('tabindex', '-1');
365            } else {
366              slider.directionNav.removeClass(disabledClass).removeAttr('tabindex');
367            }
368          } else {
369            slider.directionNav.removeClass(disabledClass).removeAttr('tabindex');
370          }
371        }
372      },
373      pausePlay: {
374        setup: function() {
375          var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a href="#"></a></div>');
376
377          // CONTROLSCONTAINER:
378          if (slider.controlsContainer) {
379            slider.controlsContainer.append(pausePlayScaffold);
380            slider.pausePlay = $('.' + namespace + 'pauseplay a', slider.controlsContainer);
381          } else {
382            slider.append(pausePlayScaffold);
383            slider.pausePlay = $('.' + namespace + 'pauseplay a', slider);
384          }
385
386          methods.pausePlay.update((slider.vars.slideshow) ? namespace + 'pause' : namespace + 'play');
387
388          slider.pausePlay.bind(eventType, function(event) {
389            event.preventDefault();
390
391            if (watchedEvent === "" || watchedEvent === event.type) {
392              if ($(this).hasClass(namespace + 'pause')) {
393                slider.manualPause = true;
394                slider.manualPlay = false;
395                slider.pause();
396              } else {
397                slider.manualPause = false;
398                slider.manualPlay = true;
399                slider.play();
400              }
401            }
402
403            // setup flags to prevent event duplication
404            if (watchedEvent === "") {
405              watchedEvent = event.type;
406            }
407            methods.setToClearWatchedEvent();
408          });
409        },
410        update: function(state) {
411          (state === "play") ? slider.pausePlay.removeClass(namespace + 'pause').addClass(namespace + 'play').html(slider.vars.playText) : slider.pausePlay.removeClass(namespace + 'play').addClass(namespace + 'pause').html(slider.vars.pauseText);
412        }
413      },
414      touch: function() {
415        var startX,
416          startY,
417          offset,
418          cwidth,
419          dx,
420          startT,
421          onTouchStart,
422          onTouchMove,
423          onTouchEnd,
424          scrolling = false,
425          localX = 0,
426          localY = 0,
427          accDx = 0;
428
429        if(!msGesture){
430            onTouchStart = function(e) {
431              if (slider.animating) {
432                e.preventDefault();
433              } else if ( ( window.navigator.msPointerEnabled ) || e.touches.length === 1 ) {
434                slider.pause();
435                // CAROUSEL:
436                cwidth = (vertical) ? slider.h : slider. w;
437                startT = Number(new Date());
438                // CAROUSEL:
439
440                // Local vars for X and Y points.
441                localX = e.touches[0].pageX;
442                localY = e.touches[0].pageY;
443
444                offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 :
445                         (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
446                         (carousel && slider.currentSlide === slider.last) ? slider.limit :
447                         (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide :
448                         (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth;
449                startX = (vertical) ? localY : localX;
450                startY = (vertical) ? localX : localY;
451
452                el.addEventListener('touchmove', onTouchMove, false);
453                el.addEventListener('touchend', onTouchEnd, false);
454              }
455            };
456
457            onTouchMove = function(e) {
458              // Local vars for X and Y points.
459
460              localX = e.touches[0].pageX;
461              localY = e.touches[0].pageY;
462
463              dx = (vertical) ? startX - localY : startX - localX;
464              scrolling = (vertical) ? (Math.abs(dx) < Math.abs(localX - startY)) : (Math.abs(dx) < Math.abs(localY - startY));
465
466              var fxms = 500;
467
468              if ( ! scrolling || Number( new Date() ) - startT > fxms ) {
469                e.preventDefault();
470                if (!fade && slider.transitions) {
471                  if (!slider.vars.animationLoop) {
472                    dx = dx/((slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1);
473                  }
474                  slider.setProps(offset + dx, "setTouch");
475                }
476              }
477            };
478
479            onTouchEnd = function(e) {
480              // finish the touch by undoing the touch session
481              el.removeEventListener('touchmove', onTouchMove, false);
482
483              if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
484                var updateDx = (reverse) ? -dx : dx,
485                    target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev');
486
487                if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) {
488                  slider.flexAnimate(target, slider.vars.pauseOnAction);
489                } else {
490                  if (!fade) { slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true); }
491                }
492              }
493              el.removeEventListener('touchend', onTouchEnd, false);
494
495              startX = null;
496              startY = null;
497              dx = null;
498              offset = null;
499            };
500
501            el.addEventListener('touchstart', onTouchStart, false);
502        }else{
503            el.style.msTouchAction = "none";
504            el._gesture = new MSGesture();
505            el._gesture.target = el;
506            el.addEventListener("MSPointerDown", onMSPointerDown, false);
507            el._slider = slider;
508            el.addEventListener("MSGestureChange", onMSGestureChange, false);
509            el.addEventListener("MSGestureEnd", onMSGestureEnd, false);
510
511            function onMSPointerDown(e){
512                e.stopPropagation();
513                if (slider.animating) {
514                    e.preventDefault();
515                }else{
516                    slider.pause();
517                    el._gesture.addPointer(e.pointerId);
518                    accDx = 0;
519                    cwidth = (vertical) ? slider.h : slider. w;
520                    startT = Number(new Date());
521                    // CAROUSEL:
522
523                    offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 :
524                        (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
525                            (carousel && slider.currentSlide === slider.last) ? slider.limit :
526                                (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide :
527                                    (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth;
528                }
529            }
530
531            function onMSGestureChange(e) {
532                e.stopPropagation();
533                var slider = e.target._slider;
534                if(!slider){
535                    return;
536                }
537                var transX = -e.translationX,
538                    transY = -e.translationY;
539
540                //Accumulate translations.
541                accDx = accDx + ((vertical) ? transY : transX);
542                dx = 
vendor: 10,612 bytes, lines 542-799
542accDx;
543                scrolling = (vertical) ? (Math.abs(accDx) < Math.abs(-transX)) : (Math.abs(accDx) < Math.abs(-transY));
544
545                if(e.detail === e.MSGESTURE_FLAG_INERTIA){
546                    setImmediate(function (){
547                        el._gesture.stop();
548                    });
549
550                    return;
551                }
552
553                if (!scrolling || Number(new Date()) - startT > 500) {
554                    e.preventDefault();
555                    if (!fade && slider.transitions) {
556                        if (!slider.vars.animationLoop) {
557                            dx = accDx / ((slider.currentSlide === 0 && accDx < 0 || slider.currentSlide === slider.last && accDx > 0) ? (Math.abs(accDx) / cwidth + 2) : 1);
558                        }
559                        slider.setProps(offset + dx, "setTouch");
560                    }
561                }
562            }
563
564            function onMSGestureEnd(e) {
565                e.stopPropagation();
566                var slider = e.target._slider;
567                if(!slider){
568                    return;
569                }
570                if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
571                    var updateDx = (reverse) ? -dx : dx,
572                        target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev');
573
574                    if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) {
575                        slider.flexAnimate(target, slider.vars.pauseOnAction);
576                    } else {
577                        if (!fade) { slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true); }
578                    }
579                }
580
581                startX = null;
582                startY = null;
583                dx = null;
584                offset = null;
585                accDx = 0;
586            }
587        }
588      },
589      resize: function() {
590        if (!slider.animating && slider.is(':visible')) {
591          if (!carousel) { slider.doMath(); }
592
593          if (fade) {
594            // SMOOTH HEIGHT:
595            methods.smoothHeight();
596          } else if (carousel) { //CAROUSEL:
597            slider.slides.width(slider.computedW);
598            slider.update(slider.pagingCount);
599            slider.setProps();
600          }
601          else if (vertical) { //VERTICAL:
602            slider.viewport.height(slider.h);
603            slider.setProps(slider.h, "setTotal");
604          } else {
605            // SMOOTH HEIGHT:
606            if (slider.vars.smoothHeight) { methods.smoothHeight(); }
607            slider.newSlides.width(slider.computedW);
608            slider.setProps(slider.computedW, "setTotal");
609          }
610        }
611      },
612      smoothHeight: function(dur) {
613        if (!vertical || fade) {
614          var $obj = (fade) ? slider : slider.viewport;
615          (dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingTo).innerHeight()}, dur) : $obj.innerHeight(slider.slides.eq(slider.animatingTo).innerHeight());
616        }
617      },
618      sync: function(action) {
619        var $obj = $(slider.vars.sync).data("flexslider"),
620            target = slider.animatingTo;
621
622        switch (action) {
623          case "animate": $obj.flexAnimate(target, slider.vars.pauseOnAction, false, true); break;
624          case "play": if (!$obj.playing && !$obj.asNav) { $obj.play(); } break;
625          case "pause": $obj.pause(); break;
626        }
627      },
628      uniqueID: function($clone) {
629        // Append _clone to current level and children elements with id attributes
630        $clone.filter( '[id]' ).add($clone.find( '[id]' )).each(function() {
631          var $this = $(this);
632          $this.attr( 'id', $this.attr( 'id' ) + '_clone' );
633        });
634        return $clone;
635      },
636      pauseInvisible: {
637        visProp: null,
638        init: function() {
639          var visProp = methods.pauseInvisible.getHiddenProp();
640          if (visProp) {
641            var evtname = visProp.replace(/[H|h]idden/,'') + 'visibilitychange';
642            document.addEventListener(evtname, function() {
643              if (methods.pauseInvisible.isHidden()) {
644                if(slider.startTimeout) {
645                  clearTimeout(slider.startTimeout); //If clock is ticking, stop timer and prevent from starting while invisible
646                } else {
647                  slider.pause(); //Or just pause
648                }
649              }
650              else {
651                if(slider.started) {
652                  slider.play(); //Initiated before, just play
653                } else {
654                  if (slider.vars.initDelay > 0) {
655                    setTimeout(slider.play, slider.vars.initDelay);
656                  } else {
657                    slider.play(); //Didn't init before: simply init or wait for it
658                  }
659                }
660              }
661            });
662          }
663        },
664        isHidden: function() {
665          var prop = methods.pauseInvisible.getHiddenProp();
666          if (!prop) {
667            return false;
668          }
669          return document[prop];
670        },
671        getHiddenProp: function() {
672          var prefixes = ['webkit','moz','ms','o'];
673          // if 'hidden' is natively supported just return it
674          if ('hidden' in document) {
675            return 'hidden';
676          }
677          // otherwise loop over all the known prefixes until we find one
678          for ( var i = 0; i < prefixes.length; i++ ) {
679              if ((prefixes[i] + 'Hidden') in document) {
680                return prefixes[i] + 'Hidden';
681              }
682          }
683          // otherwise it's not supported
684          return null;
685        }
686      },
687      setToClearWatchedEvent: function() {
688        clearTimeout(watchedEventClearTimer);
689        watchedEventClearTimer = setTimeout(function() {
690          watchedEvent = "";
691        }, 3000);
692      }
693    };
694
695    // public methods
696    slider.flexAnimate = function(target, pause, override, withSync, fromNav) {
697      if (!slider.vars.animationLoop && target !== slider.currentSlide) {
698        slider.direction = (target > slider.currentSlide) ? "next" : "prev";
699      }
700
701      if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev";
702
703      if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) {
704        if (asNav && withSync) {
705          var master = $(slider.vars.asNavFor).data('flexslider');
706          slider.atEnd = target === 0 || target === slider.count - 1;
707          master.flexAnimate(target, true, false, true, fromNav);
708          slider.direction = (slider.currentItem < target) ? "next" : "prev";
709          master.direction = slider.direction;
710
711          if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) {
712            slider.currentItem = target;
713            slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
714            target = Math.floor(target/slider.visible);
715          } else {
716            slider.currentItem = target;
717            slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
718            return false;
719          }
720        }
721
722        slider.animating = true;
723        slider.animatingTo = target;
724
725        // SLIDESHOW:
726        if (pause) { slider.pause(); }
727
728        // API: before() animation Callback
729        slider.vars.before(slider);
730
731        // SYNC:
732        if (slider.syncExists && !fromNav) { methods.sync("animate"); }
733
734        // CONTROLNAV
735        if (slider.vars.controlNav) { methods.controlNav.active(); }
736
737        // !CAROUSEL:
738        // CANDIDATE: slide active class (for add/remove slide)
739        if (!carousel) { slider.slides.removeClass(namespace + 'active-slide').eq(target).addClass(namespace + 'active-slide'); }
740
741        // INFINITE LOOP:
742        // CANDIDATE: atEnd
743        slider.atEnd = target === 0 || target === slider.last;
744
745        // DIRECTIONNAV:
746        if (slider.vars.directionNav) { methods.directionNav.update(); }
747
748        if (target === slider.last) {
749          // API: end() of cycle Callback
750          slider.vars.end(slider);
751          // SLIDESHOW && !INFINITE LOOP:
752          if (!slider.vars.animationLoop) { slider.pause(); }
753        }
754
755        // SLIDE:
756        if (!fade) {
757          var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW,
758              margin, slideString, calcNext;
759
760          // INFINITE LOOP / REVERSE:
761          if (carousel) {
762            margin = slider.vars.itemMargin;
763            calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo;
764            slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext;
765          } else if (slider.currentSlide === 0 && target === slider.count - 1 && slider.vars.animationLoop && slider.direction !== "next") {
766            slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0;
767          } else if (slider.currentSlide === slider.last && target === 0 && slider.vars.animationLoop && slider.direction !== "prev") {
768            slideString = (reverse) ? 0 : (slider.count + 1) * dimension;
769          } else {
770            slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension;
771          }
772          slider.setProps(slideString, "", slider.vars.animationSpeed);
773          if (slider.transitions) {
774            if (!slider.vars.animationLoop || !slider.atEnd) {
775              slider.animating = false;
776              slider.currentSlide = slider.animatingTo;
777            }
778
779            // Unbind previous transitionEnd events and re-bind new transitionEnd event
780            slider.container.unbind("webkitTransitionEnd transitionend");
781            slider.container.bind("webkitTransitionEnd transitionend", function() {
782              clearTimeout(slider.ensureAnimationEnd);
783              slider.wrapup(dimension);
784            });
785
786            // Insurance for the ever-so-fickle transitionEnd event
787            clearTimeout(slider.ensureAnimationEnd);
788            slider.ensureAnimationEnd = setTimeout(function() {
789              slider.wrapup(dimension);
790            }, slider.vars.animationSpeed + 100);
791
792          } else {
793            slider.container.animate(slider.args, slider.vars.animationSpeed, slider.vars.easing, function(){
794              slider.wrapup(dimension);
795            });
796          }
797        } else { // FADE:
798          if (!touch) {
799            
vendor: 13,743 bytes, lines 799-1113
799//slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationSpeed, slider.vars.easing);
800            //slider.slides.eq(target).fadeIn(slider.vars.animationSpeed, slider.vars.easing, slider.wrapup);
801
802            slider.slides.eq(slider.currentSlide).css({"zIndex": 1}).animate({"opacity": 0}, slider.vars.animationSpeed, slider.vars.easing);
803            slider.slides.eq(target).css({"zIndex": 2}).animate({"opacity": 1}, slider.vars.animationSpeed, slider.vars.easing, slider.wrapup);
804
805          } else {
806            slider.slides.eq(slider.currentSlide).css({ "opacity": 0, "zIndex": 1 });
807            slider.slides.eq(target).css({ "opacity": 1, "zIndex": 2 });
808            slider.wrapup(dimension);
809          }
810        }
811        // SMOOTH HEIGHT:
812        if (slider.vars.smoothHeight) { methods.smoothHeight(slider.vars.animationSpeed); }
813      }
814    };
815    slider.wrapup = function(dimension) {
816      // SLIDE:
817      if (!fade && !carousel) {
818        if (slider.currentSlide === 0 && slider.animatingTo === slider.last && slider.vars.animationLoop) {
819          slider.setProps(dimension, "jumpEnd");
820        } else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && slider.vars.animationLoop) {
821          slider.setProps(dimension, "jumpStart");
822        }
823      }
824      slider.animating = false;
825      slider.currentSlide = slider.animatingTo;
826      // API: after() animation Callback
827      slider.vars.after(slider);
828    };
829
830    // SLIDESHOW:
831    slider.animateSlides = function() {
832      if (!slider.animating && focused ) { slider.flexAnimate(slider.getTarget("next")); }
833    };
834    // SLIDESHOW:
835    slider.pause = function() {
836      clearInterval(slider.animatedSlides);
837      slider.animatedSlides = null;
838      slider.playing = false;
839      // PAUSEPLAY:
840      if (slider.vars.pausePlay) { methods.pausePlay.update("play"); }
841      // SYNC:
842      if (slider.syncExists) { methods.sync("pause"); }
843    };
844    // SLIDESHOW:
845    slider.play = function() {
846      if (slider.playing) { clearInterval(slider.animatedSlides); }
847      slider.animatedSlides = slider.animatedSlides || setInterval(slider.animateSlides, slider.vars.slideshowSpeed);
848      slider.started = slider.playing = true;
849      // PAUSEPLAY:
850      if (slider.vars.pausePlay) { methods.pausePlay.update("pause"); }
851      // SYNC:
852      if (slider.syncExists) { methods.sync("play"); }
853    };
854    // STOP:
855    slider.stop = function () {
856      slider.pause();
857      slider.stopped = true;
858    };
859    slider.canAdvance = function(target, fromNav) {
860      // ASNAV:
861      var last = (asNav) ? slider.pagingCount - 1 : slider.last;
862      return (fromNav) ? true :
863             (asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true :
864             (asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next") ? false :
865             (target === slider.currentSlide && !asNav) ? false :
866             (slider.vars.animationLoop) ? true :
867             (slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next") ? false :
868             (slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next") ? false :
869             true;
870    };
871    slider.getTarget = function(dir) {
872      slider.direction = dir;
873      if (dir === "next") {
874        return (slider.currentSlide === slider.last) ? 0 : slider.currentSlide + 1;
875      } else {
876        return (slider.currentSlide === 0) ? slider.last : slider.currentSlide - 1;
877      }
878    };
879
880    // SLIDE:
881    slider.setProps = function(pos, special, dur) {
882      var target = (function() {
883        var posCheck = (pos) ? pos : ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo,
884            posCalc = (function() {
885              if (carousel) {
886                return (special === "setTouch") ? pos :
887                       (reverse && slider.animatingTo === slider.last) ? 0 :
888                       (reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
889                       (slider.animatingTo === slider.last) ? slider.limit : posCheck;
890              } else {
891                switch (special) {
892                  case "setTotal": return (reverse) ? ((slider.count - 1) - slider.currentSlide + slider.cloneOffset) * pos : (slider.currentSlide + slider.cloneOffset) * pos;
893                  case "setTouch": return (reverse) ? pos : pos;
894                  case "jumpEnd": return (reverse) ? pos : slider.count * pos;
895                  case "jumpStart": return (reverse) ? slider.count * pos : pos;
896                  default: return pos;
897                }
898              }
899            }());
900
901            return (posCalc * -1) + "px";
902          }());
903
904      if (slider.transitions) {
905        target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)";
906        dur = (dur !== undefined) ? (dur/1000) + "s" : "0s";
907        slider.container.css("-" + slider.pfx + "-transition-duration", dur);
908         slider.container.css("transition-duration", dur);
909      }
910
911      slider.args[slider.prop] = target;
912      if (slider.transitions || dur === undefined) { slider.container.css(slider.args); }
913
914      slider.container.css('transform',target);
915    };
916
917    slider.setup = function(type) {
918      // SLIDE:
919      if (!fade) {
920        var sliderOffset, arr;
921
922        if (type === "init") {
923          slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({"overflow": "hidden", "position": "relative"}).appendTo(slider).append(slider.container);
924          // INFINITE LOOP:
925          slider.cloneCount = 0;
926          slider.cloneOffset = 0;
927          // REVERSE:
928          if (reverse) {
929            arr = $.makeArray(slider.slides).reverse();
930            slider.slides = $(arr);
931            slider.container.empty().append(slider.slides);
932          }
933        }
934        // INFINITE LOOP && !CAROUSEL:
935        if (slider.vars.animationLoop && !carousel) {
936          slider.cloneCount = 2;
937          slider.cloneOffset = 1;
938          // clear out old clones
939          if (type !== "init") { slider.container.find('.clone').remove(); }
940          slider.container.append(methods.uniqueID(slider.slides.first().clone().addClass('clone')).attr('aria-hidden', 'true'))
941                          .prepend(methods.uniqueID(slider.slides.last().clone().addClass('clone')).attr('aria-hidden', 'true'));
942        }
943        slider.newSlides = $(slider.vars.selector, slider);
944
945        sliderOffset = (reverse) ? slider.count - 1 - slider.currentSlide + slider.cloneOffset : slider.currentSlide + slider.cloneOffset;
946        // VERTICAL:
947        if (vertical && !carousel) {
948          slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%");
949          setTimeout(function(){
950            slider.newSlides.css({"display": "block"});
951            slider.doMath();
952            slider.viewport.height(slider.h);
953            slider.setProps(sliderOffset * slider.h, "init");
954          }, (type === "init") ? 100 : 0);
955        } else {
956          slider.container.width((slider.count + slider.cloneCount) * 200 + "%");
957          slider.setProps(sliderOffset * slider.computedW, "init");
958          setTimeout(function(){
959            slider.doMath();
960            slider.newSlides.css({"width": slider.computedW, "marginRight" : slider.computedM, "float": "left", "display": "block"});
961            // SMOOTH HEIGHT:
962            if (slider.vars.smoothHeight) { methods.smoothHeight(); }
963          }, (type === "init") ? 100 : 0);
964        }
965      } else { // FADE:
966        slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%", "position": "relative"});
967        if (type === "init") {
968          if (!touch) {
969            //slider.slides.eq(slider.currentSlide).fadeIn(slider.vars.animationSpeed, slider.vars.easing);
970            if (slider.vars.fadeFirstSlide == false) {
971              slider.slides.css({ "opacity": 0, "display": "block", "zIndex": 1 }).eq(slider.currentSlide).css({"zIndex": 2}).css({"opacity": 1});
972            } else {
973              slider.slides.css({ "opacity": 0, "display": "block", "zIndex": 1 }).eq(slider.currentSlide).css({"zIndex": 2}).animate({"opacity": 1},slider.vars.animationSpeed,slider.vars.easing);
974            }
975          } else {
976            slider.slides.css({ "opacity": 0, "display": "block", "webkitTransition": "opacity " + slider.vars.animationSpeed / 1000 + "s ease", "zIndex": 1 }).eq(slider.currentSlide).css({ "opacity": 1, "zIndex": 2});
977          }
978        }
979        // SMOOTH HEIGHT:
980        if (slider.vars.smoothHeight) { methods.smoothHeight(); }
981      }
982      // !CAROUSEL:
983      // CANDIDATE: active slide
984      if (!carousel) { slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide"); }
985
986      //FlexSlider: init() Callback
987      slider.vars.init(slider);
988    };
989
990    slider.doMath = function() {
991      var slide = slider.slides.first(),
992          slideMargin = slider.vars.itemMargin,
993          minItems = slider.vars.minItems,
994          maxItems = slider.vars.maxItems;
995
996      slider.w = (slider.viewport===undefined) ? slider.width() : slider.viewport.width();
997      slider.h = slide.height();
998      slider.boxPadding = slide.outerWidth() - slide.width();
999
1000      // CAROUSEL:
1001      if (carousel) {
1002        slider.itemT = slider.vars.itemWidth + slideMargin;
1003        slider.itemM = slideMargin;
1004        slider.minW = (minItems) ? minItems * slider.itemT : slider.w;
1005        slider.maxW = (maxItems) ? (maxItems * slider.itemT) - slideMargin : slider.w;
1006        slider.itemW = (slider.minW > slider.w) ? (slider.w - (slideMargin * (minItems - 1)))/minItems :
1007                       (slider.maxW < slider.w) ? (slider.w - (slideMargin * (maxItems - 1)))/maxItems :
1008                       (slider.vars.itemWidth > slider.w) ? slider.w : slider.vars.itemWidth;
1009
1010        slider.visible = Math.floor(slider.w/(slider.itemW));
1011        slider.move = (slider.vars.move > 0 && slider.vars.move < slider.visible ) ? slider.vars.move : slider.visible;
1012        slider.pagingCount = Math.ceil(((slider.count - slider.visible)/slider.move) + 1);
1013        slider.last =  slider.pagingCount - 1;
1014        slider.limit = (slider.pagingCount === 1) ? 0 :
1015                       (slider.vars.itemWidth > slider.w) ? (slider.itemW * (slider.count - 1)) + (slideMargin * (slider.count - 1)) : ((slider.itemW + slideMargin) * slider.count) - slider.w - slideMargin;
1016      } else {
1017        slider.itemW = slider.w;
1018        slider.itemM = slideMargin;
1019        slider.pagingCount = slider.count;
1020        slider.last = slider.count - 1;
1021      }
1022      slider.computedW = slider.itemW - slider.boxPadding;
1023      slider.computedM = slider.itemM;
1024    };
1025
1026    slider.update = function(pos, action) {
1027      slider.doMath();
1028
1029      // update currentSlide and slider.animatingTo if necessary
1030      if (!carousel) {
1031        if (pos < slider.currentSlide) {
1032          slider.currentSlide += 1;
1033        } else if (pos <= slider.currentSlide && pos !== 0) {
1034          slider.currentSlide -= 1;
1035        }
1036        slider.animatingTo = slider.currentSlide;
1037      }
1038
1039      // update controlNav
1040      if (slider.vars.controlNav && !slider.manualControls) {
1041        if ((action === "add" && !carousel) || slider.pagingCount > slider.controlNav.length) {
1042          methods.controlNav.update("add");
1043        } else if ((action === "remove" && !carousel) || slider.pagingCount < slider.controlNav.length) {
1044          if (carousel && slider.currentSlide > slider.last) {
1045            slider.currentSlide -= 1;
1046            slider.animatingTo -= 1;
1047          }
1048          methods.controlNav.update("remove", slider.last);
1049        }
1050      }
1051      // update directionNav
1052      if (slider.vars.directionNav) { methods.directionNav.update(); }
1053
1054    };
1055
1056    slider.addSlide = function(obj, pos) {
1057      var $obj = $(obj);
1058
1059      slider.count += 1;
1060      slider.last = slider.count - 1;
1061
1062      // append new slide
1063      if (vertical && reverse) {
1064        (pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj);
1065      } else {
1066        (pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj);
1067      }
1068
1069      // update currentSlide, animatingTo, controlNav, and directionNav
1070      slider.update(pos, "add");
1071
1072      // update slider.slides
1073      slider.slides = $(slider.vars.selector + ':not(.clone)', slider);
1074      // re-setup the slider to accomdate new slide
1075      slider.setup();
1076
1077      //FlexSlider: added() Callback
1078      slider.vars.added(slider);
1079    };
1080    slider.removeSlide = function(obj) {
1081      var pos = (isNaN(obj)) ? slider.slides.index($(obj)) : obj;
1082
1083      // update count
1084      slider.count -= 1;
1085      slider.last = slider.count - 1;
1086
1087      // remove slide
1088      if (isNaN(obj)) {
1089        $(obj, slider.slides).remove();
1090      } else {
1091        (vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove();
1092      }
1093
1094      // update currentSlide, animatingTo, controlNav, and directionNav
1095      slider.doMath();
1096      slider.update(pos, "remove");
1097
1098      // update slider.slides
1099      slider.slides = $(slider.vars.selector + ':not(.clone)', slider);
1100      // re-setup the slider to accomdate new slide
1101      slider.setup();
1102
1103      // FlexSlider: removed() Callback
1104      slider.vars.removed(slider);
1105    };
1106
1107    //FlexSlider: Initialize
1108    methods.init();
1109  };
1110
1111  // Ensure the slider isn't focussed if the window loses focus.
1112  $( window ).blur( function ( e ) {
1113    focused = false;
1114  }).focus( function ( e ) {
1115    focused = true;
1116  });
1117
1118  //FlexSlider: Default Settings
1119  $.flexslider.defaults = {
1120    namespace: "flex-",             //{NEW} String: Prefix string attached to the class of every element generated by the plugin
1121    selector: ".slides > li",       //{NEW} Selector: Must match a simple pattern. '{container} > {slide}' -- Ignore pattern at your own peril
1122    animation: "fade",              //String: Select your animation type, "fade" or "slide"
1123    easing: "swing",                //{NEW} String: Determines the easing method used in jQuery transitions. jQuery easing plugin is supported!
1124    direction: "horizontal",        //String: Select the sliding direction, "horizontal" or "vertical"
1125    reverse: false,                 //{NEW} Boolean: Reverse the animation direction
1126    animationLoop: true,            //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end
1127    smoothHeight: false,            //{NEW} Boolean: Allow height of the slider to animate smoothly in horizontal mode
1128    startAt: 0,                     //Integer: The slide that the slider should start on. Array notation (0 = first slide)
1129    slideshow: true,                //Boolean: Animate slider automatically
1130    slideshowSpeed: 7000,           //Integer: Set the speed of the slideshow cycling, in milliseconds
1131    animationSpeed: 600,            //Integer: Set the speed of animations, in milliseconds
1132    initDelay: 0,                   //{NEW} Integer: Set an initialization delay, in milliseconds
1133    randomize: false,               //Boolean: Randomize slide order
1134    fadeFirstSlide: true,           //Boolean: Fade in the first slide when animation type is "fade"
1135    thumbCaptions: false,           //Boolean: Whether or not to put captions on thumbnails when using the "thumbnails" controlNav.
1136
1137    // Usability features
1138    pauseOnAction: true,            //Boolean: Pause the slideshow when interacting with control elements, highly recommended.
1139    pauseOnHover: false,            //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering
1140    pauseInvisible: true,   		//{NEW} Boolean: Pause the slideshow when tab is invisible, resume when visible. Provides better UX, lower CPU usage.
1141    useCSS: true,                   //{NEW} Boolean: Slider will use CSS3 transitions if available
1142    touch: true,                    //{NEW} Boolean: Allow touch swipe navigation of the slider on touch-enabled devices
1143    video: false,                   //{NEW} Boolean: If using video in the slider, will prevent CSS3 3D Transforms to avoid graphical glitches
1144
1145    // Primary Controls
1146    controlNav: true,               //Boolean: Create navigation for paging control of each slide? Note: Leave true for manualControls usage
1147    directionNav: true,             //Boolean: Create navigation for previous/next navigation? (true/false)
1148    prevText: "Previous",           //String: Set the text for the "previous" directionNav item
1149    nextText: "Next",               //String: Set the text for the "next" directionNav item
1150
1151    // Secondary Navigation
1152    keyboard: true,                 //Boolean: Allow slider navigating via keyboard left/right keys
1153    multipleKeyboard: false,        //{NEW} Boolean: Allow keyboard navigation to affect multiple sliders. Default behavior cuts out keyboard navigation with more than one slider present.
1154    mousewheel: false,              //{UPDATED} Boolean: Requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - Allows slider navigating via mousewheel
1155    pausePlay: false,               //Boolean: Create pause/play dynamic element
1156    pauseText: "Pause",             //String: Set the text for the "pause" pausePlay item
1157    playText: "Play",               //String: Set the text for the "play" pausePlay item
1158
1159    // Special properties
1160    controlsContainer: "",          //{UPDATED} jQuery Object/Selector: Declare which container the navigation elements should be appended too. Default container is the FlexSlider element. Example use would be $(".flexslider-container"). Property is ignored if given element is not found.
1161    manualControls: "",             //{UPDATED} jQuery Object/Selector: Declare custom control navigation. Examples would be $(".flex-control-nav li") or "#tabs-nav li img", etc. The number of elements in your controlNav should match the number of slides/tabs.
1162    customDirectionNav: "",         //{NEW}
1162 jQuery Object/Selector: Custom prev / next button. Must be two jQuery elements. In order to make the events work they have to have the classes "prev" and "next" (plus namespace)
1163    sync: "",                       //{NEW} Selector: Mirror the actions performed on this slider with another slider. Use with care.
1164    asNavFor: "",                   //{NEW} Selector: Internal property exposed for turning the slider into a thumbnail navigation for another slider
1165
1166    // Carousel Options
1167    itemWidth: 0,                   //{NEW} Integer: Box-model width of individual carousel items, including horizontal borders and padding.
1168    itemMargin: 0,                  //{NEW} Integer: Margin between carousel items.
1169    minItems: 1,                    //{NEW} Integer: Minimum number of carousel items that should be visible. Items will resize fluidly when below this.
1170    maxItems: 0,                    //{NEW} Integer: Maxmimum number of carousel items that should be visible. Items will resize fluidly when above this limit.
1171    move: 0,                        //{NEW} Integer: Number of carousel items that should move on animation. If 0, slider will move all visible items.
1172    allowOneSlide: true,           //{NEW} Boolean: Whether or not to allow a slider comprised of a single slide
1173
1174    // Callback API
1175    start: function(){},            //Callback: function(slider) - Fires when the slider loads the first slide
1176    before: function(){},           //Callback: function(slider) - Fires asynchronously with each slider animation
1177    after: function(){},            //Callback: function(slider) - Fires after each slider animation completes
1178    end: function(){},              //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous)
1179    added: function(){},            //{NEW} Callback: function(slider) - Fires after a slide is added
1180    removed: function(){},           //{NEW} Callback: function(slider) - Fires after a slide is removed
1181    init: function() {}             //{NEW} Callback: function(slider) - Fires after the slider is initially setup
1182  };
1183
1184  //FlexSlider: Plugin Function
1185  $.fn.flexslider = function(options) {
1186    if (options === undefined) { options = {}; }
1187
1188    if (typeof options === "object") {
1189      return this.each(function() {
1190        var $this = $(this),
1191            selector = (options.selector) ? options.selector : ".slides > li",
1192            $slides = $this.find(selector);
1193
1194      if ( ( $slides.length === 1 && options.allowOneSlide === false ) || $slides.length === 0 ) {
1195          $slides.fadeIn(400);
1196          if (options.start) { options.start($this); }
1197        } else if ($this.data('flexslider') === undefined) {
1198          new $.flexslider(this, options);
1199        }
1200      });
1201    } else {
1202      // Helper strings to quickly perform functions on the slider
1203      var $slider = $(this).data('flexslider');
1204      switch (options) {
1205        case "play": $slider.play(); break;
1206        case "pause": $slider.pause(); break;
1207        case "stop": $slider.stop(); break;
1208        case "next": $slider.flexAnimate($slider.getTarget("next"), true); break;
1209        case "prev":
1210        case "previous": $slider.flexAnimate($slider.getTarget("prev"), true); break;
1211        default: if (typeof options === "number") { $slider.flexAnimate(options, true); }
1212      }
1213    }
1214  };
1215})(jQuery);
1216;
1217/**
1218 * Column list Plugin
1219 * - Breaks up a list into separate columns
1220 * - src: https://github.com/weblinc/jquery-columnlist
1221 *
1222	Copyright (c) 2012 WebLinc LLC
1223
1224	Permission is hereby granted, free of charge, to any person obtaining a copy
1225	of this software and associated documentation files (the "Software"), to deal
1226	in the Software without restriction, including without limitation the rights
1227	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1228	copies of the Software, and to permit persons to whom the Software is
1229	furnished to do so, subject to the following conditions:
1230
1231	The above copyright notice and this permission notice shall be included in
1232	all copies or substantial portions of the Software.
1233 */
1234
1235(function($){
1236
1237	jQuery.fn.columnlist = function( options ) {
1238
1239		options = $.extend( {}, $.fn.columnlist.defaults, options );
1240
1241		return this.each(function () {
1242
1243			var	$list			= $( this ),
1244				size			= options.size || $list.data( 'columnList' ) || 1,
1245				$children	= $list.children('li'),
1246				perColumn	= Math.ceil( $children.length / size ),
1247				$column;
1248
1249			for ( var i = 0; i < size; i++ ) {
1250
1251				// Set up column wrapper
1252				$column = $('<ul />');
1253
1254				for ( var j = 0; j < perColumn; j++ ) {
1255					if ( $children.length > i * perColumn + j ) {
1256						// Add class to column wrapper
1257						$column.addClass(options['class']).addClass(options.incrementClass + i).append( $children[ i * perColumn + j ]);
1258					}
1259				}
1260
1261				// Add new columns
1262				$list.parent().append( $column );
1263			}
1264
1265			// Remove original list
1266			$list.remove();
1267		});
1268	};
1269
1270	// Defaults
1271	$.fn.columnlist.defaults = {
1272		'class'        : 'nav-menu',
1273		incrementClass : 'nav-menu-'
1274	};
1275
1276})(jQuery);
1277;
1278/**
1279 * File navigation.js.
1280 *
1281 * Handles toggling the navigation menu for small screens and enables TAB key
1282 * navigation support for dropdown menus.
1283 */
1284
1285/* global altoFocusScreenReaderText */
1286( function( $ ) {
1287
1288	var body,
1289		masthead           = $( '#masthead' ),
1290		menuToggle         = masthead.find( '.menu-toggle' ),
1291		siteMenu           = masthead.find( '.top-navigation' ),
1292		siteNavigation     = masthead.find( '.top-navigation > div' ),
1293		siteBrandingHeight = masthead.find( '.site-branding-wrap' ).outerHeight(),
1294		topNavigation      = $( '.top-navigation' );
1295
1296	/**
1297	 * Initialize the main navigation
1298	 */
1299	function initMainNavigation( container ) {
1300
1301		// Add parent class to sub-menu parent items
1302		container.find( '.sub-menu, .children' ).parents( 'li' ).addClass( 'menu-item-has-children' );
1303
1304		// Add dropdown toggle button
1305		var dropdownToggle = $( '<button />', {
1306				'class': 'dropdown-toggle',
1307				'aria-expanded': false
1308			} ).append( $( '<span />', {
1309				'class': 'screen-reader-text',
1310				text: altoFocusScreenReaderText.expand
1311			})).append( '<span class="meta-nav" aria-hidden="true"><svg class="dropdown-icon dropdown-icon-open" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><polyline class="line" points="2.5,3.8 5,6.2 7.5,3.8 "/></svg><svg class="dropdown-icon dropdown-icon-close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10"><line class="line" x1="2.5" y1="7.5" x2="7.5" y2="2.5"/><line class="line" x1="2.5" y1="2.5" x2="7.5" y2="7.5"/></svg></span>' );
1312
1313		container.find( '.menu-item-has-children > a' ).after( dropdownToggle );
1314
1315		// Change menu items with submenus to aria-haspopup="true".
1316		container.find( '.menu-item-has-children' ).attr( 'aria-haspopup', 'true' );
1317
1318		// Drop down toggle setup
1319		container.find( '.dropdown-toggle' ).click( function( e ) {
1320
1321			var _this            = $( this ),
1322			    otherSubMenus    = _this.parents( '.menu-item-has-children' ).siblings( '.menu-item-has-children' ),
1323			    screenReaderSpan = _this.find( '.screen-reader-text' );
1324
1325			// Disable default behavior
1326			e.preventDefault();
1327
1328			// Stop click outside area function
1329			e.stopPropagation();
1330
1331			// Reveal sub-menus
1332			_this.not( '.menu-toggle' ).toggleClass( 'toggled-on' );
1333			_this.not( '.menu-toggle' ).parent().toggleClass( 'toggled-on' );
1334			_this.next( '.children, .sub-menu' ).toggleClass( 'toggled-on' );
1335
1336			// Close other sub-menus if they're open
1337			otherSubMenus.removeClass( 'toggled-on' );
1338			otherSubMenus.find( '.toggled-on' ).removeClass( 'toggled-on' );
1339
1340			// jscs:disable
1341			_this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );
1342			// jscs:enable
1343
1344			// Update screen reader text
1345			screenReaderSpan.text( screenReaderSpan.text() === altoFocusScreenReaderText.expand ? altoFocusScreenReaderText.collapse : altoFocusScreenReaderText.expand );
1346
1347		} );
1348
1349		// Navigation height should never be shorter than site branding height
1350		container.css( "min-height", siteBrandingHeight );
1351
1352		// Close sub-menus when click outside of menus
1353		$( 'html' ).click( function() {
1354
1355			container.find( '.toggled-on' ).removeClass( 'toggled-on' );
1356		});
1357
1358		// Close expanded sub-menus when clicking links
1359		container.find( 'a' ).click( function( e ) {
1360
1361			var _this         = $( this ),
1362				anchor        = _this.attr( 'href' ),
1363				otherSubMenus = container.find( '.toggled-on' );
1364
1365			//console.log(anchor);
1366			e.preventDefault();
1367
1368			otherSubMenus.removeClass( 'toggled-on' ).attr( 'aria-expanded', 'false' ).attr( 'aria-haspopup', 'false' );
1369
1370			window.location.href = anchor;
1371
1372		} );
1373	}
1374
1375	/**
1376	 * Enable menuToggle
1377	 */
1378	function enableMenuToggle() {
1379
1380		// Return early if menuToggle is missing.
1381		if ( ! menuToggle.length ) {
1382
1383			return;
1384		}
1385
1386		// Add an initial values for the attribute.
1387		menuToggle.add( siteNavigation ).attr( 'aria-expanded', 'false' );
1388
1389		menuToggle.on( 'click.altofocus', function() {
1390
1391			$( this ).toggleClass( 'toggled-on' );
1392
1393			$( this ).add( siteMenu ).add( siteNavigation ).toggleClass( 'toggled-on' );
1394
1395			// jscs:disable
1396			$( this ).add( siteMenu ).add( siteNavigation ).attr( 'aria-expanded', $( this ).add( siteNavigation ).attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );
1397			// jscs:enable
1398		} );
1399	}
1400
1401	/**
1402	 * Fix sub-menus for touch devices and better focus for hidden submenu items for accessibility
1403	 */
1404	function addTouchSupport() {
1405
1406		if ( ! siteNavigation.length || ! siteNavigation.children().length ) {
1407
1408			return;
1409		}
1410
1411		// Toggle `focus` class to allow submenu access on tablets.
1412		function toggleFocusClassTouchScreen() {
1413
1414			//	if ( window.innerWidth >= 896 ) {
1415			$( document.body ).on( 'touchstart.altofocus', function( e ) {
1416
1417				if ( ! $( e.target ).closest( '.top-navigation li' ).length ) {
1418
1419					$( '.top-navigation li' ).removeClass( 'focus' );
1420				}
1421			} );
1422
1423			siteNavigation.find( '.menu-item-has-children > a' ).on( 'touchstart.altofocus', function( e ) {
1424
1425				var el = $( this ).parent( 'li' );
1426
1427				if ( ! el.hasClass( 'focus' ) ) {
1428
1429					e.preventDefault();
1430					el.toggleClass( 'focus' );
1431					el.siblings( '.focus' ).removeClass( 'focus' );
1432				}
1433			} );
1434		}
1435
1436		if ( 'ontouchstart' in window ) {
1437
1438			$( window ).on( 'resize.altofocus', toggleFocusClassTouchScreen );
1439			toggleFocusClassTouchScreen();
1440		}
1441
1442		siteNavigation.find( 'a' ).on( 'focus.altofocus blur.altofocus', function() {
1443
1444			$( this ).parents( '.menu-item' ).toggleClass( 'focus' );
1445		} );
1446	}
1447
1448	/**
1449	 * Add the default ARIA attributes for the menu toggle and the navigations
1450	 */
1451	function onResizeARIA() {
1452
1453		if ( window.innerWidth < 896 ) {
1454
1455			if ( menuToggle.hasClass( 'toggled-on' ) ) {
1456
1457				menuToggle.attr( 'aria-expanded', 'true' );
1458				siteMenu.attr( 'aria-expanded', 'true' );
1459				siteNavigation.attr( 'aria-expanded', 'true' );
1460
1461			} else {
1462
1463				menuToggle.attr( 'aria-expanded', 'false' );
1464				siteMenu.attr( 'aria-expanded', 'false' );
1465				siteNavigation.attr( 'aria-expanded', 'false' );
1466			}
1467
1468		} else {
1469
1470			menuToggle.removeAttr( 'aria-expanded' );
1471			siteMenu.removeAttr( 'aria-expanded' );
1472			siteNavigation.removeAttr( 'aria-expanded' );
1473		}
1474	}
1475
1476	/**
1477	 * Re-initialize the main navigation when it is updated in the customizer
1478	 * - Borrowed from twentysixteen: https://goo.gl/O6msL1
1479	 */
1480	$( document ).on( 'customize-preview-menu-refreshed', function( e, params ) {
1481
1482		if ( 'menu-1' === params.wpNavMenuArgs.theme_location ) {
1483
1484			initMainNavigation( params.newContainer );
1485		}
1486	});
1487
1488	/**
1489	 * Execute functions
1490	 */
1491	$( document )
1492		.ready( initMainNavigation( topNavigation ) )
1493		.ready( enableMenuToggle )
1494		.ready( addTouchSupport )
1495		.ready( function() {
1496
1497			body = $( document.body );
1498
1499			$( window )
1500				.on( 'load.altofocus', onResizeARIA )
1501				.on( 'resize.altofocus', onResizeARIA );
1502		});
1503
1504} )( jQuery );
1505;
1506/*!
1507 * imagesLoaded PACKAGED v4.1.1
1508 * JavaScript is all like "You images are done yet or what?"
1509 * MIT License
1510 */
1511
1512/**
1513 * EvEmitter v1.0.3
1514 * Lil' event emitter
1515 * MIT License
1516 */
1517
1518/* jshint unused: true, undef: true, strict: true */
1519
1520( function( global, factory ) {
1521  // universal module definition
1522  /* jshint strict: false */ /* globals define, module, window */
1523  if ( typeof define == 'function' && define.amd ) {
1524    // AMD - RequireJS
1525    define( 'ev-emitter/ev-emitter',factory );
1526  } else if ( typeof module == 'object' && module.exports ) {
1527    // CommonJS - Browserify, Webpack
1528    module.exports = factory();
1529  } else {
1530    // Browser globals
1531    global.EvEmitter = factory();
1532  }
1533
1534}( typeof window != 'undefined' ? window : this, function() {
1535
1536
1537
1538function EvEmitter() {}
1539
1540var proto = EvEmitter.prototype;
1541
1542proto.on = function( eventName, listener ) {
1543  if ( !eventName || !listener ) {
1544    return;
1545  }
1546  // set events hash
1547  var events = this._events = this._events || {};
1548  // set listeners array
1549  var listeners = events[ eventName ] = events[ eventName ] || [];
1550  // only add once
1551  if ( listeners.indexOf( listener ) == -1 ) {
1552    listeners.push( listener );
1553  }
1554
1555  return this;
1556};
1557
1558proto.once = function( eventName, listener ) {
1559  if ( !eventName || !listener ) {
1560    return;
1561  }
1562  // add event
1563  this.on( eventName, listener );
1564  // set once flag
1565  // set onceEvents hash
1566  var onceEvents = this._onceEvents = this._onceEvents || {};
1567  // set onceListeners object
1568  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
1569  // set flag
1570  onceListeners[ listener ] = true;
1571
1572  return this;
1573};
1574
1575proto.off = function( eventName, listener ) {
1576  var listeners = this._events && this._events[ eventName ];
1577  if ( !listeners || !listeners.length ) {
1578    return;
1579  }
1580  var index = listeners.indexOf( listener );
1581  if ( index != -1 ) {
1582    listeners.splice( index, 1 );
1583  }
1584
1585  return this;
1586};
1587
1588proto.emitEvent = function( eventName, args ) {
1589  var listeners = this._events && this._events[ eventName ];
1590  if ( !listeners || !listeners.length ) {
1591    return;
1592  }
1593  var i = 0;
1594  var listener = listeners[i];
1595  args = args || [];
1596  // once stuff
1597  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
1598
1599  while ( listener ) {
1600    var isOnce = onceListeners && onceListeners[ listener ];
1601    if ( isOnce ) {
1602      // remove listener
1603      // remove before trigger to prevent recursion
1604      this.off( eventName, listener );
1605      // unset once flag
1606      delete onceListeners[ listener ];
1607    }
1608    // trigger listener
1609    listener.apply( this, args );
1610    // get next listener
1611    i += isOnce ? 0 : 1;
1612    listener = listeners[i];
1613  }
1614
1615  return this;
1616};
1617
1618return EvEmitter;
1619
1620}));
1621
1622/*!
1623 * imagesLoaded v4.1.1
1624 * JavaScript is all like "You images are done yet or what?"
1625 * MIT License
1626 */
1627
1628( function( window, factory ) { 'use strict';
1629  // universal module definition
1630
1631  /*global define: false, module: false, require: false */
1632
1633  if ( typeof define == 'function' && define.amd ) {
1634    // AMD
1635    define( [
1636      'ev-emitter/ev-emitter'
1637    ], function( EvEmitter ) {
1638      return factory( window, EvEmitter );
1639    });
1640  } else if ( typeof module == 'object' && module.exports ) {
1641    // CommonJS
1642    module.exports = factory(
1643      window,
1644      require('ev-emitter')
1645    );
1646  } else {
1647    // browser global
1648    window.imagesLoaded = factory(
1649      window,
1650      window.EvEmitter
1651    );
1652  }
1653
1654})( window,
1655
1656// --------------------------  factory -------------------------- //
1657
1658function factory( window, EvEmitter ) {
1659
1660
1661
1662var $ = window.jQuery;
1663var console = window.console;
1664
1665// -------------------------- helpers -------------------------- //
1666
1667// extend objects
1668function extend( a, b ) {
1669  for ( var prop in b ) {
1670    a[ prop ] = b[ prop ];
1671  }
1672  return a;
1673}
1674
1675// turn element or nodeList into an array
1676function makeArray( obj ) {
1677  var ary = [];
1678  if ( Array.isArray( obj ) ) {
1679    // use object if already an array
1680    ary = obj;
1681  } else if ( typeof obj.length == 'number' ) {
1682    // convert nodeList to array
1683    for ( var i=0; i < obj.length; i++ ) {
1684      ary.push( obj[i] );
1685    }
1686  } else {
1687    // array of single index
1688    ary.push( obj );
1689  }
1690  return ary;
1691}
1692
1693// -------------------------- imagesLoaded -------------------------- //
1694
1695/**
1696 * @param {Array, Element, NodeList, String} elem
1697 * @param {Object or Function} options - if function, use as callback
1698 * @param {Function} onAlways - callback function
1699 */
1700function ImagesLoaded( elem, options, onAlways ) {
1701  // coerce ImagesLoaded() without new, to be new ImagesLoaded()
1702  if ( !( this instanceof ImagesLoaded ) ) {
1703    return new ImagesLoaded( elem, options, onAlways );
1704  }
1705  // use elem as selector string
1706  if ( typeof elem == 'string' ) {
1707    elem = document.querySelectorAll( elem );
1708  }
1709
1710  this.elements = makeArray( elem );
1711  this.options = extend( {}, this.options );
1712
1713  if ( typeof options == 'function' ) {
1714    onAlways = options;
1715  } else {
1716    extend( this.options, options );
1717  }
1718
1719  if ( onAlways ) {
1720    this.on( 'always', onAlways );
1721  }
1722
1723  this.getImages();
1724
1725  if ( $ ) {
1726    // add jQuery Deferred object
1727    this.jqDeferred = new $.Deferred();
1728  }
1729
1730  // HACK check async to allow time to bind listeners
1731  setTimeout( function() {
1732    this.check();
1733  }.bind( this ));
1734}
1735
1736ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
1737
1738ImagesLoaded.prototype.options = {};
1739
1740ImagesLoaded.prototype.getImages = function() {
1741  this.images = [];
1742
1743  // filter & find items if we have an item selector
vendor: 4,347 bytes, lines 1744-1900
1744  this.elements.forEach( this.addElementImages, this );
1745};
1746
1747/**
1748 * @param {Node} element
1749 */
1750ImagesLoaded.prototype.addElementImages = function( elem ) {
1751  // filter siblings
1752  if ( elem.nodeName == 'IMG' ) {
1753    this.addImage( elem );
1754  }
1755  // get background image on element
1756  if ( this.options.background === true ) {
1757    this.addElementBackgroundImages( elem );
1758  }
1759
1760  // find children
1761  // no non-element nodes, #143
1762  var nodeType = elem.nodeType;
1763  if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
1764    return;
1765  }
1766  var childImgs = elem.querySelectorAll('img');
1767  // concat childElems to filterFound array
1768  for ( var i=0; i < childImgs.length; i++ ) {
1769    var img = childImgs[i];
1770    this.addImage( img );
1771  }
1772
1773  // get child background images
1774  if ( typeof this.options.background == 'string' ) {
1775    var children = elem.querySelectorAll( this.options.background );
1776    for ( i=0; i < children.length; i++ ) {
1777      var child = children[i];
1778      this.addElementBackgroundImages( child );
1779    }
1780  }
1781};
1782
1783var elementNodeTypes = {
1784  1: true,
1785  9: true,
1786  11: true
1787};
1788
1789ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
1790  var style = getComputedStyle( elem );
1791  if ( !style ) {
1792    // Firefox returns null if in a hidden iframe https://bugzil.la/548397
1793    return;
1794  }
1795  // get url inside url("...")
1796  var reURL = /url\((['"])?(.*?)\1\)/gi;
1797  var matches = reURL.exec( style.backgroundImage );
1798  while ( matches !== null ) {
1799    var url = matches && matches[2];
1800    if ( url ) {
1801      this.addBackground( url, elem );
1802    }
1803    matches = reURL.exec( style.backgroundImage );
1804  }
1805};
1806
1807/**
1808 * @param {Image} img
1809 */
1810ImagesLoaded.prototype.addImage = function( img ) {
1811  var loadingImage = new LoadingImage( img );
1812  this.images.push( loadingImage );
1813};
1814
1815ImagesLoaded.prototype.addBackground = function( url, elem ) {
1816  var background = new Background( url, elem );
1817  this.images.push( background );
1818};
1819
1820ImagesLoaded.prototype.check = function() {
1821  var _this = this;
1822  this.progressedCount = 0;
1823  this.hasAnyBroken = false;
1824  // complete if no images
1825  if ( !this.images.length ) {
1826    this.complete();
1827    return;
1828  }
1829
1830  function onProgress( image, elem, message ) {
1831    // HACK - Chrome triggers event before object properties have changed. #83
1832    setTimeout( function() {
1833      _this.progress( image, elem, message );
1834    });
1835  }
1836
1837  this.images.forEach( function( loadingImage ) {
1838    loadingImage.once( 'progress', onProgress );
1839    loadingImage.check();
1840  });
1841};
1842
1843ImagesLoaded.prototype.progress = function( image, elem, message ) {
1844  this.progressedCount++;
1845  this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
1846  // progress event
1847  this.emitEvent( 'progress', [ this, image, elem ] );
1848  if ( this.jqDeferred && this.jqDeferred.notify ) {
1849    this.jqDeferred.notify( this, image );
1850  }
1851  // check if completed
1852  if ( this.progressedCount == this.images.length ) {
1853    this.complete();
1854  }
1855
1856  if ( this.options.debug && console ) {
1857    console.log( 'progress: ' + message, image, elem );
1858  }
1859};
1860
1861ImagesLoaded.prototype.complete = function() {
1862  var eventName = this.hasAnyBroken ? 'fail' : 'done';
1863  this.isComplete = true;
1864  this.emitEvent( eventName, [ this ] );
1865  this.emitEvent( 'always', [ this ] );
1866  if ( this.jqDeferred ) {
1867    var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
1868    this.jqDeferred[ jqMethod ]( this );
1869  }
1870};
1871
1872// --------------------------  -------------------------- //
1873
1874function LoadingImage( img ) {
1875  this.img = img;
1876}
1877
1878LoadingImage.prototype = Object.create( EvEmitter.prototype );
1879
1880LoadingImage.prototype.check = function() {
1881  // If complete is true and browser supports natural sizes,
1882  // try to check for image status manually.
1883  var isComplete = this.getIsImageComplete();
1884  if ( isComplete ) {
1885    // report based on naturalWidth
1886    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
1887    return;
1888  }
1889
1890  // If none of the checks above matched, simulate loading on detached element.
1891  this.proxyImage = new Image();
1892  this.proxyImage.addEventListener( 'load', this );
1893  this.proxyImage.addEventListener( 'error', this );
1894  // bind to image as well for Firefox. #191
1895  this.img.addEventListener( 'load', this );
1896  this.img.addEventListener( 'error', this );
1897  this.proxyImage.src = this.img.src;
1898};
1899
1900LoadingImage.prototype.getIsImageComplete = function() {
1901  return this.img.complete && this.img.naturalWidth !== undefined;
1902};
1903
1904LoadingImage.prototype.confirm = function( isLoaded, message ) {
1905  this.isLoaded = isLoaded;
1906  this.emitEvent( 'progress', [ this, this.img, message ] );
1907};
1908
1909// ----- events ----- //
1910
1911// trigger specified handler for event type
1912LoadingImage.prototype.handleEvent = function( event ) {
1913  var method = 'on' + event.type;
1914  if ( this[ method ] ) {
1915    this[ method ]( event );
1916  }
1917};
1918
1919LoadingImage.prototype.onload = function() {
1920  this.confirm( true, 'onload' );
1921  this.unbindEvents();
1922};
1923
1924LoadingImage.prototype.onerror = function() {
1925  this.confirm( false, 'onerror' );
1926  this.unbindEvents();
1927};
1928
1929LoadingImage.prototype.unbindEvents = function() {
1930  this.proxyImage.removeEventListener( 'load', this );
1931  this.proxyImage.removeEventListener( 'error', this );
1932  this.img.removeEventListener( 'load', this );
1933  this.img.removeEventListener( 'error', this );
1934};
1935
1936// -------------------------- Background -------------------------- //
1937
1938function Background( url, element ) {
1939  this.url = url;
1940  this.element = element;
1941  this.img = new Image();
1942}
1943
1944// inherit LoadingImage prototype
1945Background.prototype = Object.create( LoadingImage.prototype );
1946
1947Background.prototype.check = function() {
1948  this.img.addEventListener( 'load', this );
1949  this.img.addEventListener( 'error', this );
1950  this.img.src = this.url;
1951  // check if image is already complete
1952  var isComplete = this.getIsImageComplete();
1953  if ( isComplete ) {
1954    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
1955    this.unbindEvents();
1956  }
1957};
1958
1959Background.prototype.unbindEvents = function() {
1960  this.img.removeEventListener( 'load', this );
1961  this.img.removeEventListener( 'error', this );
1962};
1963
1964Background.prototype.confirm = function( isLoaded, message ) {
1965  this.isLoaded = isLoaded;
1966  this.emitEvent( 'progress', [ this, this.element, message ] );
1967};
1968
1969// -------------------------- jQuery -------------------------- //
1970
1971ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
1972  jQuery = jQuery || window.jQuery;
1973  if ( !jQuery ) {
1974    return;
1975  }
1976  // set local variable
1977  $ = jQuery;
1978  // $().imagesLoaded()
1979  $.fn.imagesLoaded = function( options, callback ) {
1980    var instance = new ImagesLoaded( this, options, callback );
1981    return instance.jqDeferred.promise( $(this) );
1982  };
1983};
1984// try making plugin
1985ImagesLoaded.makeJQueryPlugin();
1986
1987// --------------------------  -------------------------- //
1988
1989return ImagesLoaded;
1990
1991});
1992;
1993/*!
1994 * Isotope PACKAGED v3.0.1
1995 *
1996 * Licensed GPLv3 for open source use
1997 * or Isotope Commercial License for commercial use
1998 *
1999 * http://isotope.metafizzy.co
2000 * Copyright 2016 Metafizzy
2001 */
2002
2003/**
2004 * Bridget makes jQuery widgets
2005 * v2.0.0
2006 * MIT license
2007 */
2008
2009/* jshint browser: true, strict: true, undef: true, unused: true */
2010
2011( function( window, factory ) {
2012  'use strict';
2013  /* globals define: false, module: false, require: false */
2014
2015  if ( typeof define == 'function' && define.amd ) {
2016    // AMD
2017    define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
2018      factory( window, jQuery );
2019    });
2020  } else if ( typeof module == 'object' && module.exports ) {
2021    // CommonJS
2022    module.exports = factory(
2023      window,
2024      require('jquery')
2025    );
2026  } else {
2027    // browser global
2028    window.jQueryBridget = factory(
2029      window,
2030      window.jQuery
2031    );
2032  }
2033
2034}( window, function factory( window, jQuery ) {
2035'use strict';
2036
2037// ----- utils ----- //
2038
2039var arraySlice = Array.prototype.slice;
2040
2041// helper function for logging errors
2042// $.error breaks jQuery chaining
2043var console = window.console;
2044var logError = typeof console == 'undefined' ? function() {} :
2045  function( message ) {
2046    console.error( message );
2047  };
2048
2049// ----- jQueryBridget ----- //
2050
2051function jQueryBridget( namespace, PluginClass, $ ) {
2052  $ = $ || jQuery || window.jQuery;
2053  if ( !$ ) {
2054    return;
2055  }
2056
2057  // add option method -> $().plugin('option', {...})
2058  if ( !PluginClass.prototype.option ) {
2059    // option setter
2060    PluginClass.prototype.option = function( opts ) {
2061      // bail out if not an object
2062      if ( !$.isPlainObject( opts ) ){
2063        return;
2064      }
2065      this.options = $.extend( true, this.options, opts );
2066    };
2067  }
2068
2069  // make jQuery plugin
2070  $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
2071    if ( typeof arg0 == 'string' ) {
2072      // method call $().plugin( 'methodName', { options } )
2073      // shift arguments by 1
2074      var args = arraySlice.call( arguments, 1 );
2075      return methodCall( this, arg0, args );
2076    }
2077    // just $().plugin({ options })
2078    plainCall( this, arg0 );
2079    return this;
2080  };
2081
2082  // $().plugin('methodName')
2083  function methodCall( $elems, methodName, args ) {
2084    var returnValue;
2085    var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
2086
2087    $elems.each( function( i, elem ) {
2088      // get instance
2089      var instance = $.data( elem, namespace );
2090      if ( !instance ) {
2091        logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
2092          pluginMethodStr );
2093        return;
2094      }
2095
2096      var method = instance[ methodName ];
2097      if ( !method || methodName.charAt(0) == '_' ) {
2098        logError( pluginMethodStr + ' is not a valid method' );
2099        return;
2100      }
2101
2102      // apply method, get return value
2103      var value = method.apply( instance, args );
2104      // set return value if value is returned, use only first value
2105      returnValue = returnValue === undefined ? value : returnValue;
2106    });
2107
2108    return returnValue !== undefined ? returnValue : $elems;
2109  }
2110
2111  function plainCall( $elems, options ) {
2112    $elems.each( function( i, elem ) {
2113      var instance = $.data( elem, namespace );
2114      if ( instance ) {
2115        // set options & init
2116        instance.option( options );
2117        instance._init();
2118      } else {
2119        // initialize new instance
2120        instance = new PluginClass( elem, options );
2121        $.data( elem, namespace, instance );
2122      }
2123    });
2124  }
2125
2126  updateJQuery( $ );
2127
2128}
2129
vendor: 18,101 bytes, lines 2130-2881
2130// ----- updateJQuery ----- //
2131
2132// set $.bridget for v1 backwards compatibility
2133function updateJQuery( $ ) {
2134  if ( !$ || ( $ && $.bridget ) ) {
2135    return;
2136  }
2137  $.bridget = jQueryBridget;
2138}
2139
2140updateJQuery( jQuery || window.jQuery );
2141
2142// -----  ----- //
2143
2144return jQueryBridget;
2145
2146}));
2147
2148/**
2149 * EvEmitter v1.0.3
2150 * Lil' event emitter
2151 * MIT License
2152 */
2153
2154/* jshint unused: true, undef: true, strict: true */
2155
2156( function( global, factory ) {
2157  // universal module definition
2158  /* jshint strict: false */ /* globals define, module, window */
2159  if ( typeof define == 'function' && define.amd ) {
2160    // AMD - RequireJS
2161    define( 'ev-emitter/ev-emitter',factory );
2162  } else if ( typeof module == 'object' && module.exports ) {
2163    // CommonJS - Browserify, Webpack
2164    module.exports = factory();
2165  } else {
2166    // Browser globals
2167    global.EvEmitter = factory();
2168  }
2169
2170}( typeof window != 'undefined' ? window : this, function() {
2171
2172
2173
2174function EvEmitter() {}
2175
2176var proto = EvEmitter.prototype;
2177
2178proto.on = function( eventName, listener ) {
2179  if ( !eventName || !listener ) {
2180    return;
2181  }
2182  // set events hash
2183  var events = this._events = this._events || {};
2184  // set listeners array
2185  var listeners = events[ eventName ] = events[ eventName ] || [];
2186  // only add once
2187  if ( listeners.indexOf( listener ) == -1 ) {
2188    listeners.push( listener );
2189  }
2190
2191  return this;
2192};
2193
2194proto.once = function( eventName, listener ) {
2195  if ( !eventName || !listener ) {
2196    return;
2197  }
2198  // add event
2199  this.on( eventName, listener );
2200  // set once flag
2201  // set onceEvents hash
2202  var onceEvents = this._onceEvents = this._onceEvents || {};
2203  // set onceListeners object
2204  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
2205  // set flag
2206  onceListeners[ listener ] = true;
2207
2208  return this;
2209};
2210
2211proto.off = function( eventName, listener ) {
2212  var listeners = this._events && this._events[ eventName ];
2213  if ( !listeners || !listeners.length ) {
2214    return;
2215  }
2216  var index = listeners.indexOf( listener );
2217  if ( index != -1 ) {
2218    listeners.splice( index, 1 );
2219  }
2220
2221  return this;
2222};
2223
2224proto.emitEvent = function( eventName, args ) {
2225  var listeners = this._events && this._events[ eventName ];
2226  if ( !listeners || !listeners.length ) {
2227    return;
2228  }
2229  var i = 0;
2230  var listener = listeners[i];
2231  args = args || [];
2232  // once stuff
2233  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
2234
2235  while ( listener ) {
2236    var isOnce = onceListeners && onceListeners[ listener ];
2237    if ( isOnce ) {
2238      // remove listener
2239      // remove before trigger to prevent recursion
2240      this.off( eventName, listener );
2241      // unset once flag
2242      delete onceListeners[ listener ];
2243    }
2244    // trigger listener
2245    listener.apply( this, args );
2246    // get next listener
2247    i += isOnce ? 0 : 1;
2248    listener = listeners[i];
2249  }
2250
2251  return this;
2252};
2253
2254return EvEmitter;
2255
2256}));
2257
2258/*!
2259 * getSize v2.0.2
2260 * measure size of elements
2261 * MIT license
2262 */
2263
2264/*jshint browser: true, strict: true, undef: true, unused: true */
2265/*global define: false, module: false, console: false */
2266
2267( function( window, factory ) {
2268  'use strict';
2269
2270  if ( typeof define == 'function' && define.amd ) {
2271    // AMD
2272    define( 'get-size/get-size',[],function() {
2273      return factory();
2274    });
2275  } else if ( typeof module == 'object' && module.exports ) {
2276    // CommonJS
2277    module.exports = factory();
2278  } else {
2279    // browser global
2280    window.getSize = factory();
2281  }
2282
2283})( window, function factory() {
2284'use strict';
2285
2286// -------------------------- helpers -------------------------- //
2287
2288// get a number from a string, not a percentage
2289function getStyleSize( value ) {
2290  var num = parseFloat( value );
2291  // not a percent like '100%', and a number
2292  var isValid = value.indexOf('%') == -1 && !isNaN( num );
2293  return isValid && num;
2294}
2295
2296function noop() {}
2297
2298var logError = typeof console == 'undefined' ? noop :
2299  function( message ) {
2300    console.error( message );
2301  };
2302
2303// -------------------------- measurements -------------------------- //
2304
2305var measurements = [
2306  'paddingLeft',
2307  'paddingRight',
2308  'paddingTop',
2309  'paddingBottom',
2310  'marginLeft',
2311  'marginRight',
2312  'marginTop',
2313  'marginBottom',
2314  'borderLeftWidth',
2315  'borderRightWidth',
2316  'borderTopWidth',
2317  'borderBottomWidth'
2318];
2319
2320var measurementsLength = measurements.length;
2321
2322function getZeroSize() {
2323  var size = {
2324    width: 0,
2325    height: 0,
2326    innerWidth: 0,
2327    innerHeight: 0,
2328    outerWidth: 0,
2329    outerHeight: 0
2330  };
2331  for ( var i=0; i < measurementsLength; i++ ) {
2332    var measurement = measurements[i];
2333    size[ measurement ] = 0;
2334  }
2335  return size;
2336}
2337
2338// -------------------------- getStyle -------------------------- //
2339
2340/**
2341 * getStyle, get style of element, check for Firefox bug
2342 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
2343 */
2344function getStyle( elem ) {
2345  var style = getComputedStyle( elem );
2346  if ( !style ) {
2347    logError( 'Style returned ' + style +
2348      '. Are you running this code in a hidden iframe on Firefox? ' +
2349      'See http://bit.ly/getsizebug1' );
2350  }
2351  return style;
2352}
2353
2354// -------------------------- setup -------------------------- //
2355
2356var isSetup = false;
2357
2358var isBoxSizeOuter;
2359
2360/**
2361 * setup
2362 * check isBoxSizerOuter
2363 * do on first getSize() rather than on page load for Firefox bug
2364 */
2365function setup() {
2366  // setup once
2367  if ( isSetup ) {
2368    return;
2369  }
2370  isSetup = true;
2371
2372  // -------------------------- box sizing -------------------------- //
2373
2374  /**
2375   * WebKit measures the outer-width on style.width on border-box elems
2376   * IE & Firefox<29 measures the inner-width
2377   */
2378  var div = document.createElement('div');
2379  div.style.width = '200px';
2380  div.style.padding = '1px 2px 3px 4px';
2381  div.style.borderStyle = 'solid';
2382  div.style.borderWidth = '1px 2px 3px 4px';
2383  div.style.boxSizing = 'border-box';
2384
2385  var body = document.body || document.documentElement;
2386  body.appendChild( div );
2387  var style = getStyle( div );
2388
2389  getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200;
2390  body.removeChild( div );
2391
2392}
2393
2394// -------------------------- getSize -------------------------- //
2395
2396function getSize( elem ) {
2397  setup();
2398
2399  // use querySeletor if elem is string
2400  if ( typeof elem == 'string' ) {
2401    elem = document.querySelector( elem );
2402  }
2403
2404  // do not proceed on non-objects
2405  if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
2406    return;
2407  }
2408
2409  var style = getStyle( elem );
2410
2411  // if hidden, everything is 0
2412  if ( style.display == 'none' ) {
2413    return getZeroSize();
2414  }
2415
2416  var size = {};
2417  size.width = elem.offsetWidth;
2418  size.height = elem.offsetHeight;
2419
2420  var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
2421
2422  // get all measurements
2423  for ( var i=0; i < measurementsLength; i++ ) {
2424    var measurement = measurements[i];
2425    var value = style[ measurement ];
2426    var num = parseFloat( value );
2427    // any 'auto', 'medium' value will be 0
2428    size[ measurement ] = !isNaN( num ) ? num : 0;
2429  }
2430
2431  var paddingWidth = size.paddingLeft + size.paddingRight;
2432  var paddingHeight = size.paddingTop + size.paddingBottom;
2433  var marginWidth = size.marginLeft + size.marginRight;
2434  var marginHeight = size.marginTop + size.marginBottom;
2435  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
2436  var borderHeight = size.borderTopWidth + size.borderBottomWidth;
2437
2438  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
2439
2440  // overwrite width and height if we can get it from style
2441  var styleWidth = getStyleSize( style.width );
2442  if ( styleWidth !== false ) {
2443    size.width = styleWidth +
2444      // add padding and border unless it's already including it
2445      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
2446  }
2447
2448  var styleHeight = getStyleSize( style.height );
2449  if ( styleHeight !== false ) {
2450    size.height = styleHeight +
2451      // add padding and border unless it's already including it
2452      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
2453  }
2454
2455  size.innerWidth = size.width - ( paddingWidth + borderWidth );
2456  size.innerHeight = size.height - ( paddingHeight + borderHeight );
2457
2458  size.outerWidth = size.width + marginWidth;
2459  size.outerHeight = size.height + marginHeight;
2460
2461  return size;
2462}
2463
2464return getSize;
2465
2466});
2467
2468/**
2469 * matchesSelector v2.0.1
2470 * matchesSelector( element, '.selector' )
2471 * MIT license
2472 */
2473
2474/*jshint browser: true, strict: true, undef: true, unused: true */
2475
2476( function( window, factory ) {
2477  /*global define: false, module: false */
2478  'use strict';
2479  // universal module definition
2480  if ( typeof define == 'function' && define.amd ) {
2481    // AMD
2482    define( 'desandro-matches-selector/matches-selector',factory );
2483  } else if ( typeof module == 'object' && module.exports ) {
2484    // CommonJS
2485    module.exports = factory();
2486  } else {
2487    // browser global
2488    window.matchesSelector = factory();
2489  }
2490
2491}( window, function factory() {
2492  'use strict';
2493
2494  var matchesMethod = ( function() {
2495    var ElemProto = Element.prototype;
2496    // check for the standard method name first
2497    if ( ElemProto.matches ) {
2498      return 'matches';
2499    }
2500    // check un-prefixed
2501    if ( ElemProto.matchesSelector ) {
2502      return 'matchesSelector';
2503    }
2504    // check vendor prefixes
2505    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
2506
2507    for ( var i=0; i < prefixes.length; i++ ) {
2508      var prefix = prefixes[i];
2509      var method = prefix + 'MatchesSelector';
2510      if ( ElemProto[ method ] ) {
2511        return method;
2512      }
2513    }
2514  })();
2515
2516  return function matchesSelector( elem, selector ) {
2517    return elem[ matchesMethod ]( selector );
2518  };
2519
2520}));
2521
2522/**
2523 * Fizzy UI utils v2.0.2
2524 * MIT license
2525 */
2526
2527/*jshint browser: true, undef: true, unused: true, strict: true */
2528
2529( function( window, factory ) {
2530  // universal module definition
2531  /*jshint strict: false */ /*globals define, module, require */
2532
2533  if ( typeof define == 'function' && define.amd ) {
2534    // AMD
2535    define( 'fizzy-ui-utils/utils',[
2536      'desandro-matches-selector/matches-selector'
2537    ], function( matchesSelector ) {
2538      return factory( window, matchesSelector );
2539    });
2540  } else if ( typeof module == 'object' && module.exports ) {
2541    // CommonJS
2542    module.exports = factory(
2543      window,
2544      require('desandro-matches-selector')
2545    );
2546  } else {
2547    // browser global
2548    window.fizzyUIUtils = factory(
2549      window,
2550      window.matchesSelector
2551    );
2552  }
2553
2554}( window, function factory( window, matchesSelector ) {
2555
2556
2557
2558var utils = {};
2559
2560// ----- extend ----- //
2561
2562// extends objects
2563utils.extend = function( a, b ) {
2564  for ( var prop in b ) {
2565    a[ prop ] = b[ prop ];
2566  }
2567  return a;
2568};
2569
2570// ----- modulo ----- //
2571
2572utils.modulo = function( num, div ) {
2573  return ( ( num % div ) + div ) % div;
2574};
2575
2576// ----- makeArray ----- //
2577
2578// turn element or nodeList into an array
2579utils.makeArray = function( obj ) {
2580  var ary = [];
2581  if ( Array.isArray( obj ) ) {
2582    // use object if already an array
2583    ary = obj;
2584  } else if ( obj && typeof obj.length == 'number' ) {
2585    // convert nodeList to array
2586    for ( var i=0; i < obj.length; i++ ) {
2587      ary.push( obj[i] );
2588    }
2589  } else {
2590    // array of single index
2591    ary.push( obj );
2592  }
2593  return ary;
2594};
2595
2596// ----- removeFrom ----- //
2597
2598utils.removeFrom = function( ary, obj ) {
2599  var index = ary.indexOf( obj );
2600  if ( index != -1 ) {
2601    ary.splice( index, 1 );
2602  }
2603};
2604
2605// ----- getParent ----- //
2606
2607utils.getParent = function( elem, selector ) {
2608  while ( elem != document.body ) {
2609    elem = elem.parentNode;
2610    if ( matchesSelector( elem, selector ) ) {
2611      return elem;
2612    }
2613  }
2614};
2615
2616// ----- getQueryElement ----- //
2617
2618// use element as selector string
2619utils.getQueryElement = function( elem ) {
2620  if ( typeof elem == 'string' ) {
2621    return document.querySelector( elem );
2622  }
2623  return elem;
2624};
2625
2626// ----- handleEvent ----- //
2627
2628// enable .ontype to trigger from .addEventListener( elem, 'type' )
2629utils.handleEvent = function( event ) {
2630  var method = 'on' + event.type;
2631  if ( this[ method ] ) {
2632    this[ method ]( event );
2633  }
2634};
2635
2636// ----- filterFindElements ----- //
2637
2638utils.filterFindElements = function( elems, selector ) {
2639  // make array of elems
2640  elems = utils.makeArray( elems );
2641  var ffElems = [];
2642
2643  elems.forEach( function( elem ) {
2644    // check that elem is an actual element
2645    if ( !( elem instanceof HTMLElement ) ) {
2646      return;
2647    }
2648    // add elem if no selector
2649    if ( !selector ) {
2650      ffElems.push( elem );
2651      return;
2652    }
2653    // filter & find items if we have a selector
2654    // filter
2655    if ( matchesSelector( elem, selector ) ) {
2656      ffElems.push( elem );
2657    }
2658    // find children
2659    var childElems = elem.querySelectorAll( selector );
2660    // concat childElems to filterFound array
2661    for ( var i=0; i < childElems.length; i++ ) {
2662      ffElems.push( childElems[i] );
2663    }
2664  });
2665
2666  return ffElems;
2667};
2668
2669// ----- debounceMethod ----- //
2670
2671utils.debounceMethod = function( _class, methodName, threshold ) {
2672  // original method
2673  var method = _class.prototype[ methodName ];
2674  var timeoutName = methodName + 'Timeout';
2675
2676  _class.prototype[ methodName ] = function() {
2677    var timeout = this[ timeoutName ];
2678    if ( timeout ) {
2679      clearTimeout( timeout );
2680    }
2681    var args = arguments;
2682
2683    var _this = this;
2684    this[ timeoutName ] = setTimeout( function() {
2685      method.apply( _this, args );
2686      delete _this[ timeoutName ];
2687    }, threshold || 100 );
2688  };
2689};
2690
2691// ----- docReady ----- //
2692
2693utils.docReady = function( callback ) {
2694  var readyState = document.readyState;
2695  if ( readyState == 'complete' || readyState == 'interactive' ) {
2696    callback();
2697  } else {
2698    document.addEventListener( 'DOMContentLoaded', callback );
2699  }
2700};
2701
2702// ----- htmlInit ----- //
2703
2704// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
2705utils.toDashed = function( str ) {
2706  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
2707    return $1 + '-' + $2;
2708  }).toLowerCase();
2709};
2710
2711var console = window.console;
2712/**
2713 * allow user to initialize classes via [data-namespace] or .js-namespace class
2714 * htmlInit( Widget, 'widgetName' )
2715 * options are parsed from data-namespace-options
2716 */
2717utils.htmlInit = function( WidgetClass, namespace ) {
2718  utils.docReady( function() {
2719    var dashedNamespace = utils.toDashed( namespace );
2720    var dataAttr = 'data-' + dashedNamespace;
2721    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
2722    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
2723    var elems = utils.makeArray( dataAttrElems )
2724      .concat( utils.makeArray( jsDashElems ) );
2725    var dataOptionsAttr = dataAttr + '-options';
2726    var jQuery = window.jQuery;
2727
2728    elems.forEach( function( elem ) {
2729      var attr = elem.getAttribute( dataAttr ) ||
2730        elem.getAttribute( dataOptionsAttr );
2731      var options;
2732      try {
2733        options = attr && JSON.parse( attr );
2734      } catch ( error ) {
2735        // log error, do not initialize
2736        if ( console ) {
2737          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
2738          ': ' + error );
2739        }
2740        return;
2741      }
2742      // initialize
2743      var instance = new WidgetClass( elem, options );
2744      // make available via $().data('layoutname')
2745      if ( jQuery ) {
2746        jQuery.data( elem, namespace, instance );
2747      }
2748    });
2749
2750  });
2751};
2752
2753// -----  ----- //
2754
2755return utils;
2756
2757}));
2758
2759/**
2760 * Outlayer Item
2761 */
2762
2763( function( window, factory ) {
2764  // universal module definition
2765  /* jshint strict: false */ /* globals define, module, require */
2766  if ( typeof define == 'function' && define.amd ) {
2767    // AMD - RequireJS
2768    define( 'outlayer/item',[
2769        'ev-emitter/ev-emitter',
2770        'get-size/get-size'
2771      ],
2772      factory
2773    );
2774  } else if ( typeof module == 'object' && module.exports ) {
2775    // CommonJS - Browserify, Webpack
2776    module.exports = factory(
2777      require('ev-emitter'),
2778      require('get-size')
2779    );
2780  } else {
2781    // browser global
2782    window.Outlayer = {};
2783    window.Outlayer.Item = factory(
2784      window.EvEmitter,
2785      window.getSize
2786    );
2787  }
2788
2789}( window, function factory( EvEmitter, getSize ) {
2790'use strict';
2791
2792// ----- helpers ----- //
2793
2794function isEmptyObj( obj ) {
2795  for ( var prop in obj ) {
2796    return false;
2797  }
2798  prop = null;
2799  return true;
2800}
2801
2802// -------------------------- CSS3 support -------------------------- //
2803
2804
2805var docElemStyle = document.documentElement.style;
2806
2807var transitionProperty = typeof docElemStyle.transition == 'string' ?
2808  'transition' : 'WebkitTransition';
2809var transformProperty = typeof docElemStyle.transform == 'string' ?
2810  'transform' : 'WebkitTransform';
2811
2812var transitionEndEvent = {
2813  WebkitTransition: 'webkitTransitionEnd',
2814  transition: 'transitionend'
2815}[ transitionProperty ];
2816
2817// cache all vendor properties that could have vendor prefix
2818var vendorProperties = {
2819  transform: transformProperty,
2820  transition: transitionProperty,
2821  transitionDuration: transitionProperty + 'Duration',
2822  transitionProperty: transitionProperty + 'Property',
2823  transitionDelay: transitionProperty + 'Delay'
2824};
2825
2826// -------------------------- Item -------------------------- //
2827
2828function Item( element, layout ) {
2829  if ( !element ) {
2830    return;
2831  }
2832
2833  this.element = element;
2834  // parent layout class, i.e. Masonry, Isotope, or Packery
2835  this.layout = layout;
2836  this.position = {
2837    x: 0,
2838    y: 0
2839  };
2840
2841  this._create();
2842}
2843
2844// inherit EvEmitter
2845var proto = Item.prototype = Object.create( EvEmitter.prototype );
2846proto.constructor = Item;
2847
2848proto._create = function() {
2849  // transition objects
2850  this._transn = {
2851    ingProperties: {},
2852    clean: {},
2853    onEnd: {}
2854  };
2855
2856  this.css({
2857    position: 'absolute'
2858  });
2859};
2860
2861// trigger specified handler for event type
2862proto.handleEvent = function( event ) {
2863  var method = 'on' + event.type;
2864  if ( this[ method ] ) {
2865    this[ method ]( event );
2866  }
2867};
2868
2869proto.getSize = function() {
2870  this.size = getSize( this.element );
2871};
2872
2873/**
2874 * apply CSS styles to element
2875 * @param {Object} style
2876 */
2877proto.css = function( style ) {
2878  var elemStyle = this.element.style;
2879
2880  for ( var prop in style ) {
2881    // use vendor property if available
2882    var supportedProp = vendorProperties[ prop ] || prop;
2883    elemStyle[ supportedProp ] = style[ prop ];
2884  }
2885};
2886
2887 // measure position, and sets it
2888proto.getPosition = function() {
2889  var style = getComputedStyle( this.element );
2890  var isOriginLeft = this.layout._getOption('originLeft');
2891  var isOriginTop = this.layout._getOption('originTop');
2892  var xValue = style[ isOriginLeft ? 'left' : 'right' ];
2893  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
2894  // convert percent to pixels
2895  var layoutSize = this.layout.size;
2896  var x = xValue.indexOf('%') != -1 ?
2897    ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );
2898  var y = yValue.indexOf('%') != -1 ?
2899    ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );
2900
2901  // clean up 'auto' or other non-integer values
2902  x = isNaN( x ) ? 0 : x;
2903  y = isNaN( y ) ? 0 : y;
2904  // remove padding from measurement
2905  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
2906  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
2907
2908  this.position.x = x;
2909  this.position.y = y;
2910};
2911
2912// set settled position, apply padding
2913proto.layoutPosition = function() {
2914  var layoutSize = this.layout.size;
2915  var style = {};
2916  var isOriginLeft = this.layout._getOption('originLeft');
2917  var isOriginTop = this.layout._getOption('originTop');
2918
2919  // x
2920  var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
2921  var xProperty = isOriginLeft ? 'left' : 'right';
2922  var xResetProperty = isOriginLeft ? 'right' : 'left';
2923
2924  var x = this.position.x + layoutSize[ xPadding ];
2925  // set in percentage or pixels
2926  style[ xProperty ] = this.getXValue( x );
2927  // reset other property
2928  style[ xResetProperty ] = '';
2929
2930  // y
2931  var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
2932  var yProperty = isOriginTop ? 'top' : 'bottom';
2933  var yResetProperty = isOriginTop ? 'bottom' : 'top';
2934
2935  var y = this.position.y + layoutSize[ yPadding ];
2936  // set in percentage or pixels
2937  style[ yProperty ] = this.getYValue( y );
2938  // reset other property
2939  style[ yResetProperty ] = '';
2940
2941  this.css( style );
2942  this.emitEvent( 'layout', [ this ] );
2943};
2944
2945proto.getXValue = function( x ) {
2946  var isHorizontal = this.layout._getOption('horizontal');
2947  return this.layout.options.percentPosition && !isHorizontal ?
2948    ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
2949};
2950
2951proto.getYValue = function( y ) {
2952  var isHorizontal = this.layout._getOption('horizontal');
2953  return this.layout.options.percentPosition && isHorizontal ?
2954    ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
2955};
2956
2957proto._transitionTo = function( x, y ) {
2958  this.getPosition();
2959  // get current x & y from top/left
2960  var curX = this.position.x;
2961  var curY = this.position.y;
2962
2963  var compareX = parseInt( x, 10 );
2964  var compareY = parseInt( y, 10 );
2965  var didNotMove = compareX === this.position.x && compareY === this.position.y;
2966
2967  // save end position
2968  this.setPosition( x, y );
2969
2970  // if did not move and not transitioning, just go to layout
2971  if ( didNotMove && !this.isTransitioning ) {
2972    this.layoutPosition();
2973    return;
2974  }
2975
2976  var transX = x - curX;
2977  var transY = y - curY;
2978  var transitionStyle = {};
2979  transitionStyle.transform = this.getTranslate( transX, transY );
2980
2981  this.transition({
2982    to: transitionStyle,
2983    onTransitionEnd: {
2984      transform: this.layoutPosition
2985    },
2986    isCleaning: true
2987  });
2988};
2989
2990proto.getTranslate = function( x, y ) {
2991  // flip cooridinates if origin on right or bottom
2992  var isOriginLeft = this.layout._getOption('originLeft');
2993  var isOriginTop = this.layout._getOption('originTop');
2994  x = isOriginLeft ? x : -x;
2995  y = isOriginTop ? y : -y;
2996  return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
2997};
2998
2999// non transition + transform support
3000proto.goTo = function( x, y ) {
3001  this.setPosition( x, y );
3002  this.layoutPosition();
3003};
3004
3005proto.moveTo = proto._transitionTo;
3006
3007proto.setPosition = function( x, y ) {
3008  this.position.x = parseInt( x, 10 );
3009  this.position.y = parseInt( y, 10 );
3010};
3011
3012// ----- transition ----- //
3013
3014/**
3015 * @param {Object} style - CSS
3016 * @param {Function} onTransitionEnd
3017 */
3018
3019// non transition, just trigger callback
3020proto._nonTransition = function( args ) {
3021  this.css( args.to );
3022  if ( args.isCleaning ) {
3023    this._removeStyles( args.to );
3024  }
3025  for ( var prop in args.onTransitionEnd ) {
3026    args.onTransitionEnd[ prop ].call( this );
3027  }
3028};
3029
3030/**
3031 * proper transition
3032 * @param {Object} args - arguments
3033 *   @param {Object} to - style to transition to
3034 *   @param {Object} from - style to start transition from
3035 *   @param {Boolean} isCleaning - removes transition styles after transition
3036 *   @param {Function} onTransitionEnd - callback
3037 */
3038proto.transition = function( args ) {
3039  // redirect to nonTransition if no transition duration
3040  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
3041    this._nonTransition( args );
3042    return;
3043  }
3044
3045  var _transition = this._transn;
3046  // keep track of onTransitionEnd callback by css property
3047  for ( var prop in args.onTransitionEnd ) {
3048    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
3049  }
3050  // keep track of properties that are transitioning
3051  for ( prop in args.to ) {
3052    _transition.ingProperties[ prop ] = true;
3053    // keep track of properties to clean up when transition is done
3054    if ( args.isCleaning ) {
3055      _transition.clean[ prop ] = true;
3056    }
3057  }
3058
3059  // set from styles
3060  if ( args.from ) {
3061    this.css( args.from );
3062    // force redraw. http://blog.alexmaccaw.com/css-transitions
3063    var h = this.element.offsetHeight;
3064    // hack for JSHint to hush about unused var
3065    h = null;
3066  }
3067  // enable transition
3068  this.enableTransition( args.to );
3069  // set styles that are transitioning
3070  this.css( args.to );
3071
3072  this.isTransitioning = true;
3073
3074};
3075
3076// dash before all cap letters, including first for
3077// WebkitTransform => -webkit-transform
3078function toDashedAll( str ) {
3079  return str.replace( /([A-Z])/g, function( $1 ) {
3080    return '-' + $1.toLowerCase();
3081  });
3082}
3083
3084var transitionProps = 'opacity,' + toDashedAll( transformProperty );
3085
3086proto.enableTransition = function(/* style */) {
3087  // HACK changing transitionProperty during a transition
3088  // will cause transition to jump
3089  if ( this.isTransitioning ) {
3090    return;
3091  }
3092
3093  // make `transition: foo, bar, baz` from style object
3094  // HACK un-comment this when enableTransition can work
3095  // while a transition is happening
3096  // var transitionValues = [];
3097  // for ( var prop in style ) {
3098  //   // dash-ify camelCased properties like WebkitTransition
vendor: 5,416 bytes, lines 3099-3314
3099  //   prop = vendorProperties[ prop ] || prop;
3100  //   transitionValues.push( toDashedAll( prop ) );
3101  // }
3102  // munge number to millisecond, to match stagger
3103  var duration = this.layout.options.transitionDuration;
3104  duration = typeof duration == 'number' ? duration + 'ms' : duration;
3105  // enable transition styles
3106  this.css({
3107    transitionProperty: transitionProps,
3108    transitionDuration: duration,
3109    transitionDelay: this.staggerDelay || 0
3110  });
3111  // listen for transition end event
3112  this.element.addEventListener( transitionEndEvent, this, false );
3113};
3114
3115// ----- events ----- //
3116
3117proto.onwebkitTransitionEnd = function( event ) {
3118  this.ontransitionend( event );
3119};
3120
3121proto.onotransitionend = function( event ) {
3122  this.ontransitionend( event );
3123};
3124
3125// properties that I munge to make my life easier
3126var dashedVendorProperties = {
3127  '-webkit-transform': 'transform'
3128};
3129
3130proto.ontransitionend = function( event ) {
3131  // disregard bubbled events from children
3132  if ( event.target !== this.element ) {
3133    return;
3134  }
3135  var _transition = this._transn;
3136  // get property name of transitioned property, convert to prefix-free
3137  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
3138
3139  // remove property that has completed transitioning
3140  delete _transition.ingProperties[ propertyName ];
3141  // check if any properties are still transitioning
3142  if ( isEmptyObj( _transition.ingProperties ) ) {
3143    // all properties have completed transitioning
3144    this.disableTransition();
3145  }
3146  // clean style
3147  if ( propertyName in _transition.clean ) {
3148    // clean up style
3149    this.element.style[ event.propertyName ] = '';
3150    delete _transition.clean[ propertyName ];
3151  }
3152  // trigger onTransitionEnd callback
3153  if ( propertyName in _transition.onEnd ) {
3154    var onTransitionEnd = _transition.onEnd[ propertyName ];
3155    onTransitionEnd.call( this );
3156    delete _transition.onEnd[ propertyName ];
3157  }
3158
3159  this.emitEvent( 'transitionEnd', [ this ] );
3160};
3161
3162proto.disableTransition = function() {
3163  this.removeTransitionStyles();
3164  this.element.removeEventListener( transitionEndEvent, this, false );
3165  this.isTransitioning = false;
3166};
3167
3168/**
3169 * removes style property from element
3170 * @param {Object} style
3171**/
3172proto._removeStyles = function( style ) {
3173  // clean up transition styles
3174  var cleanStyle = {};
3175  for ( var prop in style ) {
3176    cleanStyle[ prop ] = '';
3177  }
3178  this.css( cleanStyle );
3179};
3180
3181var cleanTransitionStyle = {
3182  transitionProperty: '',
3183  transitionDuration: '',
3184  transitionDelay: ''
3185};
3186
3187proto.removeTransitionStyles = function() {
3188  // remove transition
3189  this.css( cleanTransitionStyle );
3190};
3191
3192// ----- stagger ----- //
3193
3194proto.stagger = function( delay ) {
3195  delay = isNaN( delay ) ? 0 : delay;
3196  this.staggerDelay = delay + 'ms';
3197};
3198
3199// ----- show/hide/remove ----- //
3200
3201// remove element from DOM
3202proto.removeElem = function() {
3203  this.element.parentNode.removeChild( this.element );
3204  // remove display: none
3205  this.css({ display: '' });
3206  this.emitEvent( 'remove', [ this ] );
3207};
3208
3209proto.remove = function() {
3210  // just remove element if no transition support or no transition
3211  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
3212    this.removeElem();
3213    return;
3214  }
3215
3216  // start transition
3217  this.once( 'transitionEnd', function() {
3218    this.removeElem();
3219  });
3220  this.hide();
3221};
3222
3223proto.reveal = function() {
3224  delete this.isHidden;
3225  // remove display: none
3226  this.css({ display: '' });
3227
3228  var options = this.layout.options;
3229
3230  var onTransitionEnd = {};
3231  var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
3232  onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
3233
3234  this.transition({
3235    from: options.hiddenStyle,
3236    to: options.visibleStyle,
3237    isCleaning: true,
3238    onTransitionEnd: onTransitionEnd
3239  });
3240};
3241
3242proto.onRevealTransitionEnd = function() {
3243  // check if still visible
3244  // during transition, item may have been hidden
3245  if ( !this.isHidden ) {
3246    this.emitEvent('reveal');
3247  }
3248};
3249
3250/**
3251 * get style property use for hide/reveal transition end
3252 * @param {String} styleProperty - hiddenStyle/visibleStyle
3253 * @returns {String}
3254 */
3255proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
3256  var optionStyle = this.layout.options[ styleProperty ];
3257  // use opacity
3258  if ( optionStyle.opacity ) {
3259    return 'opacity';
3260  }
3261  // get first property
3262  for ( var prop in optionStyle ) {
3263    return prop;
3264  }
3265};
3266
3267proto.hide = function() {
3268  // set flag
3269  this.isHidden = true;
3270  // remove display: none
3271  this.css({ display: '' });
3272
3273  var options = this.layout.options;
3274
3275  var onTransitionEnd = {};
3276  var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
3277  onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
3278
3279  this.transition({
3280    from: options.visibleStyle,
3281    to: options.hiddenStyle,
3282    // keep hidden stuff hidden
3283    isCleaning: true,
3284    onTransitionEnd: onTransitionEnd
3285  });
3286};
3287
3288proto.onHideTransitionEnd = function() {
3289  // check if still hidden
3290  // during transition, item may have been un-hidden
3291  if ( this.isHidden ) {
3292    this.css({ display: 'none' });
3293    this.emitEvent('hide');
3294  }
3295};
3296
3297proto.destroy = function() {
3298  this.css({
3299    position: '',
3300    left: '',
3301    right: '',
3302    top: '',
3303    bottom: '',
3304    transition: '',
3305    transform: ''
3306  });
3307};
3308
3309return Item;
3310
3311}));
3312
3313/*!
3314 * Outlayer v2.1.0
vendor: 22,038 bytes, lines 3314-4254
3314
3315 * the brains and guts of a layout library
3316 * MIT license
3317 */
3318
3319( function( window, factory ) {
3320  'use strict';
3321  // universal module definition
3322  /* jshint strict: false */ /* globals define, module, require */
3323  if ( typeof define == 'function' && define.amd ) {
3324    // AMD - RequireJS
3325    define( 'outlayer/outlayer',[
3326        'ev-emitter/ev-emitter',
3327        'get-size/get-size',
3328        'fizzy-ui-utils/utils',
3329        './item'
3330      ],
3331      function( EvEmitter, getSize, utils, Item ) {
3332        return factory( window, EvEmitter, getSize, utils, Item);
3333      }
3334    );
3335  } else if ( typeof module == 'object' && module.exports ) {
3336    // CommonJS - Browserify, Webpack
3337    module.exports = factory(
3338      window,
3339      require('ev-emitter'),
3340      require('get-size'),
3341      require('fizzy-ui-utils'),
3342      require('./item')
3343    );
3344  } else {
3345    // browser global
3346    window.Outlayer = factory(
3347      window,
3348      window.EvEmitter,
3349      window.getSize,
3350      window.fizzyUIUtils,
3351      window.Outlayer.Item
3352    );
3353  }
3354
3355}( window, function factory( window, EvEmitter, getSize, utils, Item ) {
3356'use strict';
3357
3358// ----- vars ----- //
3359
3360var console = window.console;
3361var jQuery = window.jQuery;
3362var noop = function() {};
3363
3364// -------------------------- Outlayer -------------------------- //
3365
3366// globally unique identifiers
3367var GUID = 0;
3368// internal store of all Outlayer intances
3369var instances = {};
3370
3371
3372/**
3373 * @param {Element, String} element
3374 * @param {Object} options
3375 * @constructor
3376 */
3377function Outlayer( element, options ) {
3378  var queryElement = utils.getQueryElement( element );
3379  if ( !queryElement ) {
3380    if ( console ) {
3381      console.error( 'Bad element for ' + this.constructor.namespace +
3382        ': ' + ( queryElement || element ) );
3383    }
3384    return;
3385  }
3386  this.element = queryElement;
3387  // add jQuery
3388  if ( jQuery ) {
3389    this.$element = jQuery( this.element );
3390  }
3391
3392  // options
3393  this.options = utils.extend( {}, this.constructor.defaults );
3394  this.option( options );
3395
3396  // add id for Outlayer.getFromElement
3397  var id = ++GUID;
3398  this.element.outlayerGUID = id; // expando
3399  instances[ id ] = this; // associate via id
3400
3401  // kick it off
3402  this._create();
3403
3404  var isInitLayout = this._getOption('initLayout');
3405  if ( isInitLayout ) {
3406    this.layout();
3407  }
3408}
3409
3410// settings are for internal use only
3411Outlayer.namespace = 'outlayer';
3412Outlayer.Item = Item;
3413
3414// default options
3415Outlayer.defaults = {
3416  containerStyle: {
3417    position: 'relative'
3418  },
3419  initLayout: true,
3420  originLeft: true,
3421  originTop: true,
3422  resize: true,
3423  resizeContainer: true,
3424  // item options
3425  transitionDuration: '0.4s',
3426  hiddenStyle: {
3427    opacity: 0,
3428    transform: 'scale(0.001)'
3429  },
3430  visibleStyle: {
3431    opacity: 1,
3432    transform: 'scale(1)'
3433  }
3434};
3435
3436var proto = Outlayer.prototype;
3437// inherit EvEmitter
3438utils.extend( proto, EvEmitter.prototype );
3439
3440/**
3441 * set options
3442 * @param {Object} opts
3443 */
3444proto.option = function( opts ) {
3445  utils.extend( this.options, opts );
3446};
3447
3448/**
3449 * get backwards compatible option value, check old name
3450 */
3451proto._getOption = function( option ) {
3452  var oldOption = this.constructor.compatOptions[ option ];
3453  return oldOption && this.options[ oldOption ] !== undefined ?
3454    this.options[ oldOption ] : this.options[ option ];
3455};
3456
3457Outlayer.compatOptions = {
3458  // currentName: oldName
3459  initLayout: 'isInitLayout',
3460  horizontal: 'isHorizontal',
3461  layoutInstant: 'isLayoutInstant',
3462  originLeft: 'isOriginLeft',
3463  originTop: 'isOriginTop',
3464  resize: 'isResizeBound',
3465  resizeContainer: 'isResizingContainer'
3466};
3467
3468proto._create = function() {
3469  // get items from children
3470  this.reloadItems();
3471  // elements that affect layout, but are not laid out
3472  this.stamps = [];
3473  this.stamp( this.options.stamp );
3474  // set container style
3475  utils.extend( this.element.style, this.options.containerStyle );
3476
3477  // bind resize method
3478  var canBindResize = this._getOption('resize');
3479  if ( canBindResize ) {
3480    this.bindResize();
3481  }
3482};
3483
3484// goes through all children again and gets bricks in proper order
3485proto.reloadItems = function() {
3486  // collection of item elements
3487  this.items = this._itemize( this.element.children );
3488};
3489
3490
3491/**
3492 * turn elements into Outlayer.Items to be used in layout
3493 * @param {Array or NodeList or HTMLElement} elems
3494 * @returns {Array} items - collection of new Outlayer Items
3495 */
3496proto._itemize = function( elems ) {
3497
3498  var itemElems = this._filterFindItemElements( elems );
3499  var Item = this.constructor.Item;
3500
3501  // create new Outlayer Items for collection
3502  var items = [];
3503  for ( var i=0; i < itemElems.length; i++ ) {
3504    var elem = itemElems[i];
3505    var item = new Item( elem, this );
3506    items.push( item );
3507  }
3508
3509  return items;
3510};
3511
3512/**
3513 * get item elements to be used in layout
3514 * @param {Array or NodeList or HTMLElement} elems
3515 * @returns {Array} items - item elements
3516 */
3517proto._filterFindItemElements = function( elems ) {
3518  return utils.filterFindElements( elems, this.options.itemSelector );
3519};
3520
3521/**
3522 * getter method for getting item elements
3523 * @returns {Array} elems - collection of item elements
3524 */
3525proto.getItemElements = function() {
3526  return this.items.map( function( item ) {
3527    return item.element;
3528  });
3529};
3530
3531// ----- init & layout ----- //
3532
3533/**
3534 * lays out all items
3535 */
3536proto.layout = function() {
3537  this._resetLayout();
3538  this._manageStamps();
3539
3540  // don't animate first layout
3541  var layoutInstant = this._getOption('layoutInstant');
3542  var isInstant = layoutInstant !== undefined ?
3543    layoutInstant : !this._isLayoutInited;
3544  this.layoutItems( this.items, isInstant );
3545
3546  // flag for initalized
3547  this._isLayoutInited = true;
3548};
3549
3550// _init is alias for layout
3551proto._init = proto.layout;
3552
3553/**
3554 * logic before any new layout
3555 */
3556proto._resetLayout = function() {
3557  this.getSize();
3558};
3559
3560
3561proto.getSize = function() {
3562  this.size = getSize( this.element );
3563};
3564
3565/**
3566 * get measurement from option, for columnWidth, rowHeight, gutter
3567 * if option is String -> get element from selector string, & get size of element
3568 * if option is Element -> get size of element
3569 * else use option as a number
3570 *
3571 * @param {String} measurement
3572 * @param {String} size - width or height
3573 * @private
3574 */
3575proto._getMeasurement = function( measurement, size ) {
3576  var option = this.options[ measurement ];
3577  var elem;
3578  if ( !option ) {
3579    // default to 0
3580    this[ measurement ] = 0;
3581  } else {
3582    // use option as an element
3583    if ( typeof option == 'string' ) {
3584      elem = this.element.querySelector( option );
3585    } else if ( option instanceof HTMLElement ) {
3586      elem = option;
3587    }
3588    // use size of element, if element
3589    this[ measurement ] = elem ? getSize( elem )[ size ] : option;
3590  }
3591};
3592
3593/**
3594 * layout a collection of item elements
3595 * @api public
3596 */
3597proto.layoutItems = function( items, isInstant ) {
3598  items = this._getItemsForLayout( items );
3599
3600  this._layoutItems( items, isInstant );
3601
3602  this._postLayout();
3603};
3604
3605/**
3606 * get the items to be laid out
3607 * you may want to skip over some items
3608 * @param {Array} items
3609 * @returns {Array} items
3610 */
3611proto._getItemsForLayout = function( items ) {
3612  return items.filter( function( item ) {
3613    return !item.isIgnored;
3614  });
3615};
3616
3617/**
3618 * layout items
3619 * @param {Array} items
3620 * @param {Boolean} isInstant
3621 */
3622proto._layoutItems = function( items, isInstant ) {
3623  this._emitCompleteOnItems( 'layout', items );
3624
3625  if ( !items || !items.length ) {
3626    // no items, emit event with empty array
3627    return;
3628  }
3629
3630  var queue = [];
3631
3632  items.forEach( function( item ) {
3633    // get x/y object from method
3634    var position = this._getItemLayoutPosition( item );
3635    // enqueue
3636    position.item = item;
3637    position.isInstant = isInstant || item.isLayoutInstant;
3638    queue.push( position );
3639  }, this );
3640
3641  this._processLayoutQueue( queue );
3642};
3643
3644/**
3645 * get item layout position
3646 * @param {Outlayer.Item} item
3647 * @returns {Object} x and y position
3648 */
3649proto._getItemLayoutPosition = function( /* item */ ) {
3650  return {
3651    x: 0,
3652    y: 0
3653  };
3654};
3655
3656/**
3657 * iterate over array and position each item
3658 * Reason being - separating this logic prevents 'layout invalidation'
3659 * thx @paul_irish
3660 * @param {Array} queue
3661 */
3662proto._processLayoutQueue = function( queue ) {
3663  this.updateStagger();
3664  queue.forEach( function( obj, i ) {
3665    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
3666  }, this );
3667};
3668
3669// set stagger from option in milliseconds number
3670proto.updateStagger = function() {
3671  var stagger = this.options.stagger;
3672  if ( stagger === null || stagger === undefined ) {
3673    this.stagger = 0;
3674    return;
3675  }
3676  this.stagger = getMilliseconds( stagger );
3677  return this.stagger;
3678};
3679
3680/**
3681 * Sets position of item in DOM
3682 * @param {Outlayer.Item} item
3683 * @param {Number} x - horizontal position
3684 * @param {Number} y - vertical position
3685 * @param {Boolean} isInstant - disables transitions
3686 */
3687proto._positionItem = function( item, x, y, isInstant, i ) {
3688  if ( isInstant ) {
3689    // if not transition, just set CSS
3690    item.goTo( x, y );
3691  } else {
3692    item.stagger( i * this.stagger );
3693    item.moveTo( x, y );
3694  }
3695};
3696
3697/**
3698 * Any logic you want to do after each layout,
3699 * i.e. size the container
3700 */
3701proto._postLayout = function() {
3702  this.resizeContainer();
3703};
3704
3705proto.resizeContainer = function() {
3706  var isResizingContainer = this._getOption('resizeContainer');
3707  if ( !isResizingContainer ) {
3708    return;
3709  }
3710  var size = this._getContainerSize();
3711  if ( size ) {
3712    this._setContainerMeasure( size.width, true );
3713    this._setContainerMeasure( size.height, false );
3714  }
3715};
3716
3717/**
3718 * Sets width or height of container if returned
3719 * @returns {Object} size
3720 *   @param {Number} width
3721 *   @param {Number} height
3722 */
3723proto._getContainerSize = noop;
3724
3725/**
3726 * @param {Number} measure - size of width or height
3727 * @param {Boolean} isWidth
3728 */
3729proto._setContainerMeasure = function( measure, isWidth ) {
3730  if ( measure === undefined ) {
3731    return;
3732  }
3733
3734  var elemSize = this.size;
3735  // add padding and border width if border box
3736  if ( elemSize.isBorderBox ) {
3737    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
3738      elemSize.borderLeftWidth + elemSize.borderRightWidth :
3739      elemSize.paddingBottom + elemSize.paddingTop +
3740      elemSize.borderTopWidth + elemSize.borderBottomWidth;
3741  }
3742
3743  measure = Math.max( measure, 0 );
3744  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
3745};
3746
3747/**
3748 * emit eventComplete on a collection of items events
3749 * @param {String} eventName
3750 * @param {Array} items - Outlayer.Items
3751 */
3752proto._emitCompleteOnItems = function( eventName, items ) {
3753  var _this = this;
3754  function onComplete() {
3755    _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
3756  }
3757
3758  var count = items.length;
3759  if ( !items || !count ) {
3760    onComplete();
3761    return;
3762  }
3763
3764  var doneCount = 0;
3765  function tick() {
3766    doneCount++;
3767    if ( doneCount == count ) {
3768      onComplete();
3769    }
3770  }
3771
3772  // bind callback
3773  items.forEach( function( item ) {
3774    item.once( eventName, tick );
3775  });
3776};
3777
3778/**
3779 * emits events via EvEmitter and jQuery events
3780 * @param {String} type - name of event
3781 * @param {Event} event - original event
3782 * @param {Array} args - extra arguments
3783 */
3784proto.dispatchEvent = function( type, event, args ) {
3785  // add original event to arguments
3786  var emitArgs = event ? [ event ].concat( args ) : args;
3787  this.emitEvent( type, emitArgs );
3788
3789  if ( jQuery ) {
3790    // set this.$element
3791    this.$element = this.$element || jQuery( this.element );
3792    if ( event ) {
3793      // create jQuery event
3794      var $event = jQuery.Event( event );
3795      $event.type = type;
3796      this.$element.trigger( $event, args );
3797    } else {
3798      // just trigger with type if no event available
3799      this.$element.trigger( type, args );
3800    }
3801  }
3802};
3803
3804// -------------------------- ignore & stamps -------------------------- //
3805
3806
3807/**
3808 * keep item in collection, but do not lay it out
3809 * ignored items do not get skipped in layout
3810 * @param {Element} elem
3811 */
3812proto.ignore = function( elem ) {
3813  var item = this.getItem( elem );
3814  if ( item ) {
3815    item.isIgnored = true;
3816  }
3817};
3818
3819/**
3820 * return item to layout collection
3821 * @param {Element} elem
3822 */
3823proto.unignore = function( elem ) {
3824  var item = this.getItem( elem );
3825  if ( item ) {
3826    delete item.isIgnored;
3827  }
3828};
3829
3830/**
3831 * adds elements to stamps
3832 * @param {NodeList, Array, Element, or String} elems
3833 */
3834proto.stamp = function( elems ) {
3835  elems = this._find( elems );
3836  if ( !elems ) {
3837    return;
3838  }
3839
3840  this.stamps = this.stamps.concat( elems );
3841  // ignore
3842  elems.forEach( this.ignore, this );
3843};
3844
3845/**
3846 * removes elements to stamps
3847 * @param {NodeList, Array, or Element} elems
3848 */
3849proto.unstamp = function( elems ) {
3850  elems = this._find( elems );
3851  if ( !elems ){
3852    return;
3853  }
3854
3855  elems.forEach( function( elem ) {
3856    // filter out removed stamp elements
3857    utils.removeFrom( this.stamps, elem );
3858    this.unignore( elem );
3859  }, this );
3860};
3861
3862/**
3863 * finds child elements
3864 * @param {NodeList, Array, Element, or String} elems
3865 * @returns {Array} elems
3866 */
3867proto._find = function( elems ) {
3868  if ( !elems ) {
3869    return;
3870  }
3871  // if string, use argument as selector string
3872  if ( typeof elems == 'string' ) {
3873    elems = this.element.querySelectorAll( elems );
3874  }
3875  elems = utils.makeArray( elems );
3876  return elems;
3877};
3878
3879proto._manageStamps = function() {
3880  if ( !this.stamps || !this.stamps.length ) {
3881    return;
3882  }
3883
3884  this._getBoundingRect();
3885
3886  this.stamps.forEach( this._manageStamp, this );
3887};
3888
3889// update boundingLeft / Top
3890proto._getBoundingRect = function() {
3891  // get bounding rect for container element
3892  var boundingRect = this.element.getBoundingClientRect();
3893  var size = this.size;
3894  this._boundingRect = {
3895    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
3896    top: boundingRect.top + size.paddingTop + size.borderTopWidth,
3897    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
3898    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
3899  };
3900};
3901
3902/**
3903 * @param {Element} stamp
3904**/
3905proto._manageStamp = noop;
3906
3907/**
3908 * get x/y position of element relative to container element
3909 * @param {Element} elem
3910 * @returns {Object} offset - has left, top, right, bottom
3911 */
3912proto._getElementOffset = function( elem ) {
3913  var boundingRect = elem.getBoundingClientRect();
3914  var thisRect = this._boundingRect;
3915  var size = getSize( elem );
3916  var offset = {
3917    left: boundingRect.left - thisRect.left - size.marginLeft,
3918    top: boundingRect.top - thisRect.top - size.marginTop,
3919    right: thisRect.right - boundingRect.right - size.marginRight,
3920    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
3921  };
3922  return offset;
3923};
3924
3925// -------------------------- resize -------------------------- //
3926
3927// enable event handlers for listeners
3928// i.e. resize -> onresize
3929proto.handleEvent = utils.handleEvent;
3930
3931/**
3932 * Bind layout to window resizing
3933 */
3934proto.bindResize = function() {
3935  window.addEventListener( 'resize', this );
3936  this.isResizeBound = true;
3937};
3938
3939/**
3940 * Unbind layout to window resizing
3941 */
3942proto.unbindResize = function() {
3943  window.removeEventListener( 'resize', this );
3944  this.isResizeBound = false;
3945};
3946
3947proto.onresize = function() {
3948  this.resize();
3949};
3950
3951utils.debounceMethod( Outlayer, 'onresize', 100 );
3952
3953proto.resize = function() {
3954  // don't trigger if size did not change
3955  // or if resize was unbound. See #9
3956  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
3957    return;
3958  }
3959
3960  this.layout();
3961};
3962
3963/**
3964 * check if layout is needed post layout
3965 * @returns Boolean
3966 */
3967proto.needsResizeLayout = function() {
3968  var size = getSize( this.element );
3969  // check that this.size and size are there
3970  // IE8 triggers resize on body size change, so they might not be
3971  var hasSizes = this.size && size;
3972  return hasSizes && size.innerWidth !== this.size.innerWidth;
3973};
3974
3975// -------------------------- methods -------------------------- //
3976
3977/**
3978 * add items to Outlayer instance
3979 * @param {Array or NodeList or Element} elems
3980 * @returns {Array} items - Outlayer.Items
3981**/
3982proto.addItems = function( elems ) {
3983  var items = this._itemize( elems );
3984  // add items to collection
3985  if ( items.length ) {
3986    this.items = this.items.concat( items );
3987  }
3988  return items;
3989};
3990
3991/**
3992 * Layout newly-appended item elements
3993 * @param {Array or NodeList or Element} elems
3994 */
3995proto.appended = function( elems ) {
3996  var items = this.addItems( elems );
3997  if ( !items.length ) {
3998    return;
3999  }
4000  // layout and reveal just the new items
4001  this.layoutItems( items, true );
4002  this.reveal( items );
4003};
4004
4005/**
4006 * Layout prepended elements
4007 * @param {Array or NodeList or Element} elems
4008 */
4009proto.prepended = function( elems ) {
4010  var items = this._itemize( elems );
4011  if ( !items.length ) {
4012    return;
4013  }
4014  // add items to beginning of collection
4015  var previousItems = this.items.slice(0);
4016  this.items = items.concat( previousItems );
4017  // start new layout
4018  this._resetLayout();
4019  this._manageStamps();
4020  // layout new stuff without transition
4021  this.layoutItems( items, true );
4022  this.reveal( items );
4023  // layout previous items
4024  this.layoutItems( previousItems );
4025};
4026
4027/**
4028 * reveal a collection of items
4029 * @param {Array of Outlayer.Items} items
4030 */
4031proto.reveal = function( items ) {
4032  this._emitCompleteOnItems( 'reveal', items );
4033  if ( !items || !items.length ) {
4034    return;
4035  }
4036  var stagger = this.updateStagger();
4037  items.forEach( function( item, i ) {
4038    item.stagger( i * stagger );
4039    item.reveal();
4040  });
4041};
4042
4043/**
4044 * hide a collection of items
4045 * @param {Array of Outlayer.Items} items
4046 */
4047proto.hide = function( items ) {
4048  this._emitCompleteOnItems( 'hide', items );
4049  if ( !items || !items.length ) {
4050    return;
4051  }
4052  var stagger = this.updateStagger();
4053  items.forEach( function( item, i ) {
4054    item.stagger( i * stagger );
4055    item.hide();
4056  });
4057};
4058
4059/**
4060 * reveal item elements
4061 * @param {Array}, {Element}, {NodeList} items
4062 */
4063proto.revealItemElements = function( elems ) {
4064  var items = this.getItems( elems );
4065  this.reveal( items );
4066};
4067
4068/**
4069 * hide item elements
4070 * @param {Array}, {Element}, {NodeList} items
4071 */
4072proto.hideItemElements = function( elems ) {
4073  var items = this.getItems( elems );
4074  this.hide( items );
4075};
4076
4077/**
4078 * get Outlayer.Item, given an Element
4079 * @param {Element} elem
4080 * @param {Function} callback
4081 * @returns {Outlayer.Item} item
4082 */
4083proto.getItem = function( elem ) {
4084  // loop through items to get the one that matches
4085  for ( var i=0; i < this.items.length; i++ ) {
4086    var item = this.items[i];
4087    if ( item.element == elem ) {
4088      // return item
4089      return item;
4090    }
4091  }
4092};
4093
4094/**
4095 * get collection of Outlayer.Items, given Elements
4096 * @param {Array} elems
4097 * @returns {Array} items - Outlayer.Items
4098 */
4099proto.getItems = function( elems ) {
4100  elems = utils.makeArray( elems );
4101  var items = [];
4102  elems.forEach( function( elem ) {
4103    var item = this.getItem( elem );
4104    if ( item ) {
4105      items.push( item );
4106    }
4107  }, this );
4108
4109  return items;
4110};
4111
4112/**
4113 * remove element(s) from instance and DOM
4114 * @param {Array or NodeList or Element} elems
4115 */
4116proto.remove = function( elems ) {
4117  var removeItems = this.getItems( elems );
4118
4119  this._emitCompleteOnItems( 'remove', removeItems );
4120
4121  // bail if no items to remove
4122  if ( !removeItems || !removeItems.length ) {
4123    return;
4124  }
4125
4126  removeItems.forEach( function( item ) {
4127    item.remove();
4128    // remove item from collection
4129    utils.removeFrom( this.items, item );
4130  }, this );
4131};
4132
4133// ----- destroy ----- //
4134
4135// remove and disable Outlayer instance
4136proto.destroy = function() {
4137  // clean up dynamic styles
4138  var style = this.element.style;
4139  style.height = '';
4140  style.position = '';
4141  style.width = '';
4142  // destroy items
4143  this.items.forEach( function( item ) {
4144    item.destroy();
4145  });
4146
4147  this.unbindResize();
4148
4149  var id = this.element.outlayerGUID;
4150  delete instances[ id ]; // remove reference to instance by id
4151  delete this.element.outlayerGUID;
4152  // remove data for jQuery
4153  if ( jQuery ) {
4154    jQuery.removeData( this.element, this.constructor.namespace );
4155  }
4156
4157};
4158
4159// -------------------------- data -------------------------- //
4160
4161/**
4162 * get Outlayer instance from element
4163 * @param {Element} elem
4164 * @returns {Outlayer}
4165 */
4166Outlayer.data = function( elem ) {
4167  elem = utils.getQueryElement( elem );
4168  var id = elem && elem.outlayerGUID;
4169  return id && instances[ id ];
4170};
4171
4172
4173// -------------------------- create Outlayer class -------------------------- //
4174
4175/**
4176 * create a layout class
4177 * @param {String} namespace
4178 */
4179Outlayer.create = function( namespace, options ) {
4180  // sub-class Outlayer
4181  var Layout = subclass( Outlayer );
4182  // apply new options and compatOptions
4183  Layout.defaults = utils.extend( {}, Outlayer.defaults );
4184  utils.extend( Layout.defaults, options );
4185  Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions  );
4186
4187  Layout.namespace = namespace;
4188
4189  Layout.data = Outlayer.data;
4190
4191  // sub-class Item
4192  Layout.Item = subclass( Item );
4193
4194  // -------------------------- declarative -------------------------- //
4195
4196  utils.htmlInit( Layout, namespace );
4197
4198  // -------------------------- jQuery bridge -------------------------- //
4199
4200  // make into jQuery plugin
4201  if ( jQuery && jQuery.bridget ) {
4202    jQuery.bridget( namespace, Layout );
4203  }
4204
4205  return Layout;
4206};
4207
4208function subclass( Parent ) {
4209  function SubClass() {
4210    Parent.apply( this, arguments );
4211  }
4212
4213  SubClass.prototype = Object.create( Parent.prototype );
4214  SubClass.prototype.constructor = SubClass;
4215
4216  return SubClass;
4217}
4218
4219// ----- helpers ----- //
4220
4221// how many milliseconds are in each unit
4222var msUnits = {
4223  ms: 1,
4224  s: 1000
4225};
4226
4227// munge time-like parameter into millisecond number
4228// '0.4s' -> 40
4229function getMilliseconds( time ) {
4230  if ( typeof time == 'number' ) {
4231    return time;
4232  }
4233  var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
4234  var num = matches && matches[1];
4235  var unit = matches && matches[2];
4236  if ( !num.length ) {
4237    return 0;
4238  }
4239  num = parseFloat( num );
4240  var mult = msUnits[ unit ] || 1;
4241  return num * mult;
4242}
4243
4244// ----- fin ----- //
4245
4246// back in global
4247Outlayer.Item = Item;
4248
4249return Outlayer;
4250
4251}));
4252
4253/**
4254 * 
vendor: 23,322 bytes, lines 4254-5129
4254Isotope Item
4255**/
4256
4257( function( window, factory ) {
4258  // universal module definition
4259  /* jshint strict: false */ /*globals define, module, require */
4260  if ( typeof define == 'function' && define.amd ) {
4261    // AMD
4262    define( 'isotope/js/item',[
4263        'outlayer/outlayer'
4264      ],
4265      factory );
4266  } else if ( typeof module == 'object' && module.exports ) {
4267    // CommonJS
4268    module.exports = factory(
4269      require('outlayer')
4270    );
4271  } else {
4272    // browser global
4273    window.Isotope = window.Isotope || {};
4274    window.Isotope.Item = factory(
4275      window.Outlayer
4276    );
4277  }
4278
4279}( window, function factory( Outlayer ) {
4280'use strict';
4281
4282// -------------------------- Item -------------------------- //
4283
4284// sub-class Outlayer Item
4285function Item() {
4286  Outlayer.Item.apply( this, arguments );
4287}
4288
4289var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
4290
4291var _create = proto._create;
4292proto._create = function() {
4293  // assign id, used for original-order sorting
4294  this.id = this.layout.itemGUID++;
4295  _create.call( this );
4296  this.sortData = {};
4297};
4298
4299proto.updateSortData = function() {
4300  if ( this.isIgnored ) {
4301    return;
4302  }
4303  // default sorters
4304  this.sortData.id = this.id;
4305  // for backward compatibility
4306  this.sortData['original-order'] = this.id;
4307  this.sortData.random = Math.random();
4308  // go thru getSortData obj and apply the sorters
4309  var getSortData = this.layout.options.getSortData;
4310  var sorters = this.layout._sorters;
4311  for ( var key in getSortData ) {
4312    var sorter = sorters[ key ];
4313    this.sortData[ key ] = sorter( this.element, this );
4314  }
4315};
4316
4317var _destroy = proto.destroy;
4318proto.destroy = function() {
4319  // call super
4320  _destroy.apply( this, arguments );
4321  // reset display, #741
4322  this.css({
4323    display: ''
4324  });
4325};
4326
4327return Item;
4328
4329}));
4330
4331/**
4332 * Isotope LayoutMode
4333 */
4334
4335( function( window, factory ) {
4336  // universal module definition
4337  /* jshint strict: false */ /*globals define, module, require */
4338  if ( typeof define == 'function' && define.amd ) {
4339    // AMD
4340    define( 'isotope/js/layout-mode',[
4341        'get-size/get-size',
4342        'outlayer/outlayer'
4343      ],
4344      factory );
4345  } else if ( typeof module == 'object' && module.exports ) {
4346    // CommonJS
4347    module.exports = factory(
4348      require('get-size'),
4349      require('outlayer')
4350    );
4351  } else {
4352    // browser global
4353    window.Isotope = window.Isotope || {};
4354    window.Isotope.LayoutMode = factory(
4355      window.getSize,
4356      window.Outlayer
4357    );
4358  }
4359
4360}( window, function factory( getSize, Outlayer ) {
4361  'use strict';
4362
4363  // layout mode class
4364  function LayoutMode( isotope ) {
4365    this.isotope = isotope;
4366    // link properties
4367    if ( isotope ) {
4368      this.options = isotope.options[ this.namespace ];
4369      this.element = isotope.element;
4370      this.items = isotope.filteredItems;
4371      this.size = isotope.size;
4372    }
4373  }
4374
4375  var proto = LayoutMode.prototype;
4376
4377  /**
4378   * some methods should just defer to default Outlayer method
4379   * and reference the Isotope instance as `this`
4380  **/
4381  var facadeMethods = [
4382    '_resetLayout',
4383    '_getItemLayoutPosition',
4384    '_manageStamp',
4385    '_getContainerSize',
4386    '_getElementOffset',
4387    'needsResizeLayout',
4388    '_getOption'
4389  ];
4390
4391  facadeMethods.forEach( function( methodName ) {
4392    proto[ methodName ] = function() {
4393      return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
4394    };
4395  });
4396
4397  // -----  ----- //
4398
4399  // for horizontal layout modes, check vertical size
4400  proto.needsVerticalResizeLayout = function() {
4401    // don't trigger if size did not change
4402    var size = getSize( this.isotope.element );
4403    // check that this.size and size are there
4404    // IE8 triggers resize on body size change, so they might not be
4405    var hasSizes = this.isotope.size && size;
4406    return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
4407  };
4408
4409  // ----- measurements ----- //
4410
4411  proto._getMeasurement = function() {
4412    this.isotope._getMeasurement.apply( this, arguments );
4413  };
4414
4415  proto.getColumnWidth = function() {
4416    this.getSegmentSize( 'column', 'Width' );
4417  };
4418
4419  proto.getRowHeight = function() {
4420    this.getSegmentSize( 'row', 'Height' );
4421  };
4422
4423  /**
4424   * get columnWidth or rowHeight
4425   * segment: 'column' or 'row'
4426   * size 'Width' or 'Height'
4427  **/
4428  proto.getSegmentSize = function( segment, size ) {
4429    var segmentName = segment + size;
4430    var outerSize = 'outer' + size;
4431    // columnWidth / outerWidth // rowHeight / outerHeight
4432    this._getMeasurement( segmentName, outerSize );
4433    // got rowHeight or columnWidth, we can chill
4434    if ( this[ segmentName ] ) {
4435      return;
4436    }
4437    // fall back to item of first element
4438    var firstItemSize = this.getFirstItemSize();
4439    this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
4440      // or size of container
4441      this.isotope.size[ 'inner' + size ];
4442  };
4443
4444  proto.getFirstItemSize = function() {
4445    var firstItem = this.isotope.filteredItems[0];
4446    return firstItem && firstItem.element && getSize( firstItem.element );
4447  };
4448
4449  // ----- methods that should reference isotope ----- //
4450
4451  proto.layout = function() {
4452    this.isotope.layout.apply( this.isotope, arguments );
4453  };
4454
4455  proto.getSize = function() {
4456    this.isotope.getSize();
4457    this.size = this.isotope.size;
4458  };
4459
4460  // -------------------------- create -------------------------- //
4461
4462  LayoutMode.modes = {};
4463
4464  LayoutMode.create = function( namespace, options ) {
4465
4466    function Mode() {
4467      LayoutMode.apply( this, arguments );
4468    }
4469
4470    Mode.prototype = Object.create( proto );
4471    Mode.prototype.constructor = Mode;
4472
4473    // default options
4474    if ( options ) {
4475      Mode.options = options;
4476    }
4477
4478    Mode.prototype.namespace = namespace;
4479    // register in Isotope
4480    LayoutMode.modes[ namespace ] = Mode;
4481
4482    return Mode;
4483  };
4484
4485  return LayoutMode;
4486
4487}));
4488
4489/*!
4490 * Masonry v4.1.0
4491 * Cascading grid layout library
4492 * http://masonry.desandro.com
4493 * MIT License
4494 * by David DeSandro
4495 */
4496
4497( function( window, factory ) {
4498  // universal module definition
4499  /* jshint strict: false */ /*globals define, module, require */
4500  if ( typeof define == 'function' && define.amd ) {
4501    // AMD
4502    define( 'masonry/masonry',[
4503        'outlayer/outlayer',
4504        'get-size/get-size'
4505      ],
4506      factory );
4507  } else if ( typeof module == 'object' && module.exports ) {
4508    // CommonJS
4509    module.exports = factory(
4510      require('outlayer'),
4511      require('get-size')
4512    );
4513  } else {
4514    // browser global
4515    window.Masonry = factory(
4516      window.Outlayer,
4517      window.getSize
4518    );
4519  }
4520
4521}( window, function factory( Outlayer, getSize ) {
4522
4523
4524
4525// -------------------------- masonryDefinition -------------------------- //
4526
4527  // create an Outlayer layout class
4528  var Masonry = Outlayer.create('masonry');
4529  // isFitWidth -> fitWidth
4530  Masonry.compatOptions.fitWidth = 'isFitWidth';
4531
4532  Masonry.prototype._resetLayout = function() {
4533    this.getSize();
4534    this._getMeasurement( 'columnWidth', 'outerWidth' );
4535    this._getMeasurement( 'gutter', 'outerWidth' );
4536    this.measureColumns();
4537
4538    // reset column Y
4539    this.colYs = [];
4540    for ( var i=0; i < this.cols; i++ ) {
4541      this.colYs.push( 0 );
4542    }
4543
4544    this.maxY = 0;
4545  };
4546
4547  Masonry.prototype.measureColumns = function() {
4548    this.getContainerWidth();
4549    // if columnWidth is 0, default to outerWidth of first item
4550    if ( !this.columnWidth ) {
4551      var firstItem = this.items[0];
4552      var firstItemElem = firstItem && firstItem.element;
4553      // columnWidth fall back to item of first element
4554      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
4555        // if first elem has no width, default to size of container
4556        this.containerWidth;
4557    }
4558
4559    var columnWidth = this.columnWidth += this.gutter;
4560
4561    // calculate columns
4562    var containerWidth = this.containerWidth + this.gutter;
4563    var cols = containerWidth / columnWidth;
4564    // fix rounding errors, typically with gutters
4565    var excess = columnWidth - containerWidth % columnWidth;
4566    // if overshoot is less than a pixel, round up, otherwise floor it
4567    var mathMethod = excess && excess < 1 ? 'round' : 'floor';
4568    cols = Math[ mathMethod ]( cols );
4569    this.cols = Math.max( cols, 1 );
4570  };
4571
4572  Masonry.prototype.getContainerWidth = function() {
4573    // container is parent if fit width
4574    var isFitWidth = this._getOption('fitWidth');
4575    var container = isFitWidth ? this.element.parentNode : this.element;
4576    // check that this.size and size are there
4577    // IE8 triggers resize on body size change, so they might not be
4578    var size = getSize( container );
4579    this.containerWidth = size && size.innerWidth;
4580  };
4581
4582  Masonry.prototype._getItemLayoutPosition = function( item ) {
4583    item.getSize();
4584    // how many columns does this brick span
4585    var remainder = item.size.outerWidth % this.columnWidth;
4586    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
4587    // round if off by 1 pixel, otherwise use ceil
4588    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
4589    colSpan = Math.min( colSpan, this.cols );
4590
4591    var colGroup = this._getColGroup( colSpan );
4592    // get the minimum Y value from the columns
4593    var minimumY = Math.min.apply( Math, colGroup );
4594    var shortColIndex = colGroup.indexOf( minimumY );
4595
4596    // position the brick
4597    var position = {
4598      x: this.columnWidth * shortColIndex,
4599      y: minimumY
4600    };
4601
4602    // apply setHeight to necessary columns
4603    var setHeight = minimumY + item.size.outerHeight;
4604    var setSpan = this.cols + 1 - colGroup.length;
4605    for ( var i = 0; i < setSpan; i++ ) {
4606      this.colYs[ shortColIndex + i ] = setHeight;
4607    }
4608
4609    return position;
4610  };
4611
4612  /**
4613   * @param {Number} colSpan - number of columns the element spans
4614   * @returns {Array} colGroup
4615   */
4616  Masonry.prototype._getColGroup = function( colSpan ) {
4617    if ( colSpan < 2 ) {
4618      // if brick spans only one column, use all the column Ys
4619      return this.colYs;
4620    }
4621
4622    var colGroup = [];
4623    // how many different places could this brick fit horizontally
4624    var groupCount = this.cols + 1 - colSpan;
4625    // for each group potential horizontal position
4626    for ( var i = 0; i < groupCount; i++ ) {
4627      // make an array of colY values for that one group
4628      var groupColYs = this.colYs.slice( i, i + colSpan );
4629      // and get the max value of the array
4630      colGroup[i] = Math.max.apply( Math, groupColYs );
4631    }
4632    return colGroup;
4633  };
4634
4635  Masonry.prototype._manageStamp = function( stamp ) {
4636    var stampSize = getSize( stamp );
4637    var offset = this._getElementOffset( stamp );
4638    // get the columns that this stamp affects
4639    var isOriginLeft = this._getOption('originLeft');
4640    var firstX = isOriginLeft ? offset.left : offset.right;
4641    var lastX = firstX + stampSize.outerWidth;
4642    var firstCol = Math.floor( firstX / this.columnWidth );
4643    firstCol = Math.max( 0, firstCol );
4644    var lastCol = Math.floor( lastX / this.columnWidth );
4645    // lastCol should not go over if multiple of columnWidth #425
4646    lastCol -= lastX % this.columnWidth ? 0 : 1;
4647    lastCol = Math.min( this.cols - 1, lastCol );
4648    // set colYs to bottom of the stamp
4649
4650    var isOriginTop = this._getOption('originTop');
4651    var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
4652      stampSize.outerHeight;
4653    for ( var i = firstCol; i <= lastCol; i++ ) {
4654      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
4655    }
4656  };
4657
4658  Masonry.prototype._getContainerSize = function() {
4659    this.maxY = Math.max.apply( Math, this.colYs );
4660    var size = {
4661      height: this.maxY
4662    };
4663
4664    if ( this._getOption('fitWidth') ) {
4665      size.width = this._getContainerFitWidth();
4666    }
4667
4668    return size;
4669  };
4670
4671  Masonry.prototype._getContainerFitWidth = function() {
4672    var unusedCols = 0;
4673    // count unused columns
4674    var i = this.cols;
4675    while ( --i ) {
4676      if ( this.colYs[i] !== 0 ) {
4677        break;
4678      }
4679      unusedCols++;
4680    }
4681    // fit container to columns that have been used
4682    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
4683  };
4684
4685  Masonry.prototype.needsResizeLayout = function() {
4686    var previousWidth = this.containerWidth;
4687    this.getContainerWidth();
4688    return previousWidth != this.containerWidth;
4689  };
4690
4691  return Masonry;
4692
4693}));
4694
4695/*!
4696 * Masonry layout mode
4697 * sub-classes Masonry
4698 * http://masonry.desandro.com
4699 */
4700
4701( function( window, factory ) {
4702  // universal module definition
4703  /* jshint strict: false */ /*globals define, module, require */
4704  if ( typeof define == 'function' && define.amd ) {
4705    // AMD
4706    define( 'isotope/js/layout-modes/masonry',[
4707        '../layout-mode',
4708        'masonry/masonry'
4709      ],
4710      factory );
4711  } else if ( typeof module == 'object' && module.exports ) {
4712    // CommonJS
4713    module.exports = factory(
4714      require('../layout-mode'),
4715      require('masonry-layout')
4716    );
4717  } else {
4718    // browser global
4719    factory(
4720      window.Isotope.LayoutMode,
4721      window.Masonry
4722    );
4723  }
4724
4725}( window, function factory( LayoutMode, Masonry ) {
4726'use strict';
4727
4728// -------------------------- masonryDefinition -------------------------- //
4729
4730  // create an Outlayer layout class
4731  var MasonryMode = LayoutMode.create('masonry');
4732
4733  var proto = MasonryMode.prototype;
4734
4735  var keepModeMethods = {
4736    _getElementOffset: true,
4737    layout: true,
4738    _getMeasurement: true
4739  };
4740
4741  // inherit Masonry prototype
4742  for ( var method in Masonry.prototype ) {
4743    // do not inherit mode methods
4744    if ( !keepModeMethods[ method ] ) {
4745      proto[ method ] = Masonry.prototype[ method ];
4746    }
4747  }
4748
4749  var measureColumns = proto.measureColumns;
4750  proto.measureColumns = function() {
4751    // set items, used if measuring first item
4752    this.items = this.isotope.filteredItems;
4753    measureColumns.call( this );
4754  };
4755
4756  // point to mode options for fitWidth
4757  var _getOption = proto._getOption;
4758  proto._getOption = function( option ) {
4759    if ( option == 'fitWidth' ) {
4760      return this.options.isFitWidth !== undefined ?
4761        this.options.isFitWidth : this.options.fitWidth;
4762    }
4763    return _getOption.apply( this.isotope, arguments );
4764  };
4765
4766  return MasonryMode;
4767
4768}));
4769
4770/**
4771 * fitRows layout mode
4772 */
4773
4774( function( window, factory ) {
4775  // universal module definition
4776  /* jshint strict: false */ /*globals define, module, require */
4777  if ( typeof define == 'function' && define.amd ) {
4778    // AMD
4779    define( 'isotope/js/layout-modes/fit-rows',[
4780        '../layout-mode'
4781      ],
4782      factory );
4783  } else if ( typeof exports == 'object' ) {
4784    // CommonJS
4785    module.exports = factory(
4786      require('../layout-mode')
4787    );
4788  } else {
4789    // browser global
4790    factory(
4791      window.Isotope.LayoutMode
4792    );
4793  }
4794
4795}( window, function factory( LayoutMode ) {
4796'use strict';
4797
4798var FitRows = LayoutMode.create('fitRows');
4799
4800var proto = FitRows.prototype;
4801
4802proto._resetLayout = function() {
4803  this.x = 0;
4804  this.y = 0;
4805  this.maxY = 0;
4806  this._getMeasurement( 'gutter', 'outerWidth' );
4807};
4808
4809proto._getItemLayoutPosition = function( item ) {
4810  item.getSize();
4811
4812  var itemWidth = item.size.outerWidth + this.gutter;
4813  // if this element cannot fit in the current row
4814  var containerWidth = this.isotope.size.innerWidth + this.gutter;
4815  if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
4816    this.x = 0;
4817    this.y = this.maxY;
4818  }
4819
4820  var position = {
4821    x: this.x,
4822    y: this.y
4823  };
4824
4825  this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
4826  this.x += itemWidth;
4827
4828  return position;
4829};
4830
4831proto._getContainerSize = function() {
4832  return { height: this.maxY };
4833};
4834
4835return FitRows;
4836
4837}));
4838
4839/**
4840 * vertical layout mode
4841 */
4842
4843( function( window, factory ) {
4844  // universal module definition
4845  /* jshint strict: false */ /*globals define, module, require */
4846  if ( typeof define == 'function' && define.amd ) {
4847    // AMD
4848    define( 'isotope/js/layout-modes/vertical',[
4849        '../layout-mode'
4850      ],
4851      factory );
4852  } else if ( typeof module == 'object' && module.exports ) {
4853    // CommonJS
4854    module.exports = factory(
4855      require('../layout-mode')
4856    );
4857  } else {
4858    // browser global
4859    factory(
4860      window.Isotope.LayoutMode
4861    );
4862  }
4863
4864}( window, function factory( LayoutMode ) {
4865'use strict';
4866
4867var Vertical = LayoutMode.create( 'vertical', {
4868  horizontalAlignment: 0
4869});
4870
4871var proto = Vertical.prototype;
4872
4873proto._resetLayout = function() {
4874  this.y = 0;
4875};
4876
4877proto._getItemLayoutPosition = function( item ) {
4878  item.getSize();
4879  var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
4880    this.options.horizontalAlignment;
4881  var y = this.y;
4882  this.y += item.size.outerHeight;
4883  return { x: x, y: y };
4884};
4885
4886proto._getContainerSize = function() {
4887  return { height: this.y };
4888};
4889
4890return Vertical;
4891
4892}));
4893
4894/*!
4895 * Isotope v3.0.1
4896 *
4897 * Licensed GPLv3 for open source use
4898 * or Isotope Commercial License for commercial use
4899 *
4900 * http://isotope.metafizzy.co
4901 * Copyright 2016 Metafizzy
4902 */
4903
4904( function( window, factory ) {
4905  // universal module definition
4906  /* jshint strict: false */ /*globals define, module, require */
4907  if ( typeof define == 'function' && define.amd ) {
4908    // AMD
4909    define( [
4910        'outlayer/outlayer',
4911        'get-size/get-size',
4912        'desandro-matches-selector/matches-selector',
4913        'fizzy-ui-utils/utils',
4914        'isotope/js/item',
4915        'isotope/js/layout-mode',
4916        // include default layout modes
4917        'isotope/js/layout-modes/masonry',
4918        'isotope/js/layout-modes/fit-rows',
4919        'isotope/js/layout-modes/vertical'
4920      ],
4921      function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
4922        return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
4923      });
4924  } else if ( typeof module == 'object' && module.exports ) {
4925    // CommonJS
4926    module.exports = factory(
4927      window,
4928      require('outlayer'),
4929      require('get-size'),
4930      require('desandro-matches-selector'),
4931      require('fizzy-ui-utils'),
4932      require('isotope/js/item'),
4933      require('isotope/js/layout-mode'),
4934      // include default layout modes
4935      require('isotope/js/layout-modes/masonry'),
4936      require('isotope/js/layout-modes/fit-rows'),
4937      require('isotope/js/layout-modes/vertical')
4938    );
4939  } else {
4940    // browser global
4941    window.Isotope = factory(
4942      window,
4943      window.Outlayer,
4944      window.getSize,
4945      window.matchesSelector,
4946      window.fizzyUIUtils,
4947      window.Isotope.Item,
4948      window.Isotope.LayoutMode
4949    );
4950  }
4951
4952}( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
4953  Item, LayoutMode ) {
4954
4955
4956
4957// -------------------------- vars -------------------------- //
4958
4959var jQuery = window.jQuery;
4960
4961// -------------------------- helpers -------------------------- //
4962
4963var trim = String.prototype.trim ?
4964  function( str ) {
4965    return str.trim();
4966  } :
4967  function( str ) {
4968    return str.replace( /^\s+|\s+$/g, '' );
4969  };
4970
4971// -------------------------- isotopeDefinition -------------------------- //
4972
4973  // create an Outlayer layout class
4974  var Isotope = Outlayer.create( 'isotope', {
4975    layoutMode: 'masonry',
4976    isJQueryFiltering: true,
4977    sortAscending: true
4978  });
4979
4980  Isotope.Item = Item;
4981  Isotope.LayoutMode = LayoutMode;
4982
4983  var proto = Isotope.prototype;
4984
4985  proto._create = function() {
4986    this.itemGUID = 0;
4987    // functions that sort items
4988    this._sorters = {};
4989    this._getSorters();
4990    // call super
4991    Outlayer.prototype._create.call( this );
4992
4993    // create layout modes
4994    this.modes = {};
4995    // start filteredItems with all items
4996    this.filteredItems = this.items;
4997    // keep of track of sortBys
4998    this.sortHistory = [ 'original-order' ];
4999    // create from registered layout modes
5000    for ( var name in LayoutMode.modes ) {
5001      this._initLayoutMode( name );
5002    }
5003  };
5004
5005  proto.reloadItems = function() {
5006    // reset item ID counter
5007    this.itemGUID = 0;
5008    // call super
5009    Outlayer.prototype.reloadItems.call( this );
5010  };
5011
5012  proto._itemize = function() {
5013    var items = Outlayer.prototype._itemize.apply( this, arguments );
5014    // assign ID for original-order
5015    for ( var i=0; i < items.length; i++ ) {
5016      var item = items[i];
5017      item.id = this.itemGUID++;
5018    }
5019    this._updateItemsSortData( items );
5020    return items;
5021  };
5022
5023
5024  // -------------------------- layout -------------------------- //
5025
5026  proto._initLayoutMode = function( name ) {
5027    var Mode = LayoutMode.modes[ name ];
5028    // set mode options
5029    // HACK extend initial options, back-fill in default options
5030    var initialOpts = this.options[ name ] || {};
5031    this.options[ name ] = Mode.options ?
5032      utils.extend( Mode.options, initialOpts ) : initialOpts;
5033    // init layout mode instance
5034    this.modes[ name ] = new Mode( this );
5035  };
5036
5037
5038  proto.layout = function() {
5039    // if first time doing layout, do all magic
5040    if ( !this._isLayoutInited && this._getOption('initLayout') ) {
5041      this.arrange();
5042      return;
5043    }
5044    this._layout();
5045  };
5046
5047  // private method to be used in layout() & magic()
5048  proto._layout = function() {
5049    // don't animate first layout
5050    var isInstant = this._getIsInstant();
5051    // layout flow
5052    this._resetLayout();
5053    this._manageStamps();
5054    this.layoutItems( this.filteredItems, isInstant );
5055
5056    // flag for initalized
5057    this._isLayoutInited = true;
5058  };
5059
5060  // filter + sort + layout
5061  proto.arrange = function( opts ) {
5062    // set any options pass
5063    this.option( opts );
5064    this._getIsInstant();
5065    // filter, sort, and layout
5066
5067    // filter
5068    var filtered = this._filter( this.items );
5069    this.filteredItems = filtered.matches;
5070
5071    this._bindArrangeComplete();
5072
5073    if ( this._isInstant ) {
5074      this._noTransition( this._hideReveal, [ filtered ] );
5075    } else {
5076      this._hideReveal( filtered );
5077    }
5078
5079    this._sort();
5080    this._layout();
5081  };
5082  // alias to _init for main plugin method
5083  proto._init = proto.arrange;
5084
5085  proto._hideReveal = function( filtered ) {
5086    this.reveal( filtered.needReveal );
5087    this.hide( filtered.needHide );
5088  };
5089
5090  // HACK
5091  // Don't animate/transition first layout
5092  // Or don't animate/transition other layouts
5093  proto._getIsInstant = function() {
5094    var isLayoutInstant = this._getOption('layoutInstant');
5095    var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :
5096      !this._isLayoutInited;
5097    this._isInstant = isInstant;
5098    return isInstant;
5099  };
5100
5101  // listen for layoutComplete, hideComplete and revealComplete
5102  // to trigger arrangeComplete
5103  proto._bindArrangeComplete = function() {
5104    // listen for 3 events to trigger arrangeComplete
5105    var isLayoutComplete, isHideComplete, isRevealComplete;
5106    var _this = this;
5107    function arrangeParallelCallback() {
5108      if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
5109        _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
5110      }
5111    }
5112    this.once( 'layoutComplete', function() {
5113      isLayoutComplete = true;
5114      arrangeParallelCallback();
5115    });
5116    this.once( 'hideComplete', function() {
5117      isHideComplete = true;
5118      arrangeParallelCallback();
5119    });
5120    this.once( 'revealComplete', function() {
5121      isRevealComplete = true;
5122      arrangeParallelCallback();
5123    });
5124  };
5125
5126  // -------------------------- filter -------------------------- //
5127
5128  proto._filter = function( items ) {
5129    var filter = this.options.filter;
vendor: 10,963 bytes, lines 5130-5517
5130    filter = filter || '*';
5131    var matches = [];
5132    var hiddenMatched = [];
5133    var visibleUnmatched = [];
5134
5135    var test = this._getFilterTest( filter );
5136
5137    // test each item
5138    for ( var i=0; i < items.length; i++ ) {
5139      var item = items[i];
5140      if ( item.isIgnored ) {
5141        continue;
5142      }
5143      // add item to either matched or unmatched group
5144      var isMatched = test( item );
5145      // item.isFilterMatched = isMatched;
5146      // add to matches if its a match
5147      if ( isMatched ) {
5148        matches.push( item );
5149      }
5150      // add to additional group if item needs to be hidden or revealed
5151      if ( isMatched && item.isHidden ) {
5152        hiddenMatched.push( item );
5153      } else if ( !isMatched && !item.isHidden ) {
5154        visibleUnmatched.push( item );
5155      }
5156    }
5157
5158    // return collections of items to be manipulated
5159    return {
5160      matches: matches,
5161      needReveal: hiddenMatched,
5162      needHide: visibleUnmatched
5163    };
5164  };
5165
5166  // get a jQuery, function, or a matchesSelector test given the filter
5167  proto._getFilterTest = function( filter ) {
5168    if ( jQuery && this.options.isJQueryFiltering ) {
5169      // use jQuery
5170      return function( item ) {
5171        return jQuery( item.element ).is( filter );
5172      };
5173    }
5174    if ( typeof filter == 'function' ) {
5175      // use filter as function
5176      return function( item ) {
5177        return filter( item.element );
5178      };
5179    }
5180    // default, use filter as selector string
5181    return function( item ) {
5182      return matchesSelector( item.element, filter );
5183    };
5184  };
5185
5186  // -------------------------- sorting -------------------------- //
5187
5188  /**
5189   * @params {Array} elems
5190   * @public
5191   */
5192  proto.updateSortData = function( elems ) {
5193    // get items
5194    var items;
5195    if ( elems ) {
5196      elems = utils.makeArray( elems );
5197      items = this.getItems( elems );
5198    } else {
5199      // update all items if no elems provided
5200      items = this.items;
5201    }
5202
5203    this._getSorters();
5204    this._updateItemsSortData( items );
5205  };
5206
5207  proto._getSorters = function() {
5208    var getSortData = this.options.getSortData;
5209    for ( var key in getSortData ) {
5210      var sorter = getSortData[ key ];
5211      this._sorters[ key ] = mungeSorter( sorter );
5212    }
5213  };
5214
5215  /**
5216   * @params {Array} items - of Isotope.Items
5217   * @private
5218   */
5219  proto._updateItemsSortData = function( items ) {
5220    // do not update if no items
5221    var len = items && items.length;
5222
5223    for ( var i=0; len && i < len; i++ ) {
5224      var item = items[i];
5225      item.updateSortData();
5226    }
5227  };
5228
5229  // ----- munge sorter ----- //
5230
5231  // encapsulate this, as we just need mungeSorter
5232  // other functions in here are just for munging
5233  var mungeSorter = ( function() {
5234    // add a magic layer to sorters for convienent shorthands
5235    // `.foo-bar` will use the text of .foo-bar querySelector
5236    // `[foo-bar]` will use attribute
5237    // you can also add parser
5238    // `.foo-bar parseInt` will parse that as a number
5239    function mungeSorter( sorter ) {
5240      // if not a string, return function or whatever it is
5241      if ( typeof sorter != 'string' ) {
5242        return sorter;
5243      }
5244      // parse the sorter string
5245      var args = trim( sorter ).split(' ');
5246      var query = args[0];
5247      // check if query looks like [an-attribute]
5248      var attrMatch = query.match( /^\[(.+)\]$/ );
5249      var attr = attrMatch && attrMatch[1];
5250      var getValue = getValueGetter( attr, query );
5251      // use second argument as a parser
5252      var parser = Isotope.sortDataParsers[ args[1] ];
5253      // parse the value, if there was a parser
5254      sorter = parser ? function( elem ) {
5255        return elem && parser( getValue( elem ) );
5256      } :
5257      // otherwise just return value
5258      function( elem ) {
5259        return elem && getValue( elem );
5260      };
5261
5262      return sorter;
5263    }
5264
5265    // get an attribute getter, or get text of the querySelector
5266    function getValueGetter( attr, query ) {
5267      // if query looks like [foo-bar], get attribute
5268      if ( attr ) {
5269        return function getAttribute( elem ) {
5270          return elem.getAttribute( attr );
5271        };
5272      }
5273
5274      // otherwise, assume its a querySelector, and get its text
5275      return function getChildText( elem ) {
5276        var child = elem.querySelector( query );
5277        return child && child.textContent;
5278      };
5279    }
5280
5281    return mungeSorter;
5282  })();
5283
5284  // parsers used in getSortData shortcut strings
5285  Isotope.sortDataParsers = {
5286    'parseInt': function( val ) {
5287      return parseInt( val, 10 );
5288    },
5289    'parseFloat': function( val ) {
5290      return parseFloat( val );
5291    }
5292  };
5293
5294  // ----- sort method ----- //
5295
5296  // sort filteredItem order
5297  proto._sort = function() {
5298    var sortByOpt = this.options.sortBy;
5299    if ( !sortByOpt ) {
5300      return;
5301    }
5302    // concat all sortBy and sortHistory
5303    var sortBys = [].concat.apply( sortByOpt, this.sortHistory );
5304    // sort magic
5305    var itemSorter = getItemSorter( sortBys, this.options.sortAscending );
5306    this.filteredItems.sort( itemSorter );
5307    // keep track of sortBy History
5308    if ( sortByOpt != this.sortHistory[0] ) {
5309      // add to front, oldest goes in last
5310      this.sortHistory.unshift( sortByOpt );
5311    }
5312  };
5313
5314  // returns a function used for sorting
5315  function getItemSorter( sortBys, sortAsc ) {
5316    return function sorter( itemA, itemB ) {
5317      // cycle through all sortKeys
5318      for ( var i = 0; i < sortBys.length; i++ ) {
5319        var sortBy = sortBys[i];
5320        var a = itemA.sortData[ sortBy ];
5321        var b = itemB.sortData[ sortBy ];
5322        if ( a > b || a < b ) {
5323          // if sortAsc is an object, use the value given the sortBy key
5324          var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
5325          var direction = isAscending ? 1 : -1;
5326          return ( a > b ? 1 : -1 ) * direction;
5327        }
5328      }
5329      return 0;
5330    };
5331  }
5332
5333  // -------------------------- methods -------------------------- //
5334
5335  // get layout mode
5336  proto._mode = function() {
5337    var layoutMode = this.options.layoutMode;
5338    var mode = this.modes[ layoutMode ];
5339    if ( !mode ) {
5340      // TODO console.error
5341      throw new Error( 'No layout mode: ' + layoutMode );
5342    }
5343    // HACK sync mode's options
5344    // any options set after init for layout mode need to be synced
5345    mode.options = this.options[ layoutMode ];
5346    return mode;
5347  };
5348
5349  proto._resetLayout = function() {
5350    // trigger original reset layout
5351    Outlayer.prototype._resetLayout.call( this );
5352    this._mode()._resetLayout();
5353  };
5354
5355  proto._getItemLayoutPosition = function( item  ) {
5356    return this._mode()._getItemLayoutPosition( item );
5357  };
5358
5359  proto._manageStamp = function( stamp ) {
5360    this._mode()._manageStamp( stamp );
5361  };
5362
5363  proto._getContainerSize = function() {
5364    return this._mode()._getContainerSize();
5365  };
5366
5367  proto.needsResizeLayout = function() {
5368    return this._mode().needsResizeLayout();
5369  };
5370
5371  // -------------------------- adding & removing -------------------------- //
5372
5373  // HEADS UP overwrites default Outlayer appended
5374  proto.appended = function( elems ) {
5375    var items = this.addItems( elems );
5376    if ( !items.length ) {
5377      return;
5378    }
5379    // filter, layout, reveal new items
5380    var filteredItems = this._filterRevealAdded( items );
5381    // add to filteredItems
5382    this.filteredItems = this.filteredItems.concat( filteredItems );
5383  };
5384
5385  // HEADS UP overwrites default Outlayer prepended
5386  proto.prepended = function( elems ) {
5387    var items = this._itemize( elems );
5388    if ( !items.length ) {
5389      return;
5390    }
5391    // start new layout
5392    this._resetLayout();
5393    this._manageStamps();
5394    // filter, layout, reveal new items
5395    var filteredItems = this._filterRevealAdded( items );
5396    // layout previous items
5397    this.layoutItems( this.filteredItems );
5398    // add to items and filteredItems
5399    this.filteredItems = filteredItems.concat( this.filteredItems );
5400    this.items = items.concat( this.items );
5401  };
5402
5403  proto._filterRevealAdded = function( items ) {
5404    var filtered = this._filter( items );
5405    this.hide( filtered.needHide );
5406    // reveal all new items
5407    this.reveal( filtered.matches );
5408    // layout new items, no transition
5409    this.layoutItems( filtered.matches, true );
5410    return filtered.matches;
5411  };
5412
5413  /**
5414   * Filter, sort, and layout newly-appended item elements
5415   * @param {Array or NodeList or Element} elems
5416   */
5417  proto.insert = function( elems ) {
5418    var items = this.addItems( elems );
5419    if ( !items.length ) {
5420      return;
5421    }
5422    // append item elements
5423    var i, item;
5424    var len = items.length;
5425    for ( i=0; i < len; i++ ) {
5426      item = items[i];
5427      this.element.appendChild( item.element );
5428    }
5429    // filter new stuff
5430    var filteredInsertItems = this._filter( items ).matches;
5431    // set flag
5432    for ( i=0; i < len; i++ ) {
5433      items[i].isLayoutInstant = true;
5434    }
5435    this.arrange();
5436    // reset flag
5437    for ( i=0; i < len; i++ ) {
5438      delete items[i].isLayoutInstant;
5439    }
5440    this.reveal( filteredInsertItems );
5441  };
5442
5443  var _remove = proto.remove;
5444  proto.remove = function( elems ) {
5445    elems = utils.makeArray( elems );
5446    var removeItems = this.getItems( elems );
5447    // do regular thing
5448    _remove.call( this, elems );
5449    // bail if no items to remove
5450    var len = removeItems && removeItems.length;
5451    // remove elems from filteredItems
5452    for ( var i=0; len && i < len; i++ ) {
5453      var item = removeItems[i];
5454      // remove item from collection
5455      utils.removeFrom( this.filteredItems, item );
5456    }
5457  };
5458
5459  proto.shuffle = function() {
5460    // update random sortData
5461    for ( var i=0; i < this.items.length; i++ ) {
5462      var item = this.items[i];
5463      item.sortData.random = Math.random();
5464    }
5465    this.options.sortBy = 'random';
5466    this._sort();
5467    this._layout();
5468  };
5469
5470  /**
5471   * trigger fn without transition
5472   * kind of hacky to have this in the first place
5473   * @param {Function} fn
5474   * @param {Array} args
5475   * @returns ret
5476   * @private
5477   */
5478  proto._noTransition = function( fn, args ) {
5479    // save transitionDuration before disabling
5480    var transitionDuration = this.options.transitionDuration;
5481    // disable transition
5482    this.options.transitionDuration = 0;
5483    // do it
5484    var returnValue = fn.apply( this, args );
5485    // re-enable transition for reveal
5486    this.options.transitionDuration = transitionDuration;
5487    return returnValue;
5488  };
5489
5490  // ----- helper methods ----- //
5491
5492  /**
5493   * getter method for getting filtered item elements
5494   * @returns {Array} elems - collection of item elements
5495   */
5496  proto.getFilteredItemElements = function() {
5497    return this.filteredItems.map( function( item ) {
5498      return item.element;
5499    });
5500  };
5501
5502  // -----  ----- //
5503
5504  return Isotope;
5505
5506}));
5507;
5508/*!
5509 * Setup Isotope Grid
5510 *
5511 * JavaScript specific to posts displayed in a grid templates
5512 *
5513 * Initiates Isotope, handles sorting and triggers lazy-loading for images
5514 *
5515 * @package Altofocus
5516 */
5517
5518/* global loadedPosts */
5519( function( $ ) {
5520
5521	// Define initial variable for Isotope
5522	var $body        = $( document.body ),
5523	    $isotopeWrap = $( '.hfeed:not(.error404, .search-no-results) #main' ),
5524	    isoOptions   = {
5525			layoutMode: 'masonry',
5526			itemSelector: '.grid-item',
5527			masonry: {
5528				columnWidth: '.grid-sizer',
5529				gutter: '.gutter-sizer'
5530			},
5531			percentPosition: true
5532		};
5533
5534	/**
5535	 * Debounce script
5536	 */
5537	function altofocus_debounce(func, wait, immediate) {
5538		var timeout;
5539		return function() {
5540
5541			var context = this,
5542				args = arguments;
5543
5544			var later = function() {
5545				timeout = null;
5546				if (!immediate) {
5547					func.apply(context, args);
5548				}
5549			};
5550
5551			var callNow = immediate && !timeout;
5552			clearTimeout(timeout);
5553			timeout = setTimeout(later, wait);
5554			if (callNow) {
5555				func.apply(context, args);
5556			}
5557		};
5558	}
5559
5560	/**
5561	 * Init Isotope
5562	 *
5563	 * - Add Isotope class
5564	 * - Add empty grid sizing elements for resposnive isotope sizing
5565	 */
5566	function initIsotope() {
5567
5568		// Init Isotope
5569		$isotopeWrap
5570			.append( "<div class=\'grid-sizer\'></div><div class=\'gutter-sizer\'></div>" );
5571	}
5572
5573	/**
5574	 * Run Isotope
5575	 */
5576	function runIsotope() {
5577
5578		$isotopeWrap.imagesLoaded().fail( function() {
5579
5580			// broken images
5581			// console.log('All images loaded but at least one is broken');
5582
5583			// Initialize Isotope
5584			$isotopeWrap.isotope( isoOptions );
5585
5586		} ).done( function() {
5587
5588			// Initialize Isotope
5589			$isotopeWrap.isotope( isoOptions );
5590
5591		} );
5592
5593		// jQuery
5594		$isotopeWrap.on( 'layoutComplete', function() {
5595
5596			$isotopeWrap.addClass( "has-isotope" );
5597		} );
5598	}
5599
5600	/**
5601	 * Triggers re-layout on Isotope wrapper after infinite scroll has loaded new posts
5602	 */
5603	function reLayoutIsotope( loadedPosts ) {
5604
5605		// Set array for newly added post IDs
5606		var newPostIds = [];
5607
5608		// If new posts have been loaded from Infinite Scroll, attach them to the isotope wrapper and lay them out
5609		// note: loadedPosts variable is set globally in altofocus_infinite_scroll_render(). See jetpack.php
5610		if ( typeof loadedPosts !== 'undefined' ) {
5611
5612			// Create post IDs from IS results and push into post ID array
5613			$.each( JSON.parse(loadedPosts), function( index, value ) {
5614
5615				var $appendedPost = '#post-'+ value;
5616
5617				newPostIds.push( $appendedPost );
5618
5619			});
5620
5621			// Place infinite scroll results into a jQuery object
5622			var $newPostObj = $( newPostIds.join( ", " ) ),
5623			    $appendedPosts = $( $newPostObj );
5624
5625			// Get each new post, add it to Isotope, and relayout Isotope
5626			$appendedPosts
5627
5628				// Hide newly loaded posts to prevent animation jumping
5629				.hide()
5630
5631				// Get each post with an image and without
5632				.each( function() {
5633
5634					var $this = $( this );
5635
5636					// Cue posts with images separately to account for varying image load times
5637					if ( $this.find( "img" ).length > 0 ) {
5638
5639						// Make sure images are loaded before laying them out
5640						$this.imagesLoaded()
5641
5642							// After image load completes, append newly loaded posts to Isotope wrapper and lay them out
5643							.done( altofocus_debounce( function() {
5644
5645									$isotopeWrap
5646
5647										// Append this post
5648										.append( $this )
5649
5650										// Layout this post
5651										.isotope( 'appended', $this );
5652
5653								}, 200, 1 ) );
5654
5655					// Append and layout posts without images normally
5656					} else {
5657
5658						$isotopeWrap
5659
5660							// Append this post
5661							.append( $this )
5662
5663							// Layout this post
5664							.isotope( 'appended', $this );
5665					}
5666
5667				});
5668		}
5669	}
5670
5671	/**
5672	 * Document calls
5673	 */
5674	$( document )
5675		.ready( initIsotope )
5676		.ready( function() {
5677
5678			/**
5679			 * Relayout Isotope on post-load (Infinite Scroll)
5680			 */
5681			$body.on( 'post-load', function() {
5682				var loadedPosts = $('#infinite-ids').attr('data');
5683				reLayoutIsotope( loadedPosts );
5684				$('#infinite-ids').remove();
5685			});
5686
5687			/**
5688			 * Window calls
5689			 */
5690			$( window )
5691				.load( runIsotope );
5692		} );
5693
5694} )( jQuery );
5695;
5696/*!
5697 * Script for AltoFocus
5698 *
5699 * @package Altofocus
5700 */
5701
5702/* global altoFocusFlexSliderText */
5703( function( $ ) {
5704
5705	/**
5706	 * Set variables
5707	 */
5708	var body,
5709		$wrapper        = $( '.js body' ),
5710		$widgetlist     = $( '.widget > ul' ).not( '.widget_wpcom_social_media_icons_widget > ul, .widget_author_grid > ul, .jetpack_widget_social_icons > ul' ),
5711		$gallery_slider = $( '.flexslider' );
5712
5713	/**
5714	 * Debounce script
5715	 */
5716	function altofocus_debounce(func, wait, immediate) {
5717		var timeout;
5718		return function() {
5719
5720			var context = this,
5721				args = arguments;
5722
5723			var later = function() {
5724				timeout = null;
5725				if (!immediate) {
5726					func.apply(context, args);
5727				}
5728			};
5729
5730			var callNow = immediate && !timeout;
5731			clearTimeout(timeout);
5732			timeout = setTimeout(later, wait);
5733			if (callNow) {
5734				func.apply(context, args);
5735			}
5736		};
5737	}
5738
5739	/**
5740	 * Stick header to window when scrolling passes the masthead height threshold
5741	 */
5742	function stickyPageHeader() {
5743
5744		// get the amount the window has scrolled
5745		var scroll        = $( this ).scrollTop(),
5746			header_height = $( '#masthead' ).outerHeight(),
5747			$page_header  = $( '.hfeed .page-header' );
5748
5749		// add the 'fixed' class to the header menu based on the window position
5750		if ( scroll >= header_height ) {
5751
5752			$page_header.addClass( 'sticky' );
5753
5754		} else {
5755
5756			$page_header.removeClass( 'sticky' );
5757		}
5758	}
5759
5760	/**
5761	 * Split widget lists
5762	 */
5763	function initColumnLists() {
5764
5765		$widgetlist.columnlist({
5766			size           : 2,
5767			'class'        : 'widget-list',
5768			incrementClass : 'widget-list-'
5769		});
5770	}
5771
5772	/**
5773	 * Init Gallery Slider
5774	 */
5775	function initGallerySlider() {
5776
5777		// Determine text direction
5778		var $text_direction = true;
5779		if ( $( 'html' ).attr( 'dir' ) === 'rtl' ) {
5780
5781			$text_direction = false;
5782		}
5783
5784		$gallery_slider.flexslider({
5785			// options
5786			animation:    "slide",
5787			selector:     ".slides > .slide",
5788			smoothHeight: true,
5789			slideshow:    false,
5790			rtl:          $text_direction,
5791			prevText:     '<span class="screen-reader-text">'+ altoFocusFlexSliderText.previous +'</span> <span class="meta-nav" aria-hidden="true"><svg class="arrow-icon left-arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect class="rectangle" x="0" y="0" width="40" height="40" /><polyline class="arrow" points="27,6 13,20 27,34" /></svg></span>',
5792			nextText:     '<span class="screen-reader-text">'+ altoFocusFlexSliderText.next +'</span> <span class="meta-nav" aria-hidden="true"><svg class="arrow-icon right-arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><rect class="rectangle" x="0" y="0" width="40" height="40" /><polyline class="arrow" points="13 34 27 20 13 6" /></svg></span>',
5793		});
5794	}
5795
5796	/*
5797	 * Fade in page
5798	 * - only if js is enabled
5799	 */
5800	function fadeInPage() {
5801
5802		$wrapper.animate({
5803			opacity: 1,
5804		}, 100);
5805	}
5806
5807	/**
5808	 * Execute functions
5809	 */
5810	$( document )
5811		.ready( initColumnLists )
5812		.ready( initGallerySlider )
5813		.ready( fadeInPage )
5814		.ready( function() {
5815
5816			body = $( document.body );
5817
5818			window.addEventListener( 'scroll', altofocus_debounce( stickyPageHeader, 20, 1 ) );
5819
5820		} );
5821
5822})(jQuery);
5823;
5824/**
5825 * File skip-link-focus-fix.js.
5826 *
5827 * Helps with accessibility for keyboard only users.
5828 *
5829 * Learn more: https://git.io/vWdr2
5830 */
5831( function() {
5832
5833	var isWebkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1,
5834	    isOpera  = navigator.userAgent.toLowerCase().indexOf( 'opera' )  > -1,
5835	    isIe     = navigator.userAgent.toLowerCase().indexOf( 'msie' )   > -1;
5836
5837	if ( ( isWebkit || isOpera || isIe ) && document.getElementById && window.addEventListener ) {
5838
5839		window.addEventListener( 'hashchange', function() {
5840
5841			var id = location.hash.substring( 1 ),
5842				element;
5843
5844			if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) {
5845
5846				return;
5847			}
5848
5849			element = document.getElementById( id );
5850
5851			if ( element ) {
5852
5853				if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) {
5854
5855					element.tabIndex = -1;
5856				}
5857
5858				element.focus();
5859			}
5860		}, false );
5861	}
5862})();
5863;
5864!function(){"use strict";var e,t={noop:function(){},texturize:function(e){return(e=(e=(e=(e+="").replace(/'/g,"&#8217;").replace(/&#039;/g,"&#8217;")).replace(/"/g,"&#8221;").replace(/&#034;/g,"&#8221;").replace(/&quot;/g,"&#8221;").replace(/[\u201D]/g,"&#8221;")).replace(/([\w]+)=&#[\d]+;(.+?)&#[\d]+;/g,'$1="$2"')).trim()},applyReplacements:function(e,t){if(e)return t?e.replace(/{(\d+)}/g,function(e,r){return void 0!==t[r]?t[r]:e}):e},getBackgroundImage:function(e){var t=document.createElement("canvas"),r=t.getContext&&t.getContext("2d");if(e){r.filter="blur(20px) ",r.drawImage(e,0,0);var o=t.toDataURL("image/png");return t=null,o}}},r=function(){function e(e,t){return Element.prototype.matches?e.matches(t):Element.prototype.msMatchesSelector?e.msMatchesSelector(t):void 0}function r(e,t,r,o){if(!e)return o();e.jpCarouselCancelFade&&e.jpCarouselCancelFade(),e.classList.remove("jp-carousel-fade"),e.style.removeProperty("display"),e.style.opacity=t,e.style.pointerEvents="none",e.offsetWidth,e.classList.add("jp-carousel-fade"),e.style.opacity=r;var a=1e3*parseFloat(getComputedStyle(e).transitionDuration)||0,n=setTimeout(function(){e.jpCarouselCancelFade=null,e.style.removeProperty("pointer-events"),o()},a+50);e.jpCarouselCancelFade=function(){clearTimeout(n),e.jpCarouselCancelFade=null}}return{closest:function(t,r){if(t.closest)return t.closest(r);var o=t;do{if(e(o,r))return o;o=o.parentElement||o.parentNode}while(null!==o&&1===o.nodeType);return null},matches:e,hide:function(e){e&&(e.style.display="none")},show:function(e){e&&(e.style.display="block")},fadeIn:function(e,o){r(e,0,1,o=o||t.noop)},fadeOut:function(e,o){o=o||t.noop,r(e,1,0,function(){e&&(e.style.display="none"),o()})},scrollToElement:function(e,t,r){if(!e||!t)return r?r():void 0;var o=t.querySelector(".jp-carousel-info-extra");o&&(o.style.minHeight=window.innerHeight-64+"px");var a=!0,n=Date.now(),i=t.scrollTop,l=Math.max(0,e.offsetTop-Math.max(0,window.innerHeight-function(e){var t=e.querySelector(".jp-carousel-info-footer"),r=e.querySelector(".jp-carousel-info-extra"),o=e.querySelector(".jp-carousel-info-content-wrapper");if(t&&r&&o){var a=window.getComputedStyle(r),n=parseInt(a.paddingTop,10)+parseInt(a.paddingBottom,10);return n=isNaN(n)?0:n,o.offsetHeight+t.offsetHeight+n}return 0}(t)))-t.scrollTop;function s(){a=!1}
5864l=Math.min(l,t.scrollHeight-window.innerHeight),t.addEventListener("wheel",s),function e(){var c,u=Date.now(),d=(c=(u-n)/300)<.5?2*c*c:1-Math.pow(-2*c+2,2)/2,m=(d=d>1?1:d)*l;if(t.scrollTop=i+m,u<=n+300&&a)return requestAnimationFrame(e);r&&r(),o&&(o.style.minHeight=""),a=!1,t.removeEventListener("wheel",s)}()},getJSONAttribute:function(e,t){if(e&&e.hasAttribute(t))try{return JSON.parse(e.getAttribute(t))}catch{return}},convertToPlainText:function(e){var t=document.createElement("div");return t.textContent=e,t.innerHTML},stripHTML:function(e){var t=document.createElement("div");return t.innerHTML=e.replace(/<[^>]*>?/gm,""),t.textContent},emitEvent:function(e,t,r){var o;try{o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:r||null})}catch{(o=document.createEvent("CustomEvent")).initCustomEvent(t,!0,!0,r||null)}e.dispatchEvent(o)},isTouch:function(){return"ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch},prefersReducedMotion:function(){return!!window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}}}();function o(){var o,a,n,i,l={},s={},c="",u=!1,d="div.gallery, div.tiled-gallery, ul.wp-block-gallery, ul.blocks-gallery-grid, figure.wp-block-gallery.has-nested-images, div.wp-block-jetpack-tiled-gallery, a.single-image-gallery",m=".gallery-item, .tiled-gallery-item, .blocks-gallery-item,  .tiled-gallery__item",p=m+", .wp-block-image",g={},h="undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.stat?wpcom.carousel.stat:t.noop,f="undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.pageview?wpcom.carousel.pageview:t.noop;function v(t){if(!u)switch(t.which){case 38:t.preventDefault(),g.overlay.scrollTop-=100;break;case 40:t.preventDefault(),g.overlay.scrollTop+=100;break;case 39:t.preventDefault(),e.slideNext();break;case 37:case 8:t.preventDefault(),e.slidePrev();break;case 27:t.preventDefault(),k()}}function y(){u=!0}function w(){u=!1}function S(e){e.role="button",e.tabIndex=0,e.ariaLabel=jetpackCarouselStrings.image_label}function j(){g.overlay||(g.overlay=document.querySelector(".jp-carousel-overlay"),g.container=g.overlay.querySelector(".jp-carousel-wrap"),g.gallery=g.container.querySelector(".jp-carousel"),g.info=g.overlay.querySelector(".jp-carousel-info"),g.caption=g.info.querySelector(".jp-carousel-caption"),g.commentField=g.overlay.querySelector("#jp-carousel-comment-form-comment-field"),g.emailField=g.overlay.querySelector("#jp-carousel-comment-form-email-field"),g.authorField=g.overlay.querySelector("#jp-carousel-comment-form-author-field"),g.urlField=g.overlay.querySelector("#jp-carousel-comment-form-url-field"),window.innerWidth<=760&&Math.round(window.innerWidth/760*110)<40&&r.isTouch(),[g.commentField,g.emailField,g.authorField,g.urlField].forEach(function(e){e&&(e.addEventListener("focus",y),e.addEventListener("blur",w))}),g.overlay.addEventListener("click",function(e){var t,o,a=e.target,n=!!r.closest(a,".jp-carousel-close-hint"),i=!!window.matchMedia("(max-device-width: 760px)").matches;a===g.overlay?i||k():n?k():a.classList.contains("jp-carousel-image-download")?h("download_original_click"):a.classList.contains("jp-carousel-comment-login")?(t=g.currentSlide,o=t?t.attrs.attachmentId:"0",window.location.href=jetpackCarouselStrings.login_url+"%23jp-carousel-"+o):r.closest(a,"#jp-carousel-comment-form-container")?function(e){var t=e.target,o=r.getJSONAttribute(g.container,"data-carousel-extra")||{},a=g.currentSlide.attrs.attachmentId,n=document.querySelector("#jp-carousel-comment-form-submit-and-info-wrapper"),i=document.querySelector("#jp-carousel-comment-form-spinner"),s=document.querySelector("#jp-carousel-comment-form-button-submit"),c=document.querySelector("#jp-carousel-comment-form");if(g.commentField&&g.commentField.getAttribute("id")===t.getAttribute("id"))y(),r.show(n);else if(r.matches(t,'input[type="submit"]')){e.preventDefault(),e.stopPropagation(),r.show(i),c.classList.add("jp-carousel-is-disabled");var u={action:"post_attachment_comment",nonce:jetpackCarouselStrings.nonce,blog_id:o.blog_id,id:a,comment:g.commentField.value};if(!u.comment.length)return void b(jetpackCarouselStrings.no_comment_text,!1);if(1!==Number(jetpackCarouselStrings.is_logged_in)&&(u.email=g.emailField.value,u.author=g.authorField.value,u.url=g.urlField.value,1===Number(jetpackCarouselStrings.require_name_email))){if(!u.email.length||!u.email.match("@"))return void b(jetpackCarouselStrings.no_comment_email,!1);if(!u.author.length)return void b(jetpackCarouselStrings.no_comment_author,!1)}var d=new XMLHttpRequest;d.open("POST",jetpackCarouselStrings.ajaxurl,!0),d.setRequestHeader("X-Requested-With","XMLHttpRequest"),d.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8"),d.onreadystatechange=function(){if(this.readyState===XMLHttpRequest.DONE&&this.status>=200&&this.status<300){var e;try{e=JSON.parse(this.response)}catch{return void b(jetpackCarouselStrings.comment_post_error,!1)}if("approved"===e.comment_status){b(jetpackCarouselStrings.comment_approved,!0);var t=function(e){for(var t=0;t<g.slides.length;t++)if(g.slides[t].attrs.attachmentId===e)return g.slides[t];return null}(a);t&&(t.attrs.commentsCount=(parseInt(t.attrs.commentsCount,10)||0)+1)}else"unapproved"===e.comment_status?b(jetpackCarouselStrings.comment_unapproved,!0):b(jetpackCarouselStrings.comment_post_error,!1);W(),delete l[a],_(a,void 0,!0),s.value=jetpackCarouselStrings.post_comment,r.hide(i),c.classList.remove("jp-carousel-is-disabled")}else b(jetpackCarouselStrings.comment_post_error,!1)};var m=[];for(var p in u)if(p){var h=encodeURIComponent(p)+"="+encodeURIComponent(u[p]);m.push(h.replace(/%20/g,"+"))}var f=m.join("&");d.send(f)}}(e):(r.closest(a,".jp-carousel-photo-icons-container")||a.classList.contains("jp-carousel-photo-title"))&&function(e){e.preventDefault();var t=e.target,o=g.info.querySelector(".jp-carousel-info-extra"),a=g.info.querySelector(".jp-carousel-image-meta"),n=g.info.querySelector(".jp-carousel-comments-wrapper"),i=g.info.querySelector(".jp-carousel-icon-info"),s=g.info.querySelector(".jp-carousel-icon-comments");function c(){s&&s.classList.remove("jp-carousel-selected"),i.classList.toggle("jp-carousel-selected"),n&&n.classList.remove("jp-carousel-show"),a&&(a.classList.toggle("jp-carousel-show"),a.classList.contains("jp-carousel-show")?o.classList.add("jp-carousel-show"):o.classList.remove("jp-carousel-show"))}function u(){if(i&&i.classList.remove("jp-carousel-selected"),s.classList.toggle("jp-carousel-selected"),a&&a.classList.remove("jp-carousel-show"),n)if(n.classList.toggle("jp-carousel-show"),n.classList.contains("jp-carousel-show")){o.classList.add("jp-carousel-show");var e=g.currentSlide;if(e){var t=l[e.attrs.attachmentId];t?t.hasMore&&T(e.attrs.attachmentId,t.nextOffset):_(e.attrs.attachmentId)}}else o.classList.remove("jp-carousel-show")}(r.closest(t,".jp-carousel-icon-info")||t.classList.contains("jp-carousel-photo-title"))&&(a&&a.classList.contains("jp-carousel-show")?r.scrollToElement(g.overlay,g.overlay,c):(c(),r.scrollToElement(g.info,g.overlay))),r.closest(t,".jp-carousel-icon-comments")&&(n&&n.classList.contains("jp-carousel-show")?r.scrollToElement(g.overlay,g.overlay,u):(u(),r.scrollToElement(g.info,g.overlay)))}(e)}),window.addEventListener("keydown",v),g.overlay.addEventListener("jp_carousel.afterOpen",function(){w(),g.slides.length<=1||(g.slides.length<=5?r.show(g.info.querySelector(".jp-swiper-pagination")):r.show(g.info.querySelector(".jp-carousel-pagination")))}),g.overlay.addEventListener("jp_carousel.beforeClose",function(){y(),document.documentElement.style.removeProperty("height"),e&&e.enable(),r.hide(g.info.querySelector(".jp-swiper-pagination")),r.hide(g.info.querySelector(".jp-carousel-pagination"))}),g.overlay.addEventListener("jp_carousel.afterClose",function(){window.history.pushState?history.pushState("",document.title,window.location.pathname+window.location.search):window.location.href="",c="",g.isOpen=!1}),g.overlay.addEventListener("touchstart",function(e){e.touches.length>1&&e.preventDefault()}))}function b(e,t){var o=g.overlay.querySelector("#jp-carousel-comment-post-results"),a="jp-carousel-comment-post-"+(t?"success":"error");o.innerHTML='<span class="'+a+'">'+e+"</span>",r.hide(g.overlay.querySelector("#jp-carousel-comment-form-spinner")),g.overlay.querySelector("#jp-carousel-comment-form").classList.remove("jp-carousel-is-disabled"),r.show(o)}function L(){var e=document.querySelectorAll("a img[data-attachment-id]");Array.prototype.forEach.call(e,function(e){var t=e.parentElement,o=t.parentElement;if(!o.classList.contains("gallery-icon")&&!r.closest(o,m)&&t.hasAttribute("href")){var a=!1;t.getAttribute("href").split("?")[0]===e.getAttribute("data-orig-file").split("?")[0]&&1===Number(jetpackCarouselStrings.single_image_gallery_media_file)&&(a=!0),t.getAttribute("href")===e.getAttribute("data-permalink")&&(a=!0),a&&(S(e),t.classList.add("single-image-gallery"),t.setAttribute("data-carousel-extra",JSON.stringify({blog_id:Number(jetpackCarouselStrings.blog_id)})))}})}function x(t,r){g.isOpen?(C(r),e.slideTo(r+1)):z(t,{startIndex:r})}function C(e){(!e||e<0||e>g.slides.length)&&(e=0),g.currentSlide=g.slides[e];var a,n,i=g.currentSlide,s=i.attrs.attachmentId;M(g.slides[e]),function(e){var t=[],r=g.slides.length;if(r>1){var o=e>0?e-1:r-1;t.push(o);var a=e<r-1?e+1:0;t.push(a)}t.forEach(function(e){var t=g.slides[e];t&&(M(t),1!==Number(jetpackCarouselStrings.display_background_image)||t.backgroundImage||F(t))})}(e),1!==Number(jetpackCarouselStrings.display_background_image)||g.slides[e].backgroundImage||F(g.slides[e]),r.hide(g.caption),function(e){var t,o,a,n,i,l,s;if(n=g.overlay.querySelector(".jp-carousel-photo-caption"),i=g.overlay.querySelector(".jp-carousel-caption"),l=g.overlay.querySelector(".jp-carousel-photo-title"),s=g.overlay.querySelector(".jp-carousel-photo-description"),r.hide(n),r.hide(i),r.hide(l),r.hide(s),t=A(e.caption)||"",o=A(e.title)||"",a=A(e.desc)||"",(t||o||a)&&(t&&(n.innerHTML=t,i.innerHTML=t,r.show(n),r.show(i)),r.stripHTML(t)===r.stripHTML(o)&&(o=""),r.stripHTML(t)===r.stripHTML(a)&&(a=""),r.stripHTML(o)===r.stripHTML(a)&&(a=""),a&&(s.innerHTML=a,r.show(s),o||t||(n.textContent=r.stripHTML(a),r.show(n))),o)){var c=r.stripHTML(o);l.textContent=c,t||(n.textContent=c,i.textContent=c,r.show(n)),r.show(l)}}
5864({caption:i.attrs.caption,title:i.attrs.title,desc:i.attrs.desc}),function(e){if(!e||1!==Number(jetpackCarouselStrings.display_exif))return!1;var t=g.info.querySelector(".jp-carousel-image-meta");if(!t)return!1;var r="";for(var o in e){var a=e[o],n=jetpackCarouselStrings.meta_data||[];if(0!==parseFloat(a)&&a.length&&-1!==n.indexOf(o)){switch(o){case"focal_length":a+="mm";break;case"shutter_speed":a=E(a);break;case"aperture":a="f/"+a}r+="<li><h5>"+jetpackCarouselStrings[o]+"</h5>"+a+"</li>"}}var i=t.querySelector("ul.jp-carousel-image-exif");if(""!==r){if(!i){(i=document.createElement("ul")).className="jp-carousel-image-exif";var l=t.querySelector(".jp-carousel-title-and-caption");l&&l.nextSibling?t.insertBefore(i,l.nextSibling):t.insertBefore(i,t.firstChild)}i.innerHTML=r,i.style.removeProperty("display")}else i&&i.parentNode.removeChild(i)}(g.slides[e].attrs.imageMeta),function(e){if(!e)return!1;var r,o=[e.attrs.origWidth,e.attrs.origHeight],a=document.createElement("a");a.href=e.attrs.src.replace(/\?.+$/,""),r=null!==a.hostname.match(/^i[\d]{1}\.wp\.com$/i)?a.href:e.attrs.origFile.replace(/\?.+$/,"");var n=g.info.querySelector(".jp-carousel-download-text"),i=g.info.querySelector(".jp-carousel-image-download");n.innerHTML=t.applyReplacements(jetpackCarouselStrings.download_original,o),i.setAttribute("href",r),i.style.removeProperty("display")}(i),1===Number(jetpackCarouselStrings.display_comments)&&(a=g.slides[e].attrs.commentsOpened,n=g.info.querySelector("#jp-carousel-comment-form-container"),1===parseInt(a,10)?r.fadeIn(n):r.fadeOut(n),function(e){var t=e.attrs.attachmentId,a=g.info.querySelector(".jp-carousel-comments"),n=l[t];if(clearInterval(o),r.hide(g.info.querySelector("#jp-carousel-comments-loading")),n)return a.innerHTML=n.html,H(n.count),r.show(a),void(n.hasMore&&I()&&T(t,n.nextOffset));a.innerHTML="",r.hide(a),H(parseInt(e.attrs.commentsCount,10)||0),I()&&_(t)}(i),r.hide(g.info.querySelector("#jp-carousel-comment-post-results")));var u=g.info.querySelector(".jp-carousel-pagination");if(u&&g.slides.length>5){var d=e+1;u.innerHTML="<span>"+d+" / "+g.slides.length+"</span>"}jetpackCarouselStrings.stats&&g.isOpen&&((new Image).src=document.location.protocol+"//pixel.wp.com/g.gif?"+jetpackCarouselStrings.stats+"&post="+encodeURIComponent(s)+"&rand="+Math.random()),g.isOpen&&f(s),c="#jp-carousel-"+s,window.location.hash=c}function k(){document.body.style.overflow=a,document.documentElement.style.overflow=n,W(),y(),r.emitEvent(g.overlay,"jp_carousel.beforeClose"),window.scrollTo(window.scrollX||window.pageXOffset||0,i||0),g.isOpen=!1,e.destroy(),g.slides=[],l={},s={},g.currentSlide=void 0,g.gallery.innerHTML="",r.fadeOut(g.overlay,function(){r.emitEvent(g.overlay,"jp_carousel.afterClose")})}function q(e){if("object"!=typeof e&&(e={}),void 0===e.origFile)return"";if(void 0===e.origWidth||void 0===e.maxWidth)return e.origFile;if(!e.largeFile)return e.origFile;var t=document.createElement("a");t.href=e.largeFile;var r=/^i[0-2]\.wp\.com$/i.test(t.hostname),o=function(e,t,r){var o,a=r?e.replace(/.*=([\d]+%2C[\d]+).*$/,"$1"):e.replace(/.*-([\d]+x[\d]+)\..+$/,"$1");return"9999"===(o=a!==e?r?a.split("%2C"):a.split("x"):[t,0])[0]&&(o[0]="0"),"9999"===o[1]&&(o[1]="0"),o}(e.largeFile,e.origWidth,r),a=parseInt(o[0],10),n=parseInt(o[1],10);e.origMaxWidth=e.maxWidth,e.origMaxHeight=e.maxHeight,void 0!==window.devicePixelRatio&&window.devicePixelRatio>1&&(e.maxWidth=e.maxWidth*window.devicePixelRatio,e.maxHeight=e.maxHeight*window.devicePixelRatio);var i=e.zoomHeadroom||1;if(i>1&&(e.maxWidth=e.maxWidth*i,e.maxHeight=e.maxHeight*i),a>=e.maxWidth||n>=e.maxHeight)return e.largeFile;if(r){if(-1===e.largeFile.lastIndexOf("?"))return e.largeFile;var l=function(e){var t;try{t=new URL(e)}catch(t){return e}var r=["quality","ssl","filter","brightness","contrast","colorize","smooth"],o=Array.from(t.searchParams.entries());return t.search="",o.forEach(([e,o])=>{r.includes(e)&&t.searchParams.append(e,o)}),t}(e.largeFile);return(e.origWidth>e.maxWidth||e.origHeight>e.maxHeight)&&(e.origMaxWidth=e.maxWidth,e.origMaxHeight=e.maxHeight,l.searchParams.set("fit",e.origMaxWidth+","+e.origMaxHeight)),l.toString()}return e.origFile}function E(e){return e>=1?Math.round(10*e)/10+"s":"1/"+Math.round(1/e)+"s"}
5864function A(e){return!e.match(" ")&&e.match("_")?"":e}function I(){var e=g.info.querySelector(".jp-carousel-comments-wrapper");return!!e&&e.classList.contains("jp-carousel-show")}function H(e){var t=g.info.querySelector(".jp-carousel-icon-comments .jp-carousel-has-comments-indicator");t&&(e>0?(t.innerText=e,t.classList.add("jp-carousel-show")):t.classList.remove("jp-carousel-show"))}function T(e,t){clearInterval(o),o=setInterval(function(){g.container.scrollTop+150>window.innerHeight&&(clearInterval(o),_(e,t))},300)}function _(e,t,a){var n=void 0===t;if(clearInterval(o),e&&g.currentSlide&&g.currentSlide.attrs.attachmentId===e&&(!s[e]||a)){(!t||t<1)&&(t=0);var i=g.info.querySelector(".jp-carousel-comments"),c=g.info.querySelector("#jp-carousel-comments-loading");r.show(c),n&&(r.hide(i),i.innerHTML="");var u=new XMLHttpRequest;s[e]=u;var d=function(){return s[e]===u},m=jetpackCarouselStrings.ajaxurl+"?action=get_attachment_comments&nonce="+jetpackCarouselStrings.nonce+"&id="+e+"&offset="+t;u.open("GET",m),u.setRequestHeader("X-Requested-With","XMLHttpRequest");var p=function(){r.fadeIn(i),r.fadeOut(c)};u.onload=function(){if(d()&&(delete s[e],g.currentSlide&&g.currentSlide.attrs.attachmentId===e)){var o,a=u.status>=200&&u.status<300;try{o=JSON.parse(u.responseText)}catch{}if(a&&o&&Array.isArray(o)){n&&(i.innerHTML="");for(var m=0;m<o.length;m++){var h=o[m];if(!i.querySelector("#jp-carousel-comment-"+h.id)){var f=document.createElement("div");f.classList.add("jp-carousel-comment"),f.setAttribute("id","jp-carousel-comment-"+h.id),f.innerHTML='<div class="comment-gravatar">'+h.gravatar_markup+'</div><div class="comment-content"><div class="comment-author">'+h.author_markup+'</div><div class="comment-date">'+h.date_gmt+"</div>"+h.content+"</div>",i.appendChild(f)}}var v=o.length>=10,y=t+10;v&&T(e,y);var w=i.querySelectorAll(".jp-carousel-comment").length,S=Math.max(parseInt(g.currentSlide.attrs.commentsCount,10)||0,w);o.length>0&&(r.show(i),H(S)),l[e]={html:i.innerHTML,count:S,hasMore:v,nextOffset:y},r.hide(c)}else p()}},u.onerror=function(){d()&&(delete s[e],g.currentSlide&&g.currentSlide.attrs.attachmentId===e&&p())},u.send()}}function M(e){var t=e.attrs,r=e.el.querySelector("img");if(!r.hasAttribute("data-loaded"))if(r.setAttribute("itemprop","image"),r.setAttribute("data-loaded",1),t.previewImage&&t.previewImage!==t.src){r.src=t.previewImage,r.style.filter="blur(8px)";var o=new window.Image;o.addEventListener("load",function(){r.hasAttribute("data-zoom-loaded")||(r.src=t.src),r.style.filter=""},{once:!0}),o.addEventListener("error",function(){r.style.filter=""},{once:!0}),o.src=t.src}else r.src=t.src}function F(e){var t=e.attrs.originalElement;if(t)if(t.complete&&0!==t.naturalHeight)O(e,t);else{var r=function(){t.removeEventListener("error",o),O(e,t)},o=function(){t.removeEventListener("load",r)};t.addEventListener("load",r,{once:!0}),t.addEventListener("error",o,{once:!0})}}function O(e,r){var o=t.getBackgroundImage(r);o&&(e.backgroundImage=o,e.el.style.backgroundImage="url("+o+")",e.el.style.backgroundSize="cover",e.el.style.backgroundPosition="center")}function W(){g.commentField&&(g.commentField.value="")}function N(e,o){g.slides=[];var a={width:window.innerWidth,height:window.innerHeight-64};0!==o&&null!==e[o].getAttribute("data-gallery-src")&&((new Image).src=e[o].getAttribute("data-gallery-src")),Array.prototype.forEach.call(e,function(e,o){var n=r.closest(e,"a"),i=e.getAttribute("data-orig-file")||e.getAttribute("src-orig"),l=e.getAttribute("data-attachment-id")||e.getAttribute("data-id")||"0",s=document.querySelector('img[data-attachment-id="'+l+'"] + figcaption');s=s?s.innerHTML:e.getAttribute("data-image-caption");var c={originalElement:e,attachmentId:l,commentsOpened:e.getAttribute("data-comments-opened")||"0",commentsCount:e.getAttribute("data-comments-count")||"0",imageMeta:r.getJSONAttribute(e,"data-image-meta")||{},title:e.getAttribute("data-image-title")||"",desc:e.getAttribute("data-image-description")||"",largeFile:e.getAttribute("data-large-file")||"",origFile:i||"",thumbSize:{width:e.naturalWidth,height:e.naturalHeight},caption:s||"",permalink:n&&n.getAttribute("href"),src:i||e.getAttribute("src")||""},u=r.closest(e,".tiled-gallery-item"),d=u&&u.querySelector(".tiled-gallery-caption"),m=d&&d.innerHTML;m&&(c.caption=m);var p=function(e){var t=e.getAttribute("data-orig-size")||"";if(t){var r=t.split(",");return{width:parseInt(r[0],10),height:parseInt(r[1],10)}}return{width:e.getAttribute("data-original-width")||e.getAttribute("width")||void 0,height:e.getAttribute("data-original-height")||e.getAttribute("height")||void 0}}(e);if(c.origWidth=p.width||c.thumbSize.width,c.origHeight=p.height||c.thumbSize.height,"undefined"!=typeof wpcom&&wpcom.carousel&&wpcom.carousel.generateImgSrc)c.src=wpcom.carousel.generateImgSrc(e,a);else{var h=function(e){return{origFile:c.src,origWidth:c.origWidth,origHeight:c.origHeight,maxWidth:a.width,maxHeight:a.height,largeFile:c.largeFile,zoomHeadroom:e}};c.zoomSrc=q(h(2)),c.src=q(h(1))}if(e.setAttribute("data-gallery-src",c.src),"0"!==c.attachmentId){c.title=t.texturize(c.title),c.desc=t.texturize(c.desc),c.caption=t.texturize(c.caption);var f=new Image,v=document.createElement("div");v.classList.add("swiper-slide"),v.setAttribute("itemprop","associatedMedia"),v.setAttribute("itemscope",""),v.setAttribute("itemtype","https://schema.org/ImageObject");var y=document.createElement("div");y.classList.add("swiper-zoom-container"),g.gallery.appendChild(v),v.appendChild(y),y.appendChild(f),v.setAttribute("data-attachment-id",c.attachmentId),v.setAttribute("data-permalink",c.permalink),v.setAttribute("data-orig-file",c.origFile),c.previewImage=e.currentSrc||e.getAttribute("src")||"";var w={el:v,attrs:c,index:o};g.slides.push(w)}})}function z(e,t){if(!window.JetpackSwiper){var o=document.querySelector("#jp-carousel-loading-overlay");r.show(o);var a=document.createElement("script");return a.id="jetpack-carousel-swiper-js",a.src=window.jetpackSwiperLibraryPath.url,a.async=!0,a.onload=function(){r.hide(o),R(e,t)},a.onerror=function(){r.hide(o)},void document.head.appendChild(a)}R(e,t)}function R(t,o){var c,u={imgSelector:".gallery-item [data-attachment-id], .tiled-gallery-item [data-attachment-id], img[data-attachment-id], img[data-id]",startIndex:0},d=r.getJSONAttribute(t,"data-carousel-extra");if(!d)return;const m=t.querySelectorAll(u.imgSelector);if(m.length&&(j(),!g.isOpen)){for(var p in g.isOpen=!0,a=getComputedStyle(document.body).overflow,document.body.style.overflow="hidden",n=getComputedStyle(document.documentElement).overflow,document.documentElement.style.overflow="hidden",i=window.scrollY||window.pageYOffset||0,g.container.setAttribute("data-carousel-extra",JSON.stringify(d)),h(["open","view_image"]),o||{})u[p]=o[p];-1===u.startIndex&&(u.startIndex=0),r.emitEvent(g.overlay,"jp_carousel.beforeOpen"),g.gallery.innerHTML="",l={},s={},g.overlay.style.opacity=1,g.overlay.style.display="block",N(m,u.startIndex),(e=new window.JetpackSwiper(".jp-carousel-swiper-container",{centeredSlides:!0,speed:r.prefersReducedMotion()?0:250,zoom:!0,loop:g.slides.length>1,enabled:g.slides.length>1,pagination:{el:".jp-swiper-pagination",clickable:!0},navigation:{nextEl:".jp-swiper-button-next",prevEl:".jp-swiper-button-prev"},initialSlide:u.startIndex,on:{init:function(){C(u.startIndex)}},preventClicks:!1,preventClicksPropagation:!1,preventInteractionOnTransition:!r.isTouch(),threshold:5})).on("slideChange",function(e){g.isOpen&&(C(e.realIndex),g.overlay.classList.remove("jp-carousel-hide-control
5864s"))}),e.on("zoomChange",function(e,t){t>1&&(function(e){if(e&&e.attrs.zoomSrc&&e.attrs.zoomSrc!==e.attrs.src){var t=e.el.querySelector("img");t&&!t.hasAttribute("data-zoom-loaded")&&(t.setAttribute("data-zoom-loaded",1),t.src=e.attrs.zoomSrc)}}(g.currentSlide),g.overlay.classList.add("jp-carousel-hide-controls")),1===t&&g.overlay.classList.remove("jp-carousel-hide-controls")}),e.on("doubleTap",function(e){if(clearTimeout(c),1===e.zoom.scale)var t=setTimeout(function(){g.overlay.classList.remove("jp-carousel-hide-controls"),clearTimeout(t)},150)}),e.on("tap",function(){e.zoom.scale>1&&(c=setTimeout(function(){g.overlay.classList.toggle("jp-carousel-hide-controls")},150))}),r.fadeIn(g.overlay,function(){r.emitEvent(g.overlay,"jp_carousel.afterOpen")})}}function P(e){if("click"!==e.type){if("keydown"===e.type){const t=document.activeElement.parentElement,r=t&&t.classList.contains("tiled-gallery__item");" "!==e.key&&"Enter"!==e.key||!r||$(e)}}else $(e)}function D(e){return(e||"").split("?")[0].replace(/\/$/,"")}function J(e){"A"===e.tagName&&(e=e.querySelector("img")||e);var t=e.parentElement,o=t?t.parentElement:null,a=null;if(o&&o.classList.contains("wp-block-image")?a=t.getAttribute("href"):t&&t.classList.contains("wp-block-image")&&t.querySelector(":scope > a")&&(a=t.querySelector(":scope > a").getAttribute("href")),a){var n=D(a),i=D(e.getAttribute("data-orig-file")),l=D(e.getAttribute("data-permalink"));if(n!==i&&n!==l)return!1}return!(t&&t.classList.contains("gallery-caption")||r.matches(t,"figcaption"))}function $(e){if(window.CSS&&window.CSS.supports&&window.CSS.supports("display","grid")){var t,o=e.target,a=r.closest(o,d);if(a){if(!(t=a)||!t.getAttribute("data-carousel-extra"))return;if(!J(o))return;document.documentElement.style.height="auto",e.preventDefault(),e.stopPropagation();var n=r.closest(o,p),i=Array.prototype.indexOf.call(a.querySelectorAll(p),n);z(a,{startIndex:i})}}}document.body.addEventListener("click",P),document.body.addEventListener("keydown",P),document.querySelectorAll(m+"img").forEach(function(e){J(e)&&S(e)}),1===Number(jetpackCarouselStrings.single_image_gallery)&&(L(),document.body.addEventListener("is.post-load",function(){L()})),window.addEventListener("hashchange",function(){var e=/jp-carousel-(\d+)/;if(window.location.hash&&e.test(window.location.hash)){if(window.location.hash!==c||!g.isOpen)if(window.location.hash&&g.gallery&&!g.isOpen&&history.back)history.back();else{c=window.location.hash;for(var t=window.location.hash.match(e),r=parseInt(t[1],10),o=document.querySelectorAll(d),a=0;a<o.length;a++){for(var n,i=o[a],l=i.querySelectorAll("img"),s=0;s<l.length;s++)if(parseInt(l[s].getAttribute("data-attachment-id"),10)===r||parseInt(l[s].getAttribute("data-id"),10)===r){n=s;break}if(void 0!==n){x(i,n);break}}}}else g.isOpen&&k()}),window.location.hash&&r.emitEvent(window,"hashchange")}"loading"!==document.readyState?o():document.addEventListener("DOMContentLoaded",o)}();;

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.