PageSourceSearch

https://www.palladiummag.com/wp-content/themes/hive/assets/js/main.js?ver=1.0.0

js palladiummag.com collected 2026-09-24 18:00:26 UTC 22,317 bytes, 938 lines download raw bytes

1(function ($, window, undefined) {
2
3	"use strict";
4
5	// /* ====== SHARED VARS  - jQuery ====== */
6	// These depend on jQuery
7	var $window = $(window),
8		windowHeight = $window.height(),
9		windowWidth = $window.width();
10
11	/**
12	 * Detect browser size and remember it in global variables
13	 */
14
15	function browserSize() {
16		wh = $window.height();
17		ww = $window.width();
18		dh = $(document).height();
19		ar = ww / wh;
20	}
21
22
23	/**
24	 * Detect what platform are we on (browser, mobile, etc)
25	 */
26
27	function platformDetect() {
28		$.support.touch = 'ontouchend' in document;
29		var navUA = navigator.userAgent.toLowerCase(),
30			navPlat = navigator.platform.toLowerCase();
31
32		var isiPhone = navPlat.indexOf("iphone"),
33			isiPod = navPlat.indexOf("ipod"),
34			isAndroidPhone = navPlat.indexOf("android"),
35			safari = (navUA.indexOf('safari') != -1 && navUA.indexOf('chrome') == -1) ? true : false,
36			svgSupport = (window.SVGAngle) ? true : false,
37			svgSupportAlt = (document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")) ? true : false,
38			ff3x = (/gecko/i.test(navUA) && /rv:1.9/i.test(navUA)) ? true : false,
39
40			ieMobile = navigator.userAgent.match(/Windows Phone/i) ? true : false,
41			phone = (isiPhone > -1 || isiPod > -1 || isAndroidPhone > -1) ? true : false,
42			touch = $.support.touch ? true : false;
43
44		if (touch) $html.addClass('touch');
45
46		if (ieMobile) $html.addClass('is--winmob');
47		if (is_android) $html.addClass('is--ancient-android');
48
49		if (safari) $body.addClass('safari');
50		if (phone) $body.addClass('phone');
51	}
52
53	// /* ====== SHARED VARS ====== */
54	// These do not depend on jQuery
55	var phone, touch, wh, ww, dh, ar, fonts;
56
57	var ua = navigator.userAgent;
58	var winLoc = window.location.toString();
59
60	var is_webkit = ua.match(/webkit/i);
61	var is_firefox = ua.match(/gecko/i);
62	var is_newer_ie = ua.match(/msie (9|([1-9][0-9]))/i);
63	var is_older_ie = ua.match(/msie/i) && !is_newer_ie;
64	var is_ancient_ie = ua.match(/msie 6/i);
65	var is_mobile = ua.match(/mobile/i);
66	var is_OSX = (ua.match(/(iPad|iPhone|iPod|Macintosh)/g) ? true : false);
67
68	var nua = navigator.userAgent;
69	var is_android = ((nua.indexOf('Mozilla/5.0') !== -1 && nua.indexOf('Android ') !== -1 && nua.indexOf('AppleWebKit') !== -1) && nua.indexOf('Chrome') === -1);
70
71	var useTransform = true;
72	var use2DTransform = (ua.match(/msie 9/i) || winLoc.match(/transform\=2d/i));
73	var transform;
74
75	var $html = $('html');
76	var $body = $('body');
77
78	// setting up transform prefixes
79	var prefixes = {
80		webkit: 'webkitTransform',
81		firefox: 'MozTransform',
82		ie: 'msTransform',
83		w3c: 'transform'
84	};
85
86	if (useTransform) {
87		if (is_webkit) {
88			transform = prefixes.webkit;
89		} else if (is_firefox) {
90			transform = prefixes.firefox;
91		} else if (is_newer_ie) {
92			transform = prefixes.ie;
93		}
94	}
95	// /* ====== Masonry Logic ====== */
96	(function () {
97
98		var $container = $('.archive__grid'),
99			$blocks = $container.children().addClass('post--animated  post--loaded'),
100			slices = $blocks.first().children().length;
101
102        var observerConfig = { attributes: false, childList: true, characterData: true },
103            observer;
104
105        if ( "MutationObserver" in window ) {
106            observer = new MutationObserver( function( mutations ) {
107                $container.masonry( 'layout' );
108            } );
109        }
110
111        // initialize masonry after the images have loaded
112        $container.imagesLoaded(function () {
113
114			// prepare hover animations
115			if (!$html.hasClass('touch'))
116				$blocks.addHoverAnimation();
117
118            // initialize masonry
119            $container.masonry({
120                isAnimated: false,
121                itemSelector: '.grid__item',
122                hiddenStyle: {
123                    opacity: 0
124                }
125            });
126
127			/**
128			 * function used to display cards with a simple fade in transition
129			 */
130
131			function showBlocks($blocks) {
132
133				// use different delays for each card to stagger them
134				$blocks.each(function (i, obj) {
135
136					var $block = $(obj),
137						duration = 200 + slices * 0.1;
138
139					$block.velocity({
140						translateY: 40
141					}, {
142						duration: 0
143					});
144					setTimeout(function () {
145						$block.velocity({
146							translateY: 0
147						}, {
148							easing: "easeOutQuad",
149							duration: 100
150						});
151
152						$block.children().each(function (j, child) {
153							var $child = $(child),
154								timeout = (j + 1) * 100;
155
156							$child.velocity({
157								opacity: 0,
158								translateY: 40
159							}, {
160								duration: 0
161							});
162
163							$child.velocity({
164								opacity: 1,
165								translateY: 0
166							}, {
167								duration: 300,
168								delay: timeout
169							});
170						});
171
172						setTimeout(function () {
173							$block.toggleClass('sticky--bg', $block.hasClass('sticky'));
174							$block.addClass('post--visible');
175						}, 300);
176
177					}, i * 200);
178				});
179			}
180
181			// animate cards in
182			showBlocks($blocks);
183
184            // update the masonry layout on window.resize
185            $(window).smartresize(function () {
186                $container.masonry('layout');
187            });
188
189			$(window).on('load', function () {
190				$container.masonry('layout');
191			});
192
193			// handle behavior for infinite scroll
194			$(document.body).on('post-load', function () {
195
196				// figure out which are the new loaded posts
197				var $newBlocks = $('.archive__grid').children().not('.post--loaded').addClass('post--loaded');
198
199				// when images have loaded take care of the layout, prepare hover animations, and animate cards in
200				$newBlocks.imagesLoaded( function() {
201					$container.masonry( 'appended', $newBlocks, true ).masonry( 'layout' );
202					if ( ! $html.hasClass( 'touch' ) ) {
203						$newBlocks.addHoverAnimation();
204					}
205					showBlocks( $newBlocks );
206				} );
207
208				if ( typeof observer !== "undefined" ) {
209					$newBlocks.each( function(i, obj ) {
210						observer.observe( obj, observerConfig );
211					} );
212				}
213			});
214		});
215	})();
216
217	// /* ====== Navigation Logic ====== */
218	$('.nav--main .menu-item-has-children').children('a').append('<span>+</span>');
219
220    var $nav = $('.nav--main'),
221        $navTrigger = $('.navigation__trigger'),
222        $navContainer = $('.main-navigation'),
223        navTop = (typeof $navContainer.offset() !== 'undefined') ? $navContainer.offset().top : 0,
224        navLeft = (typeof $navContainer.offset() !== 'undefined') ? $navContainer.offset().left : 0,
225        navWidth = $nav.outerWidth(),
226        containerWidth = $navContainer.outerWidth(),
227        navHeight = $nav.outerHeight(),
228        $toolbar = $('.toolbar'),
229        isOpen = false,
230        pageTop = $('#page').offset().top,
231        pageWidth = $('#page').width(),
232        pageLeft = $('#page').offset().left,
233		pageWidth = $('#page').width(),
234		pageLeft = $('#page').offset().left,
235		sticked = false;
236
237	/**
238	 * bind toggling the navigation drawer to click and touchstart
239	 *in order to get rid of the 300ms delay on touch devices we use the touchstart event
240	 */
241	var triggerEvents = 'click touchstart';
242	if (is_android) triggerEvents = 'click';
243
244	// Set the Navigation Container Height
245	$navContainer.height(navHeight);
246
247	$navTrigger.on(triggerEvents, function (e) {
248		// but we still have to prevent the default behavior of the touchstart event
249		// because this way we're making sure the click event won't fire anymore
250		e.preventDefault();
251		e.stopPropagation();
252
253		isOpen = !isOpen;
254		$('body').toggleClass('nav--is-open');
255
256		var offset;
257
258		navWidth = $nav.outerWidth();
259
260		if ($('body').hasClass('rtl')) {
261			offset = -1 * navWidth;
262		} else {
263			offset = navWidth;
264		}
265
266		if (!is_android) {
267			if (!isOpen) {
268
269				$([$nav, $navTrigger]).each(function (i, obj) {
270					$(obj).velocity({
271						translateX: 0,
272						translateZ: 0.01
273					}, {
274						duration: 300,
275						easing: "easeInQuart",
276						begin: function () {
277							$navContainer.removeClass('shadow');
278						}
279					});
280				});
281
282			} else {
283
284				$([$nav, $navTrigger]).each(function (i, obj) {
285					$(obj).velocity({
286						translateX: offset,
287						translateZ: 0.01
288					}, {
289						easing: "easeOutCubic",
290						duration: 300,
291						complete: function () {
292							$navContainer.addClass('shadow');
293						}
294					});
295				});
296			}
297		}
298	});
299
300	var HandleParentMenuItems = (function() {
301		// Handle parent menu items on tablet in landscape mode;
302		// use case: normal, horizontal menu, touch events,
303		// sub menus are not visible.
304		function handleParentMenuItems() {
305			// Make sure there are no open menu items
306			$('[class*="has-children"]').removeClass('hover');
307
308			$('[class*="has-children"] > a').each( function(){
309				// Add a class so we know the items to handle
310				$(this).addClass('prevent-one').attr('hasbeenclicked', false);
311			});
312
313			$('a.prevent-one').on('click', function(e) {
314				if( $( this ).attr( 'hasbeenclicked' ) == "false" ) {
315					e.preventDefault();
316					e.stopPropagation();
317
318					$(this).attr('hasbeenclicked', true);
319
320                    // Open the sub menu of this parent item
321                    $(this).parent().addClass('hover')
322                    // When a parent menu item is activated,
323                    // close other menu items on the same level
324                        .siblings().removeClass('hover').find('> a.prevent-one').attr('hasbeenclicked', false);
325                }
326            });
327        }
328
329		// Restore the original behaviour when in portrait mode;
330		// use case: vertical menu, all menu items are visible.
331		function unHandleParentMenuItems() {
332			$('a.prevent-one').each(function(){
333				// Unbind te click handler
334				$(this).unbind();
335			});
336		}
337
338		// When a sub menu is open, close it by a touch on
339		// any other part of the viewport than navigation.
340		// use case: normal, horizontal menu, touch events,
341		// sub menus are not visible.
342		function bindOuterNavClick() {
343			$('body').on( 'touchstart', function (e) {
344				var container = $('.nav--main');
345
346				if (!container.is(e.target) // if the target of the click isn't the container...
347				    && container.has(e.target).length === 0) // ... nor a descendant of the container
348				{
349					$('[class*="has-children"]').removeClass('hover');
350					$('a.prevent-one').attr('hasbeenclicked', false);
351				}
352			});
353		}
354
355		return {
356			handle: handleParentMenuItems,
357			unHandle: unHandleParentMenuItems,
358			bindOuterNavClick: bindOuterNavClick
359		}
360	}());
361
362	/**
363	 * function used to make the navigation bar on big screens
364	 * sticky or static depending on the scroll position
365	 */
366
367	function updateStickyMenu() {
368
369		// pin
370		if (latestKnownScrollY + pageTop > navTop && !sticked) {
371			$nav.css({
372				position: 'fixed',
373				top: pageTop,
374				left: pageLeft,
375				width: pageWidth
376			});
377
378			sticked = true;
379			return;
380		}
381
382		// unpin
383		if (latestKnownScrollY + pageTop <= navTop && sticked) {
384
385			$nav.css({
386				position: '',
387				left: '',
388				top: '',
389				width: ''
390			});
391
392			sticked = false;
393		}
394
395	}
396
397	/**
398	 * because we hard-code properties on the navigation bar when we stick it at the top of the window
399	 * we need to update some properties on window resize
400	 */
401
402    function refreshNavigation() {
403        navTop = (typeof $navContainer.offset() !== 'undefined') ? $navContainer.offset().top : 0;
404        navLeft = (typeof $navContainer.offset() !== 'undefined') ? $navContainer.offset().left : 0;
405        containerWidth = $navContainer.outerWidth();
406        navWidth = $nav.outerWidth();
407        navHeight = $nav.outerHeight();
408        pageTop = $('#page').offset().top;
409        pageWidth = $('#page').width();
410
411		$navContainer.height(navHeight);
412
413		if (sticked) {
414			$nav.velocity({
415				width: pageWidth
416			}, {
417				easing: "easeOutCubic",
418				duration: 200
419			});
420		}
421
422		if (isOpen) {
423			$([$nav, $navTrigger]).each(function (i, obj) {
424				$(obj).velocity({
425					translateX: navWidth
426				}, {
427					easing: "easeOutQuint",
428					duration: 200
429				});
430			});
431		}
432
433		navWidth = containerWidth;
434	}
435
436	/**
437	 * cardHover jQuery plugin
438	 *
439	 * we need to create a jQuery plugin so we can easily create the hover animations on the archive
440	 * both an window.load and on jetpack's infinite scroll 'post-load'
441	 */
442	$.fn.addHoverAnimation = function () {
443
444		return this.each(function (i, obj) {
445
446			var $obj = $(obj),
447				$handler = $obj.find('.hover__handler'),
448				$hover = $obj.find('.hover');
449
450			// if we don't have have elements that need to be animated return
451			if (!$hover.length) {
452				return;
453			}
454
455			var $letter = $hover.find('.hover__letter'),
456				letterWidth = $letter.outerWidth,
457				letterHeight = $letter.outerHeight;
458
459			$hover.find('.hover__bg').velocity({
460				opacity: 0
461			}, {
462				duration: 0
463			});
464			$hover.find('.hover__line').velocity({
465				height: 0
466			}, {
467				duration: 0
468			});
469			$hover.find('.hover__more').velocity({
470				opacity: 0
471			}, {
472				duration: 0
473			});
474			$hover.find('.hover__letter').velocity({
475				opacity: 0,
476				translateX: '-50%',
477				translateY: '-50%',
478				scaleX: 1.25,
479				scaleY: 1.25
480			}, {
481				duration: 0
482			});
483
484			// bind the tweens we created above to mouse events accordingly, through hoverIntent to avoid flickering
485			if ($handler.length) {
486				$handler.hoverIntent({
487					over: animateHoverIn,
488					out: animateHoverOut,
489					timeout: 100,
490					interval: 50
491				});
492			}
493
494			function animateHoverIn() {
495
496				$hover.find('.hover__bg').velocity("reverse", {
497					easing: "easeOutQuart",
498					duration: 500
499				});
500				$hover.find('.hover__line').velocity("reverse", {
501					easing: "easeOutQuart",
502					duration: 350,
503					delay: 150
504				});
505				$hover.find('.hover__more').velocity("reverse", {
506					easing: "easeOutQuart",
507					duration: 350,
508					delay: 150
509				});
510				$hover.find('.hover__letter').velocity({
511					scaleX: 1,
512					scaleY: 1,
513					opacity: 0.2,
514					translateX: '-50%',
515					translateY: '-50%'
516				}, {
517					easing: "easeOutQuart",
518					duration: 350,
519					delay: 150
520				});
521
522			}
523
524			function animateHoverOut() {
525
526				var letterHeight = $hover.find('.hover__letter-mask').outerHeight();
527
528				$hover.find('.hover__letter').velocity({
529					opacity: 0,
530					translateX: '-50%',
531					translateY: '-50%',
532					scaleX: 1.25,
533					scaleY: 1.25
534				}, {
535					easing: "easeOutQuart",
536					duration: 350,
537					delay: 0
538				});
539				$hover.find('.hover__more').velocity("reverse", {
540					duration: 350,
541					delay: 0
542				});
543				$hover.find('.hover__line').velocity("reverse", {
544					duration: 350,
545					delay: 0
546				});
547				$hover.find('.hover__bg').velocity("reverse", {
548					duration: 350,
549					delay: 0
550				});
551
552			}
553
554		});
555	};
556
557	// /* ====== Search Overlay Logic ====== */
558	(function () {
559
560		var isOpen = false,
561			$overlay = $('.overlay--search');
562
563		// update overlay position (if it's open) on window.resize
564		$(window).on('smartresize', function () {
565
566			windowWidth = $(window).outerWidth();
567
568			if (isOpen) {
569				$overlay.velocity({
570					translateX: -1 * windowWidth
571				}, {
572					duration: 200,
573					easing: "easeInCubic"
574				});
575			}
576
577		});
578
579		/**
580		 * dismiss overlay
581		 */
582
583		function closeOverlay() {
584
585			if (!isOpen) {
586				return;
587			}
588
589			var offset;
590
591			if ($('body').hasClass('rtl')) {
592				offset = windowWidth
593			} else {
594				offset = -1 * windowWidth
595			}
596
597			// we don't need a timeline for this animations so we'll use a simple tween between two states
598			$overlay.velocity({
599				translateX: offset
600			}, {
601				duration: 0
602			});
603			$overlay.velocity({
604				translateX: 0
605			}, {
606				duration: 300,
607				easing: "easeInCubic"
608			});
609
610			// remove focus from the search field
611			$overlay.find('input').blur();
612
613			isOpen = false;
614		}
615
616		function escOverlay(e) {
617			if (e.keyCode == 27) {
618				closeOverlay();
619			}
620		}
621
622		// create animation and run it on
623		$('.nav__item--search').on('click touchstart', function (e) {
624			// prevent default behavior and stop propagation
625			e.preventDefault();
626			e.stopPropagation();
627
628			// if through some kind of sorcery the navigation drawer is already open return
629			if (isOpen) {
630				return;
631			}
632
633			var offset;
634
635			if ($('body').hasClass('rtl')) {
636				offset = windowWidth
637			} else {
638				offset = -1 * windowWidth
639			}
640
641			// automatically focus the search field so the user can type right away
642			$overlay.find('input').focus();
643
644			$overlay.velocity({
645				translateX: 0
646			}, {
647				duration: 0
648			}).velocity({
649				translateX: offset
650			}, {
651				duration: 300,
652				easing: "easeOut",
653				queue: false
654			});
655
656			$('.search-form').velocity({
657				translateX: 300,
658				opacity: 0
659			}, {
660				duration: 0
661			}).velocity({
662				opacity: 1
663			}, {
664				duration: 200,
665				easing: "easeOutQuad",
666				delay: 200,
667				queue: false
668			}).velocity({
669				translateX: 0
670			}, {
671				duration: 400,
672				easeing: [0.175, 0.885, 0.320, 1.275],
673				delay: 50,
674				queue: false
675			});
676
677			$('.overlay__wrapper > p').velocity({
678				translateX: 200,
679				opacity: 0
680			}, {
681				duration: 0
682			}).velocity({
683				opacity: 1
684			}, {
685				duration: 400,
686				easing: "easeOutQuad",
687				delay: 350,
688				queue: false
689			}).velocity({
690				translateX: 0
691			}, {
692				duration: 400,
693				easing: [0.175, 0.885, 0.320, 1.275],
694				delay: 250,
695				queue: false
696			});
697
698			// bind overlay dismissal to escape key
699			$(document).on('keyup', escOverlay);
700
701			isOpen = true;
702		});
703
704		// create function to hide the search overlay and bind it to the click event
705		$('.overlay__close').on('click touchstart', function (e) {
706
707			e.preventDefault();
708			e.stopPropagation();
709
710			closeOverlay();
711
712			// unbind overlay dismissal from escape key
713			$(document).off('keyup', escOverlay);
714
715		});
716
717	})();
718
719	// /* ====== Smart Resize Logic ====== */
720	// It's best to debounce the resize event to a void performance hiccups
721	(function ($, sr) {
722
723		/**
724		 * debouncing function from John Hann
725		 * http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
726		 */
727		var debounce = function (func, threshold, execAsap) {
728			var timeout;
729
730			return function debounced() {
731				var obj = this,
732					args = arguments;
733
734				function delayed() {
735					if (!execAsap) func.apply(obj, args);
736					timeout = null;
737				}
738
739				if (timeout) clearTimeout(timeout);
740				else if (execAsap) func.apply(obj, args);
741
742				timeout = setTimeout(delayed, threshold || 200);
743			};
744		}
745		// smartresize
746		jQuery.fn[sr] = function (fn) {
747			return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr);
748		};
749
750	})(jQuery, 'smartresize');
751	var latestKnownScrollY = window.scrollY,
752		ticking = false;
753
754	function requestTick() {
755		"use strict";
756
757		if (!ticking) {
758			requestAnimationFrame(update);
759		}
760		ticking = true;
761	}
762
763	function update() {
764		"use strict";
765
766		ticking = false;
767
768		if (!is_android) {
769			updateStickyMenu();
770		}
771	}
772
773	/* ====== INTERNAL FUNCTIONS END ====== */
774
775
776	/* ====== ONE TIME INIT ====== */
777
778	function init() {
779
780		// /* GLOBAL VARS */
781		touch = false;
782
783		//  GET BROWSER DIMENSIONS
784		browserSize();
785
786		// /* DETECT PLATFORM */
787		platformDetect();
788	}
789
790
791	/* --- GLOBAL EVENT HANDLERS --- */
792
793
794	/* ====== ON DOCUMENT READY ====== */
795
796	$(document).ready(function () {
797		init();
798	});
799
800
801	/* ====== ON WINDOW LOAD ====== */
802
803	$window.on('load', function () {
804
805		if ( !$html.hasClass( 'touch' ) ) {
806			var $nav = $( '.nav--main' ).addClass( 'hover-intent' );
807
808			$( '.nav--main li' ).hoverIntent({
809				over: showSubMenu,
810				out: hideSubMenu,
811				timeout: 300
812			});
813		} else if ( $html.hasClass( 'touch') ) {
814			HandleParentMenuItems.handle();
815			HandleParentMenuItems.bindOuterNavClick();
816		}
817
818		function showSubMenu() {
819			$(this).addClass('hover');
820		}
821
822		function hideSubMenu() {
823			$(this).removeClass('hover');
824		}
825
826	});
827
828	/* ====== ON RESIZE ====== */
829
830	$(window).smartresize(function () {
831		if (!is_android) {
832			refreshNavigation();
833		}
834		windowWidth = $(window).outerWidth();
835		windowHeight = $(window).outerHeight();
836
837		if( $html.hasClass( 'touch' ) ) {
838			if( windowWidth >= 1000 ) {
839				// Handle parent menu items
840				HandleParentMenuItems.handle();
841			} else if ( windowWidth < 1000 ) {
842				// Remove handlers
843				HandleParentMenuItems.unHandle();
844			}
845		}
846	});
847
848	/* ====== ON SCROLL ====== */
849
850	$window.on('scroll', function (e) {
851		"use strict";
852
853		latestKnownScrollY = window.scrollY;
854		requestTick();
855	});
856	// /* ====== HELPER FUNCTIONS ====== */
857	/**
858	 * function similar to PHP's empty function
859	 */
860
861	function empty(data) {
862		if (typeof(data) == 'number' || typeof(data) == 'boolean') {
863			return false;
864		}
865		if (typeof(data) == 'undefined' || data === null) {
866			return true;
867		}
868		if (typeof(data.length) != 'undefined') {
869			return data.length === 0;
870		}
871		var count = 0;
872		for (var i in data) {
873			// if(data.hasOwnProperty(i))
874			//
875			// This doesn't work in ie8/ie9 due the fact that hasOwnProperty works only on native objects.
876			// http://stackoverflow.com/questions/8157700/object-has-no-hasownproperty-method-i-e-its-undefined-ie8
877			//
878			// for hosts objects we do this
879			if (Object.prototype.hasOwnProperty.call(data, i)) {
880				count++;
881			}
882		}
883		return count === 0;
884	}
885
886	/**
887	 * function to add/modify a GET parameter
888	 */
889
890	function setQueryParameter(uri, key, value) {
891		var re = new RegExp("([?|&])" + key + "=.*?(&|$)", "i");
892		separator = uri.indexOf('?') !== -1 ? "&" : "?";
893		if (uri.match(re)) {
894			return uri.replace(re, '$1' + key + "=" + value + '$2');
895		}
896		else {
897			return uri + separator + key + "=" + value;
898		}
899	}
900
901	/**
902	 * requestAnimationFrame polyfill by Erik Möller.
903	 * Fixes from Paul Irish, Tino Zijdel, Andrew Mao, Klemen Slavič, Darius Bacon
904	 *
905	 * MIT license
906	 */
907
908	if (!Date.now)
909		Date.now = function () {
910			return new Date().getTime();
911		};
912
913	(function () {
914		'use strict';
915
916		var vendors = ['webkit', 'moz'];
917		for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
918			var vp = vendors[i];
919			window.requestAnimationFrame = window[vp + 'RequestAnimationFrame'];
920			window.cancelAnimationFrame = (window[vp + 'CancelAnimationFrame']
921			                               || window[vp + 'CancelRequestAnimationFrame']);
922		}
923		if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy
924		    || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
925			var lastTime = 0;
926			window.requestAnimationFrame = function (callback) {
927				var now = Date.now();
928				var nextTime = Math.max(lastTime + 16, now);
929				return setTimeout(function () {
930						callback(lastTime = nextTime);
931					},
932					nextTime - now);
933			};
934			window.cancelAnimationFrame = clearTimeout;
935		}
936	}());
937
938})(jQuery, window);

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.