PageSourceSearch

https://georgiaepiscopal.org/wp-content/themes/peak/js/libs/jquery.plugins.lib.js?ver=1.0

js georgiaepiscopal.org collected 2026-10-02 10:57:04 UTC 96,027 bytes, 2,479 lines download raw bytes

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) ? '&amp;media=' + settings.image : '') + (settings.description !== undefined ? '&amp;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 ? '&amp;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 = '&shy;<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.