1jQuery(window).on('load', function () { 2 jQuery('.prev-photo i').show(); 3 jQuery('.next-photo i').show(); 4}); 5 6jQuery(document).ready(function () { 7 /** PHOTOS GALLERY */ 8 jQuery('.wp-block-gallery a').attr('data-fancybox', 'gallery'); 9 if (jQuery('.wp-block-gallery').length > 0) { 10 // var imgs = document.images, 11 var imgs = jQuery('.wp-block-gallery img'), 12 len = imgs.length, 13 counter = 0; 14 [].forEach.call(imgs, function (img) { 15 if (img.complete) { 16 incrementCounter(); 17 } else { 18 img.addEventListener('load', incrementCounter, false); 19 } 20 }); 21 function incrementCounter() { 22 counter++; 23 jQuery('.loading-photos span').text(counter + '/' + len); 24 if (counter === len) { 25 waterfall('.wp-block-gallery'); 26 setTimeout(function () { 27 jQuery('.wp-block-gallery').css('opacity', 1); 28 jQuery('.loading-photos').hide(); 29 }, 1000); 30 } 31 } 32 jQuery(window).resize(function () { 33 waterfall('.wp-block-gallery'); 34 }); 35 } 36 jQuery('.gallery a').attr('data-fancybox', 'gallery'); 37 if (jQuery('.gallery').length > 0) { 38 // var imgs = document.images, 39 var imgs = jQuery('.gallery img'), 40 len = imgs.length, 41 counter = 0; 42 [].forEach.call(imgs, function (img) { 43 if (img.complete) { 44 incrementCounter(); 45 } else { 46 img.addEventListener('load', incrementCounter, false); 47 } 48 }); 49 function incrementCounter() { 50 counter++; 51 jQuery('.loading-photos span').text(counter + '/' + len); 52 if (counter === len) { 53 waterfall('.gallery'); 54 setTimeout(function () { 55 jQuery('.gallery').css('opacity', 1); 56 jQuery('.loading-photos').hide(); 57 }, 1000); 58 } 59 } 60 jQuery(window).resize(function () { 61 waterfall('.gallery'); 62 }); 63 jQuery(window).load(function () { 64 waterfall('.wp-block-gallery'); 65 }); 66 } 67 68 /** VideoJS loading **/ 69 if (jQuery('#wpst-video').length > 0 && !wpst_ajax_var.ctpl_installed) { 70 var playerOptions = { 71 controlBar: { 72 children: [ 73 'playToggle', 74 'progressControl', 75 'durationDisplay', 76 'volumePanel', 77 'qualitySelector', 78 'fullscreenToggle', 79 ], 80 }, 81 }; 82 videojs('wpst-video', playerOptions); 83 } 84 85 /** Lazy load **/ 86 var imgDefer = document.getElementsByTagName('img'); 87 for (var i = 0; i < imgDefer.length; i++) { 88 var dataSrc = imgDefer[i].getAttribute('data-src'); 89 if (dataSrc) { 90 imgDefer[i].setAttribute('src', dataSrc); 91 imgDefer[i].classList.add('display-img'); 92 } 93 } 94 95 /** In-video Ad Close button **/ 96 // if(wpst_ajax_var.ctpl_installed == ''){ 97 jQuery('body').on('click', '.happy-inside-player .close', function (e) { 98 jQuery(this).parent('.happy-inside-player').hide(); 99 }); 100 // } 101 102 /** IIFE Set Post views with ajax request for cache compatibility */ 103 (function () { 104 var is_post = jQuery('body.single-post').length > 0; 105 if (!is_post) return; 106 var post_id = jQuery('article.post').attr('id').replace('post-', ''); 107 jQuery 108 .ajax({ 109 type: 'post', 110 url: wpst_ajax_var.url, 111 dataType: 'json', 112 data: { 113 action: 'post-views', 114 nonce: wpst_ajax_var.nonce, 115 post_id: post_id, 116 }, 117 }) 118 .done(function (doneData) { 119 // done stuff 120 }) 121 .fail(function (errorData) { 122 console.error(errorData); 123 }) 124 .always(function (alwaysData) { 125 //get post views & rating data 126 jQuery 127 .ajax({ 128 type: 'post', 129 url: wpst_ajax_var.url, 130 dataType: 'json', 131 data: { 132 action: 'get-post-data', 133 nonce: wpst_ajax_var.nonce, 134 post_id: post_id, 135 }, 136 }) 137 .done(function (doneData) { 138 if (doneData.views) { 139 jQuery('.video-views span').text(doneData.views); 140 } 141 if (doneData.likes) { 142 jQuery('.likes_count').text(doneData.likes); 143 } 144 }) 145 .fail(function (errorData) { 146 console.error(errorData); 147 }) 148 .always(function () { 149 // always stuff 150 }); 151 }); 152 })(); 153 154 /** Post like **/ 155 jQuery('.post-like a').on('click', function (e) { 156 e.preventDefault(); 157 158 var heart = jQuery(this); 159 var post_id = heart.data('post_id'); 160 var post_like = heart.data('post_like'); 161 162 jQuery.ajax({ 163 type: 'post', 164 url: wpst_ajax_var.url, 165 dataType: 'json', 166 data: 167 'action=post-like&nonce=' + 168 wpst_ajax_var.nonce + 169 '&post_like=' + 170 post_like + 171 '&post_id=' + 172 post_id, 173 success: function (data, textStatus, jqXHR) { 174 if (data.alreadyrate !== true) { 175 jQuery('.rating-result .percentage').text( 176 Math.floor(data.percentage) + '%', 177 ); 178 jQuery('.rating-result .percentage').show(); 179 jQuery('.likes .likes_count').text(data.likes); 180 jQuery('.post-like').html(data.button); 181 } 182 }, 183 }); 184 return false;
185 }); 186 187 //Main thumbs 188 main_setThumbsHeight(); 189 190 function ratio_format() { 191 var width = options.thumbnails_ratio.split('/')[0]; 192 var height = options.thumbnails_ratio.split('/')[1]; 193 return height / width; 194 } 195 196 jQuery(window).resize(function () { 197 main_setThumbsHeight(); 198 }); 199 200 function main_setThumbsHeight() { 201 var eltWidthMain = jQuery(jQuery('.post-thumbnail')[0]).width(); 202 jQuery('.post-thumbnail img').height(eltWidthMain * ratio_format()); 203 jQuery('.post-thumbnail .wpst-trailer').height( 204 eltWidthMain * ratio_format(), 205 ); 206 jQuery('.photos-thumb').height(eltWidthMain); 207 jQuery('.photos .post-thumbnail .photo-bg').height(eltWidthMain); 208 jQuery('.post-thumbnail .no-thumb').height(eltWidthMain * ratio_format()); 209 } 210 211 //Footer thumbs 212 footer_setThumbsHeight(); 213 214 jQuery(window).resize(function () { 215 footer_setThumbsHeight(); 216 }); 217 function footer_setThumbsHeight() { 218 var eltWidthFooter = jQuery( 219 jQuery('.site-footer .post-thumbnail')[0], 220 ).width(); 221 jQuery('.site-footer .post-thumbnail img').height( 222 eltWidthFooter * ratio_format(), 223 ); 224 jQuery('.site-footer .post-thumbnail .wpst-trailer').height( 225 eltWidthFooter * ratio_format(), 226 ); 227 jQuery('.site-footer .no-thumb').height(eltWidthFooter * ratio_format()); 228 } 229 230 //Hide title hover thumb 231 jQuery('.thumb-block a').hover( 232 function (e) { 233 jQuery(this).attr('data-title', jQuery(this).attr('title')); 234 jQuery(this).removeAttr('title'); 235 }, 236 function (e) { 237 jQuery(this).attr('title', jQuery(this).attr('data-title')); 238 }, 239 ); 240 241 jQuery(function ($) { 242 const thumbsInterval = 750; 243 const thumbsTimers = {}; 244 const trailersState = {}; 245 246 function debounce(fn, wait, immediate = false) { 247 let timer; 248 return function (...args) { 249 const callNow = immediate && !timer; 250 clearTimeout(timer); 251 timer = setTimeout(() => { 252 timer = null; 253 if (!immediate) fn.apply(this, args); 254 }, wait); 255 if (callNow) fn.apply(this, args); 256 }; 257 } 258 259 function initVideoPreviews() { 260 $('.video-preview-item').each(function () { 261 const $item = $(this); 262 const videoId = $item.data('video-id'); 263 const thumbsData = $item.data('thumbs'); 264 const trailerSrc = $item.data('trailer'); 265 const $postThumb = $item.find('.post-thumbnail'); 266 const $mainImg = $item.find('.video-main-thumb'); 267 const $overlay = $item.find('.video-overlay'); 268 269 let thumbs = thumbsData 270 ? thumbsData.split(',').map((s) => s.trim()) 271 : []; 272 273 const hasThumbs = thumbs.length > 0; 274 const isVideoTrailer = 275 trailerSrc && trailerSrc.match(/\.(mp4|webm)(\?.*)?$/i); 276 const isImageTrailer = 277 trailerSrc && trailerSrc.match(/\.(gif|webp)(\?.*)?$/i); 278 279 $postThumb.on( 280 'mouseenter touchstart', 281 debounce( 282 function () { 283 stopPreview($postThumb); 284 285 if (hasThumbs) { 286 startThumbs(videoId, $mainImg, thumbs); 287 } else if (isVideoTrailer || isImageTrailer) { 288 startTrailer( 289 videoId, 290 $overlay, 291 trailerSrc, 292 $mainImg, 293 isVideoTrailer, 294 ); 295 } 296 }, 297 100, 298 true, 299 ), // Debounce to avoid flickering, 300 ); 301 302 $postThumb.on('mouseleave touchend touchcancel', function () { 303 stopPreview($postThumb); 304 }); 305 }); 306 } 307 308 function startThumbs(id, $img, thumbs) { 309 if (!thumbs.length) return; 310 311 let index = 1; // on commence à 1 car la 0 est déjà affichée 312 const initialDelay = 150; // délai pour la 1ʳᵠrotation 313 const regularDelay = thumbsInterval; 314 315 function cycle() { 316 if (!thumbsTimers[id]) return; 317 $img.attr('src', thumbs[index]); 318 index = (index + 1) % thumbs.length; 319 thumbsTimers[id] = setTimeout(cycle, regularDelay); 320 } 321 322 // Lance la 1ère rotation plus vite 323 thumbsTimers[id] = setTimeout(cycle, initialDelay); 324 } 325 326 function stopThumbs(id, $img, mainSrc) { 327 clearTimeout(thumbsTimers[id]); 328 delete thumbsTimers[id]; 329 $img.attr('src', mainSrc); 330 } 331 332 function startTrailer(id, $overlay, src, $mainImg, isVideo) { 333 stopTrailer(id); 334 $overlay.empty(); 335 336 if (isVideo) { 337 const $video = $('<video muted autoplay loop playsinline></video>') 338 .attr('src', src) 339 .css({ width: '100%', height: 'auto' }); 340 341 $overlay.append($video).fadeIn(200); 342 $mainImg.fadeOut(200); 343 344 trailersState[id] = { type: 'video', $video, $mainImg, $overlay }; 345 } else { 346 const $img = $('<img class="preview-thumb" />').attr('src', src); 347 $overlay.append($img).fadeIn(200); 348 $mainImg.fadeOut(200); 349 350 trailersState[id] = { type: 'image', $img, $mainImg, $overlay }; 351 } 352 } 353 354 function stopTrailer(id) { 355 if (!trailersState[id]) return; 356 357 const { $mainImg, $overlay } = trailersState[id]; 358 $overlay.fadeOut(200, function () { 359 // $overlay.empty(); 360 }); 361 $mainImg.fadeIn(200); 362 delete trailersState[id]; 363 } 364 365 function stopPreview($trigger) { 366 if ($trigger) { 367 const $item = $trigger.parents('.video-preview-item'); 368 const id = $item.data('video-id'); 369 const $mainImg = $item.find('.video-main-thumb'); 370 const mainThumb = $item.data('main-thumb'); 371 stopThumbs(id, $mainImg, mainThumb); 372 stopTrailer(id); 373 } 374 return; 375 } 376 377 initVideoPreviews(); 378 }); 379 380 jQuery('.video-description .more').readmore({ 381 speed: 75, 382 collapsedHeight: 50, 383 moreLink: 384 '<a class="morelink" href="#">Read More <i class="fa fa-chevron-down"></i></a>', 385 lessLink: 386 '<a class="morelink" href="#">Read Less <i class="fa fa-chevron-up"></i></a>', 387 }); 388 389 /** Back to top */ 390 if (jQuery('#back-to-top').length) { 391 var scrollTrigger = 100, // px 392 backToTop = function () { 393 var scrollTop = jQuery(window).scrollTop(); 394 if (scrollTop > scrollTrigger) { 395 jQuery('#back-to-top').addClass('show'); 396 } else { 397 jQuery('#back-to-top').removeClass('show'); 398 } 399 }; 400 backToTop(); 401 jQuery(window).on('scroll', function () { 402 backToTop(); 403 }); 404 jQuery('#back-to-top').on('click', function (e) { 405 e.preventDefault(); 406 jQuery('html,body').animate( 407 { 408 scrollTop: 0, 409 }, 410 700, 411 ); 412 }); 413 } 414}); 415 416/** TRAILER */ 417function hoverVideo(i) {
418 var playPromise = jQuery('.wpst-trailer')[i].play(); 419 if (playPromise !== undefined) { 420 playPromise 421 .then((_) => { 422 // Automatic playback started! 423 // Show playing UI. 424 }) 425 .catch((error) => { 426 // Auto-play was prevented 427 // Show paused UI. 428 }); 429 } 430} 431 432function hideVideo(i) { 433 //jQuery('.wpst-trailer')[i].currentTime = 0; 434 jQuery('.wpst-trailer')[i].load(); 435} 436 437/** LOGIN / REGISTER POPUP */ 438function wpst_open_login_dialog(href) { 439 jQuery('#wpst-user-modal .modal-dialog').removeClass('registration-complete'); 440 var modal_dialog = jQuery('#wpst-user-modal .modal-dialog'); 441 modal_dialog.attr('data-active-tab', ''); 442 switch (href) { 443 case '#wpst-register': 444 modal_dialog.attr('data-active-tab', '#wpst-register'); 445 break; 446 case '#wpst-login': 447 default: 448 modal_dialog.attr('data-active-tab', '#wpst-login'); 449 break; 450 } 451 jQuery('#wpst-user-modal').modal('show'); 452} 453function wpst_close_login_dialog() { 454 jQuery('#wpst-user-modal').modal('hide'); 455} 456 457jQuery(function ($) { 458 'use strict'; 459 /*************************** 460 ** LOGIN / REGISTER DIALOG 461 ***************************/ 462 463 // Open login/register modal 464 $('[href="#wpst-login"], [href="#wpst-register"]').click(function (e) { 465 e.preventDefault(); 466 467 wpst_open_login_dialog($(this).attr('href')); 468 }); 469 470 // Switch forms login/register 471 $('.modal-footer a, a[href="#wpst-reset-password"]').click(function (e) { 472 e.preventDefault(); 473 $('#wpst-user-modal .modal-dialog').attr( 474 'data-active-tab', 475 $(this).attr('href'), 476 ); 477 }); 478 479 // Post login form 480 $('#wpst_login_form').on('submit', function (e) { 481 e.preventDefault(); 482 483 var button = $(this).find('button'); 484 button.button('loading'); 485 486 $.post( 487 wpst_ajax_var.url, 488 $('#wpst_login_form').serialize(), 489 function (data) { 490 var obj = $.parseJSON(data); 491 492 $('.wpst-login .wpst-errors').html(obj.message); 493 494 if (obj.error == false) { 495 $('#wpst-user-modal .modal-dialog').addClass('loading'); 496 window.location.reload(true); 497 button.hide(); 498 } 499 500 button.button('reset'); 501 }, 502 ); 503 }); 504 505 // Post register form 506 $('#wpst_registration_form').on('submit', function (e) { 507 e.preventDefault(); 508 509 var button = $(this).find('button'); 510 button.button('loading'); 511 512 $.post( 513 wpst_ajax_var.url, 514 $('#wpst_registration_form').serialize(), 515 function (data) { 516 var obj = $.parseJSON(data); 517 518 $('.wpst-register .wpst-errors').html(obj.message); 519 520 if (obj.error == false) { 521 $('#wpst-user-modal .modal-dialog').addClass('registration-complete'); 522 // window.location.reload(true); 523 button.hide(); 524 } 525 526 button.button('reset'); 527 }, 528 ); 529 }); 530 531 // Reset Password 532 $('#wpst_reset_password_form').on('submit', function (e) { 533 e.preventDefault(); 534 535 var button = $(this).find('button'); 536 button.button('loading'); 537 538 $.post( 539 wpst_ajax_var.url, 540 $('#wpst_reset_password_form').serialize(), 541 function (data) { 542 var obj = $.parseJSON(data); 543 544 $('.wpst-reset-password .wpst-errors').html(obj.message); 545 546 // if(obj.error == false){ 547 // $('#wpst-user-modal .modal-dialog').addClass('loading'); 548 // $('#wpst-user-modal').modal('hide'); 549 // } 550 551 button.button('reset'); 552 }, 553 ); 554 }); 555 556 if (window.location.hash == '#login') { 557 wpst_open_login_dialog('#wpst-login'); 558 } 559}); 560 561/*! 562 * @preserve 563 * 564 * Readmore.js jQuery plugin 565 * Author: @jed_foster 566 * Project home: http://jedfoster.github.io/Readmore.js 567 * Licensed under the MIT license 568 * 569 * Debounce function from http://davidwalsh.name/javascript-debounce-function 570 */ 571 572/* global jQuery */ 573 574(function (factory) { 575 if (typeof define === 'function' && define.amd) { 576 // AMD 577 define(['jquery'], factory); 578 } else if (typeof exports === 'object') { 579 // CommonJS 580 module.exports = factory(require('jquery')); 581 } else { 582 // Browser globals 583 factory(jQuery); 584 } 585})(function ($) { 586 'use strict'; 587 588 var readmore = 'readmore', 589 defaults = { 590 speed: 100, 591 collapsedHeight: 200, 592 heightMargin: 16, 593 moreLink: '<a href="#">Read More</a>', 594 lessLink: '<a href="#">Close</a>', 595 embedCSS: true, 596 blockCSS: 'display: block; width: 100%;', 597 startOpen: false, 598 599 // callbacks 600 blockProcessed: function () {}, 601 beforeToggle: function () {}, 602 afterToggle: function () {}, 603 }, 604 cssEmbedded = {}, 605 uniqueIdCounter = 0; 606 607 function debounce(func, wait, immediate) { 608 var timeout; 609 610 return function () { 611 var context = this, 612 args = arguments; 613 var later = function () { 614 timeout = null; 615 if (!immediate) {
616 func.apply(context, args); 617 } 618 }; 619 var callNow = immediate && !timeout; 620 621 clearTimeout(timeout); 622 timeout = setTimeout(later, wait); 623 624 if (callNow) { 625 func.apply(context, args); 626 } 627 }; 628 } 629 630 function uniqueId(prefix) { 631 var id = ++uniqueIdCounter; 632 633 return String(prefix == null ? 'rmjs-' : prefix) + id; 634 } 635 636 function setBoxHeights(element) { 637 var el = element 638 .clone() 639 .css({ 640 height: 'auto', 641 width: element.width(), 642 maxHeight: 'none', 643 overflow: 'hidden', 644 }) 645 .insertAfter(element), 646 expandedHeight = el.outerHeight(), 647 cssMaxHeight = parseInt( 648 el 649 .css({ maxHeight: '' }) 650 .css('max-height') 651 .replace(/[^-\d\.]/g, ''), 652 10, 653 ), 654 defaultHeight = element.data('defaultHeight'); 655 656 el.remove(); 657 658 var collapsedHeight = 659 cssMaxHeight || element.data('collapsedHeight') || defaultHeight; 660 661 // Store our measurements. 662 element 663 .data({ 664 expandedHeight: expandedHeight, 665 maxHeight: cssMaxHeight, 666 collapsedHeight: collapsedHeight, 667 }) 668 // and disable any `max-height` property set in CSS 669 .css({ 670 maxHeight: 'none', 671 }); 672 } 673 674 var resizeBoxes = debounce(function () { 675 $('[data-readmore]').each(function () { 676 var current = $(this), 677 isExpanded = current.attr('aria-expanded') === 'true'; 678 679 setBoxHeights(current); 680 681 current.css({ 682 height: current.data(isExpanded ? 'expandedHeight' : 'collapsedHeight'), 683 }); 684 }); 685 }, 100); 686 687 function embedCSS(options) { 688 if (!cssEmbedded[options.selector]) { 689 var styles = ' '; 690 691 if (options.embedCSS && options.blockCSS !== '') { 692 styles += 693 options.selector + 694 ' + [data-readmore-toggle], ' + 695 options.selector + 696 '[data-readmore]{' + 697 options.blockCSS + 698 '}'; 699 } 700 701 // Include the transition CSS even if embedCSS is false 702 styles += 703 options.selector + 704 '[data-readmore]{' + 705 'transition: height ' + 706 options.speed + 707 'ms;' + 708 'overflow: hidden;' + 709 '}'; 710 711 (function (d, u) { 712 var css = d.createElement('style'); 713 css.type = 'text/css'; 714 715 if (css.styleSheet) { 716 css.styleSheet.cssText = u; 717 } else { 718 css.appendChild(d.createTextNode(u)); 719 } 720 721 d.getElementsByTagName('head')[0].appendChild(css); 722 })(document, styles); 723 724 cssEmbedded[options.selector] = true; 725 } 726 } 727 728 function Readmore(element, options) { 729 this.element = element; 730 731 this.options = $.extend({}, defaults, options); 732 733 embedCSS(this.options); 734 735 this._defaults = defaults; 736 this._name = readmore; 737 738 this.init(); 739 740 // IE8 chokes on `window.addEventListener`, so need to test for support. 741 if (window.addEventListener) { 742 // Need to resize boxes when the page has fully loaded. 743 window.addEventListener('load', resizeBoxes); 744 window.addEventListener('resize', resizeBoxes); 745 } else { 746 window.attachEvent('load', resizeBoxes); 747 window.attachEvent('resize', resizeBoxes); 748 } 749 } 750 751 Readmore.prototype = { 752 init: function () { 753 var current = $(this.element); 754 755 current.data({ 756 defaultHeight: this.options.collapsedHeight, 757 heightMargin: this.options.heightMargin, 758 }); 759 760 setBoxHeights(current); 761 762 var collapsedHeight = current.data('collapsedHeight'), 763 heightMargin = current.data('heightMargin'); 764 765 if (current.outerHeight(true) <= collapsedHeight + heightMargin) { 766 // The block is shorter than the limit, so there's no need to truncate it. 767 if ( 768 this.options.blockProcessed && 769 typeof this.options.blockProcessed === 'function' 770 ) { 771 this.options.blockProcessed(current, false); 772 } 773 return true; 774 } else { 775 var id = current.attr('id') || uniqueId(), 776 useLink = this.options.startOpen 777 ? this.options.lessLink 778 : this.options.moreLink; 779 780 current.attr({ 781 'data-readmore': '', 782 'aria-expanded': this.options.startOpen, 783 id: id, 784 }); 785 786 current.after( 787 $(useLink) 788 .on( 789 'click', 790 (function (_this) { 791 return function (event) { 792 _this.toggle(this, current[0], event); 793 }; 794 })(this), 795 ) 796 .attr({ 797 'data-readmore-toggle': id, 798 'aria-controls': id, 799 }), 800 ); 801 802 if (!this.options.startOpen) { 803 current.css({ 804 height: collapsedHeight, 805 }); 806 } 807 808 if ( 809 this.options.blockProcessed && 810 typeof this.options.blockProcessed === 'function' 811 ) { 812 this.options.blockProcessed(current, true); 813 } 814 } 815 }, 816 817 toggle: function (trigger, element, event) { 818 if (event) { 819 event.preventDefault(); 820 } 821 822 if (!trigger) {
823 trigger = $('[aria-controls="' + this.element.id + '"]')[0]; 824 } 825 826 if (!element) { 827 element = this.element; 828 } 829 830 var $element = $(element), 831 newHeight = '', 832 newLink = '', 833 expanded = false, 834 collapsedHeight = $element.data('collapsedHeight'); 835 836 if ($element.height() <= collapsedHeight) { 837 newHeight = $element.data('expandedHeight') + 'px'; 838 newLink = 'lessLink'; 839 expanded = true; 840 } else { 841 newHeight = collapsedHeight; 842 newLink = 'moreLink'; 843 } 844 845 // Fire beforeToggle callback 846 // Since we determined the new "expanded" state above we're now out of sync 847 // with our true current state, so we need to flip the value of `expanded` 848 if ( 849 this.options.beforeToggle && 850 typeof this.options.beforeToggle === 'function' 851 ) { 852 this.options.beforeToggle(trigger, $element, !expanded); 853 } 854 855 $element.css({ height: newHeight }); 856 857 // Fire afterToggle callback 858 $element.on( 859 'transitionend', 860 (function (_this) { 861 return function () { 862 if ( 863 _this.options.afterToggle && 864 typeof _this.options.afterToggle === 'function' 865 ) { 866 _this.options.afterToggle(trigger, $element, expanded); 867 } 868 869 $(this) 870 .attr({ 871 'aria-expanded': expanded, 872 }) 873 .off('transitionend'); 874 }; 875 })(this), 876 ); 877 878 $(trigger).replaceWith( 879 $(this.options[newLink]) 880 .on( 881 'click', 882 (function (_this) { 883 return function (event) { 884 _this.toggle(this, element, event); 885 }; 886 })(this), 887 ) 888 .attr({ 889 'data-readmore-toggle': $element.attr('id'), 890 'aria-controls': $element.attr('id'), 891 }), 892 ); 893 }, 894 895 destroy: function () { 896 $(this.element).each(function () { 897 var current = $(this); 898 899 current 900 .attr({ 901 'data-readmore': null, 902 'aria-expanded': null, 903 }) 904 .css({ 905 maxHeight: '', 906 height: '', 907 }) 908 .next('[data-readmore-toggle]') 909 .remove(); 910 911 current.removeData(); 912 }); 913 }, 914 }; 915 916 $.fn.readmore = function (options) { 917 var args = arguments, 918 selector = this.selector; 919 920 options = options || {}; 921 922 if (typeof options === 'object') { 923 return this.each(function () { 924 if ($.data(this, 'plugin_' + readmore)) { 925 var instance = $.data(this, 'plugin_' + readmore); 926 instance.destroy.apply(instance); 927 } 928 929 options.selector = selector; 930 931 $.data(this, 'plugin_' + readmore, new Readmore(this, options)); 932 }); 933 } else if ( 934 typeof options === 'string' && 935 options[0] !== '_' && 936 options !== 'init' 937 ) { 938 return this.each(function () { 939 var instance = $.data(this, 'plugin_' + readmore); 940 if ( 941 instance instanceof Readmore && 942 typeof instance[options] === 'function' 943 ) { 944 instance[options].apply( 945 instance, 946 Array.prototype.slice.call(args, 1), 947 ); 948 } 949 }); 950 } 951 }; 952}); 953 954/********************/ 955/** Bootstrap modal */ 956/********************/ 957/*! 958 * Bootstrap v3.3.7 (http://getbootstrap.com) 959 * Copyright 2011-2017 Twitter, Inc. 960 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 961 */ 962 963/*! 964 * Generated using the Bootstrap Customizer (http://getbootstrap.com/docs/3.3/customize/?id=2df80e69d208c504c2a17d0146de73bb) 965 * Config saved to config.json and https://gist.github.com/2df80e69d208c504c2a17d0146de73bb 966 */ 967if (typeof jQuery === 'undefined') { 968 throw new Error("Bootstrap's JavaScript requires jQuery"); 969} 970+(function ($) { 971 'use strict'; 972 var version = $.fn.jquery.split(' ')[0].split('.'); 973 if ( 974 (version[0] < 2 && version[1] < 9) || 975 (version[0] == 1 && version[1] == 9 && version[2] < 1) || 976 version[0] > 3 977 ) { 978 throw new Error( 979 "Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4", 980 ); 981 } 982})(jQuery); 983 984/* ======================================================================== 985 * Bootstrap: button.js v3.3.7 986 * http://getbootstrap.com/javascript/#buttons 987 * ======================================================================== 988 * Copyright 2011-2016 Twitter, Inc. 989 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 990 * ======================================================================== */ 991 992+(function ($) { 993 'use strict'; 994 995 // BUTTON PUBLIC CLASS DEFINITION 996 // ============================== 997 998 var Button = function (element, options) { 999 this.$element = $(element); 1000 this.options = $.extend({}, Button.DEFAULTS, options); 1001 this.isLoading = false;
1002 }; 1003 1004 Button.VERSION = '3.3.7'; 1005 1006 Button.DEFAULTS = { 1007 loadingText: 'loading...', 1008 }; 1009 1010 Button.prototype.setState = function (state) { 1011 var d = 'disabled'; 1012 var $el = this.$element; 1013 var val = $el.is('input') ? 'val' : 'html'; 1014 var data = $el.data(); 1015 1016 state += 'Text'; 1017 1018 if (data.resetText == null) $el.data('resetText', $el[val]()); 1019 1020 // push to event loop to allow forms to submit 1021 setTimeout( 1022 $.proxy(function () { 1023 $el[val](data[state] == null ? this.options[state] : data[state]); 1024 1025 if (state == 'loadingText') { 1026 this.isLoading = true; 1027 $el.addClass(d).attr(d, d).prop(d, true); 1028 } else if (this.isLoading) { 1029 this.isLoading = false; 1030 $el.removeClass(d).removeAttr(d).prop(d, false); 1031 } 1032 }, this), 1033 0, 1034 ); 1035 }; 1036 1037 Button.prototype.toggle = function () { 1038 var changed = true; 1039 var $parent = this.$element.closest('[data-toggle="buttons"]'); 1040 1041 if ($parent.length) { 1042 var $input = this.$element.find('input'); 1043 if ($input.prop('type') == 'radio') { 1044 if ($input.prop('checked')) changed = false; 1045 $parent.find('.active').removeClass('active'); 1046 this.$element.addClass('active'); 1047 } else if ($input.prop('type') == 'checkbox') { 1048 if ($input.prop('checked') !== this.$element.hasClass('active')) 1049 changed = false; 1050 this.$element.toggleClass('active'); 1051 } 1052 $input.prop('checked', this.$element.hasClass('active')); 1053 if (changed) $input.trigger('change'); 1054 } else { 1055 this.$element.attr('aria-pressed', !this.$element.hasClass('active')); 1056 this.$element.toggleClass('active'); 1057 } 1058 }; 1059 1060 // BUTTON PLUGIN DEFINITION 1061 // ======================== 1062 1063 function Plugin(option) { 1064 return this.each(function () { 1065 var $this = $(this); 1066 var data = $this.data('bs.button'); 1067 var options = typeof option == 'object' && option; 1068 1069 if (!data) $this.data('bs.button', (data = new Button(this, options))); 1070 1071 if (option == 'toggle') data.toggle(); 1072 else if (option) data.setState(option); 1073 }); 1074 } 1075 1076 var old = $.fn.button; 1077 1078 $.fn.button = Plugin; 1079 $.fn.button.Constructor = Button; 1080 1081 // BUTTON NO CONFLICT 1082 // ================== 1083 1084 $.fn.button.noConflict = function () { 1085 $.fn.button = old; 1086 return this; 1087 }; 1088 1089 // BUTTON DATA-API 1090 // =============== 1091 1092 $(document) 1093 .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { 1094 var $btn = $(e.target).closest('.btn'); 1095 Plugin.call($btn, 'toggle'); 1096 if (!$(e.target).is('input[type="radio"], input[type="checkbox"]')) { 1097 // Prevent double click on radios, and the double selections (so cancellation) on checkboxes 1098 e.preventDefault(); 1099 // The target component still receive the focus 1100 if ($btn.is('input,button')) $btn.trigger('focus'); 1101 else $btn.find('input:visible,button:visible').first().trigger('focus'); 1102 } 1103 }) 1104 .on( 1105 'focus.bs.button.data-api blur.bs.button.data-api', 1106 '[data-toggle^="button"]', 1107 function (e) { 1108 $(e.target) 1109 .closest('.btn') 1110 .toggleClass('focus', /^focus(in)?$/.test(e.type)); 1111 }, 1112 ); 1113})(jQuery); 1114 1115/* ======================================================================== 1116 * Bootstrap: modal.js v3.3.7 1117 * http://getbootstrap.com/javascript/#modals 1118 * ======================================================================== 1119 * Copyright 2011-2016 Twitter, Inc. 1120 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 1121 * ======================================================================== */ 1122 1123+(function ($) { 1124 'use strict'; 1125 1126 // MODAL CLASS DEFINITION 1127 // ====================== 1128 1129 var Modal = function (element, options) { 1130 this.options = options; 1131 this.$body = $(document.body); 1132 this.$element = $(element); 1133 this.$dialog = this.$element.find('.modal-dialog'); 1134 this.$backdrop = null; 1135 this.isShown = null; 1136 this.originalBodyPad = null; 1137 this.scrollbarWidth = 0; 1138 this.ignoreBackdropClick = false; 1139 1140 if (this.options.remote) { 1141 this.$element.find('.modal-content').load( 1142 this.options.remote, 1143 $.proxy(function () { 1144 this.$element.trigger('loaded.bs.modal'); 1145 }, this), 1146 ); 1147 } 1148 }; 1149 1150 Modal.VERSION = '3.3.7'; 1151 1152 Modal.TRANSITION_DURATION = 300; 1153 Modal.BACKDROP_TRANSITION_DURATION = 150; 1154 1155 Modal.DEFAULTS = { 1156 backdrop: true, 1157 keyboard: true, 1158 show: true, 1159 }; 1160 1161 Modal.prototype.toggle = function (_relatedTarget) { 1162 return this.isShown ? this.hide() : this.show(_relatedTarget); 1163 }; 1164 1165 Modal.prototype.show = function (_relatedTarget) { 1166 var that = this; 1167 var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }); 1168 1169 this.$element.trigger(e); 1170 1171 if (this.isShown || e.isDefaultPrevented()) return; 1172 1173 this.isShown = true; 1174 1175 this.checkScrollbar(); 1176 this.setScrollbar(); 1177 this.$body.addClass('modal-open'); 1178 1179 this.escape(); 1180 this.resize(); 1181 1182 this.$element.on( 1183 'click.dismiss.bs.modal', 1184 '[data-dismiss="modal"]', 1185 $.proxy(this.hide, this), 1186 ); 1187 1188 this.$dialog.on('mousedown.dismiss.bs.modal', function () { 1189 that.$element.one('mouseup.dismiss.bs.modal', function (e) { 1190 if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true; 1191 }); 1192 }); 1193 1194 this.backdrop(function () { 1195 var transition = $.support.transition && that.$element.hasClass('fade'); 1196 1197 if (!that.$element.parent().length) { 1198 that.$element.appendTo(that.$body); // don't move modals dom position 1199 } 1200 1201 that.$element.show().scrollTop(0); 1202 1203 that.adjustDialog(); 1204 1205 if (transition) { 1206 that.$element[0].offsetWidth; // force reflow 1207 } 1208 1209 that.$element.addClass('in'); 1210 1211 that.enforceFocus(); 1212 1213 var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }); 1214 1215 transition 1216 ? that.$dialog // wait for modal to slide in 1217 .one('bsTransitionEnd', function () { 1218 that.$element.trigger('focus').trigger(e); 1219 }) 1220 .emulateTransitionEnd(Modal.TRANSITION_DURATION) 1221 : that.$element.trigger('focus').trigger(e); 1222 }); 1223 }; 1224 1225 Modal.prototype.hide = function (e) { 1226 if (e) e.preventDefault(); 1227 1228 e = $.Event('hide.bs.modal'); 1229 1230 this.$element.trigger(e); 1231 1232 if (!this.isShown || e.isDefaultPrevented()) return; 1233 1234 this.isShown = false;
1235 1236 this.escape(); 1237 this.resize(); 1238 1239 $(document).off('focusin.bs.modal'); 1240 1241 this.$element 1242 .removeClass('in') 1243 .off('click.dismiss.bs.modal') 1244 .off('mouseup.dismiss.bs.modal'); 1245 1246 this.$dialog.off('mousedown.dismiss.bs.modal'); 1247 1248 $.support.transition && this.$element.hasClass('fade') 1249 ? this.$element 1250 .one('bsTransitionEnd', $.proxy(this.hideModal, this)) 1251 .emulateTransitionEnd(Modal.TRANSITION_DURATION) 1252 : this.hideModal(); 1253 }; 1254 1255 Modal.prototype.enforceFocus = function () { 1256 $(document) 1257 .off('focusin.bs.modal') // guard against infinite focus loop 1258 .on( 1259 'focusin.bs.modal', 1260 $.proxy(function (e) { 1261 if ( 1262 document !== e.target && 1263 this.$element[0] !== e.target && 1264 !this.$element.has(e.target).length 1265 ) { 1266 this.$element.trigger('focus'); 1267 } 1268 }, this), 1269 ); 1270 }; 1271 1272 Modal.prototype.escape = function () { 1273 if (this.isShown && this.options.keyboard) { 1274 this.$element.on( 1275 'keydown.dismiss.bs.modal', 1276 $.proxy(function (e) { 1277 e.which == 27 && this.hide(); 1278 }, this), 1279 ); 1280 } else if (!this.isShown) { 1281 this.$element.off('keydown.dismiss.bs.modal'); 1282 } 1283 }; 1284 1285 Modal.prototype.resize = function () { 1286 if (this.isShown) { 1287 $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)); 1288 } else { 1289 $(window).off('resize.bs.modal'); 1290 } 1291 }; 1292 1293 Modal.prototype.hideModal = function () { 1294 var that = this; 1295 this.$element.hide(); 1296 this.backdrop(function () { 1297 that.$body.removeClass('modal-open'); 1298 that.resetAdjustments(); 1299 that.resetScrollbar(); 1300 that.$element.trigger('hidden.bs.modal'); 1301 }); 1302 }; 1303 1304 Modal.prototype.removeBackdrop = function () { 1305 this.$backdrop && this.$backdrop.remove(); 1306 this.$backdrop = null; 1307 }; 1308 1309 Modal.prototype.backdrop = function (callback) { 1310 var that = this; 1311 var animate = this.$element.hasClass('fade') ? 'fade' : ''; 1312 1313 if (this.isShown && this.options.backdrop) { 1314 var doAnimate = $.support.transition && animate; 1315 1316 this.$backdrop = $(document.createElement('div')) 1317 .addClass('modal-backdrop ' + animate) 1318 .appendTo(this.$body); 1319 1320 this.$element.on( 1321 'click.dismiss.bs.modal', 1322 $.proxy(function (e) { 1323 if (this.ignoreBackdropClick) { 1324 this.ignoreBackdropClick = false; 1325 return; 1326 } 1327 if (e.target !== e.currentTarget) return; 1328 this.options.backdrop == 'static' 1329 ? this.$element[0].focus() 1330 : this.hide(); 1331 }, this), 1332 ); 1333 1334 if (doAnimate) this.$backdrop[0].offsetWidth; // force reflow 1335 1336 this.$backdrop.addClass('in'); 1337 1338 if (!callback) return; 1339 1340 doAnimate 1341 ? this.$backdrop 1342 .one('bsTransitionEnd', callback) 1343 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) 1344 : callback(); 1345 } else if (!this.isShown && this.$backdrop) { 1346 this.$backdrop.removeClass('in'); 1347 1348 var callbackRemove = function () { 1349 that.removeBackdrop(); 1350 callback && callback(); 1351 }; 1352 $.support.transition && this.$element.hasClass('fade') 1353 ? this.$backdrop 1354 .one('bsTransitionEnd', callbackRemove) 1355 .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) 1356 : callbackRemove(); 1357 } else if (callback) { 1358 callback(); 1359 } 1360 }; 1361 1362 // these following methods are used to handle overflowing modals 1363 1364 Modal.prototype.handleUpdate = function () { 1365 this.adjustDialog(); 1366 }; 1367 1368 Modal.prototype.adjustDialog = function () { 1369 var modalIsOverflowing = 1370 this.$element[0].scrollHeight > document.documentElement.clientHeight; 1371 1372 this.$element.css({ 1373 paddingLeft: 1374 !this.bodyIsOverflowing && modalIsOverflowing 1375 ? this.scrollbarWidth 1376 : '', 1377 paddingRight: 1378 this.bodyIsOverflowing && !modalIsOverflowing 1379 ? this.scrollbarWidth 1380 : '', 1381 }); 1382 }; 1383 1384 Modal.prototype.resetAdjustments = function () { 1385 this.$element.css({ 1386 paddingLeft: '', 1387 paddingRight: '', 1388 }); 1389 }; 1390 1391 Modal.prototype.checkScrollbar = function () { 1392 var fullWindowWidth = window.innerWidth; 1393 if (!fullWindowWidth) { 1394 // workaround for missing window.innerWidth in IE8 1395 var documentElementRect = 1396 document.documentElement.getBoundingClientRect(); 1397 fullWindowWidth = 1398 documentElementRect.right - Math.abs(documentElementRect.left); 1399 } 1400 this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth; 1401 this.scrollbarWidth = this.measureScrollbar(); 1402 }; 1403 1404 Modal.prototype.setScrollbar = function () { 1405 var bodyPad = parseInt(this.$body.css('padding-right') || 0, 10); 1406 this.originalBodyPad = document.body.style.paddingRight || ''; 1407 if (this.bodyIsOverflowing) 1408 this.$body.css('padding-right', bodyPad + this.scrollbarWidth); 1409 }; 1410 1411 Modal.prototype.resetScrollbar = function () { 1412 this.$body.css('padding-right', this.originalBodyPad); 1413 }; 1414 1415 Modal.prototype.measureScrollbar = function () { 1416 // thx walsh 1417 var scrollDiv = document.createElement('div'); 1418 scrollDiv.className = 'modal-scrollbar-measure'; 1419 this.$body.append(scrollDiv); 1420 var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth; 1421 this.$body[0].removeChild(scrollDiv); 1422 return scrollbarWidth; 1423 }; 1424 1425 // MODAL PLUGIN DEFINITION 1426 // ======================= 1427 1428 function Plugin(option, _relatedTarget) { 1429 return this.each(function () { 1430 var $this = $(this); 1431 var data = $this.data('bs.modal'); 1432 var options = $.extend( 1433 {}, 1434 Modal.DEFAULTS, 1435 $this.data(), 1436 typeof option == 'object' && option, 1437 ); 1438 1439 if (!data) $this.data('bs.modal', (data = new Modal(this, options))); 1440 if (typeof option == 'string') data[option](_relatedTarget); 1441 else if (options.show) data.show(_relatedTarget); 1442 }); 1443 } 1444 1445 var old = $.fn.modal; 1446 1447 $.fn.modal = Plugin; 1448 $.fn.modal.Constructor = Modal; 1449 1450 // MODAL NO CONFLICT 1451 // ================= 1452 1453 $.fn.modal.noConflict = function () { 1454 $.fn.modal = old; 1455 return this; 1456 }; 1457 1458 // MODAL DATA-API 1459 // ============== 1460 1461 $(document).on( 1462 'click.bs.modal.data-api', 1463 '[data-toggle="modal"]', 1464 function (e) { 1465 var $this = $(this); 1466 var href = $this.attr('href'); 1467 var $target = $( 1468 $this.attr('data-target') || 1469 (href && href.replace(/.*(?=#[^\s]+$)/, '')), 1470 ); // strip for ie7 1471 var option = $target.data('bs.modal') 1472 ? 'toggle' 1473 : $.extend( 1474 { remote: !/#/.test(href) && href }, 1475 $target.data(), 1476 $this.data(), 1477 ); 1478 1479 if ($this.is('a')) e.preventDefault(); 1480 1481 $target.one('show.bs.modal', function (showEvent) { 1482 if (showEvent.isDefaultPrevented()) return; // only register focus restorer if modal will actually get shown 1483 $target.one('hidden.bs.modal', function () { 1484 $this.is(':visible') && $this.trigger('focus'); 1485 }); 1486 }); 1487 Plugin.call($target, option, this); 1488 }, 1489 ); 1490})(jQuery);
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.