1/* global wpcom_reblog */ 2 3var jetpackLikesWidgetBatch = []; 4var jetpackLikesMasterReady = false; 5 6// Due to performance problems on pages with a large number of widget iframes that need to be loaded, 7// we are limiting the processing at any instant to unloaded widgets that are currently in viewport, 8// plus this constant that will allow processing of widgets above and bellow the current fold. 9// This aim of it is to improve the UX and hide the transition from unloaded to loaded state from users. 10var jetpackLikesLookAhead = 2000; // pixels 11 12// Keeps track of loaded comment likes widget so we can unload them when they are scrolled out of view. 13var jetpackCommentLikesLoadedWidgets = []; 14 15var jetpackLikesDocReadyPromise = new Promise( resolve => { 16 if ( document.readyState !== 'loading' ) { 17 resolve(); 18 } else { 19 window.addEventListener( 'DOMContentLoaded', () => resolve() ); 20 } 21} ); 22 23function JetpackLikesPostMessage( message, target ) { 24 if ( typeof message === 'string' ) { 25 try { 26 message = JSON.parse( message ); 27 } catch ( e ) { 28 return; 29 } 30 } 31 32 if ( target && typeof target.postMessage === 'function' ) { 33 try { 34 target.postMessage( 35 JSON.stringify( { 36 type: 'likesMessage', 37 data: message, 38 } ), 39 '*' 40 ); 41 } catch ( e ) { 42 return; 43 } 44 } 45} 46 47function JetpackLikesBatchHandler() { 48 const requests = []; 49 document.querySelectorAll( 'div.jetpack-likes-widget-unloaded' ).forEach( widget => { 50 if ( jetpackLikesWidgetBatch.indexOf( widget.id ) > -1 ) { 51 return; 52 } 53 54 if ( ! jetpackIsScrolledIntoView( widget ) ) { 55 return; 56 } 57 58 jetpackLikesWidgetBatch.push( widget.id ); 59 60 var regex = /like-(post|comment)-wrapper-(\d+)-(\d+)-(\w+)/, 61 match = regex.exec( widget.id ), 62 info; 63 64 if ( ! match || match.length !== 5 ) { 65 return; 66 } 67 68 info = { 69 blog_id: match[ 2 ], 70 width: widget.width, 71 }; 72 73 if ( 'post' === match[ 1 ] ) { 74 info.post_id = match[ 3 ]; 75 } else if ( 'comment' === match[ 1 ] ) { 76 info.comment_id = match[ 3 ]; 77 } 78 79 info.obj_id = match[ 4 ]; 80 81 requests.push( info ); 82 } ); 83 84 if ( requests.length > 0 ) { 85 JetpackLikesPostMessage( 86 { event: 'initialBatch', requests: requests }, 87 window.frames[ 'likes-master' ] 88 ); 89 } 90} 91 92function JetpackLikesMessageListener( event ) { 93 let message = event && event.data; 94 if ( typeof message === 'string' ) { 95 try { 96 message = JSON.parse( message ); 97 } catch ( err ) { 98 return; 99 } 100 } 101 102 const type = message && message.type; 103 const data = message && message.data; 104 105 if ( type !== 'likesMessage' || typeof data.event === 'undefined' ) { 106 return; 107 } 108 109 // We only allow messages from one origin 110 const allowedOrigin = 'https://widgets.wp.com'; 111 if ( allowedOrigin !== event.origin ) { 112 return; 113 } 114 115 switch ( data.event ) { 116 case 'masterReady': 117 jetpackLikesDocReadyPromise.then( () => { 118 jetpackLikesMasterReady = true; 119 120 const stylesData = { 121 event: 'injectStyles', 122 }; 123 const sdTextColor = document.querySelector( '.sd-text-color' ); 124 const sdLinkColor = document.querySelector( '.sd-link-color' ); 125 const sdTextColorStyles = ( sdTextColor && getComputedStyle( sdTextColor ) ) || {}; 126 const sdLinkColorStyles = ( sdLinkColor && getComputedStyle( sdLinkColor ) ) || {}; 127 128 // enable reblogs if they are enabled for the page 129 if ( document.body.classList.contains( 'jetpack-reblog-enabled' ) ) { 130 JetpackLikesPostMessage( { event: 'reblogsEnabled' }, window.frames[ 'likes-master' ] ); 131 } 132 133 stylesData.textStyles = { 134 color: sdTextColorStyles[ 'color' ],
135 fontFamily: sdTextColorStyles[ 'font-family' ], 136 fontSize: sdTextColorStyles[ 'font-size' ], 137 direction: sdTextColorStyles[ 'direction' ], 138 fontWeight: sdTextColorStyles[ 'font-weight' ], 139 fontStyle: sdTextColorStyles[ 'font-style' ], 140 textDecoration: sdTextColorStyles[ 'text-decoration' ], 141 }; 142 143 stylesData.linkStyles = { 144 color: sdLinkColorStyles[ 'color' ], 145 fontFamily: sdLinkColorStyles[ 'font-family' ], 146 fontSize: sdLinkColorStyles[ 'font-size' ], 147 textDecoration: sdLinkColorStyles[ 'text-decoration' ], 148 fontWeight: sdLinkColorStyles[ 'font-weight' ], 149 fontStyle: sdLinkColorStyles[ 'font-style' ], 150 }; 151 152 JetpackLikesPostMessage( stylesData, window.frames[ 'likes-master' ] ); 153 154 JetpackLikesBatchHandler(); 155 } ); 156 157 break; 158 159 // We're keeping this for planned future follow ups. 160 // @see: https://github.com/Automattic/jetpack/pull/42361#discussion_r1995338815 161 case 'showLikeWidget': 162 break; 163 164 // We're keeping this for planned future follow ups. 165 // @see: https://github.com/Automattic/jetpack/pull/42361#discussion_r1995338815 166 case 'showCommentLikeWidget': 167 break; 168 169 case 'killCommentLikes': 170 // If kill switch for comment likes is enabled remove all widgets wrappers and `Loading...` placeholders. 171 document 172 .querySelectorAll( '.jetpack-comment-likes-widget-wrapper' ) 173 .forEach( wrapper => wrapper.remove() ); 174 break; 175 176 case 'clickReblogFlair': 177 if ( wpcom_reblog && typeof wpcom_reblog.toggle_reblog_box_flair === 'function' ) { 178 wpcom_reblog.toggle_reblog_box_flair( data.obj_id, data.post_id ); 179 } 180 break; 181 182 case 'hideOtherGravatars': { 183 hideLikersPopover(); 184 break; 185 } 186 187 case 'showOtherGravatars': { 188 const container = document.querySelector( '#likes-other-gravatars' ); 189 190 if ( ! container ) { 191 break; 192 } 193 194 const list = container.querySelector( 'ul' ); 195 196 container.style.display = 'none'; 197 list.innerHTML = ''; 198 199 container 200 .querySelectorAll( '.likes-text span' ) 201 .forEach( item => ( item.textContent = data.totalLikesLabel ) ); 202 203 ( data.likers || [] ).forEach( async ( liker, index ) => { 204 if ( liker.profile_URL.substr( 0, 4 ) !== 'http' ) { 205 // We only display gravatars with http or https schema 206 return; 207 } 208 209 const element = document.createElement( 'li' ); 210 list.append( element ); 211 212 element.innerHTML = ` 213 <a href="${ encodeURI( liker.profile_URL ) }" rel="nofollow" target="_parent" class="wpl-liker"> 214 <img src="${ encodeURI( liker.avatar_URL ) }" 215 alt="" 216 style="width: 28px; height: 28px;" /> 217 <span></span> 218 </a> 219 `; 220 221 222 // Add some extra attributes through native methods, to ensure strings are sanitized. 223 element.classList.add( liker.css_class ); 224 element.querySelector( 'img' ).alt = data.avatarAltTitle.replace( '%s', liker.name ); 225 element.querySelector( 'span' ).innerText = liker.name; 226 227 if ( index === data.likers.length - 1 ) { 228 element.addEventListener( 'keydown', ( e ) => { 229 if ( e.key === 'Tab' && ! e.shiftKey ) { 230 e.preventDefault(); 231 hideLikersPopover(); 232 233 JetpackLikesPostMessage( 234 { event: 'focusLikesCount', parent: data.parent }, 235 window.frames[ 'likes-master' ] 236 ); 237 } 238 } ); 239 } 240 } ); 241 242 const positionPopup = function() { 243 const containerStyle = getComputedStyle(container); 244 const isRtl = containerStyle.direction === 'rtl'; 245 246 const el = document.querySelector( `*[name='${ data.parent }']` ); 247 const rect = el.getBoundingClientRect(); 248 const win = el.ownerDocument.defaultView; 249 250 const offset = { 251 top: rect.top + win.pageYOffset, 252 left: rect.left + win.pageXOffset, 253 }; 254 255 // don't display yet or we get skewed window.innerWidth later 256 container.style.display = 'none'; 257 258 let containerLeft = 0; 259 container.style.top = offset.top + data.position.top - 1 + 'px'; 260 261 if ( isRtl ) { 262 const visibleAvatarsCount = data && data.likers ? Math.min( data.likers.length, 5 ) : 0; 263 // 24px is the width of the avatar + 4px is the padding between avatars 264 containerLeft = offset.left + data.position.left + 24 * visibleAvatarsCount + 4; 265 container.style.transform = 'translateX(-100%)'; 266 } else { 267 containerLeft = offset.left + data.position.left; 268 } 269 container.style.left = containerLeft + 'px'; 270 271 // Container width - padding
272 const initContainerWidth = data.width - 20; 273 const rowLength = Math.floor( initContainerWidth / 37 ); 274 // # of rows + (avatar + avatar padding) + text above + container padding 275 let height = Math.ceil( data.likers.length / rowLength ) * 37 + 17 + 22; 276 if ( height > 204 ) { 277 height = 204; 278 } 279 280 // If the popup is overflows viewport width, we should show it on the next line 281 // Push it offscreen to calculated rendered width 282 const windowWidth = win.innerWidth; 283 container.style.left = '-9999px'; 284 container.style.display = 'block'; 285 286 // If the popup exceeds the viewport width, 287 // flip the position of the popup. 288 const containerWidth = container.offsetWidth; 289 const containerRight = containerLeft + containerWidth; 290 291 if ( containerRight > windowWidth && ! isRtl) { 292 containerLeft = rect.left + rect.width - containerWidth; 293 } else if ( containerLeft - containerWidth < 0 && isRtl ) { 294 container.style.transform = 'none'; 295 containerLeft = rect.left; 296 } 297 // Set the container left 298 container.style.left = containerLeft + 'px'; 299 300 container.setAttribute( 'aria-hidden', 'false' ); 301 } 302 303 positionPopup(); 304 container.focus(); 305 306 const debounce = function( func, wait ) { 307 var timeout; 308 return function() { 309 var context = this; 310 var args = arguments; 311 clearTimeout( timeout ); 312 timeout = setTimeout( function() { 313 func.apply( context, args ); 314 }, wait ); 315 }; 316 }; 317 318 const debouncedPositionPopup = debounce( positionPopup, 100 ); 319 320 // Keep a reference of this function in the element itself 321 // so that we can destroy it later 322 container.__resizeHandler = debouncedPositionPopup; 323 324 // When window is resized, resize the popup. 325 window.addEventListener( "resize", debouncedPositionPopup ); 326 } 327 } 328} 329 330window.addEventListener( 'message', JetpackLikesMessageListener ); 331 332function hideLikersPopover() { 333 const container = document.querySelector( '#likes-other-gravatars' ); 334 335 if ( container ) { 336 container.style.display = 'none'; 337 container.setAttribute( 'aria-hidden', 'true' ); 338 339 // Remove the resize event listener and cleanup. 340 const resizeHandler = container.__resizeHandler; 341 if ( resizeHandler ) { 342 window.removeEventListener( "resize", resizeHandler ); 343 delete container.__resizeHandler; 344 } 345 } 346} 347 348document.addEventListener( 'click', hideLikersPopover ); 349 350function JetpackLikesWidgetQueueHandler() { 351 var wrapperID; 352 353 if ( ! jetpackLikesMasterReady ) { 354 setTimeout( JetpackLikesWidgetQueueHandler, 500 ); 355 return; 356 } 357 358 // Restore widgets to initial unloaded state when they are scrolled out of view. 359 jetpackUnloadScrolledOutWidgets(); 360 361 var unloadedWidgetsInView = jetpackGetUnloadedWidgetsInView(); 362 363 if ( unloadedWidgetsInView.length > 0 ) { 364 // Grab any unloaded widgets for a batch request 365 JetpackLikesBatchHandler(); 366 } 367 368 for ( var i = 0, length = unloadedWidgetsInView.length; i <= length - 1; i++ ) { 369 wrapperID = unloadedWidgetsInView[ i ].id; 370 371 if ( ! wrapperID ) { 372 continue; 373 } 374 375 jetpackLoadLikeWidgetIframe( wrapperID ); 376 } 377} 378 379function jetpackLoadLikeWidgetIframe( wrapperID ) { 380 if ( typeof wrapperID === 'undefined' ) { 381 return; 382 } 383 384 const wrapper = document.querySelector( '#' + wrapperID ); 385 wrapper.querySelectorAll( 'iframe' ).forEach( iFrame => iFrame.remove() ); 386 387 const placeholder = wrapper.querySelector( '.likes-widget-placeholder' ); 388 389 // Post like iframe 390 if ( placeholder && placeholder.classList.contains( 'post-likes-widget-placeholder' ) ) { 391 const postLikesFrame = document.createElement( 'iframe' ); 392 393 postLikesFrame.classList.add( 'post-likes-widget', 'jetpack-likes-widget' ); 394 postLikesFrame.name = wrapper.dataset.name; 395 postLikesFrame.src = wrapper.dataset.src; 396 postLikesFrame.height = '55px'; 397 postLikesFrame.width = '100%'; 398 postLikesFrame.frameBorder = '0'; 399 postLikesFrame.scrolling = 'no'; 400 postLikesFrame.title = wrapper.dataset.title; 401 402 placeholder.after( postLikesFrame ); 403 } 404 405 // Comment like iframe 406 if ( placeholder.classList.contains( 'comment-likes-widget-placeholder' ) ) { 407 const commentLikesFrame = document.createElement( 'iframe' ); 408 409 commentLikesFrame.class = 'comment-likes-widget-frame jetpack-likes-widget-frame'; 410 commentLikesFrame.name = wrapper.dataset.name; 411 commentLikesFrame.src = wrapper.dataset.src; 412 commentLikesFrame.height = '18px'; 413 commentLikesFrame.width = '100%'; 414 commentLikesFrame.frameBorder = '0'; 415 commentLikesFrame.scrolling = 'no'; 416 417 wrapper.querySelector( '.comment-like-feedback' ).after( commentLikesFrame ); 418 419 jetpackCommentLikesLoadedWidgets.push( commentLikesFrame ); 420 } 421 422 wrapper.classList.remove( 'jetpack-likes-widget-unloaded' ); 423 wrapper.classList.add( 'jetpack-likes-widget-loading' ); 424 425 wrapper.querySelector( 'iframe' ).addEventListener( 'load', e => { 426 JetpackLikesPostMessage( 427 { event: 'loadLikeWidget', name: e.target.name, width: e.target.width }, 428 window.frames[ 'likes-master' ] 429 ); 430 431 wrapper.classList.remove( 'jetpack-likes-widget-loading' ); 432 wrapper.classList.add( 'jetpack-likes-widget-loaded' ); 433 } ); 434} 435 436function jetpackGetUnloadedWidgetsInView() { 437 const unloadedWidgets = document.querySelectorAll( 'div.jetpack-likes-widget-unloaded' ); 438 439 return [ ...unloadedWidgets ].filter( item => jetpackIsScrolledIntoView( item ) ); 440} 441 442function jetpackIsScrolledIntoView( element ) { 443 const top = element.getBoundingClientRect().top; 444 const bottom = element.getBoundingClientRect().bottom; 445
446 // Allow some slack above and bellow the fold with jetpackLikesLookAhead, 447 // with the aim of hiding the transition from unloaded to loaded widget from users. 448 return top + jetpackLikesLookAhead >= 0 && bottom <= window.innerHeight + jetpackLikesLookAhead; 449} 450 451function jetpackUnloadScrolledOutWidgets() { 452 for ( let i = jetpackCommentLikesLoadedWidgets.length - 1; i >= 0; i-- ) { 453 const currentWidgetIframe = jetpackCommentLikesLoadedWidgets[ i ]; 454 455 if ( ! jetpackIsScrolledIntoView( currentWidgetIframe ) ) { 456 const widgetWrapper = 457 currentWidgetIframe && 458 currentWidgetIframe.parentElement && 459 currentWidgetIframe.parentElement.parentElement; 460 461 // Restore parent class to 'unloaded' so this widget can be picked up by queue manager again if needed. 462 widgetWrapper.classList.remove( 'jetpack-likes-widget-loaded' ); 463 widgetWrapper.classList.remove( 'jetpack-likes-widget-loading' ); 464 widgetWrapper.classList.add( 'jetpack-likes-widget-unloaded' ); 465 466 // Bring back the loading placeholder into view. 467 widgetWrapper 468 .querySelectorAll( '.comment-likes-widget-placeholder' ) 469 .forEach( item => ( item.style.display = 'block' ) ); 470 471 // Remove it from the list of loaded widgets. 472 jetpackCommentLikesLoadedWidgets.splice( i, 1 ); 473 474 // Remove comment like widget iFrame. 475 currentWidgetIframe.remove(); 476 } 477 } 478} 479 480var jetpackWidgetsDelayedExec = function ( after, fn ) { 481 var timer; 482 return function () { 483 clearTimeout( timer ); 484 timer = setTimeout( fn, after ); 485 }; 486}; 487 488var jetpackOnScrollStopped = jetpackWidgetsDelayedExec( 250, JetpackLikesWidgetQueueHandler ); 489 490// Load initial batch of widgets, prior to any scrolling events. 491JetpackLikesWidgetQueueHandler(); 492 493// Add event listener to execute queue handler after scroll. 494window.addEventListener( 'scroll', jetpackOnScrollStopped, true ); 495; 496/** 497 * Comment Likes - JavaScript 498 * 499 * This handles liking and unliking comments, as well as viewing who has 500 * liked a particular comment. 501 * 502 * @dependency Swipe (dynamically loaded when needed) 503 * 504 * @package Comment_Likes 505 * @subpackage JavaScript 506 */ 507(function () { 508 function init() { 509 let extWin; 510 let extWinCheck; 511 let commentLikeEvent; 512 513 // Only run once. 514 if (window.comment_likes_loaded) { 515 return; 516 } 517 window.comment_likes_loaded = true; 518 519 // Client-side cache of who liked a particular comment to avoid 520 // having to hit the server multiple times for the same data. 521 const commentLikeCache = {}; 522 523 let swipeLibPromise; 524 525 // Load the Swipe library, if it's not already loaded. 526 function swipeLibLoader() { 527 if (!swipeLibPromise) { 528 swipeLibPromise = new Promise((resolve, reject) => { 529 if (window.Swipe) { 530 resolve(window.Swipe); 531 } else { 532 const swipeScript = document.createElement('script'); 533 swipeScript.src = comment_like_text.swipeUrl; 534 swipeScript.async = true; 535 document.body.appendChild(swipeScript); 536 swipeScript.addEventListener('load', () => resolve(window.Swipe)); 537 swipeScript.addEventListener('error', error => reject(error)); 538 } 539 }); 540 } 541 return swipeLibPromise; 542 } 543 544 /** 545 * Parse the comment ID from a comment like link. 546 */ 547 function getCommentId(link) { 548 const commentId = 549 link && link.getAttribute('href') && link.getAttribute('href').split('like_comment='); 550 return commentId[1].split('&_wpnonce=')[0]; 551 } 552 553 /** 554 * Handle an ajax action on the comment like link. 555 */ 556 function handleLinkAction(link, action, commentId, callback) { 557 const nonce = 558 link && link.getAttribute('href') && link.getAttribute('href').split('_wpnonce=')[1]; 559 560 fetch('/wp-admin/admin-ajax.php', { 561 method: 'POST', 562 body: new URLSearchParams({ 563 action: action, 564 _wpnonce: nonce, 565 like_comment: commentId, 566 blog_id: Number(link.dataset.blog), 567 }), 568 headers: { 569 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 570 'X-Requested-With': 'XMLHttpRequest', 571 Accept: 'application/json', 572 'cache-control': 'no-cache', 573 pragma: 'no-cache', 574 }, 575 }) 576 .then(response => response.json()) 577 .then(callback); 578 } 579 580 function startPolling() { 581 // Append cookie polling login iframe to this window to wait for user to finish logging in (or cancel) 582 const loginIframe = document.createElement('iframe'); 583 loginIframe.id = 'wp-login-polling-iframe'; 584 loginIframe.src = 'https://wordpress.com/public.api/connect/?iframe=true'; 585 document.body.appendChild(loginIframe); 586 loginIframe.style.display = 'none'; 587 } 588 589 function stopPolling() { 590 const iframe = document.querySelector('#wp-login-polling-iframe'); 591 if (iframe) { 592 iframe.remove(); 593 } 594 } 595 596 function hide(el) { 597 if (el && el.style) { 598 el.style.display = 'none'; 599 } 600 } 601 602 function show(el) { 603 if (el && el.style) { 604 el.style.removeProperty('display'); 605 } 606 } 607 608 // Overlay used for displaying comment like info. 609 class Overlay { 610 constructor() { 611 // Overlay element. 612 this.el = document.createElement('div'); 613 this.el.classList.add('comment-likes-overlay'); 614 document.body.appendChild(this.el); 615 hide(this.el); 616 617 this.el.addEventListener('mouseenter', () => { 618 // Don't hide the overlay if the user is mousing over it. 619 overlay.cancelHide(); 620 }); 621 622 this.el.addEventListener('mouseleave', () => overlay.requestHide()); 623 624 // Inner contents of overlay. 625 this.innerEl = null; 626 627 // Instance of the Swipe library. 628 this.swipe = null; 629 630 // Timeout used for hiding the overlay. 631 this.hideTimeout = null; 632 } 633 634 // Initialise the overlay for use, removing any old content. 635 clear() { 636 // Unload any previous instance of Swipe (to avoid leaking a global 637 // event handler). This is done before clearing the contents of the 638 // overlay because Swipe expects the slides to still be present. 639 if (this.swipe) { 640 this.swipe.kill(); 641 this.swipe = null; 642 } 643 this.el.innerHTML = ''; 644 this.innerEl = document.createElement('div'); 645 this.innerEl.classList.add('inner'); 646 this.el.appendChild(this.innerEl); 647 } 648 649 /** 650 * Construct a list (<ul>) of user (gravatar, name) details. 651 * 652 * @param data liker data returned from the server 653 * @param klass CSS class to apply to the <ul> element 654 * @param start index of user to start at 655 * @param length number of users to include in the list 656 * 657 * @return A container element with the list 658 */ 659 getUserBits(data, klass, start, length) { 660 start = start || 0; 661 let last = start + (length || data.length); 662 last = last > data.length ? data.length : last; 663 const container = document.createElement('div'); 664 container.classList.add('liker-list'); 665 let html = `<ul class="${klass || ''}">`; 666 for (let i = start; i < last; ++i) { 667 const user = data[i]; 668 html += ` 669 <li> 670 <a rel="nofollow" title="${user.display_name_esc}" href="${user.profile_url_esc}"> 671 <img src="${user.avatar_url_esc}" alt="${user.display_name_esc}" /> 672 <span class="user-name">${user.display_name_esc}</span> 673 </a> 674 </li> 675 `; 676 } 677 html += '</ul>'; 678 container.innerHTML = html; 679 return container; 680 } 681 682 /** 683 * Render the display of who has liked this comment. The type of 684 * display depends on how many people have liked the comment. 685 * If more than 10 people have liked the comment, this function 686 * renders navigation controls and sets up the Swipe library for 687 * changing between pages. 688 * 689 * @param link the element over which the user is hovering 690 * @param data the results retrieved from the server 691 */ 692 showLikes(link, data) { 693 this.clear(); 694 695 link.dataset.likeCount = data.length; 696 if (data.length === 0) { 697 // No likers after all. 698 hide(this.el); 699 return; 700 } 701 702 this.innerEl.style.padding = '12px'; 703 704 if (data.length < 6) { 705 // Only one column needed. 706 this.innerEl.style.maxWidth = '200px'; 707 this.innerEl.innerHTML = ''; 708 this.innerEl.appendChild(this.getUserBits(data, 'single')); 709 this.setPosition(link); 710 } else if (data.length < 11) { 711 // Two columns, but only one page. 712 this.innerEl.innerHTML = ''; 713 this.innerEl.appendChild(this.getUserBits(data, 'double')); 714 this.setPosition(link); 715 } else { 716 // Multiple pages. 717 this.renderLikesWithPagination(data, link); 718 } 719 } 720 721 /**
722 * Render multiple pages of likes with pagination controls. 723 * This function is intended to be called by `showLikes` above. 724 * 725 * @param data the results retrieved from the server 726 */ 727 renderLikesWithPagination(data, link) { 728 swipeLibLoader().then(() => { 729 const page_count = Math.ceil(data.length / 10); 730 // Swipe requires two nested containers. 731 const swipe = document.createElement('div'); 732 swipe.classList.add('swipe'); 733 this.innerEl.appendChild(swipe); 734 735 const wrap = document.createElement('div'); 736 wrap.classList.add('swipe-wrap'); 737 swipe.appendChild(wrap); 738 739 for (let i = 0; i < page_count; ++i) { 740 wrap.appendChild(this.getUserBits(data, 'double', i * 10, 10)); 741 } 742 743 /** 744 * Navigation controls. 745 * This is based on the Newdash controls found in 746 * reader/recommendations-templates.php 747 */ 748 const nav = document.createElement('nav'); 749 nav.classList.add('slider-nav'); 750 751 let navContents = ` 752 <a href="#" class="prev"> 753 <span class="noticon noticon-previous" title="Previous" alt="<"></span> 754 </a> 755 <span class="position"> 756 `; 757 for (let i = 0; i < page_count; ++i) { 758 navContents += `<em data-page="${i}" class="${i === 0 ? 'on' : ''}">•</em>`; 759 } 760 navContents += ` 761 </span> 762 <a href="#" class="next"> 763 <span class="noticon noticon-next" title="Next" alt=">"></span> 764 </a> 765 `; 766 this.innerEl.appendChild(nav); 767 nav.innerHTML = navContents; 768 769 /** Set up Swipe. **/ 770 // Swipe cannot be set up successfully unless its container 771 // is visible, so we show it now. 772 show(this.el); 773 this.setPosition(link); 774 775 this.swipe = new Swipe(swipe, { 776 callback: function (pos) { 777 // Update the pagination indicators. 778 // 779 // If there are exactly two pages, Swipe has a weird 780 // special case where it duplicates both pages and 781 // can return index 2 and 3 even though those aren't 782 // real pages (see swipe.js, line 47). To deal with 783 // this, we use the expression `pos % page_count`. 784 pos = pos % page_count; 785 nav.querySelectorAll('em').forEach(em => { 786 const page = Number(em.dataset.page); 787 em.setAttribute('class', pos === page ? 'on' : ''); 788 }); 789 }, 790 }); 791 792 nav.querySelectorAll('em').forEach(em => { 793 em.addEventListener('click', e => { 794 // Go to the page corresponding to the indicator clicked. 795 this.swipe.slide(Number(em.dataset.page)); 796 e.preventDefault(); 797 }); 798 }); 799 // Previous and next buttons. 800 nav.querySelector('.prev').addEventListener('click', e => { 801 this.swipe.prev(); 802 e.preventDefault(); 803 }); 804 nav.querySelector('.next').addEventListener('click', e => { 805 this.swipe.next(); 806 e.preventDefault(); 807 }); 808 }); 809 } 810 811 /** 812 * Open the overlay and show a loading message. 813 */ 814 showLoadingMessage(link) { 815 this.clear(); 816 this.innerEl.textContent = comment_like_text.loading; 817 this.setPosition(link); 818 } 819 820 /** 821 * Position the overlay near the current comment. 822 * 823 * @param link element near which to position the overlay 824 */ 825 setPosition(link) { 826 // Prepare a down arrow icon for the bottom of the overlay. 827 const icon = document.createElement('span'); 828 this.el.appendChild(icon); 829 icon.classList.add('icon', 'noticon', 'noticon-downarrow'); 830 icon.style.textShadow = '0px 1px 1px rgb(223, 223, 223)'; 831 832 const rect = link.getBoundingClientRect(); 833 const win = document.defaultView; 834 const offset = { 835 top: rect.top + win.scrollY, 836 left: rect.left + win.scrollX, 837 }; 838 839 // Take measurements with the element fully visible. 840 show(this.el); 841 let left = offset.left - (this.el.offsetWidth - link.offsetWidth) / 2; 842 left = left < 5 ? 5 : left; 843 let top = offset.top - this.el.offsetHeight + 5; 844 hide(this.el); 845 846 const adminBar = document.querySelector('#wpadminbar'); 847 848 // Check if the overlay would appear off the screen. 849 if (top < win.scrollY + ((adminBar && adminBar.offsetHeight) || 0)) { 850 // We'll display the overlay beneath the link instead. 851 top = offset.top + link.offsetHeight; 852 // Instead of using the down arrow icon, use an up arrow. 853 icon.remove(); 854 this.el.prepend(icon); 855 icon.classList.remove('noticon-downarrow'); 856 icon.classList.add('noticon-uparrow'); 857 icon.style.textShadow = '0px -1px 1px rgb(223, 223, 223)'; 858 icon.style.verticalAlign = 'bottom'; 859 } 860 861 this.el.style.left = `${left}px`; 862 this.el.style.top = `${top}px`; 863 show(this.el); 864 865 // The height of the arrow icon differs slightly between browsers, 866 // so we compute the margin here to make sure it isn't disjointed 867 // from the overlay. 868 icon.style.marginTop = `${icon.scrollHeight - 26}px`; 869 icon.style.marginBottom = `${20 - icon.scrollHeight}px`; 870 871 // Position the arrow to be horizontally centred on the link. 872 icon.style.paddingLeft = `${ 873 offset.left - left + (link.offsetWidth - icon.scrollWidth) / 2 874 }px`; 875 } 876 877 /** 878 * Return whether the overlay is visible. 879 */ 880 isVisible() { 881 return this.el.style.getPropertyValue('display') !== 'none'; 882 } 883 884 /** 885 * Request that the overlay be hidden after a short delay. 886 */ 887 requestHide() { 888 if (this.hideTimeout !== null) { 889 return; 890 } 891 this.hideTimeout = setTimeout(() => { 892 hide(this.el); 893 this.clear(); 894 }, 300); 895 } 896 897 /** 898 * Cancel a request to hide the overlay. 899 */ 900 cancelHide() { 901 if (this.hideTimeout !== null) { 902 clearTimeout(this.hideTimeout); 903 this.hideTimeout = null; 904 } 905 } 906 } 907 908 // Overlay used for displaying comment like info.
909 const overlay = new Overlay(); 910 911 // The most recent comment for which the user has requested to see 912 // who liked it. 913 var relevantComment; 914 915 // Precache after this timeout. 916 var precacheTimeout = null; 917 918 /** 919 * Fetch the like data for a particular comment. 920 */ 921 function fetchLikeData(link, commentId) { 922 commentLikeCache[commentId] = null; 923 924 const container = link && link.parentElement && link.parentElement.parentElement; 925 const star = container.querySelector('a.comment-like-link'); 926 star && 927 handleLinkAction(star, 'view_comment_likes', commentId, data => { 928 // Populate the cache. 929 commentLikeCache[commentId] = data; 930 931 // Only show the overlay if the user is interested. 932 if (overlay.isVisible() && relevantComment === commentId) { 933 overlay.showLikes(link, data); 934 } 935 }); 936 } 937 938 function readCookie(c) { 939 const nameEQ = c + '='; 940 const cookieStrings = document.cookie.split(';'); 941 942 for (let i = 0; i < cookieStrings.length; i++) { 943 let cookieString = cookieStrings[i]; 944 while (cookieString.charAt(0) === ' ') { 945 cookieString = cookieString.substring(1, cookieString.length); 946 } 947 if (cookieString.indexOf(nameEQ) === 0) { 948 const chunk = cookieString.substring(nameEQ.length, cookieString.length); 949 const pairs = chunk.split('&'); 950 const cookieData = {}; 951 for (let num = pairs.length - 1; num >= 0; num--) { 952 const pair = pairs[num].split('='); 953 cookieData[pair[0]] = decodeURIComponent(pair[1]); 954 } 955 return cookieData; 956 } 957 } 958 return null; 959 } 960 961 function getServiceData() { 962 const data = readCookie('wpc_wpc'); 963 if (data === null || typeof data.access_token === 'undefined' || !data.access_token) { 964 return false; 965 } 966 return data; 967 } 968 969 function readMessage(msg) { 970 const event = msg.data; 971 972 if (typeof event.event === 'undefined') { 973 return; 974 } 975 976 if (event.event === 'login' && event.success) { 977 extWinCheck = setInterval(function () { 978 if (!extWin || extWin.closed) { 979 clearInterval(extWinCheck); 980 if (getServiceData()) { 981 // Load page in an iframe to get the current comment nonce 982 const nonceIframe = document.createElement('iframe'); 983 nonceIframe.id = 'wp-login-comment-nonce-iframe'; 984 nonceIframe.style.display = 'none'; 985 nonceIframe.src = commentLikeEvent + ''; 986 document.body.appendChild(nonceIframe); 987 988 const commentLikeId = (commentLikeEvent + '') 989 .split('like_comment=')[1] 990 .split('&_wpnonce=')[0]; 991 let c; 992 993 // Set a 5 second timeout to redirect to the comment page without doing the Like as a fallback 994 const commentLikeTimeout = setTimeout(() => { 995 window.location = commentLikeEvent; 996 }, 5000); 997 998 // Check for a new nonced redirect and use that if available before timing out 999 const commentLikeCheck = setInterval(() => { 1000 const iframe = document.querySelector('#wp-login-comment-nonce-iframe'); 1001 if (iframe) { 1002 c = iframe.querySelector(`#comment-like-${commentLikeId} .comment-like-link`); 1003 } 1004 if (c && typeof c.href !== 'undefined') { 1005 clearTimeout(commentLikeTimeout); 1006 clearInterval(commentLikeCheck); 1007 window.location = c.href; 1008 } 1009 }, 100); 1010 } 1011 } 1012 }, 100); 1013 1014 if (extWin) { 1015 if (!extWin.closed) { 1016 extWin.close(); 1017 } 1018 extWin = false; 1019 } 1020 1021 stopPolling(); 1022 } 1023 } 1024 1025 if (typeof window.postMessage !== 'undefined') { 1026 window.addEventListener('message', e => { 1027 let message = e && e.data; 1028 if (typeof message === 'string') { 1029 try { 1030 message = JSON.parse(message); 1031 } catch (err) { 1032 return; 1033 } 1034 } 1035 1036 const type = message && message.type; 1037 if (type === 'loginMessage') { 1038 readMessage(message); 1039 } 1040 }); 1041 } 1042 1043 document.body.addEventListener('click', e => { 1044 let target = e.target; 1045 1046 // Don't do anything when clicking on the "X people" link. 1047 if (target.matches('p.comment-likes a.view-likers')) { 1048 e.preventDefault(); 1049 return; 1050 } 1051 1052 // Retrieve the surrounding paragraph to the star, if it hasn't been liked. 1053 const notLikedPar = target.closest('p.comment-not-liked'); 1054 1055 // Return if not clicking on star or surrounding paragraph. 1056 if (!target.matches('a.comment-like-link') && !notLikedPar) { 1057 return; 1058 } 1059 1060 // When a comment hasn't been liked, make the text clickable, too. 1061 if (notLikedPar) { 1062 target = notLikedPar.querySelector('a.comment-like-link'); 1063 if (!target) { 1064 return; 1065 } 1066 } 1067 1068 if (target.classList.contains('needs-login')) { 1069 e.preventDefault(); 1070 commentLikeEvent = target; 1071 if (extWin) { 1072 if (!extWin.closed) { 1073 extWin.close(); 1074 } 1075 extWin = false;
1076 } 1077 1078 stopPolling(); 1079 1080 const url = 'https://wordpress.com/public.api/connect/?action=request&service=wordpress'; 1081 extWin = window.open( 1082 url, 1083 'likeconn', 1084 'status=0,toolbar=0,location=1,menubar=0,directories=0,resizable=1,scrollbars=1,height=560,width=500' 1085 ); 1086 1087 startPolling(); 1088 1089 return false; 1090 } 1091 1092 // Record that the user likes or does not like this comment. 1093 const commentId = getCommentId(target); 1094 target.classList.add('loading'); 1095 1096 let commentEl = document.querySelector(`p#comment-like-${commentId}`); 1097 // Determine whether to like or unlike based on whether the comment is 1098 // currently liked. 1099 const action = 1100 commentEl && commentEl.dataset.liked === 'comment-liked' 1101 ? 'unlike_comment' 1102 : 'like_comment'; 1103 handleLinkAction(target, action, commentId, data => { 1104 // Invalidate the like cache for this comment. 1105 delete commentLikeCache[commentId]; 1106 1107 const countEl = document.querySelector(`#comment-like-count-${data.context}`); 1108 if (countEl) { 1109 countEl.innerHTML = data.display; 1110 } 1111 1112 commentEl = document.querySelector(`p#comment-like-${data.context}`); 1113 if (action === 'like_comment') { 1114 commentEl.classList.remove('comment-not-liked'); 1115 commentEl.classList.add('comment-liked'); 1116 commentEl.dataset.liked = 'comment-liked'; 1117 } else { 1118 commentEl.classList.remove('comment-liked'); 1119 commentEl.classList.add('comment-not-liked'); 1120 commentEl.dataset.liked = 'comment-not-liked'; 1121 } 1122 1123 // Prefetch new data for this comment (if there are likers left). 1124 const parent = target.closest('.comment-likes'); 1125 const link = parent && parent.querySelector('a.view-likers'); 1126 if (link) { 1127 fetchLikeData(link, commentId); 1128 } 1129 1130 target.classList.remove('loading'); 1131 }); 1132 e.preventDefault(); 1133 e.stopPropagation(); 1134 }); 1135 1136 document.body.addEventListener( 1137 'mouseenter', 1138 function (e) { 1139 if (!e.target.matches('p.comment-likes a.view-likers')) { 1140 return; 1141 } 1142 // Show the user a list of who has liked this comment. 1143 1144 const link = e.target; 1145 if (Number(link.dataset.likeCount || 0) === 0) { 1146 // No one has liked this comment. 1147 return; 1148 } 1149 1150 // Don't hide the overlay. 1151 overlay.cancelHide(); 1152 1153 // Get the comment ID. 1154 const container = link.parentElement && link.parentElement.parentElement; 1155 const star = container && container.querySelector('a.comment-like-link'); 1156 const commentId = star && getCommentId(star); 1157 relevantComment = commentId; 1158 1159 // Check if the list of likes for this comment is already in 1160 // the cache. 1161 if (commentId in commentLikeCache) { 1162 const entry = commentLikeCache[commentId];
1163 // Only display the likes if the ajax request is 1164 // actually done. 1165 if (entry !== null) { 1166 overlay.showLikes(link, entry); 1167 } else { 1168 // Make sure the overlay is visible (in case 1169 // the user moved the mouse away while loading 1170 // but then came back before it finished 1171 // loading). 1172 overlay.showLoadingMessage(link); 1173 } 1174 return; 1175 } 1176 1177 // Position the "Loading..." overlay. 1178 overlay.showLoadingMessage(link); 1179 1180 // Fetch the data. 1181 fetchLikeData(link, commentId); 1182 }, 1183 true 1184 ); 1185 1186 document.body.addEventListener( 1187 'mouseleave', 1188 e => { 1189 if (!e.target.matches('p.comment-likes a.view-likers')) { 1190 return; 1191 } 1192 // User has moved cursor away - hide the overlay. 1193 overlay.requestHide(); 1194 }, 1195 true 1196 ); 1197 1198 document.body.addEventListener( 1199 'mouseenter', 1200 e => { 1201 if (!e.target.matches('.comment') || !e.target.querySelector('a.comment-like-link')) { 1202 return; 1203 } 1204 // User is moving over a comment - precache the comment like data.
1205 if (precacheTimeout !== null) { 1206 clearTimeout(precacheTimeout); 1207 precacheTimeout = null; 1208 } 1209 1210 const star = e.target.querySelector('a.comment-like-link'); 1211 const parent = star.closest('.comment-likes'); 1212 const link = parent && parent.querySelector('a.view-likers'); 1213 if (!link || Number(link.dataset.likeCount || 0) === 0) { 1214 // No likes. 1215 return; 1216 } 1217 const commentId = getCommentId(star); 1218 if (commentId in commentLikeCache) { 1219 // Already in cache. 1220 return; 1221 } 1222 1223 precacheTimeout = setTimeout(() => { 1224 precacheTimeout = null; 1225 if (commentId in commentLikeCache) { 1226 // Was cached in the interim. 1227 return; 1228 } 1229 fetchLikeData(link, commentId); 1230 }, 1000); 1231 }, 1232 true 1233 ); 1234 } 1235 1236 if (document.readyState !== 'loading') { 1237 init(); 1238 } else { 1239 document.addEventListener('DOMContentLoaded', init); 1240 } 1241})(); 1242; 1243/*! 1244 * imagesLoaded PACKAGED v3.1.8 1245 * JavaScript is all like "You images are done yet or what?" 1246 * MIT License 1247 */ 1248 1249/*! 1250 * EventEmitter v4.2.6 - git.io/ee 1251 * Oliver Caldwell 1252 * MIT license 1253 * @preserve 1254 */ 1255 1256( function () { 1257 1258 /** 1259 * Class for managing events. 1260 * Can be extended to provide event functionality in other classes. 1261 * 1262 * @class EventEmitter Manages event registering and emitting. 1263 */ 1264 function EventEmitter() {} 1265 1266 // Shortcuts to improve speed and size 1267 var proto = EventEmitter.prototype; 1268 var exports = this; 1269 var originalGlobalValue = exports.EventEmitter; 1270 1271 /** 1272 * Finds the index of the listener for the event in it's storage array. 1273 * 1274 * @param {Function[]} listeners Array of listeners to search through. 1275 * @param {Function} listener Method to look for. 1276 * @return {Number} Index of the specified listener, -1 if not found 1277 * @api private 1278 */ 1279 function indexOfListener( listeners, listener ) { 1280 var i = listeners.length; 1281 while ( i-- ) { 1282 if ( listeners[i].listener === listener ) { 1283 return i; 1284 } 1285 } 1286 1287 return -1; 1288 } 1289 1290 /** 1291 * Alias a method while keeping the context correct, to allow for overwriting of target method. 1292 * 1293 * @param {String} name The name of the target method. 1294 * @return {Function} The aliased method 1295 * @api private 1296 */ 1297 function alias( name ) { 1298 return function aliasClosure() { 1299 return this[ name ].apply( this, arguments ); 1300 }; 1301 } 1302 1303 /** 1304 * Returns the listener array for the specified event. 1305 * Will initialise the event object and listener arrays if required. 1306 * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object c
vendor: 10,956 bytes, lines 1306-1599
1306ontaining bar and baz. But only if you have either defined them with defineEvent or added some listeners to them. 1307 * Each property in the object response is an array of listener functions. 1308 * 1309 * @param {String|RegExp} evt Name of the event to return the listeners from. 1310 * @return {Function[]|Object} All listener functions for the event. 1311 */ 1312 proto.getListeners = function getListeners( evt ) { 1313 var events = this._getEvents(); 1314 var response; 1315 var key; 1316 1317 // Return a concatenated array of all matching events if 1318 // the selector is a regular expression. 1319 if ( typeof evt === 'object' ) { 1320 response = {}; 1321 for ( key in events ) { 1322 if ( events.hasOwnProperty( key ) && evt.test( key ) ) { 1323 response[ key ] = events[ key ]; 1324 } 1325 } 1326 } 1327 else { 1328 response = events[ evt ] || ( events[ evt ] = [] ); 1329 } 1330 1331 return response; 1332 }; 1333 1334 /** 1335 * Takes a list of listener objects and flattens it into a list of listener functions. 1336 * 1337 * @param {Object[]} listeners Raw listener objects. 1338 * @return {Function[]} Just the listener functions. 1339 */ 1340 proto.flattenListeners = function flattenListeners( listeners ) { 1341 var flatListeners = []; 1342 var i; 1343 1344 for ( i = 0; i < listeners.length; i += 1 ) { 1345 flatListeners.push( listeners[i].listener ); 1346 } 1347 1348 return flatListeners; 1349 }; 1350 1351 /** 1352 * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful. 1353 * 1354 * @param {String|RegExp} evt Name of the event to return the listeners from. 1355 * @return {Object} All listener functions for an event in an object. 1356 */ 1357 proto.getListenersAsObject = function getListenersAsObject( evt ) { 1358 var listeners = this.getListeners( evt ); 1359 var response; 1360 1361 if ( listeners instanceof Array ) { 1362 response = {}; 1363 response[ evt ] = listeners; 1364 } 1365 1366 return response || listeners; 1367 }; 1368 1369 /** 1370 * Adds a listener function to the specified event. 1371 * The listener will not be added if it is a duplicate. 1372 * If the listener returns true then it will be removed after it is called. 1373 * If you pass a regular expression as the event name then the listener will be added to all events that match it. 1374 * 1375 * @param {String|RegExp} evt Name of the event to attach the listener to. 1376 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. 1377 * @return {Object} Current instance of EventEmitter for chaining. 1378 */ 1379 proto.addListener = function addListener( evt, listener ) { 1380 var listeners = this.getListenersAsObject( evt ); 1381 var listenerIsWrapped = typeof listener === 'object'; 1382 var key; 1383 1384 for ( key in listeners ) { 1385 if ( listeners.hasOwnProperty( key ) && indexOfListener( listeners[ key ], listener ) === -1 ) { 1386 listeners[ key ].push( listenerIsWrapped ? listener : { 1387 listener: listener, 1388 once: false 1389 } ); 1390 } 1391 } 1392 1393 return this; 1394 }; 1395 1396 /** 1397 * Alias of addListener 1398 */ 1399 proto.on = alias( 'addListener' ); 1400 1401 /** 1402 * Semi-alias of addListener. It will add a listener that will be 1403 * automatically removed after it's first execution. 1404 * 1405 * @param {String|RegExp} evt Name of the event to attach the listener to. 1406 * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling. 1407 * @return {Object} Current instance of EventEmitter for chaining. 1408 */ 1409 proto.addOnceListener = function addOnceListener( evt, listener ) { 1410 return this.addListener( evt, { 1411 listener: listener, 1412 once: true 1413 } ); 1414 }; 1415 1416 /** 1417 * Alias of addOnceListener. 1418 */ 1419 proto.once = alias( 'addOnceListener' ); 1420 1421 /** 1422 * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad. 1423 * You need to tell it what event names should be matched by a regex. 1424 * 1425 * @param {String} evt Name of the event to create. 1426 * @return {Object} Current instance of EventEmitter for chaining. 1427 */ 1428 proto.defineEvent = function defineEvent( evt ) { 1429 this.getListeners( evt ); 1430 return this; 1431 }; 1432 1433 /** 1434 * Uses defineEvent to define multiple events. 1435 * 1436 * @param {String[]} evts An array of event names to define. 1437 * @return {Object} Current instance of EventEmitter for chaining. 1438 */ 1439 proto.defineEvents = function defineEvents( evts ) { 1440 for ( var i = 0; i < evts.length; i += 1 ) { 1441 this.defineEvent( evts[i] ); 1442 } 1443 return this; 1444 }; 1445 1446 /** 1447 * Removes a listener function from the specified event. 1448 * When passed a regular expression as the event name, it will remove the listener from all events that match it. 1449 * 1450 * @param {String|RegExp} evt Name of the event to remove the listener from. 1451 * @param {Function} listener Method to remove from the event. 1452 * @return {Object} Current instance of EventEmitter for chaining. 1453 */ 1454 proto.removeListener = function removeListener( evt, listener ) { 1455 var listeners = this.getListenersAsObject( evt ); 1456 var index; 1457 var key; 1458 1459 for ( key in listeners ) { 1460 if ( listeners.hasOwnProperty( key ) ) { 1461 index = indexOfListener( listeners[ key ], listener ); 1462 1463 if ( index !== -1 ) { 1464 listeners[ key ].splice( index, 1 ); 1465 } 1466 } 1467 } 1468 1469 return this; 1470 }; 1471 1472 /** 1473 * Alias of removeListener 1474 */ 1475 proto.off = alias( 'removeListener' ); 1476 1477 /** 1478 * Adds listeners in bulk using the manipulateListeners method. 1479 * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added. 1480 * You can also pass it a regular expression to add the array of listeners to all events that match it. 1481 * Yeah, this function does quite a bit. That's probably a bad thing. 1482 * 1483 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once. 1484 * @param {Function[]} [listeners] An optional array of listener functions to add. 1485 * @return {Object} Current instance of EventEmitter for chaining. 1486 */ 1487 proto.addListeners = function addListeners( evt, listeners ) { 1488 // Pass through to manipulateListeners 1489 return this.manipulateListeners( false, evt, listeners ); 1490 }; 1491 1492 /** 1493 * Removes listeners in bulk using the manipulateListeners method. 1494 * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. 1495 * You can also pass it an event name and an array of listeners to be removed. 1496 * You can also pass it a regular expression to remove the listeners from all events that match it. 1497 * 1498 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once. 1499 * @param {Function[]} [listeners] An optional array of listener functions to remove. 1500 * @return {Object} Current instance of EventEmitter for chaining. 1501 */ 1502 proto.removeListeners = function removeListeners( evt, listeners ) { 1503 // Pass through to manipulateListeners 1504 return this.manipulateListeners( true, evt, listeners ); 1505 }; 1506 1507 /** 1508 * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level. 1509 * The first argument will determine if the listeners are removed (true) or added (false). 1510 * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. 1511 * You can also pass it an event name and an array of listeners to be added/removed. 1512 * You can also pass it a regular expression to manipulate the listeners of all events that match it. 1513 * 1514 * @param {Boolean} remove True if you want to remove listeners, false if you want to add. 1515 * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once. 1516 * @param {Function[]} [listeners] An optional array of listener functions to add/remove. 1517 * @return {Object} Current instance of EventEmitter for chaining. 1518 */ 1519 proto.manipulateListeners = function manipulateListeners( remove, evt, listeners ) { 1520 var i; 1521 var value; 1522 var single = remove ? this.removeListener : this.addListener; 1523 var multiple = remove ? this.removeListeners : this.addListeners; 1524 1525 // If evt is an object then pass each of it's properties to this method 1526 if ( typeof evt === 'object' && !( evt instanceof RegExp ) ) { 1527 for ( i in evt ) { 1528 if ( evt.hasOwnProperty(i) && ( value = evt[i] ) ) { 1529 // Pass the single listener straight through to the singular method 1530 if ( typeof value === 'function' ) { 1531 single.call( this, i, value ); 1532 } 1533 else { 1534 // Otherwise pass back to the multiple function 1535 multiple.call( this, i, value ); 1536 } 1537 } 1538 } 1539 } 1540 else { 1541 // So evt must be a string 1542 // And listeners must be an array of listeners 1543 // Loop over it and pass each one to the multiple method 1544 i = listeners.length; 1545 while (i--) { 1546 single.call( this, evt, listeners[i] ); 1547 } 1548 } 1549 1550 return this; 1551 }; 1552 1553 /** 1554 * Removes all listeners from a specified event. 1555 * If you do not specify an event then all listeners will be removed. 1556 * That means every event will be emptied. 1557 * You can also pass a regex to remove all events that match it. 1558 * 1559 * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed. 1560 * @return {Object} Current instance of EventEmitter for chaining. 1561 */ 1562 proto.removeEvent = function removeEvent( evt ) { 1563 var type = typeof evt; 1564 var events = this._getEvents(); 1565 var key; 1566 1567 // Remove different things depending on the state of evt 1568 if ( type === 'string' ) { 1569 // Remove all listeners for the specified event 1570 delete events[ evt ]; 1571 } 1572 else if ( type === 'object' ) { 1573 // Remove all events matching the regex. 1574 for ( key in events ) { 1575 if ( events.hasOwnProperty( key ) && evt.test( key ) ) { 1576 delete events[ key ]; 1577 } 1578 } 1579 } 1580 else { 1581 // Remove all listeners in all events 1582 delete this._events; 1583 } 1584 1585 return this; 1586 }; 1587 1588 /** 1589 * Alias of removeEvent. 1590 * 1591 * Added to mirror the node API. 1592 */ 1593 proto.removeAllListeners = alias( 'removeEvent' ); 1594 1595 /** 1596 * Emits an event of your choice. 1597 * When emitted, every listener attached to that event will be executed. 1598 * If you pass the optional argument array then those arguments will be passed to every listener upon execution. 1599 * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
1600 * So they will not arrive within the array on the other side, they will be separate. 1601 * You can also pass a regular expression to emit to all events that match it. 1602 * 1603 * @param {String|RegExp} evt Name of the event to emit and execute listeners for. 1604 * @param {Array} [args] Optional array of arguments to be passed to each listener. 1605 * @return {Object} Current instance of EventEmitter for chaining. 1606 */ 1607 proto.emitEvent = function emitEvent( evt, args ) { 1608 var listeners = this.getListenersAsObject( evt ); 1609 var listener; 1610 var i; 1611 var key; 1612 var response; 1613 1614 for ( key in listeners ) { 1615 if ( listeners.hasOwnProperty( key ) ) { 1616 i = listeners[ key ].length; 1617 1618 while (i--) { 1619 // If the listener returns true then it shall be removed from the event 1620 // The function is executed either with a basic call or an apply if there is an args array 1621 listener = listeners[ key ][i]; 1622 1623 if ( listener.once === true ) { 1624 this.removeListener( evt, listener.listener ); 1625 } 1626 1627 response = listener.listener.apply( this, args || [] ); 1628 1629 if ( response === this._getOnceReturnValue() ) { 1630 this.removeListener( evt, listener.listener ); 1631 } 1632 } 1633 } 1634 } 1635 1636 return this; 1637 }; 1638 1639 /** 1640 * Alias of emitEvent 1641 */ 1642 proto.trigger = alias( 'emitEvent' ); 1643 1644 /** 1645 * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on. 1646 * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it. 1647 * 1648 * @param {String|RegExp} evt Name of the event to emit and execute listeners for. 1649 * @param {...*} Optional additional arguments to be passed to each listener. 1650 * @return {Object} Current instance of EventEmitter for chaining. 1651 */ 1652 proto.emit = function emit( evt ) { 1653 var args = Array.prototype.slice.call( arguments, 1 ); 1654 return this.emitEvent( evt, args ); 1655 }; 1656 1657 /** 1658 * Sets the current value to check against when executing listeners. If a 1659 * listeners return value matches the one set here then it will be removed 1660 * after execution. This value defaults to true. 1661 * 1662 * @param {*} value The new value to check for when executing listeners. 1663 * @return {Object} Current instance of EventEmitter for chaining. 1664 */ 1665 proto.setOnceReturnValue = function setOnceReturnValue( value ) { 1666 this._onceReturnValue = value; 1667 return this; 1668 }; 1669 1670 /** 1671 * Fetches the current value to check against when executing listeners. If 1672 * the listeners return value matches this one then it should be removed 1673 * automatically. It will return true by default. 1674 * 1675 * @return {*|Boolean} The current value to check for or the default, true. 1676 * @api private 1677 */ 1678 proto._getOnceReturnValue = function _getOnceReturnValue() { 1679 if ( this.hasOwnProperty( '_onceReturnValue' ) ) { 1680 return this._onceReturnValue; 1681 } 1682 else { 1683 return true; 1684 } 1685 }; 1686 1687 /** 1688 * Fetches the events object and creates one if required. 1689 * 1690 * @return {Object} The events storage object. 1691 * @api private 1692 */ 1693 proto._getEvents = function _getEvents() { 1694 return this._events || ( this._events = {} ); 1695 }; 1696 1697 /** 1698 * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version. 1699 * 1700 * @return {Function} Non conflicting EventEmitter class. 1701 */ 1702 EventEmitter.noConflict = function noConflict() { 1703 exports.EventEmitter = originalGlobalValue; 1704 return EventEmitter; 1705 }; 1706 1707 // Expose the class either via AMD, CommonJS or the global object 1708 if ( typeof define === 'function' && define.amd ) { 1709 define( 'eventEmitter/EventEmitter', [], function () { 1710 return EventEmitter; 1711 } ); 1712 } 1713 else if ( typeof module === 'object' && module.exports ) { 1714 module.exports = EventEmitter; 1715 } 1716 else { 1717 this.EventEmitter = EventEmitter; 1718 } 1719}.call( this ) ); 1720 1721/*! 1722 * eventie v1.0.4 1723 * event binding helper 1724 * eventie.bind( elem, 'click', myFn ) 1725 * eventie.unbind( elem, 'click', myFn ) 1726 */ 1727 1728/*jshint browser: true, undef: true, unused: true */ 1729/*global define: false */ 1730 1731( function( window ) { 1732 1733 var docElem = document.documentElement; 1734 1735 var bind = function() {}; 1736 1737 function getIEEvent( obj ) { 1738 var event = window.event; 1739 // add event.target 1740 event.target = event.target || event.srcElement || obj; 1741 return event; 1742 } 1743 1744 if ( docElem.addEventListener ) { 1745 bind = function( obj, type, fn ) { 1746 obj.addEventListener( type, fn, false ); 1747 }; 1748 } else if ( docElem.attachEvent ) { 1749 bind = function( obj, type, fn ) { 1750 obj[ type + fn ] = fn.handleEvent ? 1751 function() { 1752 var event = getIEEvent( obj ); 1753 fn.handleEvent.call( fn, event ); 1754 } : 1755 function() { 1756 var event = getIEEvent( obj ); 1757 fn.call( obj, event ); 1758 }; 1759 obj.attachEvent( "on" + type, obj[ type + fn ] ); 1760 }; 1761 } 1762 1763 var unbind = function() {}; 1764 1765 if ( docElem.removeEventListener ) { 1766 unbind = function( obj, type, fn ) { 1767 obj.removeEventListener( type, fn, false ); 1768 }; 1769 } else if ( docElem.detachEvent ) { 1770 unbind = function( obj, type, fn ) { 1771 obj.detachEvent( "on" + type, obj[ type + fn ] ); 1772 try { 1773 delete obj[ type + fn ]; 1774 } catch ( err ) { 1775 // can't delete window object properties 1776 obj[ type + fn ] = undefined; 1777 } 1778 }; 1779 } 1780 1781 var eventie = { 1782 bind: bind, 1783 unbind: unbind 1784 }; 1785 1786 // transport 1787 if ( typeof define === 'function' && define.amd ) { 1788 // AMD 1789 define( 'eventie/eventie',eventie ); 1790 } else { 1791 // browser global 1792 window.eventie = eventie; 1793 } 1794 1795} )( this ); 1796 1797/*! 1798 * imagesLoaded v3.1.8 1799 * JavaScript is all like "You images are done yet or what?" 1800 * MIT License 1801 */ 1802 1803( function( window, factory ) { 1804 // universal module definition 1805 1806 /*global define: false, module: false, require: false */ 1807 1808 if ( typeof define === 'function' && define.amd ) { 1809 // AMD 1810 define( [ 1811 'eventEmitter/EventEmitter', 1812 'eventie/eventie' 1813 ], function( EventEmitter, eventie ) { 1814 return factory( window, EventEmitter, eventie ); 1815 }); 1816 } else if ( typeof exports === 'object' ) { 1817 // CommonJS 1818 module.exports = factory( 1819 window, 1820 require('wolfy87-eventemitter'), 1821 require('eventie') 1822 ); 1823 } else { 1824 // browser global 1825 window.imagesLoaded = factory( 1826 window, 1827 window.EventEmitter, 1828 window.eventie 1829 ); 1830 } 1831 1832})( window, 1833 1834 // -------------------------- factory -------------------------- // 1835 1836 function factory( window, EventEmitter, eventie ) { 1837 1838 var $ = window.jQuery; 1839 var console = window.console; 1840 var hasConsole = typeof console !== 'undefined'; 1841 1842 // -------------------------- helpers -------------------------- // 1843 1844 // extend objects 1845 function extend( a, b ) { 1846 for ( var prop in b ) { 1847 a[ prop ] = b[ prop ]; 1848 } 1849 return a; 1850 } 1851 1852 var objToString = Object.prototype.toString; 1853 function isArray( obj ) { 1854 return objToString.call( obj ) === '[object Array]'; 1855 } 1856 1857 // turn element or nodeList into an array 1858 function makeArray( obj ) { 1859 var ary = []; 1860 if ( isArray( obj ) ) { 1861 // use object if already an array 1862 ary = obj; 1863 } else if ( typeof obj.length === 'number' ) { 1864 // convert nodeList to array 1865 for ( var i=0, len = obj.length; i < len; i++ ) { 1866 ary.push( obj[i] ); 1867 } 1868 } else { 1869 // array of single index 1870 ary.push( obj ); 1871 } 1872 return ary; 1873 } 1874 1875 // -------------------------- imagesLoaded -------------------------- // 1876 1877 /** 1878 * @param {Array, Element, NodeList, String} elem 1879 * @param {Object or Function} options - if function, use as callback 1880 * @param {Function} onAlways - callback function 1881 */ 1882 function ImagesLoaded( elem, options, onAlways ) { 1883 // coerce ImagesLoaded() without new, to be new ImagesLoaded() 1884 if ( !( this instanceof ImagesLoaded ) ) { 1885 return new ImagesLoaded( elem, options ); 1886 } 1887 // use elem as selector string 1888 if ( typeof elem === 'string' ) { 1889 elem = document.querySelectorAll( elem ); 1890 } 1891 1892 this.elements = makeArray( elem ); 1893 this.options = extend( {}, this.options ); 1894 1895 if ( typeof options === 'function' ) { 1896 onAlways = options; 1897 } else { 1898 extend( this.options, options ); 1899 } 1900 1901 if ( onAlways ) { 1902 this.on( 'always', onAlways ); 1903 } 1904 1905 this.getImages(); 1906 1907 if ( $ ) { 1908 // add jQuery Deferred object 1909 this.jqDeferred = new $.Deferred(); 1910 } 1911 1912 // HACK check async to allow time to bind listeners 1913 var _this = this; 1914 setTimeout( function() { 1915 _this.check(); 1916 }); 1917 } 1918 1919 ImagesLoaded.prototype = new EventEmitter(); 1920 1921 ImagesLoaded.prototype.options = {}; 1922 1923 ImagesLoaded.prototype.getImages = function() { 1924 this.images = []; 1925 1926 // filter & find items if we have an item selector 1927 for ( var i=0, len = this.elements.length; i < len; i++ ) { 1928 var elem = this.elements[i]; 1929 // filter siblings 1930 if ( elem.nodeName === 'IMG' ) { 1931 this.addImage( elem ); 1932 } 1933 // find children 1934 // no non-element nodes, #143 1935 var nodeType = elem.nodeType; 1936 if ( !nodeType || !( nodeType === 1 || nodeType === 9 || nodeType === 11 ) ) { 1937 continue; 1938 } 1939 var childElems = elem.querySelectorAll('img'); 1940 // concat childElems to filterFound array 1941 for ( var j=0, jLen = childElems.length; j < jLen; j++ ) { 1942 var img = childElems[j]; 1943 this.addImage( img ); 1944 } 1945 } 1946 }; 1947 1948 /** 1949 * @param {Image} img 1950 */ 1951 ImagesLoaded.prototype.addImage = function( img ) { 1952 var loadingImage = new LoadingImage( img ); 1953 this.images.push( loadingImage ); 1954 }; 1955
1956 ImagesLoaded.prototype.check = function() { 1957 var _this = this; 1958 var checkedCount = 0; 1959 var length = this.images.length; 1960 this.hasAnyBroken = false; 1961 // complete if no images 1962 if ( !length ) { 1963 this.complete(); 1964 return; 1965 } 1966 1967 function onConfirm( image, message ) { 1968 if ( _this.options.debug && hasConsole ) { 1969 console.log( 'confirm', image, message ); 1970 } 1971 1972 _this.progress( image ); 1973 checkedCount++; 1974 if ( checkedCount === length ) { 1975 _this.complete(); 1976 } 1977 return true; // bind once 1978 } 1979 1980 for ( var i=0; i < length; i++ ) { 1981 var loadingImage = this.images[i]; 1982 loadingImage.on( 'confirm', onConfirm ); 1983 loadingImage.check(); 1984 } 1985 }; 1986 1987 ImagesLoaded.prototype.progress = function( image ) { 1988 this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; 1989 // HACK - Chrome triggers event before object properties have changed. #83 1990 var _this = this; 1991 setTimeout( function() { 1992 _this.emit( 'progress', _this, image ); 1993 if ( _this.jqDeferred && _this.jqDeferred.notify ) { 1994 _this.jqDeferred.notify( _this, image ); 1995 } 1996 } ); 1997 }; 1998 1999 ImagesLoaded.prototype.complete = function() { 2000 var eventName = this.hasAnyBroken ? 'fail' : 'done'; 2001 this.isComplete = true; 2002 var _this = this; 2003 // HACK - another setTimeout so that confirm happens after progress 2004 setTimeout( function() { 2005 _this.emit( eventName, _this ); 2006 _this.emit( 'always', _this ); 2007 if ( _this.jqDeferred ) { 2008 var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve'; 2009 _this.jqDeferred[ jqMethod ]( _this ); 2010 } 2011 } ); 2012 }; 2013 2014 // -------------------------- jquery -------------------------- // 2015 2016 if ( $ ) { 2017 $.fn.imagesLoaded = function( options, callback ) { 2018 var instance = new ImagesLoaded( this, options, callback ); 2019 return instance.jqDeferred.promise( $(this) ); 2020 }; 2021 } 2022 2023 2024 // -------------------------- -------------------------- // 2025 2026 function LoadingImage( img ) { 2027 this.img = img; 2028 } 2029 2030 LoadingImage.prototype = new EventEmitter(); 2031 2032 LoadingImage.prototype.check = function() { 2033 // first check cached any previous images that have same src 2034 var resource = cache[ this.img.src ] || new Resource( this.img.src ); 2035 if ( resource.isConfirmed ) { 2036 this.confirm( resource.isLoaded, 'cached was confirmed' ); 2037 return; 2038 } 2039 2040 // If complete is true and browser supports natural sizes, 2041 // try to check for image status manually. 2042 if ( this.img.complete && this.img.naturalWidth !== undefined ) { 2043 // report based on naturalWidth 2044 this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); 2045 return; 2046 } 2047 2048 // If none of the checks above matched, simulate loading on detached element. 2049 var _this = this; 2050 resource.on( 'confirm', function( resrc, message ) { 2051 _this.confirm( resrc.isLoaded, message ); 2052 return true; 2053 } ); 2054 2055 resource.check(); 2056 }; 2057 2058 LoadingImage.prototype.confirm = function( isLoaded, message ) { 2059 this.isLoaded = isLoaded; 2060 this.emit( 'confirm', this, message ); 2061 }; 2062 2063 // -------------------------- Resource -------------------------- // 2064 2065 // Resource checks each src, only once 2066 // separate class from LoadingImage to prevent memory leaks. See #115 2067 2068 var cache = {}; 2069 2070 function Resource( src ) { 2071 this.src = src; 2072 // add to cache 2073 cache[ src ] = this; 2074 } 2075 2076 Resource.prototype = new EventEmitter(); 2077 2078 Resource.prototype.check = function() { 2079 // only trigger checking once 2080 if ( this.isChecked ) { 2081 return; 2082 } 2083 // simulate loading on detached element 2084 var proxyImage = new Image(); 2085 eventie.bind( proxyImage, 'load', this ); 2086 eventie.bind( proxyImage, 'error', this ); 2087 proxyImage.src = this.src; 2088 // set flag 2089 this.isChecked = true; 2090 }; 2091 2092 // ----- events ----- // 2093 2094 // trigger specified handler for event type 2095 Resource.prototype.handleEvent = function( event ) { 2096 var method = 'on' + event.type; 2097 if ( this[ method ] ) { 2098 this[ method ]( event ); 2099 } 2100 }; 2101 2102 Resource.prototype.onload = function( event ) { 2103 this.confirm( true, 'onload' ); 2104 this.unbindProxyEvents( event ); 2105 }; 2106 2107 Resource.prototype.onerror = function( event ) { 2108 this.confirm( false, 'onerror' ); 2109 this.unbindProxyEvents( event ); 2110 }; 2111 2112 // ----- confirm ----- // 2113 2114 Resource.prototype.confirm = function( isLoaded, message ) { 2115 this.isConfirmed = true; 2116 this.isLoaded = isLoaded;
vendor: 4,692 bytes, lines 2117-2237
2117 this.emit( 'confirm', this, message ); 2118 }; 2119 2120 Resource.prototype.unbindProxyEvents = function( event ) { 2121 eventie.unbind( event.target, 'load', this ); 2122 eventie.unbind( event.target, 'error', this ); 2123 }; 2124 2125 // ----- ----- // 2126 2127 return ImagesLoaded; 2128 2129} ); 2130; 2131/* 2132 * jQuery FlexSlider v2.2.2 2133 * http://www.woothemes.com/flexslider/ 2134 * 2135 * Copyright 2012 WooThemes 2136 * Free to use under the GPLv2 license. 2137 * http://www.gnu.org/licenses/gpl-2.0.html 2138 * 2139 * Contributing author: Tyler Smith (@mbmufffin) 2140 */ 2141 2142; 2143(function ($) { 2144 2145 //FlexSlider: Object Instance 2146 $.flexslider = function(el, options) { 2147 var slider = $(el); 2148 2149 // making variables public 2150 slider.vars = $.extend({}, $.flexslider.defaults, options); 2151 2152 var namespace = slider.vars.namespace, 2153 msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture, 2154 touch = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch && document instanceof DocumentTouch) && slider.vars.touch, 2155 // depricating this idea, as devices are being released with both of these events 2156 //eventType = (touch) ? "touchend" : "click", 2157 eventType = "click touchend MSPointerUp", 2158 watchedEvent = "", 2159 watchedEventClearTimer, 2160 vertical = slider.vars.direction === "vertical", 2161 reverse = slider.vars.reverse, 2162 carousel = (slider.vars.itemWidth > 0), 2163 fade = slider.vars.animation === "fade", 2164 asNav = slider.vars.asNavFor !== "", 2165 methods = {}, 2166 focused = true; 2167 2168 // Store a reference to the slider object 2169 $.data(el, "flexslider", slider); 2170 2171 // Private slider methods 2172 methods = { 2173 init: function() { 2174 slider.animating = false; 2175 // Get current slide and make sure it is a number 2176 slider.currentSlide = parseInt( ( slider.vars.startAt ? slider.vars.startAt : 0), 10 ); 2177 if ( isNaN( slider.currentSlide ) ) slider.currentSlide = 0; 2178 slider.animatingTo = slider.currentSlide; 2179 slider.atEnd = (slider.currentSlide === 0 || slider.currentSlide === slider.last); 2180 slider.containerSelector = slider.vars.selector.substr(0,slider.vars.selector.search(' ')); 2181 slider.slides = $(slider.vars.selector, slider); 2182 slider.container = $(slider.containerSelector, slider); 2183 slider.count = slider.slides.length; 2184 // SYNC: 2185 slider.syncExists = $(slider.vars.sync).length > 0; 2186 // SLIDE: 2187 if (slider.vars.animation === "slide") slider.vars.animation = "swing"; 2188 slider.prop = (vertical) ? "top" : "marginLeft"; 2189 slider.args = {}; 2190 // SLIDESHOW: 2191 slider.manualPause = false; 2192 slider.stopped = false; 2193 //PAUSE WHEN INVISIBLE 2194 slider.started = false; 2195 slider.startTimeout = null; 2196 // TOUCH/USECSS: 2197 slider.transitions = !slider.vars.video && !fade && slider.vars.useCSS && (function() { 2198 var obj = document.createElement('div'), 2199 props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']; 2200 for (var i in props) { 2201 if ( obj.style[ props[i] ] !== undefined ) { 2202 slider.pfx = props[i].replace('Perspective','').toLowerCase(); 2203 slider.prop = "-" + slider.pfx + "-transform"; 2204 return true; 2205 } 2206 } 2207 return false; 2208 }()); 2209 // CONTROLSCONTAINER: 2210 if (slider.vars.controlsContainer !== "") slider.controlsContainer = $(slider.vars.controlsContainer).length > 0 && $(slider.vars.controlsContainer); 2211 // MANUAL: 2212 if (slider.vars.manualControls !== "") slider.manualControls = $(slider.vars.manualControls).length > 0 && $(slider.vars.manualControls); 2213 2214 // RANDOMIZE: 2215 if (slider.vars.randomize) { 2216 slider.slides.sort(function() { return (Math.round(Math.random())-0.5); }); 2217 slider.container.empty().append(slider.slides); 2218 } 2219 2220 slider.doMath(); 2221 2222 // INIT 2223 slider.setup("init"); 2224 2225 // CONTROLNAV: 2226 if (slider.vars.controlNav) methods.controlNav.setup(); 2227 2228 // DIRECTIONNAV: 2229 if (slider.vars.directionNav) methods.directionNav.setup(); 2230 2231 // KEYBOARD: 2232 if (slider.vars.keyboard && ($(slider.containerSelector).length === 1 || slider.vars.multipleKeyboard)) { 2233 $(document).bind('keyup', function(event) { 2234 var keycode = event.keyCode; 2235 if (!slider.animating && (keycode === 39 || keycode === 37)) { 2236 var target = (keycode === 39) ? slider.getTarget('next') : 2237 (keycode === 37) ? slider.getTarget('prev') : false;
2238 slider.flexAnimate(target, slider.vars.pauseOnAction); 2239 } 2240 }); 2241 } 2242 // MOUSEWHEEL: 2243 if (slider.vars.mousewheel) { 2244 slider.bind('mousewheel', function(event, delta, deltaX, deltaY) { 2245 event.preventDefault(); 2246 var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev'); 2247 slider.flexAnimate(target, slider.vars.pauseOnAction); 2248 }); 2249 } 2250 2251 // PAUSEPLAY 2252 if (slider.vars.pausePlay) methods.pausePlay.setup(); 2253 2254 //PAUSE WHEN INVISIBLE 2255 if (slider.vars.slideshow && slider.vars.pauseInvisible) methods.pauseInvisible.init(); 2256 2257 // SLIDSESHOW 2258 if (slider.vars.slideshow) { 2259 if (slider.vars.pauseOnHover) { 2260 slider.hover(function() { 2261 if (!slider.manualPlay && !slider.manualPause) slider.pause(); 2262 }, function() { 2263 if (!slider.manualPause && !slider.manualPlay && !slider.stopped) slider.play(); 2264 }); 2265 } 2266 // initialize animation 2267 //If we're visible, or we don't use PageVisibility API 2268 if(!slider.vars.pauseInvisible || !methods.pauseInvisible.isHidden()) { 2269 (slider.vars.initDelay > 0) ? slider.startTimeout = setTimeout(slider.play, slider.vars.initDelay) : slider.play(); 2270 } 2271 } 2272 2273 // ASNAV: 2274 if (asNav) methods.asNav.setup(); 2275 2276 // TOUCH 2277 if (touch && slider.vars.touch) methods.touch(); 2278 2279 // FADE&&SMOOTHHEIGHT || SLIDE: 2280 if (!fade || (fade && slider.vars.smoothHeight)) $(window).bind("resize orientationchange focus", methods.resize); 2281 2282 slider.find("img").attr("draggable", "false"); 2283 2284 // API: start() Callback 2285 setTimeout(function(){ 2286 slider.vars.start(slider); 2287 }, 200); 2288 }, 2289 asNav: { 2290 setup: function() { 2291 slider.asNav = true; 2292 slider.animatingTo = Math.floor(slider.currentSlide/slider.move); 2293 slider.currentItem = slider.currentSlide; 2294 slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide"); 2295 if(!msGesture){ 2296 slider.slides.on(eventType, function(e){ 2297 e.preventDefault(); 2298 var $slide = $(this), 2299 target = $slide.index(); 2300 var posFromLeft = $slide.offset().left - $(slider).scrollLeft(); // Find position of slide relative to left of slider container 2301 if( posFromLeft <= 0 && $slide.hasClass( namespace + 'active-slide' ) ) { 2302 slider.flexAnimate(slider.getTarget("prev"), true); 2303 } else if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass(namespace + "active-slide")) { 2304 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 2305 slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true); 2306 } 2307 }); 2308 }else{ 2309 el._slider = slider; 2310 slider.slides.each(function (){ 2311 var that = this; 2312 that._gesture = new MSGesture(); 2313 that._gesture.target = that; 2314 that.addEventListener("MSPointerDown", function (e){ 2315 e.preventDefault(); 2316 if(e.currentTarget._gesture) 2317 e.currentTarget._gesture.addPointer(e.pointerId); 2318 }, false); 2319 that.addEventListener("MSGestureTap", function (e){ 2320 e.preventDefault(); 2321 var $slide = $(this), 2322 target = $slide.index(); 2323 if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass('active')) { 2324 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 2325 slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true); 2326 } 2327 }); 2328 }); 2329 } 2330 } 2331 }, 2332 controlNav: { 2333 setup: function() { 2334 if (!slider.manualControls) {
2335 methods.controlNav.setupPaging(); 2336 } else { // MANUALCONTROLS: 2337 methods.controlNav.setupManual(); 2338 } 2339 }, 2340 setupPaging: function() { 2341 var type = (slider.vars.controlNav === "thumbnails") ? 'control-thumbs' : 'control-paging', 2342 j = 1, 2343 item, 2344 slide; 2345 2346 slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>'); 2347 2348 if (slider.pagingCount > 1) { 2349 for (var i = 0; i < slider.pagingCount; i++) { 2350 slide = slider.slides.eq(i); 2351 item = (slider.vars.controlNav === "thumbnails") ? '<img src="' + slide.attr( 'data-thumb' ) + '"/>' : '<a>' + j + '</a>'; 2352 if ( 'thumbnails' === slider.vars.controlNav && true === slider.vars.thumbCaptions ) { 2353 var captn = slide.attr( 'data-thumbcaption' ); 2354 if ( '' != captn && undefined != captn ) item += '<span class="' + namespace + 'caption">' + captn + '</span>'; 2355 } 2356 slider.controlNavScaffold.append('<li>' + item + '</li>'); 2357 j++; 2358 } 2359 } 2360 2361 // CONTROLSCONTAINER: 2362 (slider.controlsContainer) ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold); 2363 methods.controlNav.set(); 2364 2365 methods.controlNav.active(); 2366 2367 slider.controlNavScaffold.delegate('a, img', eventType, function(event) { 2368 event.preventDefault(); 2369 2370 if (watchedEvent === "" || watchedEvent === event.type) { 2371 var $this = $(this), 2372 target = slider.controlNav.index($this); 2373 2374 if (!$this.hasClass(namespace + 'active')) { 2375 slider.direction = (target > slider.currentSlide) ? "next" : "prev"; 2376 slider.flexAnimate(target, slider.vars.pauseOnAction); 2377 } 2378 } 2379 2380 // setup flags to prevent event duplication 2381 if (watchedEvent === "") { 2382 watchedEvent = event.type; 2383 } 2384 methods.setToClearWatchedEvent(); 2385 2386 }); 2387 }, 2388 setupManual: function() { 2389 slider.controlNav = slider.manualControls; 2390 methods.controlNav.active(); 2391 2392 slider.controlNav.bind(eventType, function(event) { 2393 event.preventDefault(); 2394 2395 if (watchedEvent === "" || watchedEvent === event.type) { 2396 var $this = $(this), 2397 target = slider.controlNav.index($this); 2398 2399 if (!$this.hasClass(namespace + 'active')) { 2400 (target > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev"; 2401 slider.flexAnimate(target, slider.vars.pauseOnAction); 2402 } 2403 } 2404 2405 // setup flags to prevent event duplication 2406 if (watchedEvent === "") { 2407 watchedEvent = event.type; 2408 } 2409 methods.setToClearWatchedEvent(); 2410 }); 2411 }, 2412 set: function() { 2413 var selector = (slider.vars.controlNav === "thumbnails") ? 'img' : 'a'; 2414 slider.controlNav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlsContainer) ? slider.controlsContainer : slider); 2415 }, 2416 active: function() { 2417 slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active"); 2418 }, 2419 update: function(action, pos) { 2420 if (slider.pagingCount > 1 && action === "add") { 2421 slider.controlNavScaffold.append($('<li><a>' + slider.count + '</a></li>')); 2422 } else if (slider.pagingCount === 1) { 2423 slider.controlNavScaffold.find('li').remove(); 2424 } else { 2425 slider.controlNav.eq(pos).closest('li').remove(); 2426 } 2427 methods.controlNav.set(); 2428 (slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length) ? slider.update(pos, action) : methods.controlNav.active(); 2429 } 2430 }, 2431 directionNav: { 2432 setup: function() { 2433 var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li><a class="' + namespace + 'prev" href="#">
vendor: 9,047 bytes, lines 2433-2636
2433' + slider.vars.prevText + '</a></li><li><a class="' + namespace + 'next" href="#">' + slider.vars.nextText + '</a></li></ul>'); 2434 2435 // CONTROLSCONTAINER: 2436 if (slider.controlsContainer) { 2437 $(slider.controlsContainer).append(directionNavScaffold); 2438 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider.controlsContainer); 2439 } else { 2440 slider.append(directionNavScaffold); 2441 slider.directionNav = $('.' + namespace + 'direction-nav li a', slider); 2442 } 2443 2444 methods.directionNav.update(); 2445 2446 slider.directionNav.bind(eventType, function(event) { 2447 event.preventDefault(); 2448 var target; 2449 2450 if (watchedEvent === "" || watchedEvent === event.type) { 2451 target = ($(this).hasClass(namespace + 'next')) ? slider.getTarget('next') : slider.getTarget('prev'); 2452 slider.flexAnimate(target, slider.vars.pauseOnAction); 2453 } 2454 2455 // setup flags to prevent event duplication 2456 if (watchedEvent === "") { 2457 watchedEvent = event.type; 2458 } 2459 methods.setToClearWatchedEvent(); 2460 }); 2461 }, 2462 update: function() { 2463 var disabledClass = namespace + 'disabled'; 2464 if (slider.pagingCount === 1) { 2465 slider.directionNav.addClass(disabledClass).attr('tabindex', '-1'); 2466 } else if (!slider.vars.animationLoop) { 2467 if (slider.animatingTo === 0) { 2468 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "prev").addClass(disabledClass).attr('tabindex', '-1'); 2469 } else if (slider.animatingTo === slider.last) { 2470 slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "next").addClass(disabledClass).attr('tabindex', '-1'); 2471 } else { 2472 slider.directionNav.removeClass(disabledClass).removeAttr('tabindex'); 2473 } 2474 } else { 2475 slider.directionNav.removeClass(disabledClass).removeAttr('tabindex'); 2476 } 2477 } 2478 }, 2479 pausePlay: { 2480 setup: function() { 2481 var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a></a></div>'); 2482 2483 // CONTROLSCONTAINER: 2484 if (slider.controlsContainer) { 2485 slider.controlsContainer.append(pausePlayScaffold); 2486 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider.controlsContainer); 2487 } else { 2488 slider.append(pausePlayScaffold); 2489 slider.pausePlay = $('.' + namespace + 'pauseplay a', slider); 2490 } 2491 2492 methods.pausePlay.update((slider.vars.slideshow) ? namespace + 'pause' : namespace + 'play'); 2493 2494 slider.pausePlay.bind(eventType, function(event) { 2495 event.preventDefault(); 2496 2497 if (watchedEvent === "" || watchedEvent === event.type) { 2498 if ($(this).hasClass(namespace + 'pause')) { 2499 slider.manualPause = true; 2500 slider.manualPlay = false; 2501 slider.pause(); 2502 } else { 2503 slider.manualPause = false; 2504 slider.manualPlay = true; 2505 slider.play(); 2506 } 2507 } 2508 2509 // setup flags to prevent event duplication 2510 if (watchedEvent === "") { 2511 watchedEvent = event.type; 2512 } 2513 methods.setToClearWatchedEvent(); 2514 }); 2515 }, 2516 update: function(state) { 2517 (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); 2518 } 2519 }, 2520 touch: function() { 2521 var startX, 2522 startY, 2523 offset, 2524 cwidth, 2525 dx, 2526 startT, 2527 scrolling = false, 2528 localX = 0, 2529 localY = 0, 2530 accDx = 0; 2531 2532 if(!msGesture){ 2533 el.addEventListener('touchstart', onTouchStart, false); 2534 2535 function onTouchStart(e) { 2536 if (slider.animating) { 2537 e.preventDefault(); 2538 } else if ( ( window.navigator.msPointerEnabled ) || e.touches.length === 1 ) { 2539 slider.pause(); 2540 // CAROUSEL: 2541 cwidth = (vertical) ? slider.h : slider. w; 2542 startT = Number(new Date()); 2543 // CAROUSEL: 2544 2545 // Local vars for X and Y points. 2546 localX = e.touches[0].pageX; 2547 localY = e.touches[0].pageY; 2548 2549 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 : 2550 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 2551 (carousel && slider.currentSlide === slider.last) ? slider.limit : 2552 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide : 2553 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth; 2554 startX = (vertical) ? localY : localX; 2555 startY = (vertical) ? localX : localY; 2556 2557 el.addEventListener('touchmove', onTouchMove, false); 2558 el.addEventListener('touchend', onTouchEnd, false); 2559 } 2560 } 2561 2562 function onTouchMove(e) { 2563 // Local vars for X and Y points. 2564 2565 localX = e.touches[0].pageX; 2566 localY = e.touches[0].pageY; 2567 2568 dx = (vertical) ? startX - localY : startX - localX; 2569 scrolling = (vertical) ? (Math.abs(dx) < Math.abs(localX - startY)) : (Math.abs(dx) < Math.abs(localY - startY)); 2570 2571 var fxms = 500; 2572 2573 if ( ! scrolling || Number( new Date() ) - startT > fxms ) { 2574 e.preventDefault(); 2575 if (!fade && slider.transitions) { 2576 if (!slider.vars.animationLoop) { 2577 dx = dx/((slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1); 2578 } 2579 slider.setProps(offset + dx, "setTouch"); 2580 } 2581 } 2582 } 2583 2584 function onTouchEnd(e) { 2585 // finish the touch by undoing the touch session 2586 el.removeEventListener('touchmove', onTouchMove, false); 2587 2588 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) { 2589 var updateDx = (reverse) ? -dx : dx, 2590 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 2591 2592 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) { 2593 slider.flexAnimate(target, slider.vars.pauseOnAction); 2594 } else { 2595 if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true); 2596 } 2597 } 2598 el.removeEventListener('touchend', onTouchEnd, false); 2599 2600 startX = null; 2601 startY = null; 2602 dx = null; 2603 offset = null; 2604 } 2605 }else{ 2606 el.style.msTouchAction = "none"; 2607 el._gesture = new MSGesture(); 2608 el._gesture.target = el; 2609 el.addEventListener("MSPointerDown", onMSPointerDown, false); 2610 el._slider = slider; 2611 el.addEventListener("MSGestureChange", onMSGestureChange, false); 2612 el.addEventListener("MSGestureEnd", onMSGestureEnd, false); 2613 2614 function onMSPointerDown(e){ 2615 e.stopPropagation(); 2616 if (slider.animating) { 2617 e.preventDefault(); 2618 }else{ 2619 slider.pause(); 2620 el._gesture.addPointer(e.pointerId); 2621 accDx = 0; 2622 cwidth = (vertical) ? slider.h : slider. w; 2623 startT = Number(new Date()); 2624 // CAROUSEL: 2625 2626 offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 : 2627 (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 2628 (carousel && slider.currentSlide === slider.last) ? slider.limit : 2629 (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide : 2630 (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth; 2631 } 2632 } 2633 2634 function onMSGestureChange(e) { 2635 e.stopPropagation(); 2636 var slider = e.target._slider;
2637 if(!slider){ 2638 return; 2639 } 2640 var transX = -e.translationX, 2641 transY = -e.translationY; 2642 2643 //Accumulate translations. 2644 accDx = accDx + ((vertical) ? transY : transX); 2645 dx = accDx; 2646 scrolling = (vertical) ? (Math.abs(accDx) < Math.abs(-transX)) : (Math.abs(accDx) < Math.abs(-transY)); 2647 2648 if(e.detail === e.MSGESTURE_FLAG_INERTIA){ 2649 setImmediate(function (){ 2650 el._gesture.stop(); 2651 }); 2652 2653 return; 2654 } 2655 2656 if (!scrolling || Number(new Date()) - startT > 500) { 2657 e.preventDefault(); 2658 if (!fade && slider.transitions) { 2659 if (!slider.vars.animationLoop) { 2660 dx = accDx / ((slider.currentSlide === 0 && accDx < 0 || slider.currentSlide === slider.last && accDx > 0) ? (Math.abs(accDx) / cwidth + 2) : 1); 2661 } 2662 slider.setProps(offset + dx, "setTouch"); 2663 } 2664 } 2665 } 2666 2667 function onMSGestureEnd(e) { 2668 e.stopPropagation(); 2669 var slider = e.target._slider; 2670 if(!slider){ 2671 return; 2672 } 2673 if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) { 2674 var updateDx = (reverse) ? -dx : dx, 2675 target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev'); 2676 2677 if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) { 2678 slider.flexAnimate(target, slider.vars.pauseOnAction); 2679 } else { 2680 if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true); 2681 } 2682 } 2683 2684 startX = null; 2685 startY = null; 2686 dx = null; 2687 offset = null; 2688 accDx = 0; 2689 } 2690 } 2691 }, 2692 resize: function() { 2693 if (!slider.animating && slider.is(':visible')) { 2694 if (!carousel) slider.doMath(); 2695 2696 if (fade) { 2697 // SMOOTH HEIGHT: 2698 methods.smoothHeight(); 2699 } else if (carousel) { //CAROUSEL: 2700 slider.slides.width(slider.computedW); 2701 slider.update(slider.pagingCount); 2702 slider.setProps(); 2703 } 2704 else if (vertical) { //VERTICAL: 2705 slider.viewport.height(slider.h); 2706 slider.setProps(slider.h, "setTotal"); 2707 } else { 2708 // SMOOTH HEIGHT: 2709 if (slider.vars.smoothHeight) methods.smoothHeight(); 2710 slider.newSlides.width(slider.computedW); 2711 slider.setProps(slider.computedW, "setTotal"); 2712 } 2713 } 2714 }, 2715 smoothHeight: function(dur) { 2716 if (!vertical || fade) { 2717 var $obj = (fade) ? slider : slider.viewport; 2718 (dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingTo).height()}, dur) : $obj.height(slider.slides.eq(slider.animatingTo).height()); 2719 } 2720 }, 2721 sync: function(action) { 2722 var $obj = $(slider.vars.sync).data("flexslider"), 2723 target = slider.animatingTo; 2724 2725 switch (action) { 2726 case "animate": $obj.flexAnimate(target, slider.vars.pauseOnAction, false, true); break; 2727 case "play": if (!$obj.playing && !$obj.asNav) { $obj.play(); } break; 2728 case "pause": $obj.pause(); break; 2729 } 2730 }, 2731 uniqueID: function($clone) { 2732 $clone.find( '[id]' ).each(function() { 2733 var $this = $(this); 2734 $this.attr( 'id', $this.attr( 'id' ) + '_clone' ); 2735 }); 2736 return $clone; 2737 }, 2738 pauseInvisible: { 2739 visProp: null, 2740 init: function() { 2741 var prefixes = ['webkit','moz','ms','o']; 2742 2743 if ('hidden' in document) return 'hidden'; 2744 for (var i = 0; i < prefixes.length; i++) { 2745 if ((prefixes[i] + 'Hidden') in document) 2746 methods.pauseInvisible.visProp = prefixes[i] + 'Hidden'; 2747 } 2748 if (methods.pauseInvisible.visProp) { 2749 var evtname = methods.pauseInvisible.visProp.replace(/[H|h]idden/,'') + 'visibilitychange'; 2750 document.addEventListener(evtname, function() { 2751 if (methods.pauseInvisible.isHidden()) { 2752 if(slider.startTimeout) clearTimeout(slider.startTimeout); //If clock is ticking, stop timer and prevent from starting while invisible 2753 else slider.pause(); //Or just pause 2754 } 2755 else { 2756 if(slider.started) slider.play(); //Initiated before, just play 2757 else (slider.vars.initDelay > 0) ? setTimeout(slider.play, slider.vars.initDelay) : slider.play(); //Didn't init before: simply init or wait for it 2758 } 2759 }); 2760 } 2761 }, 2762 isHidden: function() { 2763 return document[methods.pauseInvisible.visProp] || false; 2764 } 2765 }, 2766 setToClearWatchedEvent: function() { 2767 clearTimeout(watchedEventClearTimer); 2768 watchedEventClearTimer = setTimeout(function() { 2769 watchedEvent = ""; 2770 }, 3000); 2771 } 2772 }; 2773 2774 // public methods 2775 slider.flexAnimate = function(target, pause, override, withSync, fromNav) { 2776 if (!slider.vars.animationLoop && target !== slider.currentSlide) { 2777 slider.direction = (target > slider.currentSlide) ? "next" : "prev"; 2778 } 2779 2780 if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev"; 2781
2782 if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) { 2783 if (asNav && withSync) { 2784 var master = $(slider.vars.asNavFor).data('flexslider'); 2785 slider.atEnd = target === 0 || target === slider.count - 1; 2786 master.flexAnimate(target, true, false, true, fromNav); 2787 slider.direction = (slider.currentItem < target) ? "next" : "prev"; 2788 master.direction = slider.direction; 2789 2790 if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) { 2791 slider.currentItem = target; 2792 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide"); 2793 target = Math.floor(target/slider.visible); 2794 } else { 2795 slider.currentItem = target; 2796 slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide"); 2797 return false; 2798 } 2799 } 2800 2801 slider.animating = true; 2802 slider.animatingTo = target; 2803 2804 // SLIDESHOW: 2805 if (pause) slider.pause(); 2806 2807 // API: before() animation Callback 2808 slider.vars.before(slider); 2809 2810 // SYNC: 2811 if (slider.syncExists && !fromNav) methods.sync("animate"); 2812 2813 // CONTROLNAV 2814 if (slider.vars.controlNav) methods.controlNav.active(); 2815 2816 // !CAROUSEL: 2817 // CANDIDATE: slide active class (for add/remove slide) 2818 if (!carousel) slider.slides.removeClass(namespace + 'active-slide').eq(target).addClass(namespace + 'active-slide'); 2819 2820 // INFINITE LOOP: 2821 // CANDIDATE: atEnd 2822 slider.atEnd = target === 0 || target === slider.last; 2823 2824 // DIRECTIONNAV: 2825 if (slider.vars.directionNav) methods.directionNav.update(); 2826 2827 if (target === slider.last) { 2828 // API: end() of cycle Callback 2829 slider.vars.end(slider); 2830 // SLIDESHOW && !INFINITE LOOP: 2831 if (!slider.vars.animationLoop) slider.pause(); 2832 } 2833 2834 // SLIDE: 2835 if (!fade) { 2836 var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW, 2837 margin, slideString, calcNext; 2838 2839 // INFINITE LOOP / REVERSE: 2840 if (carousel) { 2841 //margin = (slider.vars.itemWidth > slider.w) ? slider.vars.itemMargin * 2 : slider.vars.itemMargin; 2842 margin = slider.vars.itemMargin; 2843 calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo; 2844 slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext; 2845 } else if (slider.currentSlide === 0 && target === slider.count - 1 && slider.vars.animationLoop && slider.direction !== "next") { 2846 slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0; 2847 } else if (slider.currentSlide === slider.last && target === 0 && slider.vars.animationLoop && slider.direction !== "prev") { 2848 slideString = (reverse) ? 0 : (slider.count + 1) * dimension; 2849 } else { 2850 slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension; 2851 } 2852 slider.setProps(slideString, "", slider.vars.animationSpeed); 2853 if (slider.transitions) { 2854 if (!slider.vars.animationLoop || !slider.atEnd) { 2855 slider.animating = false; 2856 slider.currentSlide = slider.animatingTo; 2857 } 2858 slider.container.unbind("webkitTransitionEnd transitionend"); 2859 slider.container.bind("webkitTransitionEnd transitionend", function() { 2860 slider.wrapup(dimension); 2861 }); 2862 } else { 2863 slider.container.animate(slider.args, slider.vars.animationSpeed, slider.vars.easing, function(){ 2864 slider.wrapup(dimension); 2865 }); 2866 } 2867 } else { // FADE: 2868 if (!touch) { 2869 //slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationSpeed, slider.vars.easing); 2870 //slider.slides.eq(target).fadeIn(slider.vars.animationSpeed, slider.vars.easing, slider.wrapup); 2871 2872 slider.slides.eq(slider.currentSlide).css({"zIndex": 1}).animate({"opacity": 0}, slider.vars.animationSpeed, slider.vars.easing); 2873 slider.slides.eq(target).css({"zIndex": 2}).animate({"opacity": 1}, slider.vars.animationSpeed, slider.vars.easing, slider.wrapup); 2874 2875 } else { 2876 slider.slides.eq(slider.currentSlide).css({ "opacity": 0, "zIndex": 1 }); 2877 slider.slides.eq(target).css({ "opacity": 1, "zIndex": 2 }); 2878 slider.wrapup(dimension); 2879 } 2880 } 2881 // SMOOTH HEIGHT: 2882 if (slider.vars.smoothHeight) methods.smoothHeight(slider.vars.animationSpeed); 2883 } 2884 }; 2885 slider.wrapup = function(dimension) { 2886 // SLIDE: 2887 if (!fade && !carousel) { 2888 if (slider.currentSlide === 0 && slider.animatingTo === slider.last && slider.vars.animationLoop) { 2889 slider.setProps(dimension, "jumpEnd"); 2890 } else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && slider.vars.animationLoop) { 2891 slider.setProps(dimension, "jumpStart"); 2892 } 2893 } 2894 slider.animating = false;
2895 slider.currentSlide = slider.animatingTo; 2896 // API: after() animation Callback 2897 slider.vars.after(slider); 2898 }; 2899 2900 // SLIDESHOW: 2901 slider.animateSlides = function() { 2902 if (!slider.animating && focused ) slider.flexAnimate(slider.getTarget("next")); 2903 }; 2904 // SLIDESHOW: 2905 slider.pause = function() { 2906 clearInterval(slider.animatedSlides); 2907 slider.animatedSlides = null; 2908 slider.playing = false; 2909 // PAUSEPLAY: 2910 if (slider.vars.pausePlay) methods.pausePlay.update("play"); 2911 // SYNC: 2912 if (slider.syncExists) methods.sync("pause"); 2913 }; 2914 // SLIDESHOW: 2915 slider.play = function() { 2916 if (slider.playing) clearInterval(slider.animatedSlides); 2917 slider.animatedSlides = slider.animatedSlides || setInterval(slider.animateSlides, slider.vars.slideshowSpeed); 2918 slider.started = slider.playing = true; 2919 // PAUSEPLAY: 2920 if (slider.vars.pausePlay) methods.pausePlay.update("pause"); 2921 // SYNC: 2922 if (slider.syncExists) methods.sync("play"); 2923 }; 2924 // STOP: 2925 slider.stop = function () { 2926 slider.pause(); 2927 slider.stopped = true; 2928 }; 2929 slider.canAdvance = function(target, fromNav) { 2930 // ASNAV: 2931 var last = (asNav) ? slider.pagingCount - 1 : slider.last; 2932 return (fromNav) ? true : 2933 (asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true : 2934 (asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next") ? false : 2935 (target === slider.currentSlide && !asNav) ? false : 2936 (slider.vars.animationLoop) ? true : 2937 (slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next") ? false : 2938 (slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next") ? false : 2939 true; 2940 }; 2941 slider.getTarget = function(dir) { 2942 slider.direction = dir; 2943 if (dir === "next") { 2944 return (slider.currentSlide === slider.last) ? 0 : slider.currentSlide + 1; 2945 } else { 2946 return (slider.currentSlide === 0) ? slider.last : slider.currentSlide - 1; 2947 } 2948 }; 2949 2950 // SLIDE: 2951 slider.setProps = function(pos, special, dur) { 2952 var target = (function() { 2953 var posCheck = (pos) ? pos : ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo, 2954 posCalc = (function() { 2955 if (carousel) { 2956 return (special === "setTouch") ? pos : 2957 (reverse && slider.animatingTo === slider.last) ? 0 : 2958 (reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) : 2959 (slider.animatingTo === slider.last) ? slider.limit : posCheck; 2960 } else { 2961 switch (special) { 2962 case "setTotal": return (reverse) ? ((slider.count - 1) - slider.currentSlide + slider.cloneOffset) * pos : (slider.currentSlide + slider.cloneOffset) * pos; 2963 case "setTouch": return (reverse) ? pos : pos; 2964 case "jumpEnd": return (reverse) ? pos : slider.count * pos; 2965 case "jumpStart": return (reverse) ? slider.count * pos : pos; 2966 default: return pos; 2967 } 2968 } 2969 }()); 2970 2971 return (posCalc * -1) + "px"; 2972 }()); 2973 2974 if (slider.transitions) { 2975 target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)"; 2976 dur = (dur !== undefined) ? (dur/1000) + "s" : "0s"; 2977 slider.container.css("-" + slider.pfx + "-transition-duration", dur); 2978 slider.container.css("transition-duration", dur); 2979 } 2980 2981 slider.args[slider.prop] = target; 2982 if (slider.transitions || dur === undefined) slider.container.css(slider.args); 2983 2984 slider.container.css('transform',target); 2985 }; 2986 2987 slider.setup = function(type) { 2988 // SLIDE: 2989 if (!fade) { 2990 var sliderOffset, arr; 2991 2992 if (type === "init") {
2993 slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({"overflow": "hidden", "position": "relative"}).appendTo(slider).append(slider.container); 2994 // INFINITE LOOP: 2995 slider.cloneCount = 0; 2996 slider.cloneOffset = 0; 2997 // REVERSE: 2998 if (reverse) { 2999 arr = $.makeArray(slider.slides).reverse(); 3000 slider.slides = $(arr); 3001 slider.container.empty().append(slider.slides); 3002 } 3003 } 3004 // INFINITE LOOP && !CAROUSEL: 3005 if (slider.vars.animationLoop && !carousel) { 3006 slider.cloneCount = 2; 3007 slider.cloneOffset = 1; 3008 // clear out old clones 3009 if (type !== "init") slider.container.find('.clone').remove(); 3010 slider.container.append(slider.slides.first().clone().addClass('clone').attr('aria-hidden', 'true')).prepend(slider.slides.last().clone().addClass('clone').attr('aria-hidden', 'true')); 3011 methods.uniqueID( slider.slides.first().clone().addClass('clone') ).appendTo( slider.container ); 3012 methods.uniqueID( slider.slides.last().clone().addClass('clone') ).prependTo( slider.container ); 3013 } 3014 slider.newSlides = $(slider.vars.selector, slider); 3015 3016 sliderOffset = (reverse) ? slider.count - 1 - slider.currentSlide + slider.cloneOffset : slider.currentSlide + slider.cloneOffset; 3017 // VERTICAL: 3018 if (vertical && !carousel) { 3019 slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%"); 3020 setTimeout(function(){ 3021 slider.newSlides.css({"display": "block"}); 3022 slider.doMath(); 3023 slider.viewport.height(slider.h); 3024 slider.setProps(sliderOffset * slider.h, "init"); 3025 }, (type === "init") ? 100 : 0); 3026 } else { 3027 slider.container.width((slider.count + slider.cloneCount) * 200 + "%"); 3028 slider.setProps(sliderOffset * slider.computedW, "init"); 3029 setTimeout(function(){ 3030 slider.doMath(); 3031 slider.newSlides.css({"width": slider.computedW, "float": "left", "display": "block"}); 3032 // SMOOTH HEIGHT: 3033 if (slider.vars.smoothHeight) methods.smoothHeight(); 3034 }, (type === "init") ? 100 : 0); 3035 } 3036 } else { // FADE: 3037 slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%", "position": "relative"}); 3038 if (type === "init") { 3039 if (!touch) { 3040 //slider.slides.eq(slider.currentSlide).fadeIn(slider.vars.animationSpeed, slider.vars.easing); 3041 slider.slides.css({ "opacity": 0, "display": "block", "zIndex": 1 }).eq(slider.currentSlide).css({"zIndex": 2}).animate({"opacity": 1},slider.vars.animationSpeed,slider.vars.easing); 3042 } else { 3043 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}); 3044 } 3045 } 3046 // SMOOTH HEIGHT: 3047 if (slider.vars.smoothHeight) methods.smoothHeight(); 3048 } 3049 // !CAROUSEL: 3050 // CANDIDATE: active slide 3051 if (!carousel) slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide"); 3052 3053 //FlexSlider: init() Callback 3054 slider.vars.init(slider); 3055 }; 3056 3057 slider.doMath = function() { 3058 var slide = slider.slides.first(), 3059 slideMargin = slider.vars.itemMargin, 3060 minItems = slider.vars.minItems, 3061 maxItems = slider.vars.maxItems; 3062 3063 slider.w = (slider.viewport===undefined) ? slider.width() : slider.viewport.width(); 3064 slider.h = slide.height(); 3065 slider.boxPadding = slide.outerWidth() - slide.width(); 3066 3067 // CAROUSEL: 3068 if (carousel) { 3069 slider.itemT = slider.vars.itemWidth + slideMargin; 3070 slider.minW = (minItems) ? minItems * slider.itemT : slider.w; 3071 slider.maxW = (maxItems) ? (maxItems * slider.itemT) - slideMargin : slider.w; 3072 slider.itemW = (slider.minW > slider.w) ? (slider.w - (slideMargin * (minItems - 1)))/minItems : 3073 (slider.maxW < slider.w) ? (slider.w - (slideMargin * (maxItems - 1)))/maxItems : 3074 (slider.vars.itemWidth > slider.w) ? slider.w : slider.vars.itemWidth; 3075 3076 slider.visible = Math.floor(slider.w/(slider.itemW)); 3077 slider.move = (slider.vars.move > 0 && slider.vars.move < slider.visible ) ? slider.vars.move : slider.visible;
vendor: 5,363 bytes, lines 3078-3201
3078 slider.pagingCount = Math.ceil(((slider.count - slider.visible)/slider.move) + 1); 3079 slider.last = slider.pagingCount - 1; 3080 slider.limit = (slider.pagingCount === 1) ? 0 : 3081 (slider.vars.itemWidth > slider.w) ? (slider.itemW * (slider.count - 1)) + (slideMargin * (slider.count - 1)) : ((slider.itemW + slideMargin) * slider.count) - slider.w - slideMargin; 3082 } else { 3083 slider.itemW = slider.w; 3084 slider.pagingCount = slider.count; 3085 slider.last = slider.count - 1; 3086 } 3087 slider.computedW = slider.itemW - slider.boxPadding; 3088 }; 3089 3090 slider.update = function(pos, action) { 3091 slider.doMath(); 3092 3093 // update currentSlide and slider.animatingTo if necessary 3094 if (!carousel) { 3095 if (pos < slider.currentSlide) { 3096 slider.currentSlide += 1; 3097 } else if (pos <= slider.currentSlide && pos !== 0) { 3098 slider.currentSlide -= 1; 3099 } 3100 slider.animatingTo = slider.currentSlide; 3101 } 3102 3103 // update controlNav 3104 if (slider.vars.controlNav && !slider.manualControls) { 3105 if ((action === "add" && !carousel) || slider.pagingCount > slider.controlNav.length) { 3106 methods.controlNav.update("add"); 3107 } else if ((action === "remove" && !carousel) || slider.pagingCount < slider.controlNav.length) { 3108 if (carousel && slider.currentSlide > slider.last) { 3109 slider.currentSlide -= 1; 3110 slider.animatingTo -= 1; 3111 } 3112 methods.controlNav.update("remove", slider.last); 3113 } 3114 } 3115 // update directionNav 3116 if (slider.vars.directionNav) methods.directionNav.update(); 3117 3118 }; 3119 3120 slider.addSlide = function(obj, pos) { 3121 var $obj = $(obj); 3122 3123 slider.count += 1; 3124 slider.last = slider.count - 1; 3125 3126 // append new slide 3127 if (vertical && reverse) { 3128 (pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj); 3129 } else { 3130 (pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj); 3131 } 3132 3133 // update currentSlide, animatingTo, controlNav, and directionNav 3134 slider.update(pos, "add"); 3135 3136 // update slider.slides 3137 slider.slides = $(slider.vars.selector + ':not(.clone)', slider); 3138 // re-setup the slider to accomdate new slide 3139 slider.setup(); 3140 3141 //FlexSlider: added() Callback 3142 slider.vars.added(slider); 3143 }; 3144 slider.removeSlide = function(obj) { 3145 var pos = (isNaN(obj)) ? slider.slides.index($(obj)) : obj; 3146 3147 // update count 3148 slider.count -= 1; 3149 slider.last = slider.count - 1; 3150 3151 // remove slide 3152 if (isNaN(obj)) { 3153 $(obj, slider.slides).remove(); 3154 } else { 3155 (vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove(); 3156 } 3157 3158 // update currentSlide, animatingTo, controlNav, and directionNav 3159 slider.doMath(); 3160 slider.update(pos, "remove"); 3161 3162 // update slider.slides 3163 slider.slides = $(slider.vars.selector + ':not(.clone)', slider); 3164 // re-setup the slider to accomdate new slide 3165 slider.setup(); 3166 3167 // FlexSlider: removed() Callback 3168 slider.vars.removed(slider); 3169 }; 3170 3171 //FlexSlider: Initialize 3172 methods.init(); 3173 }; 3174 3175 // Ensure the slider isn't focussed if the window loses focus. 3176 $( window ).blur( function ( e ) { 3177 focused = false; 3178 }).focus( function ( e ) { 3179 focused = true; 3180 }); 3181 3182 //FlexSlider: Default Settings 3183 $.flexslider.defaults = { 3184 namespace: "flex-", //{NEW} String: Prefix string attached to the class of every element generated by the plugin 3185 selector: ".slides > li", //{NEW} Selector: Must match a simple pattern. '{container} > {slide}' -- Ignore pattern at your own peril 3186 animation: "fade", //String: Select your animation type, "fade" or "slide" 3187 easing: "swing", //{NEW} String: Determines the easing method used in jQuery transitions. jQuery easing plugin is supported! 3188 direction: "horizontal", //String: Select the sliding direction, "horizontal" or "vertical" 3189 reverse: false, //{NEW} Boolean: Reverse the animation direction 3190 animationLoop: true, //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end 3191 smoothHeight: false, //{NEW} Boolean: Allow height of the slider to animate smoothly in horizontal mode 3192 startAt: 0, //Integer: The slide that the slider should start on. Array notation (0 = first slide) 3193 slideshow: true, //Boolean: Animate slider automatically 3194 slideshowSpeed: 7000, //Integer: Set the speed of the slideshow cycling, in milliseconds 3195 animationSpeed: 600, //Integer: Set the speed of animations, in milliseconds 3196 initDelay: 0, //{NEW} Integer: Set an initialization delay, in milliseconds 3197 randomize: false, //Boolean: Randomize slide order 3198 thumbCaptions: false, //Boolean: Whether or not to put captions on thumbnails when using the "thumbnails" controlNav. 3199 3200 // Usability features 3201 pauseOnAction: true, //Boolean: Pause the slideshow when interacting with control elements, highly recommended.
3202 pauseOnHover: false, //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering 3203 pauseInvisible: true, //{NEW} Boolean: Pause the slideshow when tab is invisible, resume when visible. Provides better UX, lower CPU usage. 3204 useCSS: true, //{NEW} Boolean: Slider will use CSS3 transitions if available 3205 touch: true, //{NEW} Boolean: Allow touch swipe navigation of the slider on touch-enabled devices 3206 video: false, //{NEW} Boolean: If using video in the slider, will prevent CSS3 3D Transforms to avoid graphical glitches 3207 3208 // Primary Controls 3209 controlNav: true, //Boolean: Create navigation for paging control of each clide? Note: Leave true for manualControls usage 3210 directionNav: true, //Boolean: Create navigation for previous/next navigation? (true/false) 3211 prevText: "Previous", //String: Set the text for the "previous" directionNav item 3212 nextText: "Next", //String: Set the text for the "next" directionNav item 3213 3214 // Secondary Navigation 3215 keyboard: true, //Boolean: Allow slider navigating via keyboard left/right keys 3216 multipleKeyboard: false, //{NEW} Boolean: Allow keyboard navigation to affect multiple sliders. Default behavior cuts out keyboard navigation with more than one slider present. 3217 mousewheel: false, //{UPDATED} Boolean: Requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - Allows slider navigating via mousewheel 3218 pausePlay: false, //Boolean: Create pause/play dynamic element 3219 pauseText: "Pause", //String: Set the text for the "pause" pausePlay item 3220 playText: "Play", //String: Set the text for the "play" pausePlay item 3221 3222 // Special properties 3223 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. 3224 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. 3225 sync: "", //{NEW} Selector: Mirror the actions performed on this slider with another slider. Use with care. 3226 asNavFor: "", //{NEW} Selector: Internal property exposed for turning the slider into a thumbnail navigation for another slider 3227 3228 // Carousel Options 3229 itemWidth: 0, //{NEW} Integer: Box-model width of individual carousel items, including horizontal borders and padding. 3230 itemMargin: 0, //{NEW} Integer: Margin between carousel items. 3231 minItems: 1, //{NEW} Integer: Minimum number of carousel items that should be visible. Items will resize fluidly when below this. 3232 maxItems: 0, //{NEW} Integer: Maxmimum number of carousel items that should be visible. Items will resize fluidly when above this limit. 3233 move: 0, //{NEW} Integer: Number of carousel items that should move on animation. If 0, slider will move all visible items. 3234 allowOneSlide: true, //{NEW} Boolean: Whether or not to allow a slider comprised of a single slide 3235 3236 // Callback API 3237 start: function(){}, //Callback: function(slider) - Fires when the slider loads the first slide 3238 before: function(){}, //Callback: function(slider) - Fires asynchronously with each slider animation 3239 after: function(){}, //Callback: function(slider) - Fires after each slider animation completes 3240 end: function(){}, //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous) 3241 added: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is added 3242 removed: function(){}, //{NEW} Callback: function(slider) - Fires after a slide is removed 3243 init: function() {} //{NEW}
3243 Callback: function(slider) - Fires after the slider is initially setup 3244 }; 3245 3246 //FlexSlider: Plugin Function 3247 $.fn.flexslider = function(options) { 3248 if (options === undefined) options = {}; 3249 3250 if (typeof options === "object") { 3251 return this.each(function() { 3252 var $this = $(this), 3253 selector = (options.selector) ? options.selector : ".slides > li", 3254 $slides = $this.find(selector); 3255 3256 if ( ( $slides.length === 1 && options.allowOneSlide === true ) || $slides.length === 0 ) { 3257 $slides.fadeIn(400); 3258 if (options.start) options.start($this); 3259 } else if ($this.data('flexslider') === undefined) { 3260 new $.flexslider(this, options); 3261 } 3262 }); 3263 } else { 3264 // Helper strings to quickly perform functions on the slider 3265 var $slider = $(this).data('flexslider'); 3266 switch (options) { 3267 case "play": $slider.play(); break; 3268 case "pause": $slider.pause(); break; 3269 case "stop": $slider.stop(); break; 3270 case "next": $slider.flexAnimate($slider.getTarget("next"), true); break; 3271 case "prev": 3272 case "previous": $slider.flexAnimate($slider.getTarget("prev"), true); break; 3273 default: if (typeof options === "number") $slider.flexAnimate(options, true); 3274 } 3275 } 3276 }; 3277})(jQuery); 3278; 3279/*! This file is auto-generated */ 3280/*! 3281 * imagesLoaded PACKAGED v5.0.0 3282 * JavaScript is all like "You images are done yet or what?" 3283 * MIT License 3284 */ 3285!function(t,e){"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,(function(){function t(){}let e=t.prototype;return e.on=function(t,e){if(!t||!e)return this;let i=this._events=this._events||{},s=i[t]=i[t]||[];return s.includes(e)||s.push(e),this},e.once=function(t,e){if(!t||!e)return this;this.on(t,e);let i=this._onceEvents=this._onceEvents||{};return(i[t]=i[t]||{})[e]=!0,this},e.off=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;let s=i.indexOf(e);return-1!=s&&i.splice(s,1),this},e.emitEvent=function(t,e){let i=this._events&&this._events[t];if(!i||!i.length)return this;i=i.slice(0),e=e||[];let s=this._onceEvents&&this._onceEvents[t];for(let n of i){s&&s[n]&&(this.off(t,n),delete s[n]),n.apply(this,e)}return this},e.allOff=function(){return delete this._events,delete this._onceEvents,this},t})), 3286/*! 3287 * imagesLoaded v5.0.0 3288 * JavaScript is all like "You images are done yet or what?" 3289 * MIT License 3290 */ 3291function(t,e){"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}("undefined"!=typeof window?window:this,(function(t,e){let i=t.jQuery,s=t.console;
vendor: 4,185 bytes, lines 3291-3292
3291function n(t,e,o){if(!(this instanceof n))return new n(t,e,o);let r=t;var h;("string"==typeof t&&(r=document.querySelectorAll(t)),r)?(this.elements=(h=r,Array.isArray(h)?h:"object"==typeof h&&"number"==typeof h.length?[...h]:[h]),this.options={},"function"==typeof e?o=e:Object.assign(this.options,e),o&&this.on("always",o),this.getImages(),i&&(this.jqDeferred=new i.Deferred),setTimeout(this.check.bind(this))):s.error(`Bad element for imagesLoaded ${r||t}`)}n.prototype=Object.create(e.prototype),n.prototype.getImages=function(){this.images=[],this.elements.forEach(this.addElementImages,this)};const o=[1,9,11];n.prototype.addElementImages=function(t){"IMG"===t.nodeName&&this.addImage(t),!0===this.options.background&&this.addElementBackgroundImages(t);let{nodeType:e}=t;if(!e||!o.includes(e))return;let i=t.querySelectorAll("img");for(let t of i)this.addImage(t);if("string"==typeof this.options.background){let e=t.querySelectorAll(this.options.background);for(let t of e)this.addElementBackgroundImages(t)}};const r=/url\((['"])?(.*?)\1\)/gi;function h(t){this.img=t}function d(t,e){this.url=t,this.element=e,this.img=new Image}return n.prototype.addElementBackgroundImages=function(t){let e=getComputedStyle(t);if(!e)return;let i=r.exec(e.backgroundImage);for(;null!==i;){let s=i&&i[2];s&&this.addBackground(s,t),i=r.exec(e.backgroundImage)}},n.prototype.addImage=function(t){let e=new h(t);this.images.push(e)},n.prototype.addBackground=function(t,e){let i=new d(t,e);this.images.push(i)},n.prototype.check=function(){if(this.progressedCount=0,this.hasAnyBroken=!1,!this.images.length)return void this.complete();let t=(t,e,i)=>{setTimeout((()=>{this.progress(t,e,i)}))};this.images.forEach((function(e){e.once("progress",t),e.check()}))},n.prototype.progress=function(t,e,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!t.isLoaded,this.emitEvent("progress",[this,t,e]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,t),this.progressedCount===this.images.length&&this.complete(),this.options.debug&&s&&s.log(`progress: ${i}`,t,e)},n.prototype.complete=function(){let t=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(t,[this]),this.emitEvent("always",[this]),this.jqDeferred){let t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},h.prototype=Object.create(e.prototype),h.prototype.check=function(){this.getIsImageComplete()?this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.img.crossOrigin&&(this.proxyImage.crossOrigin=this.img.crossOrigin),this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.proxyImage.src=this.img.currentSrc||this.img.src)},h.prototype.getIsImageComplete=function(){return this.img.complete&&this.img.naturalWidth},h.prototype.confirm=function(t,e){this.isLoaded=t;let{parentNode:i}=this.img,s="PICTURE"===i.nodeName?i:this.img;this.emitEvent("progress",[this,s,e])},h.prototype.handleEvent=function(t){let e="on"+t.type;this[e]&&this[e](t)},h.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},h.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},h.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype=Object.create(h.prototype),d.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url,this.getIsImageComplete()&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},d.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},d.prototype.confirm=function(t,e){this.isLoaded=t,this.emitEvent("progress",[this,this.element,e])},n.makeJQueryPlugin=function(e){(e=e||t.jQuery)&&(i=e,i.fn.imagesLoaded=function(t,e){return new n(this,t,e).jqDeferred.promise(i(this))})},n.makeJQueryPlugin(),n}));; 3292/*! This file is auto-generated */
vendor: 24,103 bytes, lines 3293-3301
3293/*! 3294 * Masonry PACKAGED v4.2.2 3295 * Cascading grid layout library 3296 * https://masonry.desandro.com 3297 * MIT License 3298 * by David DeSandro 3299 */ 3300 3301!function(t,e){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,r,a){function h(t,e,n){var o,r="$()."+i+'("'+e+'")';return t.each(function(t,h){var u=a.data(h,i);if(!u)return void s(i+" not initialized. Cannot call methods, i.e. "+r);var d=u[e];if(!d||"_"==e.charAt(0))return void s(r+" is not a valid method");var l=d.apply(u,n);o=void 0===o?l:o}),void 0!==o?o:t}function u(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new r(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(r.prototype.option||(r.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return h(this,t,e)}return u(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,r=t.console,s="undefined"==typeof r?function(){}:function(t){r.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){i=i.slice(0),e=e||[];for(var n=this._onceEvents&&this._onceEvents[t],o=0;o<i.length;o++){var r=i[o],s=n&&n[r];s&&(this.off(t,r),delete n[r]),r.apply(this,e)}return this}},e.allOff=function(){delete this._events,delete this._onceEvents},t}),function(t,e){"function"==typeof define&&define.amd?define("get-size/get-size",e):"object"==typeof module&&module.exports?module.exports=e():t.getSize=e()}(window,function(){"use strict";function t(t){var e=parseFloat(t),i=-1==t.indexOf("%")&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;u>e;e++){var i=h[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See https://bit.ly/getsizebug1"),e}function o(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);s=200==Math.round(t(o.width)),r.isBoxSizeOuter=s,i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==r.boxSizing,l=0;u>l;l++){var c=h[l],f=r[c],m=parseFloat(f);a[c]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,g=a.paddingTop+a.paddingBottom,y=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,z=a.borderTopWidth+a.borderBottomWidth,E=d&&s,b=t(r.width);b!==!1&&(a.width=b+(E?0:p+_));var x=t(r.height);return x!==!1&&(a.height=x+(E?0:g+z)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(g+z),a.outerWidth=a.width+y,a.outerHeight=a.height+v,a}}var s,a="undefined"==typeof console?e:function(t){console.error(t)},h=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=h.length,d=!1;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function(){"use strict";var t=function(){var t=window.Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;i<e.length;i++){var n=e[i],o=n+"MatchesSelector";if(t[o])return o}}();return function(e,i){return e[t](i)}}),function(t,e){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["desandro-matches-selector/matches-selector"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("desandro-matches-selector")):t.fizzyUIUtils=e(t,t.matchesSelector)}(window,function(t,e){var i={};i.extend=function(t,e){for(var i in e)t[i]=e[i];return t},i.modulo=function(t,e){return(t%e+e)%e};var n=Array.prototype.slice;i.makeArray=function(t){if(Array.isArray(t))return t;if(null===t||void 0===t)return[];var e="object"==typeof t&&"number"==typeof t.length;return e?n.call(t):[t]},i.removeFrom=function(t,e){var i=t.indexOf(e);-1!=i&&t.splice(i,1)},i.getParent=function(t,i){for(;t.parentNode&&t!=document.body;)if(t=t.parentNode,e(t,i))return t},i.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},i.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},i.filterFindElements=function(t,n){t=i.makeArray(t);var o=[];return t.forEach(function(t){if(t instanceof HTMLElement){if(!n)return void o.push(t);e(t,n)&&o.push(t);for(var i=t.querySelectorAll(n),r=0;r<i.length;r++)o.push(i[r])}}),o},i.debounceMethod=function(t,e,i){i=i||100;var n=t.prototype[e],o=e+"Timeout";t.prototype[e]=function(){var t=this[o];clearTimeout(t);var e=arguments,r=this;this[o]=setTimeout(function(){n.apply(r,e),delete r[o]},i)}},i.docReady=function(t){var e=document.readyState;"complete"==e||"interactive"==e?setTimeout(t):document.addEventListener("DOMContentLoaded",t)},i.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var o=t.console;return i.htmlInit=function(e,n){i.docReady(function(){var r=i.toDashed(n),s="data-"+r,a=document.querySelectorAll("["+s+"]"),h=document.querySelectorAll(".js-"+r),u=i.makeArray(a).concat(i.makeArray(h)),d=s+"-options",l=t.jQuery;u.forEach(function(t){var i,r=t.getAttribute(s)||t.getAttribute(d);try{i=r&&JSON.parse(r)}catch(a){return void(o&&o.error("Error parsing "+s+" on "+t.className+": "+a))}var h=new e(t,i);l&&l.data(t,n,h)})})},i}),function(t,e){"function"==typeof define&&define.amd?define("outlayer/item",["ev-emitter/ev-emitter","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("ev-emitter"),require("get-size")):(t.Outlayer={},t.Outlayer.Item=e(t.EvEmitter,t.getSize))}(window,function(t,e){"use strict";function i(t){for(var e in t)return!1;return e=null,!0}function n(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}var r=document.documentElement.style,s="string"==typeof r.transition?"transition":"WebkitTransition",a="string"==typeof r.transform?"transform":"WebkitTransform",h={WebkitTransition:"webkitTransitionEnd",transition:"transitionend"}[s],u={transform:a,transition:s,transitionDuration:s+"Duration",transitionProperty:s+"Property",transitionDelay:s+"Delay"},d=n.prototype=Object.create(t.prototype);d.constructor=n,d._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},d.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},d.getSize=function(){this.size=e(this.element)},d.css=function(t){var e=this.element.style;for(var i in t){var n=u[i]||i;e[n]=t[i]}},d.getPosition=function(){var t=getComputedStyle(this.element),e=this.layout._getOption("originLeft"),i=this.layout._getOption("originTop"),n=t[e?"left":"right"],o=t[i?"top":"bottom"],r=parseFloat(n),s=parseFloat(o),a=this.layout.size;-1!=n.indexOf("%")&&(r=r/100*a.width),-1!=o.indexOf("%")&&(s=s/100*a.height),r=isNaN(r)?0:r,s=isNaN(s)?0:s,r-=e?a.paddingLeft:a.paddingRight,s-=i?a.paddingTop:a.paddingBottom,this.position.x=r,this.position.y=s},d.layoutPosition=function(){var t=this.layout.size,e={},i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop"),o=i?"paddingLeft":"paddingRight",r=i?"left":"right",s=i?"right":"left",a=this.position.x+t[o];e[r]=this.getXValue(a),e[s]="";var h=n?"paddingTop":"paddingBottom",u=n?"top":"bottom",d=n?"bottom":"top",l=this.position.y+t[h];e[u]=this.getYValue(l),e[d]="",this.css(e),this.emitEvent("layout",[this])},d.getXValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&!e?t/this.layout.size.width*100+"%":t+"px"},d.getYValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&e?t/this.layout.size.height*100+"%":t+"px"},d._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=t==this.position.x&&e==this.position.y;if(this.setPosition(t,e),o&&!this.isTransitioning)return void this.layoutPosition();var r=t-i,s=e-n,a={};a.transform=this.getTranslate(r,s),this.transition({to:a,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},d.getTranslate=function(t,e){var i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop");return t=i?t:-t,e=n?e:-e,"translate3d("+t+"px, "+e+"px, 0)"},d.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},d.moveTo=d._transitionTo,d.setPosition=function(t,e){this.position.x=parseFloat(t),this.position.y=parseFloat(e)},d._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},d.transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(t);var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var n=this.element.offsetHeight;n=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var l="opacity,"+o(a);d.enableTransition=function(){if(!this.isTransitioning){var t=this.layout.options.transitionDuration;t="number"==typeof t?t+"ms":t,this.css({transitionProperty:l,transitionDuration:t,transitionDelay:this.staggerDelay||0}),this.element.addEventListener(h,this,!1)}},d.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},d.onotransitionend=function(t){this.ontransitionend(t)};var c={"-webkit-transform":"transform"};d.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,n=c[t.propertyName]||t.propertyName;if(delete e.ingProperties[n],i(e.ingProperties)&&this.disableTransition(),n in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[n]),n in e.onEnd){var o=e.onEnd[n];o.call(this),delete e.onEnd[n]}this.emitEvent("transitionEnd",[this])}},d.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(h,this,!1),this.isTransitioning=!1},d._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var f={transitionProperty:"",transitionDuration:"",transitionDelay:""};return d.removeTransitionStyles=function(){this.css(f)},d.stagger=function(t){t=isNaN(t)?0:t,this.staggerDelay=t+"ms"},d.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},d.remove=function(){return s&&parseFloat(this.layout.options.transitionDuration)?(this.once("transitionEnd",function(){this.removeElem()}),void this.hide()):void this.removeElem()},d.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},d.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},d.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},d.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},d.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},d.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},n}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("outlayer/outlayer",["ev-emitter/ev-emitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(i,n,o,r){return e(t,i,n,o,r)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):t.Outlayer=e(t,t.EvEmitter,t.getSize,t.fizzyUIUtils,t.Outlayer.Item)}(window,function(t,e,i,n,o){"use strict";function r(t,e){var i=n.getQueryElement(t);if(!i)return void(h&&h.error("Bad element for "+this.constructor.namespace+": "+(i||t)));this.element=i,u&&(this.$element=u(this.element)),this.options=n.extend({},this.constructor.defaults),this.option(e);var o=++l;this.element.outlayerGUID=o,c[o]=this,this._create();var r=this._getOption("initLayout");r&&this.layout()}function s(t){function e(){t.apply(this,arguments)}return e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e}function a(t){if("number"==typeof t)return t;var e=t.match(/(^\d*\.?\d*)(\w*)/),i=e&&e[1],n=e&&e[2];if(!i.length)return 0;i=parseFloat(i);var o=m[n]||1;return i*o}var h=t.console,u=t.jQuery,d=function(){},l=0,c={};r.namespace="outlayer",r.Item=o,r.defaults={containerStyle:{position:"relative"},initLayout:!0,originLeft:!0,originTop:!0,resize:!0,resizeContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}};var f=r.prototype;n.extend(f,e.prototype),f.option=function(t){n.extend(this.options,t)},f._getOption=function(t){var e=this.constructor.compatOptions[t];return e&&void 0!==this.options[e]?this.options[e]:this.options[t]},r.compatOptions={initLayout:"isInitLayout",horizontal:"isHorizontal",layoutInstant:"isLayoutInstant",originLeft:"isOriginLeft",originTop:"isOriginTop",resize:"isResizeBound",resizeContainer:"isResizingContainer"},f._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),n.extend(this.element.style,this.options.containerStyle);var t=this._getOption("resize");t&&this.bindResize()},f.reloadItems=function(){this.items=this._itemize(this.element.children)},f._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0;o<e.length;o++){var r=e[o],s=new i(r,this);n.push(s)}return n},f._filterFindItemElements=function(t){return n.filterFindElements(t,this.options.itemSelector)},f.getItemElements=function(){return this.items.map(function(t){return t.element})},f.layout=function(){this._resetLayout(),this._manageStamps();var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;this.layoutItems(this.items,e),this._isLayoutInited=!0},f._init=f.layout,f._resetLayout=function(){this.getSize()},f.getSize=function(){this.size=i(this.element)},f._getMeasurement=function(t,e){var n,o=this.options[t];o?("string"==typeof o?n=this.element.querySelector(o):o instanceof HTMLElement&&(n=o),this[t]=n?i(n)[e]:o):this[t]=0},f.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},f._getItemsForLayout=function(t){return t.filter(function(t){return!t.isIgnored})},f._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){var i=[];t.forEach(function(t){var n=this._getItemLayoutPosition(t);n.item=t,n.isInstant=e||t.isLayoutInstant,i.push(n)},this),this._processLayoutQueue(i)}},f._getItemLayoutPosition=function(){return{x:0,y:0}},f._processLayoutQueue=function(t){this.updateStagger(),t.forEach(function(t,e){this._positionItem(t.item,t.x,t.y,t.isInstant,e)},this)},f.updateStagger=function(){var t=this.options.stagger;return null===t||void 0===t?void(this.stagger=0):(this.stagger=a(t),this.stagger)},f._positionItem=function(t,e,i,n,o){n?t.goTo(e,i):(t.stagger(o*this.stagger),t.moveTo(e,i))},f._postLayout=function(){this.resizeContainer()},f.resizeContainer=function(){var t=this._getOption("resizeContainer");if(t){var e=this._getContainerSize();e&&(this._setContainerMeasure(e.width,!0),this._setContainerMeasure(e.height,!1))}},f._getContainerSize=d,f._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},f._emitCompleteOnItems=function(t,e){function i(){o.dispatchEvent(t+"Complete",null,[e])}function n(){s++,s==r&&i()}var o=this,r=e.length;if(!e||!r)return void i();var s=0;e.forEach(function(e){e.once(t,n)})},f.dispatchEvent=function(t,e,i){var n=e?[e].concat(i):i;if(this.emitEvent(t,n),u)if(this.$element=this.$element||u(this.element),e){var o=u.Event(e);o.type=t,this.$element.trigger(o,i)}else this.$element.trigger(t,i)},f.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},f.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},f.stamp=function(t){t=this._find(t),t&&(this.stamps=this.stamps.concat(t),t.forEach(this.ignore,this))},f.unstamp=function(t){t=this._find(t),t&&t.forEach(function(t){n.removeFrom(this.stamps,t),this.unignore(t)},this)},f._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=n.makeArray(t)):void 0},f._manageStamps=function(){this.stamps&&this.stamps.length&&(this._getBoundingRect(),this.stamps.forEach(this._manageStamp,this))},f._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},f._manageStamp=d,f._getElementOffset=function(t){var e=t.getBoundingClientRect(),n=this._boundingRect,o=i(t),r={left:e.left-n.left-o.marginLeft,top:e.top-n.top-o.marginTop,right:n.right-e.right-o.marginRight,bottom:n.bottom-e.bottom-o.marginBottom};return r},f.handleEvent=n.handleEvent,f.bindResize=function(){t.addEventListener("resize",this),this.isResizeBound=!0},f.unbindResize=function(){t.removeEventListener("resize",this),this.isResizeBound=!1},f.onresize=function(){this.resize()},n.debounceMethod(r,"onresize",100),f.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},f.needsResizeLayout=function(){var t=i(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},f.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},f.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},f.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},f.reveal=function(t){if(this._emitCompleteOnItems("reveal",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.reveal()})}},f.hide=function(t){if(this._emitCompleteOnItems("hide",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.hide()})}},f.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},f.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},f.getItem=function(t){for(var e=0;e<this.items.length;e++){var i=this.items[e];if(i.element==t)return i}},f.getItems=function(t){t=n.makeArray(t);var e=[];return t.forEach(function(t){var i=this.getItem(t);i&&e.push(i)},this),e},f.remove=function(t){var e=this.getItems(t);this._emitCompleteOnItems("remove",e),e&&e.length&&e.forEach(function(t){t.remove(),n.removeFrom(this.items,t)},this)},f.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="",this.items.forEach(function(t){t.destroy()}),this.unbindResize();var e=this.element.outlayerGUID;delete c[e],delete this.element.outlayerGUID,u&&u.removeData(this.element,this.constructor.namespace)},r.data=function(t){t=n.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&c[e]},r.create=function(t,e){var i=s(r);return i.defaults=n.extend({},r.defaults),n.extend(i.defaults,e),i.compatOptions=n.extend({},r.compatOptions),i.namespace=t,i.data=r.data,i.Item=s(o),n.htmlInit(i,t),u&&u.bridget&&u.bridget(t,i),i};var m={ms:1,s:1e3};return r.Item=o,r}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer"),require("get-size")):t.Masonry=e(t.Outlayer,t.getSize)}(window,function(t,e){var i=t.create("masonry");i.compatOptions.fitWidth="isFitWidth";var n=i.prototype;return n._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns(),this.colYs=[];for(var t=0;t<this.cols;t++)this.colYs.push(0);this.maxY=0,this.horizontalColIndex=0},n.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var n=this.columnWidth+=this.gutter,o=this.containerWidth+this.gutter,r=o/n,s=n-o%n,a=s&&1>s?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},n.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},n._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this.options.horizontalOrder?"_getHorizontalColPosition":"_getTopColPosition",r=this[o](n,t),s={x:this.columnWidth*r.col,y:r.y},a=r.y+t.size.outerHeight,h=n+r.col,u=r.col;h>u;u++)this.colYs[u]=a;return s},n._getTopColPosition=function(t){var e=this._getTopColGroup(t),i=Math.min.apply(Math,e);return{col:e.indexOf(i),y:i}},n._getTopColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++)e[n]=this._getColGroupY(n,t);return e},n._getColGroupY=function(t,e){if(2>e)return this.colYs[t];var i=this.colYs.slice(t,t+e);return Math.max.apply(Math,i)},n._getHorizontalColPosition=function(t,e){var i=this.horizontalColIndex%this.cols,n=t>1&&i+t>this.cols;i=n?0:i;var o=e.size.outerWidth&&e.size.outerHeight;return this.horizontalColIndex=o?i+t:this.horizontalColIndex,{col:i,y:this._getColGroupY(i,t)}},n._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var h=Math.floor(s/this.columnWidth);h-=s%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var u=this._getOption("originTop"),d=(u?n.top:n.bottom)+i.outerHeight,l=a;h>=l;l++)this.colYs[l]=Math.max(d,this.colYs[l])},n._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},n._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},n.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i});
3301; 3302/** 3303 * Theme functions file 3304 * 3305 * 3306 */ 3307 3308(function($) { 3309 3310 // posts block for Masonry 3311 var $blocks = $('#posts'); 3312 3313 $( window ).load( function() { 3314 /** 3315 * Initial Masonry setup 3316 */ 3317 3318 // Determine text direction 3319 var ltr = true; 3320 if ( $('html' ).attr( 'dir' ) == 'rtl') { 3321 ltr = false; 3322 } 3323 3324 // fire up Masonry! 3325 $blocks.imagesLoaded( function() { 3326 $blocks.masonry({ 3327 columnWidth: 1, 3328 itemSelector: '.post-container', 3329 transitionDuration: 0, 3330 isOriginLeft: ltr, 3331 } ).masonry( 'layout' ); 3332 3333 var masonryChild = $blocks.find( '.post-container' ); 3334 3335 // Animating JS based off Huntt theme 3336 masonryChild.each( function( i ) { 3337 // Show content 3338 setTimeout( function() { 3339 masonryChild.eq( i ).addClass( 'post-loaded fade-in' ); 3340 }, 100 * ( i + 1 ) ); 3341 } ); 3342 3343 $( '#spinner' ).fadeOut( 250, function() { 3344 $( this ).remove(); 3345 } ); 3346 } ); 3347 } ); 3348 3349 3350 $( document ).ready( function( $ ) { 3351 3352 // Flexslider for Gallery posts 3353 $( ".flexslider" ).flexslider( { 3354 animation: "slide", 3355 controlNav: false, 3356 prevText: "Previous", 3357 nextText: "Next", 3358 smoothHeight: false, 3359 startAt : 1, // make sure order reflects order in gallery format 3360 } ); 3361 3362 /** 3363 * Masonry update after Infinte Scroll 3364 * JS based off Huntt theme 3365 */ 3366 3367 $( document.body ).on( 'post-load', function() { 3368 3369 // make sure we're only grabbing new posts 3370 var newEl = $blocks.children().not( '.post-loaded, span.infinite-loader' ).addClass( 'post-loaded' ); 3371 3372 // create function for refreshing Masonry 3373 function refreshMasonry() { 3374 $blocks.masonry( 'layout' ); 3375 } 3376 3377 // check if images loaded in these new posts 3378 newEl.imagesLoaded( function () { 3379 // if images loaded, add new posts and update masonry layout 3380 $blocks.masonry( 'appended', newEl, true ).masonry( 'layout' ); 3381 3382 // reinitialize flexslider for new posts, and re-run masonry when complete 3383 $( ".flexslider" ).flexslider( { 3384 animation: "slide", 3385 controlNav: false, 3386 prevText: "Previous", 3387 nextText: "Next", 3388 smoothHeight: false, 3389 startAt : 1, 3390 start: refreshMasonry, // reload masonry layout on finish, just in case flexslider was slow 3391 } ); 3392 3393 } ).delay( 500 ).each( function( i ) { 3394 // then have a small delay between displaying each post 3395 setTimeout( function() { 3396 newEl.eq( i ).addClass( 'fade-in' ); 3397 }, 200 * ( i + 1 ) ); 3398 } ); 3399 3400 // reloading masonry layout again, after delay 3401 // fixes edge case issue with Facebook embed reloading and messing up layout 3402 setTimeout( refreshMasonry, 3000 ); 3403 } ); 3404 3405 3406 /** 3407 * Enables menu toggle for small screens 3408 */ 3409 3410 ( function() { 3411 var nav = $( '.navigation' ), button, menu; 3412 if ( ! nav ) { 3413 return; 3414 } 3415 3416 button = nav.find( '.nav-toggle' ); 3417 if ( ! button ) { 3418 return; 3419 } 3420 3421 // Hide button if menu is missing or empty. 3422 menu = nav.find( '.main-navigation' ); 3423 if ( ! menu || ! menu.children().length ) { 3424 button.hide(); 3425 return; 3426 } 3427 3428 button.on( 'click.baskerville', function() { 3429 nav.toggleClass( 'toggled-on' ); 3430 $( this ).toggleClass( "active" ); 3431 $( ".main-navigation" ).slideToggle(); 3432 } ); 3433 3434 // Fix sub-menus for touch devices. 3435 if ( 'ontouchstart' in window ) { 3436 menu.find( '.has-children > a, .page_item_has_children a' ).on( 'touchstart.baskerville', function( e ) { 3437 var el = $( this ).parent( 'li' ); 3438 3439 if ( ! el.hasClass( 'focus' ) ) { 3440 e.preventDefault(); 3441 el.toggleClass( 'focus' ); 3442 el.siblings( '.focus' ).removeClass( 'focus' ); 3443 } 3444 } ); 3445 } 3446 3447 // Better focus for hidden submenu items for accessibility. 3448 menu.find( 'a' ).on( 'focus.baskerville blur.baskerville', function() { 3449 $( this ).parents( '.menu-item, .page_item' ).toggleClass( 'focus' ); 3450 } ); 3451 3452 } )(); 3453 3454 3455 // Makes "skip to content" link work correctly in IE9 and Chrome for better 3456 // accessibility. 3457 3458 // @link http://www.nczonline.net/blog/2013/01/15/fixing-skip-to-content-links/ 3459 3460 $( window ).on( 'hashchange.baskerville', function() { 3461 var hash = location.hash.substring( 1 ), element; 3462 if ( ! hash ) { 3463 return; 3464 } 3465 element = document.getElementById( hash ); 3466 if ( element ) { 3467 if ( ! /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) { 3468 element.tabIndex = -1; 3469 } 3470 element.focus(); 3471 // Repositions the window on jump-to-anchor to account for header height. 3472 window.scrollBy( 0, -80 ); 3473 } 3474 } ); 3475 3476 3477 // Toggle search form 3478 $( ".search-toggle" ).on( "click", function() { 3479 $( this ).toggleClass( "active" ); 3480 $( ".header-search-block" ).slideToggle(); 3481 $( ".header-search-block .search-field" ).focus(); 3482 return false;
3483 } ); 3484 3485 3486 // Smooth scroll to header 3487 $( '.tothetop' ).click( function() { 3488 $( 'html, body' ).animate( { 3489 scrollTop: 0 3490 }, 500 ); 3491 $( this ).unbind( "mouseenter mouseleave" ); 3492 return false; 3493 } ); 3494 3495 3496 // Add 'focus' style to search bar and comment inputs 3497 $('.wrapper .search-form input, .footer .search-form input').focus( function() { 3498 $( this ).closest( 'form' ).addClass( 'focus' ); 3499 } ).blur( function() { 3500 $( this ).closest( 'form' ).removeClass( 'focus' ); 3501 } ); 3502 3503 $('.comment-form-author input, .comment-form-email input, .comment-form-url input').focus( function() { 3504 $( this ).parent().addClass( 'focus' ); 3505 } ).blur( function() { 3506 $( this ).parent().removeClass( 'focus' ); 3507 } ); 3508 3509 3510 // Detect CSS3 Transform support in browsers 3511 var supports = ( function() { 3512 var div = document.createElement( 'div' ), 3513 vendors = 'Khtml Ms O Moz Webkit'.split( ' ' ), 3514 len = vendors.length; 3515 3516 return function( prop ) { 3517 if ( prop in div.style ) { 3518 return true; 3519 } 3520 3521 prop = prop.replace( /^[a-z]/, function( val ) { 3522 return val.toUpperCase(); 3523 } ); 3524 3525 while ( len-- ) { 3526 if ( vendors[len] + prop in div.style ) { 3527 return true; 3528 } 3529 } 3530 return false; 3531 }; 3532 } ) (); 3533 3534 if ( supports( 'transform' ) ) { 3535 // Add a css-transform class to the html element 3536 document.documentElement.className += ' css-transform'; 3537 } 3538 3539 3540 // To add placeholder text to header search in IE9 3541 // based on https://gist.github.com/samgro/823300 3542 if ( navigator.appVersion.indexOf( "MSIE 9." ) !=-1 ) { 3543 $( '[placeholder]' ).focus( function() { 3544 var input = $( this ); 3545 if ( input.hasClass( 'placeholder' ) ) { 3546 input.val( '' ); 3547 input.removeClass( 'placeholder' ); 3548 } 3549 } ).blur( function() { 3550 var input = $( this ); 3551 if ( input.val() === '' ) { 3552 input.addClass( 'placeholder' ); 3553 input.val( input.attr( 'placeholder' ) ); 3554 } 3555 } ).blur().parents( 'form' ).submit( function() { 3556 $( this ).find( '[placeholder]' ).each( function() { 3557 var input = $( this ); 3558 if ( input.hasClass( 'placeholder' ) ) { 3559 input.val( '' ); 3560 } 3561 } ); 3562 } ); 3563 3564 // Clear input on refresh so that the placeholder class gets added back 3565 $( window ).unload( function() { 3566 $( '[placeholder]' ).val( '' ); 3567 } ); 3568 } 3569 } ); 3570} )( jQuery ); 3571; 3572/*! This file is auto-generated */ 3573window.addComment=function(v){var I,C,h,E=v.document,b={commentReplyClass:"comment-reply-link",commentReplyTitleId:"reply-title",cancelReplyId:"cancel-comment-reply-link",commentFormId:"commentform",temporaryFormId:"wp-temp-form-div",parentIdFieldId:"comment_parent",postIdFieldId:"comment_post_ID"},e=v.MutationObserver||v.WebKitMutationObserver||v.MozMutationObserver,i="querySelector"in E&&"addEventListener"in v,n=!!E.documentElement.dataset;function t(){o(),e&&new e(d).observe(E.body,{childList:!0,subtree:!0})}function o(e){if(i&&(I=g(b.cancelReplyId),C=g(b.commentFormId),I)){I.addEventListener("click",l);function t(e){if((e.metaKey||e.ctrlKey)&&13===e.keyCode&&"a"!==E.activeElement.tagName.toLowerCase())return C.removeEventListener("keydown",t),e.preventDefault(),C.submit.click(),!1}C&&C.addEventListener("keydown",t);for(var n=function(e){var t=b.commentReplyClass;e&&e.childNodes||(e=E);e=E.getElementsByClassName?e.getElementsByClassName(t):e.querySelectorAll("."+t);return e}(e),o=0,d=n.length;o<d;o++)n[o].addEventListener("click",r)}}function l(e){var t,n,o=g(b.temporaryFormId);o&&h&&(g(b.parentIdFieldId).value="0",t=o.textContent,o.parentNode.replaceChild(h,o),this.style.display="none",n=(o=(o=g(b.commentReplyTitleId))&&o.firstChild)&&o.nextSibling,o&&o.nodeType===Node.TEXT_NODE&&t&&(n&&"A"===n.nodeName&&n.id!==b.cancelReplyId&&(n.style.display=""),o.textContent=t),e.preventDefault())}function r(e){var t=g(b.commentReplyTitleId),t=t&&t.firstChild.textContent,n=this,o=a(n,"belowelement"),d=a(n,"commentid"),i=a(n,"respondelement"),l=a(n,"postid"),n=a(n,"replyto")||t;o&&d&&i&&l&&!1===v.addComment.moveForm(o,d,i,l,n)&&e.preventDefault()}function d(e){for(var t=e.length;t--;)if(e[t].addedNodes.length)return void o()}function a(e,t){return n?e.dataset[t]:e.getAttribute("data-"+t)}function g(e){return E.getElementById(e)}return i&&"loading"!==E.readyState?t():i&&v.addEventListener("DOMContentLoaded",t,!1),{init:o,moveForm:function(e,t,n,o,d){var i,l,r,a,m,c,s,e=g(e),n=(h=g(n),g(b.parentIdFieldId)),y=g(b.postIdFieldId),p=g(b.commentReplyTitleId),u=(p=p&&p.firstChild)&&p.nextSibling;if(e&&h&&n){void 0===d&&(d=p&&p.textContent),a=h,m=b.temporaryFormId,c=g(m),s=(s=g(b.commentReplyTitleId))?s.firstChild.textContent:"",c||((c=E.createElement("div")).id=m,c.style.display="none",c.textContent=s,a.parentNode.insertBefore(c,a)),o&&y&&(y.value=o),n.value=t,I.style.display="",e.parentNode.insertBefore(h,e.nextSibling),p&&p.nodeType===Node.TEXT_NODE&&(u&&"A"===u.nodeName&&u.id!==b.cancelReplyId&&(u.style.display="none"),p.textContent=d),I.onclick=function(){return!1};try{for(var f=0;f<C.elements.length;f++)if(i=C.elements[f],l=!1,"getComputedStyle"in v?r=v.getComputedStyle(i):E.documentElement.currentStyle&&(r=i.currentStyle),(i.offsetWidth<=0&&i.offsetHeight<=0||"hidden"===r.visibility)&&(l=!0),"hidden"
3573!==i.type&&!i.disabled&&!l){i.focus();break}}catch(e){}return!1}}}}(window);; 3574/* global FB, jpfbembed */ 3575( function ( window ) { 3576 var facebookEmbed = function () { 3577 var fbroot, src, newScript, firstScript; 3578 3579 if ( 'undefined' !== typeof FB && FB.XFBML ) { 3580 FB.XFBML.parse(); 3581 } else { 3582 fbroot = document.createElement( 'div' ); 3583 fbroot.id = 'fb-root'; 3584 document.getElementsByTagName( 'body' )[ 0 ].appendChild( fbroot ); 3585 3586 src = '//connect.facebook.net/' + jpfbembed.locale + '/sdk.js#xfbml=1'; 3587 if ( jpfbembed.appid ) { 3588 src += '&appId=' + jpfbembed.appid; 3589 } 3590 src += '&version=v2.3'; 3591 3592 newScript = document.createElement( 'script' ); 3593 newScript.setAttribute( 'src', src ); 3594 firstScript = document.querySelector( 'script' ); 3595 firstScript.parentNode.insertBefore( newScript, firstScript ); 3596 } 3597 }; 3598 3599 window.fbAsyncInit = function () { 3600 FB.init( { 3601 appId: jpfbembed.appid, 3602 version: 'v2.3', 3603 } ); 3604 3605 FB.XFBML.parse(); 3606 }; 3607 3608 if ( 'undefined' !== typeof infiniteScroll ) { 3609 document.body.addEventListener( 'post-load', facebookEmbed ); 3610 } 3611 3612 facebookEmbed(); 3613} )( window ); 3614; 3615!function(){"use strict";var e,t={noop:function(){},texturize:function(e){return(e=(e=(e=(e+="").replace(/'/g,"’").replace(/'/g,"’")).replace(/"/g,"”").replace(/"/g,"”").replace(/"/g,"”").replace(/[\u201D]/g,"”")).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}l=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.
3615info.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)}}
3615({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"}
3615function 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
3615s"))}),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)}();; 3616(()=>{var e={8885(e,t,a){(e=a.nmd(e))&&(e.exports=function(){var e,t="en",a=/[?&#]lang=([a-zA-Z\-_]+)/;"object"==typeof _wp_google_translate_widget&&"string"==typeof _wp_google_translate_widget.lang&&(t=_wp_google_translate_widget.lang),(e=window.location.href.match(a))&&(window.location.href=window.location.href.replace(a,"").replace(/#googtrans\([a-zA-Z\-_|]+\)/,"")+"#googtrans("+t+"|"+e[1]+")"),new google.translate.TranslateElement({pageLanguage:t,layout:_wp_google_translate_widget.layout,autoDisplay:!1},"google_translate_element")})}},t={};function a(o){var n=t[o];if(void 0!==n)return n.exports;var l=t[o]={id:o,loaded:!1,exports:{}};return e[o](l,l.exports,a),l.loaded=!0,l.exports}a.nmd=e=>(e.paths=[],e.children||(e.children=[]),e);var o=a(8885);googleTranslateElementInit=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.