PageSourceSearch

https://gulabihub.com/wp-content/themes/Archive/assets/js/main.js?ver=1.5.8

js gulabihub.com collected 2026-10-08 02:25:32 UTC 39,152 bytes, 1,472 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.