1/* 2Plugin Name: scrollToTop for jQuery. 3Written by: Okler Themes - (http://www.okler.net) 4Version: 3.1.0 5*/ 6// Theme 7window.theme = {}; 8 9(function($) { 10 $.extend({ 11 12 scrollToTop: function() { 13 14 var _isScrolling = false; 15 16 // Append Button 17 $("body").append($("<a />") 18 .addClass("scroll-to-top") 19 .attr({ 20 "href": "#", 21 "id": "scrollToTop" 22 }) 23 .append( 24 $("<i />") 25 .addClass("icon icon-chevron-up icon-white") 26 )); 27 28 $("#scrollToTop").click(function(e) { 29 30 e.preventDefault(); 31 $("body, html").animate({scrollTop : 0}, 500); 32 return false; 33 34 }); 35 36 // Show/Hide Button on Window Scroll event. 37 $(window).scroll(function() { 38 39 if(!_isScrolling) { 40 41 _isScrolling = true; 42 43 if($(window).scrollTop() > 150) { 44 45 $("#scrollToTop").stop(true, true).addClass("visible"); 46 _isScrolling = false; 47 48 } else { 49 50 $("#scrollToTop").stop(true, true).removeClass("visible"); 51 _isScrolling = false; 52 53 } 54 55 } 56 57 }); 58 59 } 60 61 }); 62})(jQuery); 63 64 65/* 66Plugin Name: BrowserSelector 67Written by: Okler Themes - (http://www.okler.net) 68*/ 69 70(function($) { 71 $.extend({ 72 73 browserSelector: function() { 74 75 var u = navigator.userAgent, 76 ua = u.toLowerCase(), 77 is = function (t) { 78 return ua.indexOf(t) > -1; 79 }, 80 g = 'gecko', 81 w = 'webkit', 82 s = 'safari', 83 o = 'opera', 84 h = document.documentElement, 85 b = [(!(/opera|webtv/i.test(ua)) && /msie\s(\d)/.test(ua)) ? ('ie ie' + parseFloat(navigator.appVersion.split("MSIE")[1])) : is('firefox/2') ? g + ' ff2' : is('firefox/3.5') ? g + ' ff3 ff3_5' : is('firefox/3') ? g + ' ff3' : is('gecko/') ? g : is('opera') ? o + (/version\/(\d+)/.test(ua) ? ' ' + o + RegExp.jQuery1 : (/opera(\s|\/)(\d+)/.test(ua) ? ' ' + o + RegExp.jQuery2 : '')) : is('konqueror') ? 'konqueror' : is('chrome') ? w + ' chrome' : is('iron') ? w + ' iron' : is('applewebkit/') ? w + ' ' + s + (/version\/(\d+)/.test(ua) ? ' ' + s + RegExp.jQuery1 : '') : is('mozilla/') ? g : '', is('j2me') ? 'mobile' : is('iphone') ? 'iphone' : is('ipod') ? 'ipod' : is('mac') ? 'mac' : is('darwin') ? 'mac' : is('webtv') ? 'webtv' : is('win') ? 'win' : is('freebsd') ? 'freebsd' : (is('x11') || is('linux')) ? 'linux' : '', 'js']; 86 87 c = b.join(' '); 88 h.className += ' ' + c; 89 90 var isIE11 = !(window.ActiveXObject) && "ActiveXObject" in window; 91 92 if (isIE11) { 93 $('html').removeClass('gecko').addClass('ie ie11'); 94 return; 95 } 96 97 } 98 99 }); 100})(jQuery); 101 102/* 103Plugin Name: waitForImages jQuery Plugin - v1.5.0 - 2013-07-20 104Written by: https://github.com/alexanderdickson/waitForImages 105 106*/ 107 108;(function ($) { 109 // Namespace all events. 110 var eventNamespace = 'waitForImages'; 111 112 // CSS properties which contain references to images. 113 $.waitForImages = { 114 hasImageProperties: ['backgroundImage', 'listStyleImage', 'borderImage', 'borderCornerImage', 'cursor'] 115 }; 116 117 // Custom selector to find `img` elements that have a valid `src` attribute and have not already loaded. 118 $.expr[':'].uncached = function (obj) { 119 // Ensure we are dealing with an `img` element with a valid `src` attribute. 120 if (!$(obj).is('img[src!=""]')) { 121 return false; 122 } 123 124 // Firefox's `complete` property will always be `true` even if the image has not been downloaded. 125 // Doing it this way works in Firefox. 126 var img = new Image(); 127 img.src = obj.src; 128 return !img.complete; 129 }; 130 131 $.fn.waitForImages = function (finishedCallback, eachCallback, waitForAll) { 132 133 var allImgsLength = 0; 134 var allImgsLoaded = 0; 135 136 // Handle options object. 137 if ($.isPlainObject(arguments[0])) { 138 waitForAll = arguments[0].waitForAll; 139 eachCallback = arguments[0].each; 140 // This must be last as arguments[0] 141 // is aliased with finishedCallback. 142 finishedCallback = arguments[0].finished; 143 } 144 145 // Handle missing callbacks. 146 finishedCallback = finishedCallback || $.noop; 147 eachCallback = eachCallback || $.noop; 148 149 // Convert waitForAll to Boolean 150 waitForAll = !! waitForAll; 151 152 // Ensure callbacks are functions. 153 if (!$.isFunction(finishedCallback) || !$.isFunction(eachCallback)) { 154 throw new TypeError('An invalid callback was supplied.'); 155 } 156 157 return this.each(function () { 158 // Build a list of all imgs, dependent on what images will be considered. 159 var obj = $(this); 160 var allImgs = []; 161 // CSS properties which may contain an image. 162 var hasImgProperties = $.waitForImages.hasImageProperties || []; 163 // To match `url()` references. 164 // Spec: http://www.w3.org/TR/CSS2/syndata.html#value-def-uri 165 var matchUrl = /url\(\s*(['"]?)(.*?)\1\s*\)/g; 166 167 if (waitForAll) { 168 169 // Get all elements (including the original), as any one of them could have a background image. 170 obj.find('*').addBack().each(function () { 171 var element = $(this); 172 173 // If an `img` element, add it. But keep iterating in case it has a background image too. 174 if (element.is('img:uncached')) { 175 allImgs.push({ 176 src: element.attr('src'), 177 element: element[0] 178 }); 179 } 180 181 $.each(hasImgProperties, function (i, property) { 182 var propertyValue = element.css(property); 183 var match; 184 185 // If it doesn't contain this property, skip. 186 if (!propertyValue) { 187 return true; 188 } 189 190 // Get all url() of this element. 191 while (match = matchUrl.exec(propertyValue)) { 192 allImgs.push({ 193 src: match[2], 194 element: element[0] 195 }); 196 } 197 }); 198 }); 199 } else { 200 // For images only, the task is simpler. 201 obj.find('img:uncached') 202 .each(function () { 203 allImgs.push({ 204 src: this.src, 205 element: this 206 }); 207 }); 208 } 209 210 allImgsLength = allImgs.length; 211 allImgsLoaded = 0; 212 213 // If no images found, don't bother. 214 if (allImgsLength === 0) { 215 finishedCallback.call(obj[0]); 216 } 217 218 $.each(allImgs, function (i, img) { 219 220 var image = new Image(); 221 222 // Handle the image loading and error with the same callback. 223 $(image).on('load.' + eventNamespace + ' error.' + eventNamespace, function (event) { 224 allImgsLoaded++; 225 226 // If an error occurred with loading the image, set the third argument accordingly. 227 eachCallback.call(img.element, allImgsLoaded, allImgsLength, event.type == 'load'); 228 229 if (allImgsLoaded == allImgsLength) { 230 finishedCallback.call(obj[0]); 231 return false;
232 } 233 234 }); 235 236 image.src = img.src; 237 }); 238 }); 239 }; 240}(jQuery)); 241 242/* 243Plugin Name: Count To 244Written by: Matt Huggins - https://github.com/mhuggins/jquery-countTo 245 246*/ 247 248(function ($) { 249 $.fn.countTo = function (options) { 250 options = options || {}; 251 252 return $(this).each(function () { 253 // set options for current element 254 var settings = $.extend({}, $.fn.countTo.defaults, { 255 from: $(this).data('from'), 256 to: $(this).data('to'), 257 speed: $(this).data('speed'), 258 refreshInterval: $(this).data('refresh-interval'), 259 decimals: $(this).data('decimals') 260 }, options); 261 262 // how many times to update the value, and how much to increment the value on each update 263 var loops = Math.ceil(settings.speed / settings.refreshInterval), 264 increment = (settings.to - settings.from) / loops; 265 266 // references & variables that will change with each update 267 var self = this, 268 $self = $(this), 269 loopCount = 0, 270 value = settings.from, 271 data = $self.data('countTo') || {}; 272 273 $self.data('countTo', data); 274 275 // if an existing interval can be found, clear it first 276 if (data.interval) { 277 clearInterval(data.interval); 278 } 279 data.interval = setInterval(updateTimer, settings.refreshInterval); 280 281 // initialize the element with the starting value 282 render(value); 283 284 function updateTimer() { 285 value += increment; 286 loopCount++; 287 288 render(value); 289
290 if (typeof(settings.onUpdate) == 'function') { 291 settings.onUpdate.call(self, value); 292 } 293 294 if (loopCount >= loops) { 295 // remove the interval 296 $self.removeData('countTo'); 297 clearInterval(data.interval); 298 value = settings.to; 299 300 if (typeof(settings.onComplete) == 'function') { 301 settings.onComplete.call(self, value); 302 } 303 } 304 } 305 306 function render(value) { 307 var formattedValue = settings.formatter.call(self, value, settings); 308 $self.html(formattedValue); 309 } 310 }); 311 }; 312 313 $.fn.countTo.defaults = { 314 from: 0, // the number the element should start at 315 to: 0, // the number the element should end at 316 speed: 1000, // how long it should take to count between the target numbers 317 refreshInterval: 100, // how often the element should be updated 318 decimals: 0, // the number of decimal places to show 319 formatter: formatter, // handler for formatting the value before rendering 320 onUpdate: null, // callback method for every time the element is updated 321 onComplete: null // callback method for when the element finishes updating 322 }; 323 324 function formatter(value, settings) { 325 return value.toFixed(settings.decimals); 326 } 327}(jQuery)); 328 329/* 330Plugin Name: afterResize.js 331Written by: https://github.com/mcshaman/afterResize.js 332Description: Simple jQuery plugin designed to emulate an 'after resize' event. 333 334*/ 335 336( function( $ ) { 337 "use strict"; 338 339 // Define default settings 340 var defaults = { 341 action: function() {}, 342 runOnLoad: false, 343 duration: 500 344 }; 345 346 // Define global variables 347 var settings = defaults, 348 running = false, 349 start; 350 351 var methods = {}; 352 353 // Initial plugin configuration 354 methods.init = function() { 355 356 // Allocate passed arguments to settings based on type 357 for( var i = 0; i <= arguments.length; i++ ) { 358 var arg = arguments[i]; 359 switch ( typeof arg ) { 360 case "function": 361 settings.action = arg; 362 break; 363 case "boolean": 364 settings.runOnLoad = arg; 365 break; 366 case "number": 367 settings.duration = arg; 368 break; 369 } 370 } 371 372 // Process each matching jQuery object 373 return this.each(function() { 374 375 if( settings.runOnLoad ) { settings.action(); } 376 377 $(this).resize( function() { 378 379 methods.timedAction.call( this ); 380 381 } ); 382 383 } ); 384 }; 385 386 methods.timedAction = function( code, millisec ) { 387 388 var doAction = function() { 389 var remaining = settings.duration; 390 391 if( running ) { 392 var elapse = new Date() - start; 393 remaining = settings.duration - elapse; 394 if( remaining <= 0 ) { 395 // Clear timeout and reset running variable 396 clearTimeout(running); 397 running = false; 398 // Perform user defined function 399 settings.action(); 400 401 return; 402 } 403 } 404 wait( remaining ); 405 }; 406 407 var wait = function( time ) { 408 running = setTimeout( doAction, time ); 409 }; 410 411 // Define new action starting time 412 start = new Date(); 413 414 // Define runtime settings if function is run directly 415 if( typeof millisec === 'number' ) { settings.duration = millisec; } 416 if( typeof code === 'function' ) { settings.action = code; } 417 418 // Only run timed loop if not already running 419 if( !running ) { doAction(); } 420 421 }; 422 423 424 $.fn.afterResize = function( method ) { 425 426 if( methods[method] ) { 427 return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ) ); 428 } else { 429 return methods.init.apply( this, arguments ); 430 } 431 432 }; 433 434})(jQuery); 435 436/* 437Plugin Name: smoothScroll for jQuery. 438Written by: Okler Themes - (http://www.okler.net) 439Version: 3.1.0 440 441Based on: 442 443 SmoothScroll v1.2.1 444 Licensed under the terms of the MIT license. 445 446 People involved 447 - Balazs Galambosi (maintainer) 448 - Patrick Brunner (original idea) 449 - Michael Herf (Pulse Algorithm) 450 451*/ 452 453(function($) { 454 $.extend({ 455 456 smoothScroll: function() { 457 458 // Scroll Variables (tweakable) 459 var defaultOptions = { 460 461 // Scrolling Core 462 frameRate : 60, // [Hz] 463 animationTime : 700, // [px] 464 stepSize : 120, // [px] 465 466 // Pulse (less tweakable) 467 // ratio of "tail" to "acceleration" 468 pulseAlgorithm : true, 469 pulseScale : 10, 470 pulseNormalize : 1, 471 472 // Acceleration 473 accelerationDelta : 20, // 20 474 accelerationMax : 1, // 1 475 476 // Keyboard Settings 477 keyboardSupport : true, // option 478 arrowScroll : 50, // [px] 479 480 // Other 481 touchpadSupport : true,
482 fixedBackground : true, 483 excluded : "" 484 }; 485 486 var options = defaultOptions; 487 488 // Other Variables 489 var isExcluded = false; 490 var isFrame = false; 491 var direction = { x: 0, y: 0 }; 492 var initDone = false; 493 var root = document.documentElement; 494 var activeElement; 495 var observer; 496 var deltaBuffer = [ 120, 120, 120 ]; 497 498 var key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32, 499 pageup: 33, pagedown: 34, end: 35, home: 36 }; 500 501 502 /*********************************************** 503 * INITIALIZE 504 ***********************************************/ 505 506 /** 507 * Tests if smooth scrolling is allowed. Shuts down everything if not. 508 */ 509 function initTest() { 510 511 var disableKeyboard = false; 512 513 // disable keys for google reader (spacebar conflict) 514 if (document.URL.indexOf("google.com/reader/view") > -1) { 515 disableKeyboard = true; 516 } 517 518 // disable everything if the page is blacklisted 519 if (options.excluded) { 520 var domains = options.excluded.split(/[,\n] ?/); 521 domains.push("mail.google.com"); // exclude Gmail for now 522 for (var i = domains.length; i--;) { 523 if (document.URL.indexOf(domains[i]) > -1) { 524 observer && observer.disconnect(); 525 removeEvent("mousewheel", wheel); 526 disableKeyboard = true; 527 isExcluded = true; 528 break; 529 } 530 } 531 } 532 533 // disable keyboard support if anything above requested it 534 if (disableKeyboard) { 535 removeEvent("keydown", keydown); 536 } 537 538 if (options.keyboardSupport && !disableKeyboard) { 539 addEvent("keydown", keydown); 540 } 541 } 542 543 /** 544 * Sets up scrolls array, determines if frames are involved. 545 */ 546 function init() { 547 548 if (!document.body) return; 549 550 var body = document.body; 551 var html = document.documentElement; 552 var windowHeight = window.innerHeight; 553 var scrollHeight = body.scrollHeight; 554 555 // check compat mode for root element 556 root = (document.compatMode.indexOf('CSS') >= 0) ? html : body; 557 activeElement = body; 558 559 initTest(); 560 initDone = true; 561 562 // Checks if this script is running in a frame 563 if (top != self) { 564 isFrame = true; 565 } 566 567 /** 568 * This fixes a bug where the areas left and right to 569 * the content does not trigger the onmousewheel event 570 * on some pages. e.g.: html, body { height: 100% } 571 */ 572 else if (scrollHeight > windowHeight && 573 (body.offsetHeight <= windowHeight || 574 html.offsetHeight <= windowHeight)) { 575 576 // DOMChange (throttle): fix height 577 var pending = false; 578 var refresh = function () { 579 if (!pending && html.scrollHeight != document.height) { 580 pending = true; // add a new pending action 581 setTimeout(function () { 582 html.style.height = document.height + 'px'; 583 pending = false; 584 }, 500); // act rarely to stay fast 585 } 586 }; 587 html.style.height = 'auto'; 588 setTimeout(refresh, 10); 589 590 var config = { 591 attributes: true, 592 childList: true, 593 characterData: false 594 }; 595 596 observer = new MutationObserver(refresh); 597 observer.observe(body, config); 598 599 // clearfix 600 if (root.offsetHeight <= windowHeight) { 601 var underlay = document.createElement("div"); 602 underlay.style.clear = "both"; 603 body.appendChild(underlay); 604 } 605 } 606 607 // gmail performance fix 608 if (document.URL.indexOf("mail.google.com") > -1) { 609 var s = document.createElement("style"); 610 s.innerHTML = ".iu { visibility: hidden }"; 611 (document.getElementsByTagName("head")[0] || html).appendChild(s); 612 } 613 // facebook better home timeline performance 614 // all the HTML resized images make rendering CPU intensive 615 else if (document.URL.indexOf("www.facebook.com") > -1) { 616 var home_stream = document.getElementById("home_stream"); 617 home_stream && (home_stream.style.webkitTransform = "translateZ(0)"); 618 } 619 // disable fixed background 620 if (!options.fixedBackground && !isExcluded) { 621 body.style.backgroundAttachment = "scroll"; 622 html.style.backgroundAttachment = "scroll"; 623 } 624 } 625 626 627 /************************************************ 628 * SCROLLING 629 ************************************************/ 630 631 var que = []; 632 var pending = false;
633 var lastScroll = +new Date; 634 635 /** 636 * Pushes scroll actions to the scrolling queue. 637 */ 638 function scrollArray(elem, left, top, delay) { 639 640 delay || (delay = 1000); 641 directionCheck(left, top); 642 643 if (options.accelerationMax != 1) { 644 var now = +new Date; 645 var elapsed = now - lastScroll; 646 if (elapsed < options.accelerationDelta) { 647 var factor = (1 + (30 / elapsed)) / 2; 648 if (factor > 1) { 649 factor = Math.min(factor, options.accelerationMax); 650 left *= factor; 651 top *= factor; 652 } 653 } 654 lastScroll = +new Date; 655 } 656 657 // push a scroll command 658 que.push({ 659 x: left, 660 y: top, 661 lastX: (left < 0) ? 0.99 : -0.99, 662 lastY: (top < 0) ? 0.99 : -0.99, 663 start: +new Date 664 }); 665 666 // don't act if there's a pending queue 667 if (pending) { 668 return; 669 } 670 671 var scrollWindow = (elem === document.body); 672 673 var step = function (time) { 674 675 var now = +new Date; 676 var scrollX = 0; 677 var scrollY = 0; 678 679 for (var i = 0; i < que.length; i++) { 680 681 var item = que[i]; 682 var elapsed = now - item.start; 683 var finished = (elapsed >= options.animationTime); 684 685 // scroll position: [0, 1] 686 var position = (finished) ? 1 : elapsed / options.animationTime; 687 688 // easing [optional] 689 if (options.pulseAlgorithm) { 690 position = pulse(position); 691 } 692 693 // only need the difference 694 var x = (item.x * position - item.lastX) >> 0; 695 var y = (item.y * position - item.lastY) >> 0; 696 697 // add this to the total scrolling 698 scrollX += x; 699 scrollY += y; 700 701 // update last values 702 item.lastX += x; 703 item.lastY += y; 704 705 // delete and step back if it's over 706 if (finished) { 707 que.splice(i, 1); i--; 708 } 709 } 710 711 // scroll left and top 712 if (scrollWindow) { 713 window.scrollBy(scrollX, scrollY); 714 } 715 else { 716 if (scrollX) elem.scrollLeft += scrollX; 717 if (scrollY) elem.scrollTop += scrollY; 718 } 719 720 // clean up if there's nothing left to do 721 if (!left && !top) { 722 que = []; 723 } 724 725 if (que.length) { 726 requestFrame(step, elem, (delay / options.frameRate + 1)); 727 } else { 728 pending = false; 729 } 730 }; 731 732 // start a new queue of actions 733 requestFrame(step, elem, 0); 734 pending = true; 735 } 736 737 738 /*********************************************** 739 * EVENTS 740 ***********************************************/ 741 742 /** 743 * Mouse wheel handler. 744 * @param {Object} event 745 */ 746 function wheel(event) { 747 748 if (!initDone) { 749 init(); 750 } 751 752 var target = event.target; 753 var overflowing = overflowingAncestor(target); 754 755 // use default if there's no overflowing 756 // element or default action is prevented 757 if (!overflowing || event.defaultPrevented || 758 isNodeName(activeElement, "embed") || 759 (isNodeName(target, "embed") && /\.pdf/i.test(target.src))) { 760 return true; 761 } 762 763 var deltaX = event.wheelDeltaX || 0; 764 var deltaY = event.wheelDeltaY || 0; 765 766 // use wheelDelta if deltaX/Y is not available 767 if (!deltaX && !deltaY) { 768 deltaY = event.wheelDelta || 0; 769 } 770 771 // check if it's a touchpad scroll that should be ignored 772 if (!options.touchpadSupport && isTouchpad(deltaY)) { 773 return true; 774 } 775 776 // scale by step size 777 // delta is 120 most of the time 778 // synaptics seems to send 1 sometimes 779 if (Math.abs(deltaX) > 1.2) { 780 deltaX *= options.stepSize / 120; 781 } 782 if (Math.abs(deltaY) > 1.2) { 783 deltaY *= options.stepSize / 120; 784 } 785 786 scrollArray(overflowing, -deltaX, -deltaY); 787 event.preventDefault(); 788 } 789 790 /** 791 * Keydown event handler. 792 * @param {Object} event 793 */ 794 function keydown(event) { 795 796 var target = event.target; 797 var modifier = event.ctrlKey || event.altKey || event.metaKey || 798 (event.shiftKey && event.keyCode !== key.spacebar); 799 800 // do nothing if user is editing text 801 // or using a modifier key (except shift) 802 // or in a dropdown 803 if ( /input|textarea|select|embed/i.test(target.nodeName) || 804 target.isContentEditable || 805 event.defaultPrevented || 806 modifier ) { 807 return true; 808 } 809 // spacebar should trigger button press 810 if (isNodeName(target, "button") && 811 event.keyCode === key.spacebar) { 812 return true; 813 } 814 815 var shift, x = 0, y = 0; 816 var elem = overflowingAncestor(activeElement); 817 var clientHeight = elem.clientHeight; 818 819 if (elem == document.body) { 820 clientHeight = window.innerHeight; 821 } 822 823 switch (event.keyCode) { 824 case key.up: 825 y = -options.arrowScroll; 826 break; 827 case key.down: 828 y = options.arrowScroll; 829 break; 830 case key.spacebar: // (+ shift) 831 shift = event.shiftKey ? 1 : -1; 832 y = -shift * clientHeight * 0.9; 833 break; 834 case key.pageup: 835 y = -clientHeight * 0.9; 836 break; 837 case key.pagedown: 838 y = clientHeight * 0.9; 839 break; 840 case key.home: 841 y = -elem.scrollTop; 842 break; 843 case key.end: 844 var damt = elem.scrollHeight - elem.scrollTop - clientHeight; 845 y = (damt > 0) ? damt+10 : 0; 846 break; 847 case key.left: 848 x = -options.arrowScroll; 849 break; 850 case key.right: 851 x = options.arrowScroll; 852 break; 853 default: 854 return true; // a key we don't care about 855 } 856 857 scrollArray(elem, x, y); 858 event.preventDefault(); 859 } 860 861 /** 862 * Mousedown event only for updating activeElement 863 */ 864 function mousedown(event) { 865 activeElement = event.target; 866 } 867 868 869 /*********************************************** 870 * OVERFLOW 871 ***********************************************/ 872 873 var cache = {}; // cleared out every once in while 874 setInterval(function () { cache = {}; }, 10 * 1000); 875 876 var uniqueID = (function () { 877 var i = 0; 878 return function (el) { 879 return el.uniqueID || (el.uniqueID = i++); 880 }; 881 })(); 882
883 function setCache(elems, overflowing) { 884 for (var i = elems.length; i--;) 885 cache[uniqueID(elems[i])] = overflowing; 886 return overflowing; 887 } 888 889 function overflowingAncestor(el) { 890 var elems = []; 891 var rootScrollHeight = root.scrollHeight; 892 do { 893 var cached = cache[uniqueID(el)]; 894 if (cached) { 895 return setCache(elems, cached); 896 } 897 elems.push(el); 898 if (rootScrollHeight === el.scrollHeight) { 899 if (!isFrame || root.clientHeight + 10 < rootScrollHeight) { 900 return setCache(elems, document.body); // scrolling root in WebKit 901 } 902 } else if (el.clientHeight + 10 < el.scrollHeight) { 903 overflow = getComputedStyle(el, "").getPropertyValue("overflow-y"); 904 if (overflow === "scroll" || overflow === "auto") { 905 return setCache(elems, el); 906 } 907 } 908 } while (el = el.parentNode); 909 } 910 911 912 /*********************************************** 913 * HELPERS 914 ***********************************************/ 915 916 function addEvent(type, fn, bubble) { 917 window.addEventListener(type, fn, (bubble||false)); 918 } 919 920 function removeEvent(type, fn, bubble) { 921 window.removeEventListener(type, fn, (bubble||false)); 922 } 923 924 function isNodeName(el, tag) { 925 return (el.nodeName||"").toLowerCase() === tag.toLowerCase(); 926 } 927 928 function directionCheck(x, y) { 929 x = (x > 0) ? 1 : -1; 930 y = (y > 0) ? 1 : -1; 931 if (direction.x !== x || direction.y !== y) { 932 direction.x = x; 933 direction.y = y; 934 que = []; 935 lastScroll = 0; 936 } 937 } 938 939 var deltaBufferTimer; 940 941 function isTouchpad(deltaY) { 942 if (!deltaY) return; 943 deltaY = Math.abs(deltaY) 944 deltaBuffer.push(deltaY); 945 deltaBuffer.shift(); 946 clearTimeout(deltaBufferTimer); 947 var allEquals = (deltaBuffer[0] == deltaBuffer[1] && 948 deltaBuffer[1] == deltaBuffer[2]); 949 var allDivisable = (isDivisible(deltaBuffer[0], 120) && 950 isDivisible(deltaBuffer[1], 120) && 951 isDivisible(deltaBuffer[2], 120)); 952 return !(allEquals || allDivisable); 953 } 954 955 function isDivisible(n, divisor) { 956 return (Math.floor(n / divisor) == n / divisor); 957 } 958 959 var requestFrame = (function () { 960 return window.requestAnimationFrame || 961 window.webkitRequestAnimationFrame || 962 function (callback, element, delay) { 963 window.setTimeout(callback, delay || (1000/60)); 964 }; 965 })(); 966 967 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver; 968 969 970 /*********************************************** 971 * PULSE 972 ***********************************************/ 973 974 /** 975 * Viscous fluid with a pulse for part and decay for the rest. 976 * - Applies a fixed force over an interval (a damped acceleration), and 977 * - Lets the exponential bleed away the velocity over a longer interval 978 * - Michael Herf, http://stereopsis.com/stopping/ 979 */ 980 function pulse_(x) { 981 var val, start, expx; 982 // test 983 x = x * options.pulseScale; 984 if (x < 1) { // acceleartion 985 val = x - (1 - Math.exp(-x)); 986 } else { // tail 987 // the previous animation ended here: 988 start = Math.exp(-1); 989 // simple viscous drag 990 x -= 1; 991 expx = 1 - Math.exp(-x); 992 val = start + (expx * (1 - start)); 993 } 994 return val * options.pulseNormalize; 995 } 996 997 function pulse(x) { 998 if (x >= 1) return 1; 999 if (x <= 0) return 0; 1000 1001 if (options.pulseNormalize == 1) { 1002 options.pulseNormalize /= pulse_(1); 1003 } 1004 return pulse_(x); 1005 } 1006 1007 addEvent("mousedown", mousedown); 1008 addEvent("mousewheel", wheel); 1009 addEvent("load", init); 1010 1011 } 1012 1013 }); 1014})(jQuery); 1015 1016/* 1017Plugin Name: Lity - v3.0.0-dev - 2017-07-17 1018Written by : http://sorgalla.com/lity/ 1019*/ 1020(function ($) { 1021 "use strict"; 1022!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(c){return b(a,c)}):"object"==typeof module&&"object"==typeof module.exports?module.exports=b(a,require("jquery")):a.lity=b(a,a.jQuery||a.Zepto)}("undefined"!=typeof window?window:this,function(a,b){"use strict";function c(a){var b=C();return O&&a.length?(a.one(O,b.resolve),setTimeout(b.resolve,500)):b.resolve(),b.promise()}function d(a,c,d){if(1===arguments.length)return b.extend({},a);if("string"==typeof c){if(void 0===d)return void 0===a[c]?null:a[c];a[c]=d}else b.extend(a,c);return this}function e(a){var b=a.indexOf("?");b>-1&&(a=a.substr(b+1));for(var c,d=decodeURI(a.split("#")[0]).split("&"),e={},f=0,g=d.length;f<g;f++)d[f]&&(c=d[f].split("="),e[c[0]]=c[1]);return e}function f(a,c){if(!c)return a;
1022if("string"===b.type(c)&&(c=e(c)),a.indexOf("?")>-1){var d=a.split("?");a=d.shift(),c=b.extend({},e(d[0]),c)}return a+"?"+b.param(c)}function g(a,b){var c=a.indexOf("#");return-1===c?b:(c>0&&(a=a.substr(c)),b+a)}function h(a,b,c,d){return b&&b.element().addClass("lity-iframe"),c&&(a=f(a,c)),d&&(a=g(d,a)),'<div class="lity-iframe-container"><iframe frameborder="0" allowfullscreen src="'+a+'"/></div>'}function i(a){return b('<span class="lity-error"/>').append(a)}function j(a,c){var d=c.opener()&&c.opener().data("lity-desc")||"Image with no description",e=b('<img src="'+a+'" alt="'+d+'"/>'),f=C(),g=function(){f.reject(i("Failed loading image"))};return e.on("load",function(){if(0===this.naturalWidth)return g();f.resolve(e)}).on("error",g),f.promise()}function k(a,c){var d,e,f;try{d=b(a)}catch(a){return!1}return!!d.length&&(e=b('<i style="display:none !important"/>'),f=d.hasClass("lity-hide"),c.element().one("lity:remove",function(){e.before(d).remove(),f&&!d.closest(".lity-content").length&&d.addClass("lity-hide")}),d.removeClass("lity-hide").after(e))}function l(a,b){var c=K.exec(a);return!!c&&h("https://www.youtube"+(c[2]||"")+".com/embed/"+c[4]+"?autoplay=1",b,c[5],a)}function m(a,b){var c=L.exec(a);return!!c&&h("https://player.vimeo.com/video/"+c[3]+"?autoplay=1",b,c[4],a)}function n(a,b){var c=N.exec(a);return!!c&&(0!==a.indexOf("http")&&(a="https:"+a),h("https://www.facebook.com/plugins/video.php?href="+a+"&autoplay=1",b,c[4],a))}function o(a,b){var c=M.exec(a);return!!c&&h("https://www.google."+c[3]+"/maps?"+c[6],b,{output:c[6].indexOf("layer=c")>0?"svembed":"embed"},a)}function p(a,b){return h(a,b)}function q(){return A.documentElement.clientHeight?A.documentElement.clientHeight:Math.round(B.height())}function r(a){var b=w();b&&(27===a.keyCode&&b.options("esc")&&b.close(),9===a.keyCode&&s(a,b))}function s(a,b){var c=b.element().find(H),d=c.index(A.activeElement);a.shiftKey&&d<=0?(c.get(c.length-1).focus(),a.preventDefault()):a.shiftKey||d!==c.length-1||(c.get(0).focus(),a.preventDefault())}function t(){b.each(E,function(a,b){b.resize()})}function u(a){1===E.unshift(a)&&(D.addClass("lity-active"),B.on({resize:t,keydown:r})),b("body > *").not(a.element()).addClass("lity-hidden").each(function(){var a=b(this);void 0===a.data(G)&&a.data(G,a.attr(F)||null)}).attr(F,"true")}function v(a){var c;a.element().attr(F,"true"),1===E.length&&(D.removeClass("lity-active"),B.off({resize:t,keydown:r})),E=b.grep(E,function(b){return a!==b}),c=E.length?E[0].element():b(".lity-hidden"),c.removeClass("lity-hidden").each(function(){var a=b(this),c=a.data(G);c?a.attr(F,c):a.removeAttr(F),a.removeData(G)})}function w(){return 0===E.length?null:E[0]}function x(a,c,d,e){var f,g="inline",h=b.extend({},d);return e&&h[e]?(f=h[e](a,c),g=e):(b.each(["inline","iframe"],function(a,b){delete h[b],h[b]=d[b]}),b.each(h,function(b,d){return!d||(!(!d.test||d.test(a,c))||(f=d(a,c),!1!==f?(g=b,!1):void 0))})),{handler:g,content:f||""}}function y(a,e,f,g){function h(a){k=b(a).css("max-height",q()+"px"),j.find(".lity-loader").each(function(){var a=b(this);c(a).always(function(){a.remove()})}),j.removeClass("lity-loading").find(".lity-content").empty().append(k),m=!0,k.trigger("lity:ready",[l])}var i,j,k,l=this,m=!1,n=!1;e=b.extend({},I,e),j=b(e.template),l.element=function(){return j},l.opener=function(){return f},l.content=function(){return k},l.options=b.proxy(d,l,e),l.handlers=b.proxy(d,l,e.handlers),l.resize=function(){m&&!n&&k.css("max-height",q()+"px").trigger("lity:resize",[l])},l.close=function(){if(m&&!n){n=!0,v(l);var a=C();if(g&&(A.activeElement===j[0]||b.contains(j[0],A.activeElement)))try{g.focus()}catch(a){}return k.trigger("lity:close",[l]),j.removeClass("lity-opened").addClass("lity-closed"),c(k.add(j)).always(function(){k.trigger("lity:remove",[l]),j.remove(),j=void 0,a.resolve()}),a.promise()}},i=x(a,l,e.handlers,e.handler),j.attr(F,"false").addClass("lity-loading lity-opened lity-"+i.handler).appendTo("body").focus().on("click","[data-lity-close]",function(a){b(a.target).is("[data-lity-close]")&&l.close()}).trigger("lity:open",[l]),u(l),b.when(i.content).always(h)}function z(a,c,d){a.preventDefault?(a.preventDefault(),d=b(this),a=d.data("lity-target")||d.attr("href")||d.attr("src")):d=b(d);var e=new y(a,b.extend({},d.data("lity-options")||d.data("lity"),c),d,A.activeElement);if(!a.preventDefault)return e}var A=a.document,B=b(a),C=b.Deferred,D=b("html"),E=[],F="aria-hidden",G="lity-"+F,H='a[href],area[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),button:not([disabled]),iframe,object,embed,[contenteditable],[tabindex]:not
1022([tabindex^="-"])',I={esc:!0,handler:null,handlers:{image:j,inline:k,youtube:l,vimeo:m,googlemaps:o,facebookvideo:n,iframe:p},template:'<div class="lity" role="dialog" aria-label="Dialog Window (Press escape to close)" tabindex="-1"><div class="lity-wrap" data-lity-close role="document"><div class="lity-loader" aria-hidden="true">Loading...</div><div class="lity-container"><div class="lity-content"></div><button class="lity-close" type="button" aria-label="Close (Press escape to close)" data-lity-close>×</button></div></div></div>'},J=/(^data:image\/)|(\.(png|jpe?g|gif|svg|webp|bmp|ico|tiff?)(\?\S*)?$)/i,K=/(youtube(-nocookie)?\.com|youtu\.be)\/(watch\?v=|v\/|u\/|embed\/?)?([\w-]{11})(.*)?/i,L=/(vimeo(pro)?\.com)\/(?:[^\d]+)?(\d+)\??(.*)?$/,M=/((maps|www)\.)?google\.([^\/\?]+)\/?((maps\/?)?\?)(.*)/i,N=/(facebook\.com)\/([a-z0-9_-]*)\/videos\/([0-9]*)(.*)?$/i,O=function(){var a=A.createElement("div"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return b[c];return!1}();return j.test=function(a){return J.test(a)},z.version="3.0.0-dev",z.options=b.proxy(d,z,I),z.handlers=b.proxy(d,z,I.handlers),z.current=w,z.iframe=h,b(A).on("click.lity","[data-lity]",z),z}); 1023 1024 1025}).apply(this, [jQuery]); 1026 1027/* 1028Plugin Name: jQuery.pin 1029Written by: Okler Themes - (http://www.okler.net) 1030Version: 4.2.0 1031 1032Based on: 1033 1034 https://github.com/webpop/jquery.pin 1035 Licensed under the terms of the MIT license. 1036 1037*/ 1038(function ($) { 1039 "use strict"; 1040 $.fn.pin = function (options) { 1041 var scrollY = 0, elements = [], disabled = false, $window = $(window); 1042 1043 options = options || {}; 1044 1045 var recalculateLimits = function () { 1046 for (var i=0, len=elements.length; i<len; i++) { 1047 var $this = elements[i]; 1048 1049 if (options.minWidth && $window.width() <= options.minWidth) { 1050 if ($this.parent().is(".pin-wrapper")) { $this.unwrap(); } 1051 $this.css({width: "", left: "", top: "", position: ""}); 1052 if (options.activeClass) { $this.removeClass(options.activeClass); } 1053 disabled = true; 1054 continue; 1055 } else { 1056 disabled = false; 1057 } 1058 1059 var $container = options.containerSelector ? $this.closest(options.containerSelector) : $(document.body); 1060 var offset = $this.offset(); 1061 var containerOffset = $container.offset(); 1062 var parentOffset = $this.parent().offset(); 1063 1064 if (!$this.parent().is(".pin-wrapper")) { 1065 $this.wrap("<div class='pin-wrapper'>"); 1066 } 1067 1068 var pad = $.extend({ 1069 top: 0, 1070 bottom: 0 1071 }, options.padding || {}); 1072 1073 $this.data("pin", { 1074 pad: pad, 1075 from: (options.containerSelector ? containerOffset.top : offset.top) - pad.top, 1076 to: containerOffset.top + $container.height() - $this.outerHeight() - pad.bottom, 1077 end: containerOffset.top + $container.height(), 1078 parentTop: parentOffset.top 1079 }); 1080 1081 $this.css({width: $this.outerWidth()}); 1082 $this.parent().css("height", $this.outerHeight()); 1083 } 1084 }; 1085 1086 var onScroll = function () { 1087 if (disabled) { return; } 1088 1089 scrollY = $window.scrollTop(); 1090 1091 var elmts = []; 1092 for (var i=0, len=elements.length; i<len; i++) { 1093 var $this = $(elements[i]), 1094 data = $this.data("pin"); 1095 1096 if (!data) { // Removed element 1097 continue; 1098 } 1099 1100 elmts.push($this); 1101 1102 var from = data.from - data.pad.bottom, 1103 to = data.to - data.pad.top; 1104 1105 if (from + $this.outerHeight() > data.end) { 1106 $this.css('position', ''); 1107 continue; 1108 } 1109 1110 if (from < scrollY && to > scrollY) { 1111 !($this.css("position") == "fixed") && $this.css({ 1112 left: $this.offset().left, 1113 top: data.pad.top 1114 }).css("position", "fixed"); 1115 if (options.activeClass) { $this.addClass(options.activeClass); } 1116 } else if (scrollY >= to) { 1117 $this.css({ 1118 left: "", 1119 top: to - data.parentTop + data.pad.top 1120 }).css("position", "absolute"); 1121 if (options.activeClass) { $this.addClass(options.activeClass); } 1122 } else { 1123 $this.css({position: "", top: "", left: ""}); 1124 if (options.activeClass) { $this.removeClass(options.activeClass); } 1125 } 1126 } 1127 elements = elmts; 1128 }; 1129 1130 var update = function () { recalculateLimits(); onScroll(); }; 1131 1132 this.each(function () { 1133 var $this = $(this), 1134 data = $(this).data('pin') || {}; 1135 1136 if (data && data.update) { return; } 1137 elements.push($this); 1138 $("img", this).one("load", recalculateLimits); 1139 data.update = update; 1140 $(this).data('pin', data); 1141 }); 1142 1143 $window.scroll(onScroll); 1144 $window.resize(function () { recalculateLimits(); }); 1145 recalculateLimits(); 1146 1147 $window.load(update); 1148 1149 return this; 1150 }; 1151})(jQuery); 1152 1153 1154// Sticky 1155(function(theme, $) { 1156 1157 theme = theme || {}; 1158 1159 var instanceName = '__sticky'; 1160 1161 var PluginSticky = function($el, opts) { 1162 return this.initialize($el, opts); 1163 }; 1164 1165 PluginSticky.defaults = { 1166 minWidth: 991, 1167 activeClass: 'sticky-active' 1168 }; 1169 1170 PluginSticky.prototype = { 1171 initialize: function($el, opts) { 1172 if ( $el.data( instanceName ) ) { 1173 return this; 1174 } 1175 1176 this.$el = $el; 1177 1178 this 1179 .setData() 1180 .setOptions(opts) 1181 .build(); 1182 1183 return this; 1184 }, 1185 1186 setData: function() { 1187 this.$el.data(instanceName, this); 1188 1189 return this; 1190 }, 1191 1192 setOptions: function(opts) { 1193 this.options = $.extend(true, {}, PluginSticky.defaults, opts, { 1194 wrapper: this.$el 1195 }); 1196 1197 return this; 1198 }, 1199 1200 build: function() { 1201 if (!($.isFunction($.fn.pin))) { 1202 return this; 1203 } 1204 1205 this.options.wrapper.pin(this.options); 1206 1207 return this; 1208 } 1209 }; 1210 1211 // expose to scope 1212 $.extend(theme, { 1213 PluginSticky: PluginSticky 1214 }); 1215 1216 // jquery plugin 1217 $.fn.themePluginSticky = function(opts) { 1218 return this.map(function() { 1219 var $this = $(this); 1220 1221 if ($this.data(instanceName)) { 1222 return $this.data(instanceName); 1223 } else { 1224 return new PluginSticky($this, opts); 1225 } 1226 1227 }); 1228 } 1229 1230}).apply(this, [ window.theme, jQuery ]); 1231 1232 1233 1234 1235 1236// Sticky 1237(function($) { 1238 1239 'use strict'; 1240 1241 if ($.isFunction($.fn['themePluginSticky'])) { 1242 1243 $(function() {
1244 $('[data-plugin-sticky]:not(.manual)').each(function() { 1245 var $this = $(this), 1246 opts; 1247 1248 var pluginOptions = $this.data('plugin-options'); 1249 if (pluginOptions) 1250 opts = pluginOptions; 1251 1252 $this.themePluginSticky(opts); 1253 }); 1254 }); 1255 1256 } 1257 1258}).apply(this, [jQuery]); 1259
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.