vendor: 4,584 bytes, lines 1-150
1/*! 2 * JavaScript Cookie v2.0.4 3 * https://github.com/js-cookie/js-cookie 4 * 5 * Copyright 2006, 2015 Klaus Hartl & Fagner Brack 6 * Released under the MIT license 7 */ 8(function (factory) { 9 if (typeof define === 'function' && define.amd) { 10 define(factory); 11 } else if (typeof exports === 'object') { 12 module.exports = factory(); 13 } else { 14 var _OldCookies = window.Cookies; 15 var api = window.Cookies = factory(); 16 api.noConflict = function () { 17 window.Cookies = _OldCookies; 18 return api; 19 }; 20 } 21}(function () { 22 function extend () { 23 var i = 0; 24 var result = {}; 25 for (; i < arguments.length; i++) { 26 var attributes = arguments[ i ]; 27 for (var key in attributes) { 28 result[key] = attributes[key]; 29 } 30 } 31 return result; 32 } 33 34 function init (converter) { 35 function api (key, value, attributes) { 36 var result; 37 38 // Write 39 40 if (arguments.length > 1) { 41 attributes = extend({ 42 path: '/' 43 }, api.defaults, attributes); 44 45 if (typeof attributes.expires === 'number') { 46 var expires = new Date(); 47 expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5); 48 attributes.expires = expires; 49 } 50 51 try { 52 result = JSON.stringify(value); 53 if (/^[\{\[]/.test(result)) { 54 value = result; 55 } 56 } catch (e) {} 57 58 value = encodeURIComponent(String(value)); 59 value = value.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent); 60 61 key = encodeURIComponent(String(key)); 62 key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent); 63 key = key.replace(/[\(\)]/g, escape); 64 65 return (document.cookie = [ 66 key, '=', value, 67 attributes.expires && '; expires=' + attributes.expires.toUTCString(), // use expires attribute, max-age is not supported by IE 68 attributes.path && '; path=' + attributes.path, 69 attributes.domain && '; domain=' + attributes.domain, 70 attributes.secure ? '; secure' : '' 71 ].join('')); 72 } 73 74 // Read 75 76 if (!key) { 77 result = {}; 78 } 79 80 // To prevent the for loop in the first place assign an empty array 81 // in case there are no cookies at all. Also prevents odd result when 82 // calling "get()" 83 var cookies = document.cookie ? document.cookie.split('; ') : []; 84 var rdecode = /(%[0-9A-Z]{2})+/g; 85 var i = 0; 86 87 for (; i < cookies.length; i++) { 88 var parts = cookies[i].split('='); 89 var name = parts[0].replace(rdecode, decodeURIComponent); 90 var cookie = parts.slice(1).join('='); 91 92 if (cookie.charAt(0) === '"') { 93 cookie = cookie.slice(1, -1); 94 } 95 96 try { 97 cookie = converter && converter(cookie, name) || cookie.replace(rdecode, decodeURIComponent); 98 99 if (this.json) { 100 try { 101 cookie = JSON.parse(cookie); 102 } catch (e) {} 103 } 104 105 if (key === name) { 106 result = cookie; 107 break; 108 } 109 110 if (!key) { 111 result[name] = cookie; 112 } 113 } catch (e) {} 114 } 115 116 return result; 117 } 118 119 api.get = api.set = api; 120 api.getJSON = function () { 121 return api.apply({ 122 json: true 123 }, [].slice.call(arguments)); 124 }; 125 api.defaults = {}; 126 127 api.remove = function (key, attributes) { 128 api(key, '', extend(attributes, { 129 expires: -1 130 })); 131 }; 132 133 api.withConverter = init; 134 135 return api; 136 } 137 138 return init(); 139})); 140 141 142/** 143 * photoset-grid - v1.0.1 144 * 2014-04-08 145 * jQuery plugin to arrange images into a flexible grid 146 * http://stylehatch.github.com/photoset-grid/ 147 * 148 * Copyright 2014 Jonathan Moore - Style Hatch 149 */ 150
151/*jshint browser: true, curly: true, eqeqeq: true, forin: false, immed: false, newcap: true, noempty: true, strict: true, undef: true, devel: true */ 152;(function ( $, window, document, undefined ) { 153 154 'use strict'; 155 156 // Plugin name and default settings 157 var pluginName = "photosetGrid", 158 defaults = { 159 // Required 160 // set the width of the container 161 width : '100%', 162 // the space between the rows / columns 163 gutter : '0px', 164 165 // Optional 166 // wrap the images in a vs. div and link to the data-highres images 167 highresLinks : false, 168 // threshold for the lowres image, if container is > swap the data-highres 169 lowresWidth : 500, 170 // relational attr to apply to the links for lightbox use 171 rel : '', 172 173 // add a border to each image 174 borderActive: false, 175 // set border width 176 borderWidth: '5px', 177 // set border color 178 borderColor: '#000000', 179 // set border radius 180 borderRadius: '0', 181 // if true it will remove "double" borders 182 borderRemoveDouble: false, 183 184 // Call back events 185 onInit : function(){}, 186 onComplete : function(){} 187 }; 188 189 // Plugin constructor 190 function Plugin( element, options ) { 191 this.element = element; 192 this.options = $.extend( {}, defaults, options ); 193 194 this._defaults = defaults; 195 this._name = pluginName; 196 197 this.init(); 198 } 199 200 Plugin.prototype = { 201 202 init: function() { 203 // Call the optional onInit event set when the plugin is called 204 this.options.onInit(); 205 206 this._setupRows(this.element, this.options); 207 this._setupColumns(this.element, this.options); 208 209 }, 210 211 _callback: function(elem){ 212 // Call the optional onComplete event after the plugin has been completed 213 this.options.onComplete(elem); 214 }, 215 216 _setupRows: function( elem, options ){ 217 // Convert the layout string into an array to build the DOM structures 218 if(options.layout) { 219 // Check for layout defined in plugin call 220 this.layout = options.layout; 221 } else if($(elem).attr('data-layout')) { 222 // If not defined in the options, check for the data-layout attr 223 this.layout = $(elem).attr('data-layout'); 224 } else { 225 // Otherwise give it a stacked layout (no grids for you) 226 // Generate a layout string of all ones based on the number of images 227 var stackedLayout = ""; 228 var defaultColumns = 1; 229 for (var imgs=0; imgs<$(elem).find('img').length; imgs++ ) { 230 stackedLayout = stackedLayout + defaultColumns.toString(); 231 } 232 this.layout = stackedLayout; 233 } 234 235 // Dump the layout into a rows array 236 // Convert the array into all numbers vs. strings 237 this.rows = this.layout.split(''); 238 for (var i in this.rows ) { 239 this.rows[i] = parseInt(this.rows[i], 10); 240 } 241 242 var $images = $(elem).find('img'); 243 var imageIndex = 0; 244 245 $.each(this.rows, function(i, val){ 246 var rowStart = imageIndex; 247 var rowEnd = imageIndex + val; 248 249 // Wrap each set of images in a row into a container div 250 $images.slice(rowStart, rowEnd).wrapAll('<div class="photoset-row cols-' + val + '"></div>'); 251 252 imageIndex = rowEnd; 253 }); 254 255 $(elem).find('.photoset-row:not(:last-child)').css({ 256 'margin-bottom': options.gutter 257 }); 258 }, 259 260 _setupColumns: function( elem, options ){ 261 262 // Reference to this Plugin 263 var $this = this; 264 265 var setupStyles = function(waitForImagesLoaded){ 266 var $rows = $(elem).find('.photoset-row'); 267 var $images = $(elem).find('img'); 268 269 // Wrap the images in links to the highres or regular image 270 // Otherwise wrap in div.photoset-cell 271 if(options.highresLinks){ 272 $images.each(function(){ 273 var title; 274 // If the image has a title pass it on 275 if($(this).attr('title')){ 276 title = ' title="' + $(this).attr('title') + '"'; 277 } else { 278 title = ''; 279 } 280 var highres; 281 // If a highres image exists link it up! 282 if($(this).attr('data-highres')){ 283 highres = $(this).attr('data-highres'); 284 } else { 285 highres = $(this).attr('src'); 286 } 287 $(this).wrapAll('<a href="' + highres + '"' + title + ' class="photoset-cell highres-link" />'); 288 if(options.borderActive){ 289 $(this).wrapAll('<span class="photoset-content-border" />'); 290 } 291 }); 292 293 // Apply the optional rel 294 if(options.rel){ 295 $images.parent().attr('rel', options.rel); 296 } 297 298 } else { 299 $images.each(function(){ 300 if(options.borderActive){ 301 $(this).wrapAll('<div class="photoset-cell photoset-cell--border" />'); 302 $(this).wrapAll('<div class="photoset-content-border" />'); 303 } else { 304 $(this).wrapAll('<div class="photoset-cell" />'); 305 } 306 }); 307 } 308 309 var $cells = $(elem).find('.photoset-cell'); 310 var $cols1 = $(elem).find('.cols-1 .photoset-cell'); 311 var $cols2 = $(elem).find('.cols-2 .photoset-cell'); 312 var $cols3 = $(elem).find('.cols-3 .photoset-cell'); 313 var $cols4 = $(elem).find('.cols-4 .photoset-cell'); 314 var $cols5 = $(elem).find('.cols-5 .photoset-cell'); 315 var $cellBorder = $(elem).find('.photoset-content-border'); 316 317 // Apply styles initial structure styles to the grid 318 $(elem).css({ 319 'width': options.width 320 }); 321 $rows.css({ 322 'clear': 'left', 323 'display': 'block', 324 'overflow': 'hidden' 325 }); 326 $cells.css({ 327 'float': 'left', 328 'display': 'block', 329 'line-height': '0',
330 '-webkit-box-sizing': 'border-box', 331 '-moz-box-sizing': 'border-box', 332 'box-sizing': 'border-box' 333 }); 334 $images.css({ 335 'width': '100%', 336 'height': 'auto' 337 }); 338 if(options.borderActive){ 339 $cellBorder.css({ 340 'display': 'block', 341 'border': options.borderWidth + ' solid ' + options.borderColor, 342 'border-radius': options.borderRadius, 343 'overflow': 'hidden', 344 '-webkit-box-sizing': 'border-box', 345 '-moz-box-sizing': 'border-box', 346 'box-sizing': 'border-box' 347 }); 348 } 349 350 // if the imaged did not have height/width attr set them 351 if (waitForImagesLoaded) { 352 $images.each(function(){ 353 $(this).attr('height', $(this).height()); 354 $(this).attr('width', $(this).width()); 355 }); 356 } 357 358 // Set the width of the cells based on the number of columns in the row 359 $cols1.css({ 'width': '100%' }); 360 $cols2.css({ 'width': '50%' }); 361 $cols3.css({ 'width': '33.3%' }); 362 $cols4.css({ 'width': '25%' }); 363 $cols5.css({ 'width': '20%' }); 364 365 366 var gutterVal = parseInt(options.gutter, 10); 367 // Apply 50% gutter to left and right 368 // this provides equal gutters a high values 369 $(elem).find('.photoset-cell:not(:last-child)').css({ 370 'padding-right': (gutterVal / 2) + 'px' 371 }); 372 $(elem).find('.photoset-cell:not(:first-child)').css({ 373 'padding-left': (gutterVal / 2) + 'px' 374 }); 375 376 // If 'borderRemoveDouble' is true, let us remove the extra gutter border 377 if(options.borderRemoveDouble){ 378 $(elem).find('.photoset-row').not(':eq(0)').find('.photoset-content-border').css({'border-top': 'none'}); 379 $(elem).find('.photoset-row').not('.cols-1').find('.photoset-content-border').not(":eq(0)").css({'border-left': 'none'}); 380 } 381 382 function resizePhotosetGrid(){ 383 384 // Give the values a floor to prevent misfires 385 var w = $(elem).width().toString(); 386 387 if( w !== $(elem).attr('data-width') ) { 388 $rows.each(function(){ 389 var $shortestImg = $(this).find('img:eq(0)'); 390 391 $(this).find('img').each(function(){ 392 var $img = $(this); 393 if( $img.attr('height') < $shortestImg.attr('height') ){ 394 $shortestImg = $(this); 395 } 396 397 if(parseInt($img.css('width'), 10) > options.lowresWidth && $img.attr('data-highres')){ 398 $img.attr('src', $img.attr('data-highres')); 399 } 400 }); 401 402 // Get the row height from the calculated/real height/width of the shortest image 403 var rowHeight = ( $shortestImg.attr('height') * parseInt($shortestImg.css('width'), 10) ) / $shortestImg.attr('width'); 404 // Adding a buffer to shave off a few pixels in height 405 var bufferHeight = Math.floor(rowHeight * 0.025); 406 $(this).height( rowHeight - bufferHeight ); 407 408 // If border is set to true, then add the parent row height to each .photoset-content-border 409 if(options.borderActive){ 410 $(this).find('.photoset-content-border').each(function(){ 411 $(this).css({'height': rowHeight - bufferHeight}); 412 }); 413 } 414 415 $(this).find('img').each(function(){ 416 // Get the image height from the calculated/real height/width 417 var imageHeight = ( $(this).attr('height') * parseInt($(this).css('width'), 10) ) / $(this).attr('width'); 418 var marginOffset = ( (rowHeight - imageHeight) * 0.5 ) + 'px'; 419 $(this).css({ 420 'margin-top' : marginOffset 421 }); 422 }); 423 424 }); 425 $(elem).attr('data-width', w ); 426 } 427 428 } 429 resizePhotosetGrid(); 430 431 $(window).on("resize", function() { 432 resizePhotosetGrid(); 433 }); 434 435 }; 436 437 // By default the plugin will wait until all of the images are loaded to setup the styles 438 var waitForImagesLoaded = true; 439 var hasDimensions = true; 440 441 // Loops through all of the images in the photoset 442 // if the height and width exists for all images set waitForImagesLoaded to fal
442se 443 $(elem).find('img').each(function(){ 444 hasDimensions = hasDimensions & ( !!$(this).attr('height') & !!$(this).attr('width') ); 445 }); 446 447 waitForImagesLoaded = !hasDimensions; 448 449 // Only use imagesLoaded() if waitForImagesLoaded 450 if(waitForImagesLoaded) { 451 $(elem).imagesLoaded(function(){ 452 setupStyles(waitForImagesLoaded); 453 $this._callback(elem); 454 }); 455 } else { 456 setupStyles(waitForImagesLoaded); 457 $this._callback(elem); 458 } 459 460 461 } 462 463 }; 464 465 // plugin wrapper around the constructor 466 $.fn[pluginName] = function ( options ) { 467 return this.each(function () { 468 if (!$.data(this, "plugin_" + pluginName)) { 469 $.data(this, "plugin_" + pluginName, new Plugin( this, options )); 470 } 471 }); 472 }; 473 474 /*! 475 * jQuery imagesLoaded plugin v2.1.1 476 * http://github.com/desandro/imagesloaded 477 * 478 * MIT License. by Paul Irish et al. 479 */ 480 481 /*jshint curly: true, eqeqeq: true, noempty: true, strict: true, undef: true, browser: true */ 482 /*global jQuery: false */ 483 484 // blank image data-uri bypasses webkit log warning (thx doug jones) 485 var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=='; 486 487 $.fn.imagesLoaded = function( callback ) { 488 var $this = this, 489 deferred = $.isFunction($.Deferred) ? $.Deferred() : 0, 490 hasNotify = $.isFunction(deferred.notify), 491 $images = $this.find('img').add( $this.filter('img') ), 492 loaded = [], 493 proper = [], 494 broken = []; 495 496 // Register deferred callbacks 497 if ($.isPlainObject(callback)) { 498 $.each(callback, function (key, value) { 499 if (key === 'callback') { 500 callback = value; 501 } else if (deferred) { 502 deferred[key](value); 503 } 504 }); 505 } 506 507 function doneLoading() { 508 var $proper = $(proper), 509 $broken = $(broken); 510 511 if ( deferred ) { 512 if ( broken.length ) { 513 deferred.reject( $images, $proper, $broken ); 514 } else { 515 deferred.resolve( $images ); 516 } 517 } 518 519 if ( $.isFunction( callback ) ) { 520 callback.call( $this, $images, $proper, $broken ); 521 } 522 } 523 524 function imgLoadedHandler( event ) { 525 imgLoaded( event.target, event.type === 'error' ); 526 } 527 528 function imgLoaded( img, isBroken ) { 529 // don't proceed if BLANK image, or image is already loaded 530 if ( img.src === BLANK || $.inArray( img, loaded ) !== -1 ) { 531 return; 532 } 533 534 // store element in loaded images array 535 loaded.push( img ); 536 537 // keep track of broken and properly loaded images 538 if ( isBroken ) { 539 broken.push( img ); 540 } else { 541 proper.push( img ); 542 } 543 544 // cache image and its state for future calls 545 $.data( img, 'imagesLoaded', { isBroken: isBroken, src: img.src } ); 546 547 // trigger deferred progress method if present 548 if ( hasNotify ) { 549 deferred.notifyWith( $(img), [ isBroken, $images, $(proper), $(broken) ] ); 550 } 551 552 // call doneLoading and clean listeners if all images are loaded 553 if ( $images.length === loaded.length ) { 554 setTimeout( doneLoading ); 555 $images.unbind( '.imagesLoaded', imgLoadedHandler ); 556 } 557 } 558 559 // if no images, trigger immediately 560 if ( !$images.length ) { 561 doneLoading(); 562 } else { 563 $images.bind( 'load.imagesLoaded error.imagesLoaded', imgLoadedHandler ) 564 .each( function( i, el ) { 565 var src = el.src; 566 567 // find out if this image has been already checked for status 568 // if it was, and src has not changed, call imgLoaded on it 569 var cached = $.data( el, 'imagesLoaded' ); 570 if ( cached && cached.src === src ) { 571 imgLoaded( el, cached.isBroken ); 572 return; 573 } 574 575 // if complete is true and browser supports natural sizes, try 576 // to check for image status manually
vendor: 12,830 bytes, lines 577-903
577 if ( el.complete && el.naturalWidth !== undefined ) { 578 imgLoaded( el, el.naturalWidth === 0 || el.naturalHeight === 0 ); 579 return; 580 } 581 582 // cached images don't fire load sometimes, so we reset src, but only when 583 // dealing with IE, or image is complete (loaded) and failed manual check 584 // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f 585 if ( el.readyState || el.complete ) { 586 el.src = BLANK; 587 el.src = src; 588 } 589 }); 590 } 591 592 return deferred ? deferred.promise( $this ) : $this; 593 }; 594 595 /* 596 * throttledresize: special jQuery event that happens at a reduced rate compared to "resize" 597 * 598 * latest version and complete README available on Github: 599 * https://github.com/louisremi/jquery-smartresize 600 * 601 * Copyright 2012 @louis_remi 602 * Licensed under the MIT license. 603 * 604 * This saved you an hour of work? 605 * Send me music http://www.amazon.co.uk/wishlist/HNTU0468LQON 606 */ 607 608 var $event = $.event, 609 $special, 610 dummy = {_:0}, 611 frame = 0, 612 wasResized, animRunning; 613 614 $special = $event.special.throttledresize = { 615 setup: function() { 616 $( this ).on( "resize", $special.handler ); 617 }, 618 teardown: function() { 619 $( this ).off( "resize", $special.handler ); 620 }, 621 handler: function( event, execAsap ) { 622 // Save the context 623 var context = this, 624 args = arguments; 625 626 wasResized = true; 627 628 if ( !animRunning ) { 629 setInterval(function(){ 630 frame++; 631 632 if ( frame > $special.threshold && wasResized || execAsap ) { 633 // set correct event type 634 event.type = "throttledresize"; 635 $event.dispatch.apply( context, args ); 636 wasResized = false; 637 frame = 0; 638 } 639 if ( frame > 9 ) { 640 $(dummy).stop(); 641 animRunning = false; 642 frame = 0; 643 } 644 }, 30); 645 animRunning = true; 646 } 647 }, 648 threshold: 0 649 }; 650 651 652})( jQuery, window, document ); 653 654 655 656/*! 657 * The Final Countdown for jQuery v2.1.0 (http://hilios.github.io/jQuery.countdown/) 658 * Copyright (c) 2015 Edson Hilios 659 * 660 * Permission is hereby granted, free of charge, to any person obtaining a copy of 661 * this software and associated documentation files (the "Software"), to deal in 662 * the Software without restriction, including without limitation the rights to 663 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 664 * the Software, and to permit persons to whom the Software is furnished to do so, 665 * subject to the following conditions: 666 * 667 * The above copyright notice and this permission notice shall be included in all 668 * copies or substantial portions of the Software. 669 * 670 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 671 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 672 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 673 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 674 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 675 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 676 */ 677(function(factory) { 678 "use strict"; 679 if (typeof define === "function" && define.amd) { 680 define([ "jquery" ], factory); 681 } else { 682 factory(jQuery); 683 } 684})(function($) { 685 "use strict"; 686 var instances = [], matchers = [], defaultOptions = { 687 precision: 100, 688 elapse: false 689 }; 690 matchers.push(/^[0-9]*$/.source); 691 matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 692 matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source); 693 matchers = new RegExp(matchers.join("|")); 694 function parseDateString(dateString) { 695 if (dateString instanceof Date) { 696 return dateString; 697 } 698 if (String(dateString).match(matchers)) { 699 if (String(dateString).match(/^[0-9]*$/)) { 700 dateString = Number(dateString); 701 } 702 if (String(dateString).match(/\-/)) { 703 dateString = String(dateString).replace(/\-/g, "/"); 704 } 705 return new Date(dateString); 706 } else { 707 throw new Error("Couldn't cast `" + dateString + "` to a date object."); 708 } 709 } 710 var DIRECTIVE_KEY_MAP = { 711 Y: "years", 712 m: "months", 713 n: "daysToMonth", 714 w: "weeks", 715 d: "daysToWeek", 716 D: "totalDays", 717 H: "hours", 718 M: "minutes", 719 S: "seconds" 720 }; 721 function escapedRegExp(str) { 722 var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1"); 723 return new RegExp(sanitize); 724 } 725 function strftime(offsetObject) { 726 return function(format) { 727 var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi); 728 if (directives) { 729 for (var i = 0, len = directives.length; i < len; ++i) { 730 var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null; 731 directive = directive[2]; 732 if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) { 733 value = DIRECTIVE_KEY_MAP[directive]; 734 value = Number(offsetObject[value]); 735 } 736 if (value !== null) { 737 if (modifier === "!") { 738 value = pluralize(plural, value); 739 } 740 if (modifier === "") { 741 if (value < 10) { 742 value = "0" + value.toString(); 743 } 744 } 745 format = format.replace(regexp, value.toString()); 746 } 747 } 748 } 749 format = format.replace(/%%/, "%"); 750 return format; 751 }; 752 } 753 function pluralize(format, count) { 754 var plural = "s", singular = ""; 755 if (format) { 756 format = format.replace(/(:|;|\s)/gi, "").split(/\,/); 757 if (format.length === 1) { 758 plural = format[0]; 759 } else { 760 singular = format[0]; 761 plural = format[1]; 762 } 763 } 764 if (Math.abs(count) === 1) { 765 return singular; 766 } else { 767 return plural; 768 } 769 } 770 var Countdown = function(el, finalDate, options) { 771 this.el = el; 772 this.$el = $(el); 773 this.interval = null; 774 this.offset = {}; 775 this.options = $.extend({}, defaultOptions); 776 this.instanceNumber = instances.length; 777 instances.push(this); 778 this.$el.data("countdown-instance", this.instanceNumber); 779 if (options) { 780 if (typeof options === "function") { 781 this.$el.on("update.countdown", options); 782 this.$el.on("stoped.countdown", options); 783 this.$el.on("finish.countdown", options); 784 } else { 785 this.options = $.extend({}, defaultOptions, options); 786 } 787 } 788 this.setFinalDate(finalDate); 789 this.start(); 790 }; 791 $.extend(Countdown.prototype, { 792 start: function() { 793 if (this.interval !== null) { 794 clearInterval(this.interval); 795 } 796 var self = this; 797 this.update(); 798 this.interval = setInterval(function() { 799 self.update.call(self); 800 }, this.options.precision); 801 }, 802 stop: function() { 803 clearInterval(this.interval); 804 this.interval = null; 805 this.dispatchEvent("stoped"); 806 }, 807 toggle: function() { 808 if (this.interval) { 809 this.stop(); 810 } else { 811 this.start(); 812 } 813 }, 814 pause: function() { 815 this.stop(); 816 }, 817 resume: function() { 818 this.start(); 819 }, 820 remove: function() { 821 this.stop.call(this); 822 instances[this.instanceNumber] = null; 823 delete this.$el.data().countdownInstance; 824 }, 825 setFinalDate: function(value) { 826 this.finalDate = parseDateString(value); 827 }, 828 update: function() { 829 if (this.$el.closest("html").length === 0) { 830 this.remove(); 831 return; 832 } 833 var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft; 834 newTotalSecsLeft = this.finalDate.getTime() - now.getTime(); 835 newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3); 836 newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft); 837 if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) { 838 return; 839 } else { 840 this.totalSecsLeft = newTotalSecsLeft; 841 } 842 this.elapsed = now >= this.finalDate; 843 this.offset = { 844 seconds: this.totalSecsLeft % 60, 845 minutes: Math.floor(this.totalSecsLeft / 60) % 60, 846 hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24, 847 days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 848 daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7, 849 daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368), 850 totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24), 851 weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7), 852 months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368), 853 years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()) 854 }; 855 if (!this.options.elapse && this.totalSecsLeft === 0) { 856 this.stop(); 857 this.dispatchEvent("finish"); 858 } else { 859 this.dispatchEvent("update"); 860 } 861 }, 862 dispatchEvent: function(eventName) { 863 var event = $.Event(eventName + ".countdown"); 864 event.finalDate = this.finalDate; 865 event.elapsed = this.elapsed; 866 event.offset = $.extend({}, this.offset); 867 event.strftime = strftime(this.offset); 868 this.$el.trigger(event); 869 } 870 }); 871 $.fn.countdown = function() { 872 var argumentsArray = Array.prototype.slice.call(arguments, 0); 873 return this.each(function() { 874 var instanceNumber = $(this).data("countdown-instance"); 875 if (instanceNumber !== undefined) { 876 var instance = instances[instanceNumber], method = argumentsArray[0]; 877 if (Countdown.prototype.hasOwnProperty(method)) { 878 instance[method].apply(instance, argumentsArray.slice(1)); 879 } else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) { 880 instance.setFinalDate.call(instance, method); 881 instance.start(); 882 } else { 883 $.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method)); 884 } 885 } else { 886 new Countdown(this, argumentsArray[0], argumentsArray[1]); 887 } 888 }); 889 }; 890}); 891 892 893/*! odometer 0.4.7 894* https://github.com/HubSpot/odometer 895*/ 896(function() { 897 var COUNT_FRAMERATE, COUNT_MS_PER_FRAME, DIGIT_FORMAT, DIGIT_HTML, DIGIT_SPEEDBOOST, DURATION, FORMAT_MARK_HTML, FORMAT_PARSER, FRAMERATE, FRAMES_PER_VALUE, MS_PER_FRAME, MutationObserver, Odometer, RIBBON_HTML, TRANSITION_END_EVENTS, TRANSITION_SUPPORT, VALUE_HTML, addClass, createFromHTML, fractionalPart, now, removeClass, requestAnimationFrame, round, transitionCheckStyles, trigger, truncate, wrapJQuery, _jQueryWrapped, _old, _ref, _ref1, 898 __slice = [].slice; 899 900 VALUE_HTML = '<span class="odometer-value"></span>'; 901 902 RIBBON_HTML = '<span class="odometer-ribbon"><span class="odometer-ribbon-inner">' + VALUE_HTML + '</span></span>'; 903
vendor: 25,869 bytes, lines 904-1596
904 DIGIT_HTML = '<span class="odometer-digit"><span class="odometer-digit-spacer">8</span><span class="odometer-digit-inner">' + RIBBON_HTML + '</span></span>'; 905 906 FORMAT_MARK_HTML = '<span class="odometer-formatting-mark"></span>'; 907 908 DIGIT_FORMAT = '(,ddd).dd'; 909 910 FORMAT_PARSER = /^\(?([^)]*)\)?(?:(.)(d+))?$/; 911 912 FRAMERATE = 30; 913 914 DURATION = 2000; 915 916 COUNT_FRAMERATE = 20; 917 918 FRAMES_PER_VALUE = 2; 919 920 DIGIT_SPEEDBOOST = .5; 921 922 MS_PER_FRAME = 1000 / FRAMERATE; 923 924 COUNT_MS_PER_FRAME = 1000 / COUNT_FRAMERATE; 925 926 TRANSITION_END_EVENTS = 'transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd'; 927 928 transitionCheckStyles = document.createElement('div').style; 929 930 TRANSITION_SUPPORT = (transitionCheckStyles.transition != null) || (transitionCheckStyles.webkitTransition != null) || (transitionCheckStyles.mozTransition != null) || (transitionCheckStyles.oTransition != null); 931 932 requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; 933 934 MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; 935 936 createFromHTML = function(html) { 937 var el; 938 el = document.createElement('div'); 939 el.innerHTML = html; 940 return el.children[0]; 941 }; 942 943 removeClass = function(el, name) { 944 return el.className = el.className.replace(new RegExp("(^| )" + (name.split(' ').join('|')) + "( |$)", 'gi'), ' '); 945 }; 946 947 addClass = function(el, name) { 948 removeClass(el, name); 949 return el.className += " " + name; 950 }; 951 952 trigger = function(el, name) { 953 var evt; 954 if (document.createEvent != null) { 955 evt = document.createEvent('HTMLEvents'); 956 evt.initEvent(name, true, true); 957 return el.dispatchEvent(evt); 958 } 959 }; 960 961 now = function() { 962 var _ref, _ref1; 963 return (_ref = (_ref1 = window.performance) != null ? typeof _ref1.now === "function" ? _ref1.now() : void 0 : void 0) != null ? _ref : +(new Date); 964 }; 965 966 round = function(val, precision) { 967 if (precision == null) { 968 precision = 0; 969 } 970 if (!precision) { 971 return Math.round(val); 972 } 973 val *= Math.pow(10, precision); 974 val += 0.5; 975 val = Math.floor(val); 976 return val /= Math.pow(10, precision); 977 }; 978 979 truncate = function(val) { 980 if (val < 0) { 981 return Math.ceil(val); 982 } else { 983 return Math.floor(val); 984 } 985 }; 986 987 fractionalPart = function(val) { 988 return val - round(val); 989 }; 990 991 _jQueryWrapped = false; 992 993 (wrapJQuery = function() { 994 var property, _i, _len, _ref, _results; 995 if (_jQueryWrapped) { 996 return; 997 } 998 if (window.jQuery != null) { 999 _jQueryWrapped = true; 1000 _ref = ['html', 'text']; 1001 _results = []; 1002 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1003 property = _ref[_i]; 1004 _results.push((function(property) { 1005 var old; 1006 old = window.jQuery.fn[property]; 1007 return window.jQuery.fn[property] = function(val) { 1008 var _ref1; 1009 if ((val == null) || (((_ref1 = this[0]) != null ? _ref1.odometer : void 0) == null)) { 1010 return old.apply(this, arguments); 1011 } 1012 return this[0].odometer.update(val); 1013 }; 1014 })(property)); 1015 } 1016 return _results; 1017 } 1018 })(); 1019 1020 setTimeout(wrapJQuery, 0); 1021 1022 Odometer = (function() { 1023 function Odometer(options) { 1024 var e, k, property, v, _base, _i, _len, _ref, _ref1, _ref2, 1025 _this = this; 1026 this.options = options; 1027 this.el = this.options.el; 1028 if (this.el.odometer != null) { 1029 return this.el.odometer; 1030 } 1031 this.el.odometer = this; 1032 _ref = Odometer.options; 1033 for (k in _ref) { 1034 v = _ref[k]; 1035 if (this.options[k] == null) { 1036 this.options[k] = v; 1037 } 1038 } 1039 if ((_base = this.options).duration == null) { 1040 _base.duration = DURATION; 1041 } 1042 this.MAX_VALUES = ((this.options.duration / MS_PER_FRAME) / FRAMES_PER_VALUE) | 0; 1043 this.resetFormat(); 1044 this.value = this.cleanValue((_ref1 = this.options.value) != null ? _ref1 : ''); 1045 this.renderInside(); 1046 this.render(); 1047 try { 1048 _ref2 = ['innerHTML', 'innerText', 'textContent']; 1049 for (_i = 0, _len = _ref2.length; _i < _len; _i++) { 1050 property = _ref2[_i]; 1051 if (this.el[property] != null) { 1052 (function(property) { 1053 return Object.defineProperty(_this.el, property, { 1054 get: function() { 1055 var _ref3; 1056 if (property === 'innerHTML') { 1057 return _this.inside.outerHTML; 1058 } else { 1059 return (_ref3 = _this.inside.innerText) != null ? _ref3 : _this.inside.textContent; 1060 } 1061 }, 1062 set: function(val) { 1063 return _this.update(val); 1064 } 1065 }); 1066 })(property); 1067 } 1068 } 1069 } catch (_error) { 1070 e = _error; 1071 this.watchForMutations(); 1072 } 1073 this; 1074 } 1075 1076 Odometer.prototype.renderInside = function() { 1077 this.inside = document.createElement('div'); 1078 this.inside.className = 'odometer-inside'; 1079 this.el.innerHTML = ''; 1080 return this.el.appendChild(this.inside); 1081 }; 1082 1083 Odometer.prototype.watchForMutations = function() { 1084 var e, 1085 _this = this; 1086 if (MutationObserver == null) { 1087 return; 1088 } 1089 try { 1090 if (this.observer == null) { 1091 this.observer = new MutationObserver(function(mutations) { 1092 var newVal; 1093 newVal = _this.el.innerText; 1094 _this.renderInside(); 1095 _this.render(_this.value); 1096 return _this.update(newVal); 1097 }); 1098 } 1099 this.watchMutations = true; 1100 return this.startWatchingMutations(); 1101 } catch (_error) { 1102 e = _error; 1103 } 1104 }; 1105 1106 Odometer.prototype.startWatchingMutations = function() { 1107 if (this.watchMutations) { 1108 return this.observer.observe(this.el, { 1109 childList: true 1110 }); 1111 } 1112 }; 1113 1114 Odometer.prototype.stopWatchingMutations = function() { 1115 var _ref; 1116 return (_ref = this.observer) != null ? _ref.disconnect() : void 0; 1117 }; 1118 1119 Odometer.prototype.cleanValue = function(val) { 1120 var _ref; 1121 if (typeof val === 'string') { 1122 val = val.replace((_ref = this.format.radix) != null ? _ref : '.', '<radix>'); 1123 val = val.replace(/[.,]/g, ''); 1124 val = val.replace('<radix>', '.'); 1125 val = parseFloat(val, 10) || 0; 1126 } 1127 return round(val, this.format.precision); 1128 }; 1129 1130 Odometer.prototype.bindTransitionEnd = function() { 1131 var event, renderEnqueued, _i, _len, _ref, _results, 1132 _this = this; 1133 if (this.transitionEndBound) { 1134 return; 1135 } 1136 this.transitionEndBound = true; 1137 renderEnqueued = false; 1138 _ref = TRANSITION_END_EVENTS.split(' '); 1139 _results = []; 1140 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1141 event = _ref[_i]; 1142 _results.push(this.el.addEventListener(event, function() { 1143 if (renderEnqueued) { 1144 return true; 1145 } 1146 renderEnqueued = true; 1147 setTimeout(function() { 1148 _this.render(); 1149 renderEnqueued = false; 1150 return trigger(_this.el, 'odometerdone'); 1151 }, 0); 1152 return true; 1153 }, false)); 1154 } 1155 return _results; 1156 }; 1157 1158 Odometer.prototype.resetFormat = function() { 1159 var format, fractional, parsed, precision, radix, repeating, _ref, _ref1; 1160 format = (_ref = this.options.format) != null ? _ref : DIGIT_FORMAT; 1161 format || (format = 'd'); 1162 parsed = FORMAT_PARSER.exec(format); 1163 if (!parsed) { 1164 throw new Error("Odometer: Unparsable digit format"); 1165 } 1166 _ref1 = parsed.slice(1, 4), repeating = _ref1[0], radix = _ref1[1], fractional = _ref1[2]; 1167 precision = (fractional != null ? fractional.length : void 0) || 0; 1168 return this.format = { 1169 repeating: repeating, 1170 radix: radix, 1171 precision: precision 1172 }; 1173 }; 1174 1175 Odometer.prototype.render = function(value) { 1176 var classes, cls, match, newClasses, theme, _i, _len; 1177 if (value == null) { 1178 value = this.value; 1179 } 1180 this.stopWatchingMutations(); 1181 this.resetFormat(); 1182 this.inside.innerHTML = ''; 1183 theme = this.options.theme; 1184 classes = this.el.className.split(' '); 1185 newClasses = []; 1186 for (_i = 0, _len = classes.length; _i < _len; _i++) { 1187 cls = classes[_i]; 1188 if (!cls.length) { 1189 continue; 1190 } 1191 if (match = /^odometer-theme-(.+)$/.exec(cls)) { 1192 theme = match[1]; 1193 continue; 1194 } 1195 if (/^odometer(-|$)/.test(cls)) { 1196 continue; 1197 } 1198 newClasses.push(cls); 1199 } 1200 newClasses.push('odometer'); 1201 if (!TRANSITION_SUPPORT) { 1202 newClasses.push('odometer-no-transitions'); 1203 } 1204 if (theme) { 1205 newClasses.push("odometer-theme-" + theme); 1206 } else { 1207 newClasses.push("odometer-auto-theme"); 1208 } 1209 this.el.className = newClasses.join(' '); 1210 this.ribbons = {}; 1211 this.formatDigits(value); 1212 return this.startWatchingMutations(); 1213 }; 1214 1215 Odometer.prototype.formatDigits = function(value) { 1216 var digit, valueDigit, valueString, wholePart, _i, _j, _len, _len1, _ref, _ref1; 1217 this.digits = []; 1218 if (this.options.formatFunction) { 1219 valueString = this.options.formatFunction(value); 1220 _ref = valueString.split('').reverse(); 1221 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1222 valueDigit = _ref[_i]; 1223 if (valueDigit.match(/0-9/)) { 1224 digit = this.renderDigit(); 1225 digit.querySelector('.odometer-value').innerHTML = valueDigit; 1226 this.digits.push(digit); 1227 this.insertDigit(digit); 1228 } else { 1229 this.addSpacer(valueDigit); 1230 } 1231 } 1232 } else { 1233 wholePart = !this.format.precision || !fractionalPart(value) || false; 1234 _ref1 = value.toString().split('').reverse(); 1235 for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { 1236 digit = _ref1[_j]; 1237 if (digit === '.') { 1238 wholePart = true; 1239 } 1240 this.addDigit(digit, wholePart); 1241 } 1242 } 1243 }; 1244 1245 Odometer.prototype.update = function(newValue) { 1246 var diff, 1247 _this = this; 1248 newValue = this.cleanValue(newValue); 1249 if (!(diff = newValue - this.value)) { 1250 return; 1251 } 1252 removeClass(this.el, 'odometer-animating-up odometer-animating-down odometer-animating'); 1253 if (diff > 0) { 1254 addClass(this.el, 'odometer-animating-up'); 1255 } else { 1256 addClass(this.el, 'odometer-animating-down'); 1257 } 1258 this.stopWatchingMutations(); 1259 this.animate(newValue); 1260 this.startWatchingMutations(); 1261 setTimeout(function() { 1262 _this.el.offsetHeight; 1263 return addClass(_this.el, 'odometer-animating'); 1264 }, 0); 1265 return this.value = newValue; 1266 }; 1267 1268 Odometer.prototype.renderDigit = function() { 1269 return createFromHTML(DIGIT_HTML); 1270 }; 1271 1272 Odometer.prototype.insertDigit = function(digit, before) { 1273 if (before != null) { 1274 return this.inside.insertBefore(digit, before); 1275 } else if (!this.inside.children.length) { 1276 return this.inside.appendChild(digit); 1277 } else { 1278 return this.inside.insertBefore(digit, this.inside.children[0]); 1279 } 1280 }; 1281 1282 Odometer.prototype.addSpacer = function(chr, before, extraClasses) { 1283 var spacer; 1284 spacer = createFromHTML(FORMAT_MARK_HTML); 1285 spacer.innerHTML = chr; 1286 if (extraClasses) { 1287 addClass(spacer, extraClasses); 1288 } 1289 return this.insertDigit(spacer, before); 1290 }; 1291 1292 Odometer.prototype.addDigit = function(value, repeating) { 1293 var chr, digit, resetted, _ref; 1294 if (repeating == null) { 1295 repeating = true; 1296 } 1297 if (value === '-') { 1298 return this.addSpacer(value, null, 'odometer-negation-mark'); 1299 } 1300 if (value === '.') { 1301 return this.addSpacer((_ref = this.format.radix) != null ? _ref : '.', null, 'odometer-radix-mark'); 1302 } 1303 if (repeating) { 1304 resetted = false; 1305 while (true) { 1306 if (!this.format.repeating.length) { 1307 if (resetted) { 1308 throw new Error("Bad odometer format without digits"); 1309 } 1310 this.resetFormat(); 1311 resetted = true; 1312 } 1313 chr = this.format.repeating[this.format.repeating.length - 1]; 1314 this.format.repeating = this.format.repeating.substring(0, this.format.repeating.length - 1); 1315 if (chr === 'd') { 1316 break; 1317 } 1318 this.addSpacer(chr); 1319 } 1320 } 1321 digit = this.renderDigit(); 1322 digit.querySelector('.odometer-value').innerHTML = value; 1323 this.digits.push(digit); 1324 return this.insertDigit(digit); 1325 }; 1326 1327 Odometer.prototype.animate = function(newValue) { 1328 if (!TRANSITION_SUPPORT || this.options.animation === 'count') { 1329 return this.animateCount(newValue); 1330 } else { 1331 return this.animateSlide(newValue); 1332 } 1333 }; 1334 1335 Odometer.prototype.animateCount = function(newValue) { 1336 var cur, diff, last, start, tick, 1337 _this = this; 1338 if (!(diff = +newValue - this.value)) { 1339 return; 1340 } 1341 start = last = now(); 1342 cur = this.value; 1343 return (tick = function() { 1344 var delta, dist, fraction; 1345 if ((now() - start) > _this.options.duration) { 1346 _this.value = newValue; 1347 _this.render(); 1348 trigger(_this.el, 'odometerdone'); 1349 return; 1350 } 1351 delta = now() - last; 1352 if (delta > COUNT_MS_PER_FRAME) { 1353 last = now(); 1354 fraction = delta / _this.options.duration; 1355 dist = diff * fraction; 1356 cur += dist; 1357 _this.render(Math.round(cur)); 1358 } 1359 if (requestAnimationFrame != null) { 1360 return requestAnimationFrame(tick); 1361 } else { 1362 return setTimeout(tick, COUNT_MS_PER_FRAME); 1363 } 1364 })(); 1365 }; 1366 1367 Odometer.prototype.getDigitCount = function() { 1368 var i, max, value, values, _i, _len; 1369 values = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 1370 for (i = _i = 0, _len = values.length; _i < _len; i = ++_i) { 1371 value = values[i]; 1372 values[i] = Math.abs(value); 1373 } 1374 max = Math.max.apply(Math, values); 1375 return Math.ceil(Math.log(max + 1) / Math.log(10)); 1376 }; 1377 1378 Odometer.prototype.getFractionalDigitCount = function() { 1379 var i, parser, parts, value, values, _i, _len; 1380 values = 1 <= arguments.length ? __slice.call(arguments, 0) : []; 1381 parser = /^\-?\d*\.(\d*?)0*$/; 1382 for (i = _i = 0, _len = values.length; _i < _len; i = ++_i) { 1383 value = values[i]; 1384 values[i] = value.toString(); 1385 parts = parser.exec(values[i]); 1386 if (parts == null) { 1387 values[i] = 0; 1388 } else { 1389 values[i] = parts[1].length; 1390 } 1391 } 1392 return Math.max.apply(Math, values); 1393 }; 1394 1395 Odometer.prototype.resetDigits = function() { 1396 this.digits = []; 1397 this.ribbons = []; 1398 this.inside.innerHTML = ''; 1399 return this.resetFormat(); 1400 }; 1401 1402 Odometer.prototype.animateSlide = function(newValue) { 1403 var boosted, cur, diff, digitCount, digits, dist, end, fractionalCount, frame, frames, i, incr, j, mark, numEl, oldValue, start, _base, _i, _j, _k, _l, _len, _len1, _len2, _m, _ref, _results; 1404 oldValue = this.value; 1405 fractionalCount = this.getFractionalDigitCount(oldValue, newValue); 1406 if (fractionalCount) { 1407 newValue = newValue * Math.pow(10, fractionalCount); 1408 oldValue = oldValue * Math.pow(10, fractionalCount); 1409 } 1410 if (!(diff = newValue - oldValue)) { 1411 return; 1412 } 1413 this.bindTransitionEnd(); 1414 digitCount = this.getDigitCount(oldValue, newValue); 1415 digits = []; 1416 boosted = 0; 1417 for (i = _i = 0; 0 <= digitCount ? _i < digitCount : _i > digitCount; i = 0 <= digitCount ? ++_i : --_i) { 1418 start = truncate(oldValue / Math.pow(10, digitCount - i - 1)); 1419 end = truncate(newValue / Math.pow(10, digitCount - i - 1)); 1420 dist = end - start; 1421 if (Math.abs(dist) > this.MAX_VALUES) { 1422 frames = []; 1423 incr = dist / (this.MAX_VALUES + this.MAX_VALUES * boosted * DIGIT_SPEEDBOOST); 1424 cur = start; 1425 while ((dist > 0 && cur < end) || (dist < 0 && cur > end)) { 1426 frames.push(Math.round(cur)); 1427 cur += incr; 1428 } 1429 if (frames[frames.length - 1] !== end) { 1430 frames.push(end); 1431 } 1432 boosted++; 1433 } else { 1434 frames = (function() { 1435 _results = []; 1436 for (var _j = start; start <= end ? _j <= end : _j >= end; start <= end ? _j++ : _j--){ _results.push(_j); } 1437 return _results; 1438 }).apply(this); 1439 } 1440 for (i = _k = 0, _len = frames.length; _k < _len; i = ++_k) { 1441 frame = frames[i]; 1442 frames[i] = Math.abs(frame % 10); 1443 } 1444 digits.push(frames); 1445 } 1446 this.resetDigits(); 1447 _ref = digits.reverse(); 1448 for (i = _l = 0, _len1 = _ref.length; _l < _len1; i = ++_l) { 1449 frames = _ref[i]; 1450 if (!this.digits[i]) { 1451 this.addDigit(' ', i >= fractionalCount); 1452 } 1453 if ((_base = this.ribbons)[i] == null) { 1454 _base[i] = this.digits[i].querySelector('.odometer-ribbon-inner'); 1455 } 1456 this.ribbons[i].innerHTML = ''; 1457 if (diff < 0) { 1458 frames = frames.reverse(); 1459 } 1460 for (j = _m = 0, _len2 = frames.length; _m < _len2; j = ++_m) { 1461 frame = frames[j]; 1462 numEl = document.createElement('div'); 1463 numEl.className = 'odometer-value'; 1464 numEl.innerHTML = frame; 1465 this.ribbons[i].appendChild(numEl); 1466 if (j === frames.length - 1) { 1467 addClass(numEl, 'odometer-last-value'); 1468 } 1469 if (j === 0) { 1470 addClass(numEl, 'odometer-first-value'); 1471 } 1472 } 1473 } 1474 if (start < 0) { 1475 this.addDigit('-'); 1476 } 1477 mark = this.inside.querySelector('.odometer-radix-mark'); 1478 if (mark != null) { 1479 mark.parent.removeChild(mark); 1480 } 1481 if (fractionalCount) { 1482 return this.addSpacer(this.format.radix, this.digits[fractionalCount - 1], 'odometer-radix-mark'); 1483 } 1484 }; 1485 1486 return Odometer; 1487 1488 })(); 1489 1490 Odometer.options = (_ref = window.odometerOptions) != null ? _ref : {}; 1491 1492 setTimeout(function() { 1493 var k, v, _base, _ref1, _results; 1494 if (window.odometerOptions) { 1495 _ref1 = window.odometerOptions; 1496 _results = []; 1497 for (k in _ref1) { 1498 v = _ref1[k]; 1499 _results.push((_base = Odometer.options)[k] != null ? (_base = Odometer.options)[k] : _base[k] = v); 1500 } 1501 return _results; 1502 } 1503 }, 0); 1504 1505 Odometer.init = function() { 1506 var el, elements, _i, _len, _ref1, _results; 1507 if (document.querySelectorAll == null) { 1508 return; 1509 } 1510 elements = document.querySelectorAll(Odometer.options.selector || '.odometer'); 1511 _results = []; 1512 for (_i = 0, _len = elements.length; _i < _len; _i++) { 1513 el = elements[_i]; 1514 _results.push(el.odometer = new Odometer({ 1515 el: el, 1516 value: (_ref1 = el.innerText) != null ? _ref1 : el.textContent 1517 })); 1518 } 1519 return _results; 1520 }; 1521 1522 if ((((_ref1 = document.documentElement) != null ? _ref1.doScroll : void 0) != null) && (document.createEventObject != null)) { 1523 _old = document.onreadystatechange; 1524 document.onreadystatechange = function() { 1525 if (document.readyState === 'complete' && Odometer.options.auto !== false) { 1526 Odometer.init(); 1527 } 1528 return _old != null ? _old.apply(this, arguments) : void 0; 1529 }; 1530 } else { 1531 document.addEventListener('DOMContentLoaded', function() { 1532 if (Odometer.options.auto !== false) { 1533 return Odometer.init(); 1534 } 1535 }, false); 1536 } 1537 1538 if (typeof define === 'function' && define.amd) { 1539 define(['jquery'], function() { 1540 return Odometer; 1541 }); 1542 } else if (typeof exports !== "undefined" && exports !== null) { 1543 module.exports = Odometer; 1544 } else { 1545 window.Odometer = Odometer; 1546 } 1547 1548}).call(this); 1549 1550 1551/** @preserve jQuery animateNumber plugin v0.0.11 1552 * (c) 2013, Alexandr Borisov. 1553 * https://github.com/aishek/jquery-animateNumber 1554 */ 1555 1556// ['...'] notation using to avoid names minification by Google Closure Compiler 1557(function($) { 1558 var reverse = function(value) { 1559 return value.split('').reverse().join(''); 1560 }; 1561 1562 var defaults = { 1563 numberStep: function(now, tween) { 1564 var floored_number = Math.floor(now), 1565 target = $(tween.elem); 1566 1567 target.text(floored_number); 1568 } 1569 }; 1570 1571 var handle = function( tween ) { 1572 var elem = tween.elem; 1573 if ( elem.nodeType && elem.parentNode ) { 1574 var handler = elem._animateNumberSetter; 1575 if (!handler) { 1576 handler = defaults.numberStep; 1577 } 1578 handler(tween.now, tween); 1579 } 1580 }; 1581 1582 if (!$.Tween || !$.Tween.propHooks) { 1583 $.fx.step.number = handle; 1584 } else { 1585 $.Tween.propHooks.number = { 1586 set: handle 1587 }; 1588 } 1589 1590 var extract_number_parts = function(separated_number, group_length) { 1591 var numbers = separated_number.split('').reverse(), 1592 number_parts = [], 1593 current_number_part, 1594 current_index, 1595 q; 1596
1597 for(var i = 0, l = Math.ceil(separated_number.length / group_length); i < l; i++) { 1598 current_number_part = ''; 1599 for(q = 0; q < group_length; q++) { 1600 current_index = i * group_length + q; 1601 if (current_index === separated_number.length) { 1602 break; 1603 } 1604 1605 current_number_part = current_number_part + numbers[current_index]; 1606 } 1607 number_parts.push(current_number_part); 1608 } 1609 1610 return number_parts; 1611 }; 1612 1613 var remove_precending_zeros = function(number_parts) { 1614 var last_index = number_parts.length - 1, 1615 last = reverse(number_parts[last_index]); 1616 1617 number_parts[last_index] = reverse(parseInt(last, 10).toString()); 1618 return number_parts; 1619 }; 1620 1621 $.animateNumber = { 1622 numberStepFactories: { 1623 /** 1624 * Creates numberStep handler, which appends string to floored animated number on each step. 1625 * 1626 * @example 1627 * // will animate to 100 with "1 %", "2 %", "3 %", ... 1628 * $('#someid').animateNumber({ 1629 * number: 100, 1630 * numberStep: $.animateNumber.numberStepFactories.append(' %') 1631 * }); 1632 * 1633 * @params {String} suffix string to append to animated number 1634 * @returns {Function} numberStep-compatible function for use in animateNumber's parameters 1635 */ 1636 append: function(suffix) { 1637 return function(now, tween) { 1638 var floored_number = Math.floor(now), 1639 target = $(tween.elem); 1640 1641 target.prop('number', now).text(floored_number + suffix); 1642 }; 1643 }, 1644 1645 /** 1646 * Creates numberStep handler, which format floored numbers by separating them to groups. 1647 * 1648 * @example 1649 * // will animate with 1 ... 217,980 ... 95,217,980 ... 7,095,217,980 1650 * $('#world-population').animateNumber({ 1651 * number: 7095217980, 1652 * numberStep: $.animateNumber.numberStepFactories.separator(',') 1653 * }); 1654 * 1655 * @params {String} [separator=' '] string to separate number groups 1656 * @params {String} [group_length=3] number group length 1657 * @returns {Function} numberStep-compatible function for use in animateNumber's parameters 1658 */ 1659 separator: function(separator, group_length) { 1660 separator = separator || ' '; 1661 group_length = group_length || 3; 1662 1663 return function(now, tween) { 1664 var floored_number = Math.floor(now), 1665 separated_number = floored_number.toString(), 1666 target = $(tween.elem); 1667 1668 if (separated_number.length > group_length) { 1669 var number_parts = extract_number_parts(separated_number, group_length); 1670 1671 separated_number = remove_precending_zeros(number_parts).join(separator); 1672 separated_number = reverse(separated_number); 1673 } 1674 1675 target.prop('number', now).text(separated_number); 1676 }; 1677 } 1678 } 1679 }; 1680 1681 $.fn.animateNumber = function() { 1682 var options = arguments[0], 1683 settings = $.extend({}, defaults, options), 1684 1685 target = $(this), 1686 args = [settings]; 1687 1688 for(var i = 1, l = arguments.length; i < l; i++) { 1689 args.push(arguments[i]); 1690 } 1691 1692 // needs of custom step function usage 1693 if (options.numberStep) { 1694 // assigns custom step functions 1695 var items = this.each(function(){ 1696 this._animateNumberSetter = options.numberStep; 1697 }); 1698 1699 // cleanup of custom step functions after animation 1700 var generic_complete = settings.complete; 1701 settings.complete = function() { 1702 items.each(function(){ 1703 delete this._animateNumberSetter; 1704 }); 1705 1706 if ( generic_complete ) { 1707 generic_complete.apply(this, arguments); 1708 } 1709 }; 1710 } 1711 1712 return target.animate.apply(target, args); 1713 }; 1714 1715}(jQuery)); 1716 1717 1718 1719/*! 1720 Ridiculously Responsive Social Sharing Buttons 1721 Team: @dbox, @joshuatuscan
1722 Site: http://www.kurtnoble.com/labs/rrssb 1723 Twitter: @therealkni 1724 1725 ___ ___ 1726 /__/| /__/\ ___ 1727 | |:| \ \:\ / /\ 1728 | |:| \ \:\ / /:/ 1729 __| |:| _____\__\:\ /__/::\ 1730 /__/\_|:|____ /__/::::::::\ \__\/\:\__ 1731 \ \:\/:::::/ \ \:\~~\~~\/ \ \:\/\ 1732 \ \::/~~~~ \ \:\ ~~~ \__\::/ 1733 \ \:\ \ \:\ /__/:/ 1734 \ \:\ \ \:\ \__\/ 1735 \__\/ \__\/ 1736 */ 1737 1738+(function(window, $, undefined) { 1739 'use strict'; 1740 1741 var support = { 1742 calc : false 1743 }; 1744 1745 /* 1746 * Public Function 1747 */ 1748 1749 $.fn.rrssb = function( options ) { 1750 1751 // Settings that $.rrssb() will accept. 1752 var settings = $.extend({ 1753 description: undefined, 1754 emailAddress: undefined, 1755 emailBody: undefined, 1756 emailSubject: undefined, 1757 image: undefined, 1758 title: undefined, 1759 url: undefined 1760 }, options ); 1761 1762 // Return the encoded strings if the settings have been changed. 1763 for (var key in settings) { 1764 if (settings.hasOwnProperty(key) && settings[key] !== undefined) { 1765 settings[key] = encodeString(settings[key]); 1766 } 1767 }; 1768 1769 if (settings.url !== undefined) { 1770 $(this).find('.rrssb-facebook a').attr('href', 'https://www.facebook.com/sharer/sharer.php?u=' + settings.url); 1771 $(this).find('.rrssb-tumblr a').attr('href', 'http://tumblr.com/share/link?url=' + settings.url + (settings.title !== undefined ? '&name=' + settings.title : '') + (settings.description !== undefined ? '&description=' + settings.description : '')); 1772 $(this).find('.rrssb-linkedin a').attr('href', 'http://www.linkedin.com/shareArticle?mini=true&url=' + settings.url + (settings.title !== undefined ? '&title=' + settings.title : '') + (settings.description !== undefined ? '&summary=' + settings.description : '')); 1773 $(this).find('.rrssb-twitter a').attr('href', 'http://twitter.com/home?status=' + (settings.description !== undefined ? settings.description : '') + '%20' + settings.url); 1774 $(this).find('.rrssb-hackernews a').attr('href', 'https://news.ycombinator.com/submitlink?u=' + settings.url + (settings.title !== undefined ? '&text=' + settings.title : '')); 1775 $(this).find('.rrssb-reddit a').attr('href', 'http://www.reddit.com/submit?url=' + settings.url + (settings.description !== undefined ? '&text=' + settings.description : '') + (settings.title !== undefined ? '&title=' + settings.title : '')); 1776 $(this).find('.rrssb-googleplus a').attr('href', 'https://plus.google.com/share?url=' + (settings.description !== undefined ? settings.description : '') + '%20' + settings.url); 1777 $(this).find('.rrssb-pinterest a').attr('href', 'http://pinterest.com/pin/create/button/?url=' + settings.url + ((settings.image !== undefined) ? '&media=' + settings.image : '') + (settings.description !== undefined ? '&description=' + settings.description : '')); 1778 $(this).find('.rrssb-pocket a').attr('href', 'https://getpocket.com/save?url=' + settings.url); 1779 $(this).find('.rrssb-github a').attr('href', settings.url); 1780 } 1781 1782 if (settings.emailAddress !== undefined) { 1783 $(this).find('.rrssb-email a').attr('href', 'mailto:' + settings.emailAddress + '?' + (settings.emailSubject !== undefined ? 'subject=' + settings.emailSubject : '') + (settings.emailBody !== undefined ? '&body=' + settings.emailBody : '')); 1784 } 1785 1786 }; 1787 1788 /* 1789 * Utility functions 1790 */ 1791 var detectCalcSupport = function(){ 1792 //detect if calc is natively supported. 1793 var el = $('<div>'); 1794 var calcProps = [ 1795 'calc', 1796 '-webkit-calc', 1797 '-moz-calc' 1798 ]; 1799 1800 $('body').append(el); 1801 1802 for (var i=0; i < calcProps.length; i++) { 1803 el.css('width', calcProps[i] + '(1px)'); 1804 if(el.width() === 1){ 1805 support.calc = calcProps[i]; 1806 break; 1807 } 1808 } 1809 1810 el.remove(); 1811 }; 1812 1813 var encodeString = function(string) { 1814 // Recursively decode string first to ensure we aren't double encoding.
1815 if (string !== undefined && string !== null) { 1816 if (string.match(/%[0-9a-f]{2}/i) !== null) { 1817 string = decodeURIComponent(string); 1818 encodeString(string); 1819 } else { 1820 return encodeURIComponent(string); 1821 } 1822 } 1823 }; 1824 1825 var setPercentBtns = function() { 1826 // loop through each instance of buttons 1827 $('.rrssb-buttons').each(function(index) { 1828 var self = $(this); 1829 var buttons = $('li:visible', self); 1830 var numOfButtons = buttons.length; 1831 var initBtnWidth = 100 / numOfButtons; 1832 1833 // set initial width of buttons 1834 buttons.css('width', initBtnWidth + '%').attr('data-initwidth',initBtnWidth); 1835 }); 1836 }; 1837 1838 var makeExtremityBtns = function() { 1839 // loop through each instance of buttons 1840 $('.rrssb-buttons').each(function(index) { 1841 var self = $(this); 1842 //get button width 1843 var containerWidth = self.width(); 1844 var buttonWidth = $('li', self).not('.small').first().width(); 1845 1846 // enlarge buttons if they get wide enough 1847 if (buttonWidth > 170 && $('li.small', self).length < 1) { 1848 self.addClass('large-format'); 1849 } else { 1850 self.removeClass('large-format'); 1851 } 1852 1853 if (containerWidth < 200) { 1854 self.removeClass('small-format').addClass('tiny-format'); 1855 } else { 1856 self.removeClass('tiny-format'); 1857 } 1858 }); 1859 }; 1860 1861 var backUpFromSmall = function() { 1862 // loop through each instance of buttons 1863 $('.rrssb-buttons').each(function(index) { 1864 var self = $(this); 1865 1866 var buttons = $('li', self); 1867 var smallButtons = buttons.filter('.small'); 1868 var totalBtnSze = 0; 1869 var totalTxtSze = 0; 1870 var upCandidate = smallButtons.first(); 1871 var nextBackUp = parseFloat(upCandidate.attr('data-size')) + 55; 1872 var smallBtnCount = smallButtons.length; 1873 1874 if (smallBtnCount === buttons.length) { 1875 var btnCalc = smallBtnCount * 42; 1876 var containerWidth = self.width(); 1877 1878 if ((btnCalc + nextBackUp) < containerWidth) { 1879 self.removeClass('small-format'); 1880 smallButtons.first().removeClass('small'); 1881 1882 sizeSmallBtns(); 1883 } 1884 1885 } else { 1886 buttons.not('.small').each(function(index) { 1887 var button = $(this); 1888 var txtWidth = parseFloat(button.attr('data-size')) + 55; 1889 var btnWidth = parseFloat(button.width()); 1890 1891 totalBtnSze = totalBtnSze + btnWidth; 1892 totalTxtSze = totalTxtSze + txtWidth; 1893 }); 1894 1895 var spaceLeft = totalBtnSze - totalTxtSze; 1896 1897 if (nextBackUp < spaceLeft) { 1898 upCandidate.removeClass('small'); 1899 sizeSmallBtns(); 1900 } 1901 } 1902 }); 1903 }; 1904 1905 var checkSize = function(init) { 1906 // loop through each instance of buttons 1907 $('.rrssb-buttons').each(function(index) { 1908 1909 var self = $(this); 1910 var buttons = $('li', self); 1911 1912 // get buttons in reverse order and loop through each 1913 $(buttons.get().reverse()).each(function(index, count) { 1914 1915 var button = $(this); 1916 1917 if (button.hasClass('small') === false) { 1918 var txtWidth = parseFloat(button.attr('data-size')) + 55; 1919 var btnWidth = parseFloat(button.width()); 1920 1921 if (txtWidth > btnWidth) { 1922 var btn2small = buttons.not('.small').last(); 1923 $(btn2small).addClass('small'); 1924 sizeSmallBtns(); 1925 } 1926 } 1927 1928 if (!--count) backUpFromSmall(); 1929 }); 1930 }); 1931 1932 // if first time running, put it through the magic layout 1933 if (init === true) { 1934 rrssbMagicLayout(sizeSmallBtns); 1935 } 1936 }; 1937 1938 var sizeSmallBtns = function() { 1939 // loop through each instance of buttons 1940 $('.rrssb-buttons').each(function(index) { 1941 var self = $(this); 1942 var regButtonCount; 1943 var regPercent; 1944 var pixelsOff; 1945 var magicWidth; 1946 var smallBtnFraction; 1947 var buttons = $('li', self); 1948 var smallButtons = buttons.filter('.small'); 1949 1950 // readjust buttons for small display 1951 var smallBtnCount = smallButtons.length; 1952 1953 // make sure there are small buttons 1954 if (smallBtnCount > 0 && smallBtnCount !== buttons.length) { 1955 self.removeClass('small-format'); 1956 1957 //make sure small buttons are square when not all small 1958 smallButtons.css('width','42px'); 1959 pixelsOff = smallBtnCount * 42; 1960 regButtonCount = buttons.not('.small').length; 1961 regPercent = 100 / regButtonCount; 1962 smallBtnFraction = pixelsOff / regButtonCount; 1963 1964 // if calc is not supported. calculate the width on the fly. 1965 if (support.calc === false) { 1966 magicWidth = ((self.innerWidth()-1) / regButtonCount) - smallBtnFraction; 1967 magicWidth = Math.floor(magicWidth*1000) / 1000; 1968 magicWidth += 'px'; 1969 } else { 1970 magicWidth = support.calc+'('+regPercent+'% - '+smallBtnFraction+'px)'; 1971 } 1972 1973 buttons.not('.small').css('width', magicWidth); 1974 1975 } else if (smallBtnCount === buttons.length) { 1976 // if all buttons are small, change back to percentage 1977 self.addClass('small-format'); 1978 setPercentBtns(); 1979 } else { 1980 self.removeClass('small-format'); 1981 setPercentBtns(); 1982 } 1983 }); //end loop 1984 1985 makeExtremityBtns(); 1986 }; 1987 1988 var rrssbInit = function() { 1989 $('.rrssb-buttons').each(function(index) { 1990 $(this).addClass('rrssb-'+(index + 1)); 1991 }); 1992 1993 detectCalcSupport(); 1994 1995 setPercentBtns(); 1996 1997 // grab initial text width of each button and add as data attr 1998 $('.rrssb-buttons li .rrssb-text').each(function(index) { 1999 var buttonTxt = $(this);
2000 var txtWdth = buttonTxt.width(); 2001 buttonTxt.closest('li').attr('data-size', txtWdth); 2002 }); 2003 2004 checkSize(true); 2005 }; 2006 2007 var rrssbMagicLayout = function(callback) { 2008 //remove small buttons before each conversion try 2009 $('.rrssb-buttons li.small').removeClass('small'); 2010 2011 checkSize(); 2012 2013 callback(); 2014 }; 2015 2016 var popupCenter = function(url, title, w, h) { 2017 // Fixes dual-screen position Most browsers Firefox 2018 var dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left; 2019 var dualScreenTop = window.screenTop !== undefined ? window.screenTop : screen.top; 2020 2021 var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width; 2022 var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height; 2023 2024 var left = ((width / 2) - (w / 2)) + dualScreenLeft; 2025 var top = ((height / 3) - (h / 3)) + dualScreenTop; 2026 2027 var newWindow = window.open(url, title, 'scrollbars=yes, width=' + w + ', height=' + h + ', top=' + top + ', left=' + left); 2028
2029 // Puts focus on the newWindow 2030 if (window.focus) { 2031 newWindow.focus(); 2032 } 2033 }; 2034 2035 var waitForFinalEvent = (function () { 2036 var timers = {}; 2037 return function (callback, ms, uniqueId) { 2038 if (!uniqueId) { 2039 uniqueId = "Don't call this twice without a uniqueId"; 2040 } 2041 if (timers[uniqueId]) { 2042 clearTimeout (timers[uniqueId]); 2043 } 2044 timers[uniqueId] = setTimeout(callback, ms); 2045 }; 2046 })(); 2047 2048 // init load 2049 $(document).ready(function(){ 2050 /* 2051 * Event listners 2052 */ 2053 2054 $(document).on('click', '.rrssb-buttons a.popup', {}, function popUp(e) { 2055 var self = $(this); 2056 popupCenter(self.attr('href'), self.find('.rrssb-text').html(), 580, 470); 2057 e.preventDefault(); 2058 }); 2059 2060 // resize function 2061 $(window).resize(function () { 2062 2063 rrssbMagicLayout(sizeSmallBtns); 2064 2065 waitForFinalEvent(function(){ 2066 rrssbMagicLayout(sizeSmallBtns); 2067 }, 200, "finished resizing"); 2068 }); 2069 2070 rrssbInit(); 2071 }); 2072 2073 // Make global 2074 window.rrssbInit = rrssbInit; 2075 2076})(window, jQuery); 2077 2078 2079/*********** 2080 Animates element's number to new number with commas 2081 Parameters: 2082 commas (boolean): turn commas on/off (default is true) 2083 duration (number): how long in ms (default is 1000) 2084 ease (string): type of easing (default is "swing", others are avaiable from jQuery's easing plugin 2085 Examples: 2086 $("#div").animateNumbers(false, 500, "linear"); // half second linear without commas 2087 $("#div").animateNumbers(true, 2000); // two second swing with commas 2088 $("#div").animateNumbers(); // one second swing with commas 2089 This fully expects an element containing an integer and with a attribute named data-stop specifying the number at which the stats needs to stop 2090 If the number is within copy then separate it with a span and target the span 2091 Inserts and accounts for commas during animation by default 2092 ***********/ 2093 2094(function($) { 2095 $.fn.animateNumbers = function(commas, duration, ease) { 2096 return this.each(function() { 2097 var $this = $(this); 2098 var start = parseInt($this.text().replace(/,/g, "")); 2099 var stop = parseInt($this.attr('data-stop').replace(/,/g, "")); 2100 commas = (commas === undefined) ? true : commas; 2101 $({value: start}).animate({value: stop}, { 2102 duration: duration == undefined ? 1000 : duration, 2103 easing: ease == undefined ? "swing" : ease, 2104 step: function() { 2105 $this.text(Math.floor(this.value)); 2106 if (commas) { $this.text($this.text().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")); } 2107 }, 2108 complete: function() { 2109 if (parseInt($this.text()) !== stop) { 2110 $this.text(stop); 2111 if (commas) { $this.text($this.text().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,")); } 2112 } 2113 } 2114 }); 2115 }); 2116 }; 2117})(jQuery); 2118 2119 2120 2121/**! 2122 * easyPieChart 2123 * Lightweight plugin to render simple, animated and retina optimized pie charts 2124 * 2125 * @license Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. 2126 * @author Robert Fleischmann <[email protected]> (http://robert-fleischmann.de) 2127 * @version 2.1.1 2128 **/ 2129!function(a,b){"object"==typeof exports?module.exports=b(require("jquery")):"function"==typeof define&&define.amd?define("EasyPieChart",["jquery"],b):b(a.jQuery)}(this,function(a){var b=function(a,b){var c,d=document.createElement("canvas");"undefined"!=typeof G_vmlCanvasManager&&G_vmlCanvasManager.initElement(d);var e=d.getContext("2d");d.width=d.height=b.size,a.appendChild(d);var f=1;window.devicePixelRatio>1&&(f=window.devicePixelRatio,d.style.width=d.style.height=[b.size,"px"].join(""),d.width=d.height=b.size*f,e.scale(f,f)),e.translate(b.size/2,b.size/2),e.rotate((-0.5+b.rotate/180)*Math.PI);var g=(b.size-b.lineWidth)/2;b.scaleColor&&b.scaleLength&&(g-=b.scaleLength+2),Date.now=Date.now||function(){return+new Date};var h=function(a,b,c){c=Math.min(Math.max(0,c||1),1),e.beginPath(),e.arc(0,0,g,0,2*Math.PI*c,!1),e.strokeStyle=a,e.lineWidth=b,e.stroke()},i=function(){var a,c,d=24;e.lineWidth=1,e.fillStyle=b.scaleColor,e.save();for(var d=24;d>0;--d)0===d%6?(c=b.scaleLength,a=0):(c=.6*b.scaleLength,a=b.scaleLength-c),e.fillRect(-b.size/2+a,0,c,1),e.rotate(Math.PI/12);
2129e.restore()},j=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(a){window.setTimeout(a,1e3/60)}}(),k=function(){b.scaleColor&&i(),b.trackColor&&h(b.trackColor,b.lineWidth)};this.clear=function(){e.clearRect(b.size/-2,b.size/-2,b.size,b.size)},this.draw=function(a){b.scaleColor||b.trackColor?e.getImageData&&e.putImageData?c?e.putImageData(c,0,0):(k(),c=e.getImageData(0,0,b.size*f,b.size*f)):(this.clear(),k()):this.clear(),e.lineCap=b.lineCap;var d;d="function"==typeof b.barColor?b.barColor(a):b.barColor,a>0&&h(d,b.lineWidth,a/100)}.bind(this),this.animate=function(a,c){var d=Date.now();b.onStart(a,c);var e=function(){var f=Math.min(Date.now()-d,b.animate),g=b.easing(this,f,a,c-a,b.animate);this.draw(g),b.onStep(a,c,g),f>=b.animate?b.onStop(a,c):j(e)}.bind(this);j(e)}.bind(this)},c=function(a,c){var d={barColor:"#ef1e25",trackColor:"#f9f9f9",scaleColor:"#dfe0e0",scaleLength:5,lineCap:"round",lineWidth:3,size:110,rotate:0,animate:1e3,easing:function(a,b,c,d,e){return b/=e/2,1>b?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},onStart:function(){},onStep:function(){},onStop:function(){}};if("undefined"!=typeof b)d.renderer=b;else{if("undefined"==typeof SVGRenderer)throw new Error("Please load either the SVG- or the CanvasRenderer");d.renderer=SVGRenderer}var e={},f=0,g=function(){this.el=a,this.options=e;for(var b in d)d.hasOwnProperty(b)&&(e[b]=c&&"undefined"!=typeof c[b]?c[b]:d[b],"function"==typeof e[b]&&(e[b]=e[b].bind(this)));e.easing="string"==typeof e.easing&&"undefined"!=typeof jQuery&&jQuery.isFunction(jQuery.easing[e.easing])?jQuery.easing[e.easing]:d.easing,this.renderer=new e.renderer(a,e),this.renderer.draw(f),a.dataset&&a.dataset.percent?this.update(parseFloat(a.dataset.percent)):a.getAttribute&&a.getAttribute("data-percent")&&this.update(parseFloat(a.getAttribute("data-percent")))}.bind(this);this.update=function(a){return a=parseFloat(a),e.animate?this.renderer.animate(f,a):this.renderer.draw(a),f=a,this}.bind(this),g()};a.fn.easyPieChart=function(b){return this.each(function(){a.data(this,"easyPieChart")||a.data(this,"easyPieChart",new c(this,b))})}}); 2130 2131 2132/*global jQuery */ 2133/*! 2134 * FitVids 1.0 2135 * 2136 * Copyright 2011, Chris Coyier - http://css-tricks.com + Dave Rupert - http://daverupert.com 2137 * Credit to Thierry Koblentz - http://www.alistapart.com/articles/creating-intrinsic-ratios-for-video/ 2138 * Released under the WTFPL license - http://sam.zoy.org/wtfpl/ 2139 * 2140 * Date: Thu Sept 01 18:00:00 2011 -0500 2141 */ 2142 2143(function( $ ){ 2144 2145 $.fn.fitVids = function( options ) { 2146 var settings = { 2147 customSelector: null 2148 } 2149 2150 var div = document.createElement('div'), 2151 ref = document.getElementsByTagName('base')[0] || document.getElementsByTagName('script')[0]; 2152 2153 div.className = 'fit-vids-style'; 2154 div.innerHTML = '­<style> \ 2155 .fluid-width-video-wrapper { \ 2156 width: 100%; \ 2157 position: relative; \ 2158 padding: 0; \ 2159 } \ 2160 \ 2161 .fluid-width-video-wrapper iframe, \ 2162 .fluid-width-video-wrapper object, \ 2163 .fluid-width-video-wrapper embed { \ 2164 position: absolute; \ 2165 top: 0; \ 2166 left: 0; \ 2167 width: 100%; \ 2168 height: 100%; \ 2169 } \ 2170 </style>'; 2171 2172 ref.parentNode.insertBefore(div,ref); 2173 2174 if ( options ) { 2175 $.extend( settings, options ); 2176 } 2177 2178 return this.each(function(){ 2179 var selectors = [ 2180 "iframe[src*='player.vimeo.com']", 2181 "iframe[src*='www.youtube.com']", 2182 "iframe[src*='www.kickstarter.com']", 2183 "object", 2184 "embed" 2185 ]; 2186 2187 if (settings.customSelector) { 2188 selectors.push(settings.customSelector); 2189 } 2190 2191 var $allVideos = $(this).find(selectors.join(',')); 2192 2193 $allVideos.each(function(){ 2194 var $this = $(this); 2195 if (this.tagName.toLowerCase() == 'embed' && $this.parent('object').length || $this.parent('.fluid-width-video-wrapper').length) { return; } 2196 var height = ( this.tagName.toLowerCase() == 'object' || $this.attr('height') ) ? $this.attr('height') : $this.height(), 2197 width = $this.attr('width') ? $this.attr('width') : $this.width(), 2198 aspectRatio = height / width; 2199 if(!$this.attr('id')){ 2200 var videoID = 'fitvid' + Math.floor(Math.random()*999999); 2201 $this.attr('id', videoID); 2202 } 2203 $this.wrap('<div class="fluid-width-video-wrapper"></div>').parent('.fluid-width-video-wrapper').css('padding-top', (aspectRatio * 100)+"%"); 2204 $this.removeAttr('height').removeAttr('width'); 2205 }); 2206 }); 2207 } 2208})( jQuery ); 2209 2210 2211/*! 2212 * jQuery Smooth Scroll - v1.5.3 - 2014-10-15 2213 * https://github.com/kswedberg/jquery-smooth-scroll 2214 * Copyright (c) 2014 Karl Swedberg 2215 * Licensed MIT (https://github.com/kswedberg/jquery-smooth-scroll/blob/master/LICENSE-MIT) 2216 */ 2217 2218(function (factory) { 2219 if (typeof define === 'function' && define.amd) { 2220 // AMD. Register as an anonymous module. 2221 define(['jquery'], factory); 2222 } else { 2223 // Browser globals 2224 factory(jQuery); 2225 } 2226}(function ($) { 2227 2228 var version = '1.5.3', 2229 optionOverrides = {}, 2230 defaults = { 2231 exclude: [], 2232 excludeWithin:[], 2233 offset: 0, 2234 2235 // one of 'top' or 'left' 2236 direction: 'top', 2237
2238 // jQuery set of elements you wish to scroll (for $.smoothScroll). 2239 // if null (default), $('html, body').firstScrollable() is used. 2240 scrollElement: null, 2241 2242 // only use if you want to override default behavior 2243 scrollTarget: null, 2244 2245 // fn(opts) function to be called before scrolling occurs. 2246 // `this` is the element(s) being scrolled 2247 beforeScroll: function() {}, 2248 2249 // fn(opts) function to be called after scrolling occurs. 2250 // `this` is the triggering element 2251 afterScroll: function() {}, 2252 easing: 'swing', 2253 speed: 400, 2254 2255 // coefficient for "auto" speed 2256 autoCoefficient: 2, 2257 2258 // $.fn.smoothScroll only: whether to prevent the default click action 2259 preventDefault: true 2260 }, 2261 2262 getScrollable = function(opts) { 2263 var scrollable = [], 2264 scrolled = false, 2265 dir = opts.dir && opts.dir === 'left' ? 'scrollLeft' : 'scrollTop'; 2266 2267 this.each(function() { 2268 2269 if (this === document || this === window) { return; } 2270 var el = $(this); 2271 if ( el[dir]() > 0 ) { 2272 scrollable.push(this); 2273 } else { 2274 // if scroll(Top|Left) === 0, nudge the element 1px and see if it moves 2275 el[dir](1); 2276 scrolled = el[dir]() > 0; 2277 if ( scrolled ) { 2278 scrollable.push(this); 2279 } 2280 // then put it back, of course 2281 el[dir](0); 2282 } 2283 }); 2284 2285 // If no scrollable elements, fall back to <body>, 2286 // if it's in the jQuery collection 2287 // (doing this because Safari sets scrollTop async, 2288 // so can't set it to 1 and immediately get the value.) 2289 if (!scrollable.length) { 2290 this.each(function() { 2291 if (this.nodeName === 'BODY') { 2292 scrollable = [this]; 2293 } 2294 }); 2295 } 2296 2297 // Use the first scrollable element if we're calling firstScrollable() 2298 if ( opts.el === 'first' && scrollable.length > 1 ) { 2299 scrollable = [ scrollable[0] ]; 2300 } 2301 2302 return scrollable; 2303 }; 2304 2305 $.fn.extend({ 2306 scrollable: function(dir) { 2307 var scrl = getScrollable.call(this, {dir: dir}); 2308 return this.pushStack(scrl); 2309 }, 2310 firstScrollable: function(dir) { 2311 var scrl = getScrollable.call(this, {el: 'first', dir: dir}); 2312 return this.pushStack(scrl); 2313 }, 2314 2315 smoothScroll: function(options, extra) { 2316 options = options || {}; 2317 2318 if ( options === 'options' ) { 2319 if ( !extra ) { 2320 return this.first().data('ssOpts'); 2321 } 2322 return this.each(function() { 2323 var $this = $(this), 2324 opts = $.extend($this.data('ssOpts') || {}, extra); 2325 2326 $(this).data('ssOpts', opts); 2327 }); 2328 } 2329 2330 var opts = $.extend({}, $.fn.smoothScroll.defaults, options), 2331 locationPath = $.smoothScroll.filterPath(location.pathname); 2332 2333 this 2334 .unbind('click.smoothscroll') 2335 .bind('click.smoothscroll', function(event) { 2336 var link = this, 2337 $link = $(this), 2338 thisOpts = $.extend({}, opts, $link.data('ssOpts') || {}), 2339 exclude = opts.exclude, 2340 excludeWithin = thisOpts.excludeWithin, 2341 elCounter = 0, ewlCounter = 0, 2342 include = true, 2343 clickOpts = {}, 2344 hostMatch = ((location.hostname === link.hostname) || !link.hostname), 2345 pathMatch = thisOpts.scrollTarget || ( $.smoothScroll.filterPath(link.pathname) === locationPath ), 2346 thisHash = escapeSelector(link.hash); 2347 2348 if ( !thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash) ) { 2349 include = false;
2350 } else { 2351 while (include && elCounter < exclude.length) { 2352 if ($link.is(escapeSelector(exclude[elCounter++]))) { 2353 include = false; 2354 } 2355 } 2356 while ( include && ewlCounter < excludeWithin.length ) { 2357 if ($link.closest(excludeWithin[ewlCounter++]).length) { 2358 include = false; 2359 } 2360 } 2361 } 2362 2363 if ( include ) { 2364 2365 if ( thisOpts.preventDefault ) { 2366 event.preventDefault(); 2367 } 2368 2369 $.extend( clickOpts, thisOpts, { 2370 scrollTarget: thisOpts.scrollTarget || thisHash, 2371 link: link 2372 }); 2373 2374 $.smoothScroll( clickOpts ); 2375 } 2376 }); 2377 2378 return this; 2379 } 2380 }); 2381 2382 $.smoothScroll = function(options, px) { 2383 if ( options === 'options' && typeof px === 'object' ) { 2384 return $.extend(optionOverrides, px); 2385 } 2386 var opts, $scroller, scrollTargetOffset, speed, delta, 2387 scrollerOffset = 0, 2388 offPos = 'offset', 2389 scrollDir = 'scrollTop', 2390 aniProps = {}, 2391 aniOpts = {}; 2392 2393 if (typeof options === 'number') { 2394 opts = $.extend({link: null}, $.fn.smoothScroll.defaults, optionOverrides); 2395 scrollTargetOffset = options; 2396 } else { 2397 opts = $.extend({link: null}, $.fn.smoothScroll.defaults, options || {}, optionOverrides); 2398 if (opts.scrollElement) { 2399 offPos = 'position'; 2400 if (opts.scrollElement.css('position') === 'static') { 2401 opts.scrollElement.css('position', 'relative'); 2402 } 2403 } 2404 } 2405 2406 scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir; 2407 2408 if ( opts.scrollElement ) { 2409 $scroller = opts.scrollElement; 2410 if ( !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName) ) { 2411 scrollerOffset = $scroller[scrollDir](); 2412 } 2413 } else { 2414 $scroller = $('html, body').firstScrollable(opts.direction); 2415 } 2416 2417 // beforeScroll callback function must fire before calculating offset 2418 opts.beforeScroll.call($scroller, opts); 2419 2420 scrollTargetOffset = (typeof options === 'number') ? options : 2421 px || 2422 ( $(opts.scrollTarget)[offPos]() && 2423 $(opts.scrollTarget)[offPos]()[opts.direction] ) || 2424 0; 2425 2426 aniProps[scrollDir] = scrollTargetOffset + scrollerOffset + opts.offset; 2427 speed = opts.speed; 2428 2429 // automatically calculate the speed of the scroll based on distance / coefficient 2430 if (speed === 'auto') { 2431 2432 // $scroller.scrollTop() is position before scroll, aniProps[scrollDir] is position after 2433 // When delta is greater, speed will be greater. 2434 delta = aniProps[scrollDir] - $scroller.scrollTop(); 2435 if(delta < 0) { 2436 delta *= -1; 2437 } 2438 2439 // Divide the delta by the coefficient 2440 speed = delta / opts.autoCoefficient; 2441 } 2442 2443 aniOpts = { 2444 duration: speed, 2445 easing: opts.easing, 2446 complete: function() { 2447 opts.afterScroll.call(opts.link, opts); 2448 } 2449 }; 2450 2451 if (opts.step) { 2452 aniOpts.step = opts.step; 2453 } 2454 2455 if ($scroller.length) { 2456 $scroller.stop().animate(aniProps, aniOpts); 2457 } else { 2458 opts.afterScroll.call(opts.link, opts); 2459 } 2460 }; 2461 2462 $.smoothScroll.version = version; 2463 $.smoothScroll.filterPath = function(string) { 2464 string = string || ''; 2465 return string 2466 .replace(/^\//,'') 2467 .replace(/(?:index|default).[a-zA-Z]{3,4}$/,'') 2468 .replace(/\/$/,''); 2469 }; 2470 2471 // default options 2472 $.fn.smoothScroll.defaults = defaults; 2473 2474 function escapeSelector (str) { 2475 return str.replace(/(:|\.)/g,'\\$1'); 2476 } 2477 2478})); 2479
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.