PageSourceSearch

https://animalface.ru/js/frontend/general.js?47

js animalface.ru collected 2026-10-08 09:22:26 UTC 23,172 bytes, 760 lines download raw bytes

1// JavaScript Document
2var page, menu, device,
3	currentButton = null, 
4	currentButtonContent = null,
5	__REPLAIN_ = 'e88783fe-dd9c-405c-8c28-38f4311d0015',
6	reposition = true,
7    optDialog;
8
9(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
10	m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
11(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
12
13// Yandex Metrika
14try {
15	ym(13743055, "init", {
16		clickmap:true,
17		trackLinks:true,
18		accurateTrackBounce:true,
19		webvisor:true,
20		trackHash:true
21	});
22} catch(e) {}
23
24
25$(function() {
26
27	device = $('#settings').data('device');
28	page = $('#settings').data('page');
29	menu = ($('#settings').data('menu') != '') ? $('#settings').data('menu') : page;
30
31	// Mobile View
32	if(device == 'mobile') {	
33        
34        optDialog = {
35            modal: false,
36            resizable: false,
37            width: '100%',
38            open: function() {
39
40                if(!$('#window form').find('button[type=reset]').length) {
41                    $('<button type="reset" class="empty"><span>Закрыть</span></button>').insertAfter('form .separator+button');	
42                }
43
44                $('body').css('overflow', 'hidden');
45
46            }
47        };
48
49		// For MaxH
50		let vh = window.innerHeight * 0.01;
51		document.documentElement.style.setProperty('--vh', `${vh}px`);
52
53
54		// Resize for message container
55		$(window).on('resize', function(){
56			let vh = window.innerHeight * 0.01;
57			document.documentElement.style.setProperty('--vh', `${vh}px`);
58		});
59
60		// Menu Selector
61		$('a[data-page="' + menu + '"]').parent().addClass('selected');
62		
63		// Menu Opener
64		$('nav#menu').mmenu({ 'slidingSubmenus': false });
65				
66		// Close Dialog
67		$(document).on('click', '#window button[type=reset]', function(event) {
68			event.preventDefault();
69			$('#window').dialog('destroy').remove();
70			$('body').css('overflow', 'inherit');
71		});
72
73	}
74
75	// Desktop View
76	else if(device == 'desktop') {
77		
78         optDialog = {
79            modal: true,
80            resizable: false,
81            width: 'auto',
82			open: function() {
83				 $(this).dialog('option', 'position', {my: 'center', at: 'center', collision: 'fit'});
84			 }
85        };
86        
87		// Set menu selector
88		$('#left-menu a[data-page="' + menu + '"]').addClass('selected-center');
89		$('footer a[data-page="' + menu + '"]').addClass('selected-footer');
90			
91		$('.tooltip').tooltip({
92			position: {
93                my: 'center top', 
94                at: 'center bottom+10'
95            },
96            content: function () {
97				return this.getAttribute('title').replace('|', '<br />');
98			}
99		});
100		
101		inputHint();
102			
103		$(document).on('focusin focusout change', 'input, textarea, select', function(event) {	
104			if($(this).hasClass('no-hint')) { return; }		
105			
106			if($(this).is('select')) {
107				
108				if(event.type == 'change') {
109					
110					if($(this).prev('.hint').length == 0) {	
111						var hint = $('<div class="hint">' + $(this).find("option:first").text() + '</div>');
112						hint.insertBefore(this);
113						$(this).css('padding-top', '17px');		
114					}	
115				}
116				
117			} else if(event.type == 'focusin') {
118						
119				if($(this).prev('.hint').length == 0) {					
120					var hint = $('<div class="hint">' + $(this).attr('placeholder') + '</div>');
121					$(this).attr('placeholder', '');
122					hint.insertBefore(this);
123					
124					if($(this).is('textarea')) {
125						$(this).css('padding-top', '24px');
126					} else {
127						$(this).attr('placeholder', '').css('padding-top', '17px');
128					}
129				}
130				
131			} else if(event.type == 'focusout') {
132				 				 
133				 if($(this).val() == '') {			 			 		 
134					 var hint = $(this).prev('.hint');
135					 $(this).attr('placeholder', hint.text()).css('padding-top', '0');
136					 $(this).next().css('padding-top', '0');
137											 
138					 if($(this).is('textarea')) {
139						$(this).css('padding-top', '20px');
140					 }
141					 hint.remove();
142				 } 
143			}
144		});
145		
146        /*
147		// Float Menu
148		$(document).scroll(function() {
149           
150            var curPos = $('footer').position().top - $(window).height() - 150;
151                
152            if($(this).scrollTop() >= curPos) {
153              $('#left-menu').css({'position': 'absolute', 'top': 'auto', 'bottom': '0'});
154            } else {
155              $('#left-menu').css({'position': 'fixed', 'top': '140px', 'bottom': 'auto'});    
156            }
157
158		});
159		
160         
161       
162        $('.l-columns').stickySidebar({
163            topSpacing: $('header').outerHeight() + 20,
164            bottomSpacing: $('footer').outerHeight(),
165            containerSelector: '#content',
166			innerWrapperSelector: '#left-menu'
167          });
168         */   
169       
170        
171		// Close PopUp Window
172		$('body').on('click','.ui-widget-overlay', function() {
173			if($('#crop-window').length == 0) {
174				$('#window').dialog('destroy').remove();
175				DefineErrors(null);
176			}
177		});
178		
179	}
180	
181	// End Desktop View 
182	
183			
184	// Global ajax events
185	$(document).ajaxStart(function(event) {
186
187		currentButton = $(event.target.activeElement);
188		var width = currentButton.outerWidth();
189		
190		// IF Button and not too small
191		if(currentButton.is('button') && width > 80) {
192
193			var loading ='<div id="loading"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>';
194				
195			currentButtonContent = currentButton.html();
196			currentButton.html(loading).prop('disabled', true).css({'width': width, 'pointer-events': 'none'});
197		}
198		
199    }).ajaxComplete(function() {
200		
201		if(currentButtonContent != null) {
202			currentButton.html(currentButtonContent).prop('disabled', false).css({'pointer-events': 'auto'});
203			currentButtonContent = null;
204		}
205		
206		if(reposition == true) {
207			$('#window').dialog('option', 'position', {my: 'center', at: 'center', of: window, collision: 'fit'});
208		}
209		
210		reposition = true;
211		inputHint();
212    });
213	
214		
215	// AntiSpam Update	
216	$(document).on('click', '#updateAntiSpam', function() {
217
218		const request = { current: $('#antispam').data('placeholder'), lang: $('#lang').val() };
219
220		$.post('/authorization/updateAntiSpam', request, function(data) {
221			reposition = false;
222			$('#antispam').prev('.hint').text(data);
223			$('#antispam').val('').attr('placeholder', data).data('placeholder', data);
224			$('#question').val(data);
225		});
226
227	});
228	
229
230	// Header Search chip and NFC
231	$('header#top-header .search input[type="search"]').keyup(function(event) {
232        		
233        if(event.which == 13 || /^[1-9]{1}\d{14}$/.test($(this).val().trim()) || /^AF(\-)?\d{7}$/i.test($(this).val().trim())) {
234            $('header#top-header .search button').trigger('click'); 
235        }
236
237	});
238
239	// Header search chip, NFC button
240	$('header#top-header .search button').click(function(event) {
241
242		event.preventDefault();
243
244        let field = $(this).closest('form').find('input[type="search"]').val();
245
246		if(/^[1-9]{1}\d{14}$/.test(field.trim()) || /^AF(\-)?\d{7}$/i.test(field.trim())) {
247			$(this).parents('form').submit();
248		} 
249        
250        else {
251			$(this).parent().effect('shake', {'distance': 4}, 200);
252		}
253
254	});
255			
256	// PopUp Forms
257	$(document).on('click', '[data-role="question"], [data-role="login"], [data-role="remind"], \
258							[data-role="reg-owner"], [data-role="reg-company"], [data-role="email"], [data-role="password"]', function(event) { 
259		
260		event.preventDefault();
261		
262		$.post('/authorization/' + $(this).data('role'), function(data) {
263			$('#window').dialog('destroy').remove();
264			$('<div id="window"><div>').html(data).dialog(optDialog, 'open');	
265		});
266
267	});
268	
269	// Submit PopUp Forms
270	$(document).on('submit', '.forgotPass, #login, #remind, #remindChange, #question, #reg-owner, #reg-company', function(event) {
271
272		event.preventDefault();
273		var id = $(this).attr('id');
274					
275		$.post('/authorization/' + $(this).attr('id') + '/do', $(this).serialize(), function(data) {
276			if(!DefineErrors(data)) { return; }
277						
278			if(data.html) {
279				$('#window').dialog('destroy').remove();
280				$('<div id="window"><div>').html(data.html).dialog(optDialog, 'open');
281				return;	
282			}
283			
284			var delay = (id == 'login') ? 500 : 5000;
285				
286			$('#window').find('form').remove().end().find('.text').html('<svg class="icon-small"><use xlink:href="/i/svg/icons.svg#ok-white"></use></svg>' + data.message).parents('.ui-dialog')
287			.delay(delay).effect('drop', {'direction' : 'up'}, 'slow', function() {
288				
289				$('#window').dialog('destroy').remove();
290				
291				if(id == 'remindChange' || id == 'login') {
292					location.href = '/'; 
293				}
294			});
295			
296		}, 'json');
297	});	
298		
299	// Change Email, Password in Profile
300	$(document).on('submit', '#email, #code, #password', function(event) {
301		event.preventDefault();
302		var id = $(this).attr('id');
303					
304		$.post('/authorization/' + $(this).attr('id') + '/do', $(this).serialize(), function(data) {
305			if(!DefineErrors(data)) { return; }
306			
307			if(id == 'email') {						
308				if(data.status == 'ok') {
309					$.post('/authorization/code', function(data) {
310						$('#window').dialog('destroy').remove();
311						$('<div id="window"><div>').html(data).dialog(optDialog, 'open');
312					});
313				} else if (data.status == 'error') {
314					PopUpMessage(data.status, data.message);	
315				}
316			
317			} else if(id == 'password' || id == 'code') {
318				PopUpMessage(data.status, data.message);
319			}
320			
321		}, 'json');
322	});	
323	
324	
325	$(document).on('change', '#kind', function() {
326		var price = $("#kind option[value='" + $(this).val() + "']").data('price');
327		$('#tariff-price').html('Абонентская плата <strong>' + price + '</strong> &#8381; в год');
328	});
329		
330	// Open Notifications Lists		
331	$('#notifications-count').click(function(event) {
332		 event.preventDefault();
333		$('<div id="window"><div>').html($('#notifications-list-container').html()).dialog(optDialog, 'open');
334	});
335	
336	// Chip Order
337	$(document).on('click', '[data-layer=order-chip]', function(event) {	
338		event.preventDefault();
339		if($(this).data('action') == 'send') {
340			$.post('/payments/orderChip/do', $(this).parents('form').serialize(), function(data) {
341				if(!DefineErrors(data)) { return; }
342				PopUpMessage(data.status, data.message);
343			}, 'json');
344		} else if($(this).data('action') == 'form') {
345			$('#window').dialog('destroy').remove();
346			$.post('/payments/orderChip/', function(data) {
347				$('<div id="window"><div>').html(data).dialog(optDialog, 'open');
348			});
349		}
350	});
351	
352	
353	// Open Horizontal Menu
354	$('#content-menu > div div').click(function() {
355		var o = $(this);				
356		if(o.data('view') == 'no-open') {return;}
357		$('#content-menu > div div').css('background', '#285d80');
358		o.css('background', '#03395d');
359		$('#content-data > div:visible').fadeOut('fast', function() {
360			$('#content-data div[data-layer="' + o.data('layer') + '"]').fadeIn();
361			$('#content-header > div[data-layer!=""]').hide();
362			$('#content-header > div[data-layer="' + o.data('layer') + '"]').show();
363		});	
364	});
365	
366	// Move Animals
367	$(document).on('click', '#notifications-list .text button', function(event) {
368		var o = $(this);
369		var action = (o.text() == 'Не присоединять') ? 'cancel' : 'do';
370		$.post('/companyAnimals/move/' + action, {'id' : o.data('id')}, function(data) {
371			if(data.status == 'error') {
372				PopUpMessage(data.status, data.message);
373			} else {
374				var value = o.parent().parent().parent().data('notification');
375				SetNotification(value);
376			}		
377		}, 'json');
378	});
379	
380	// Add Animal AnyWhere
381	$(document).on('click', '[data-role="add-anywhere"]', function(event) {
382		event.preventDefault();
383		if($(this).data('type') == 2) {
384			$('[data-role="reg-selector"]').trigger('click');
385		} else if($(this).data('type') == 1) {
386			if(page != 'companyAnimals') { location.href = '/company/animals/#registration'; } 
387			else { $('#content-menu div[data-layer="owner"][data-action="form"]').trigger('click'); }
388		} else if($(this).data('type') == 0) {
389			if(page != 'ownerAnimals') { location.href = '/owner/animals/#registration'; } 
390			else { $('#content-menu div[data-layer="add-animal"]').trigger('click'); }
391		}
392	});
393	
394	// Animal Card - settings
395	$(document).on('mouseenter mouseleave', '.button-setting', function(event) {
396		
397		// If card deleted
398		if($(this).closest('.animal-card').css('opacity') < 1) {return;}
399				
400		if(event.type == 'mouseenter') {
401			
402			$(this).find('.menu-container').html($('#block-settings'));
403		
404		} else {
405			$('#block-settings-container').html($('#block-settings'));
406		}
407	});
408	
409	// Animal Card - load next cards
410	$(document).on('click', '.more-animals button', function() {
411		loadingData($(this));
412	});
413	
414	$(document).on('change', '#country', function() {
415        
416        let pattern = $(this).children('option:selected').data('mask');
417        
418        $('#phone_1, #phone_2').data('pattern', pattern).attr('placeholder', pattern);    
419        
420        $('input[data-masked="true"]').each(function() {
421           $(this).mask($(this).data('pattern'));
422        });
423
424	});	
425	
426	// Date Picker Translate
427	$.datepicker.regional['ru'] = {
428		closeText: 'Закрыть',
429		prevText: '<Пред',
430		nextText: 'След>',
431		currentText: 'Сегодня',
432		monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
433		monthNamesShort: ['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'],
434		dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'],
435		dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'],
436		dayNamesMin: ['Вс','Пн','Вт','Ср','Чт','Пт','Сб'],
437		weekHeader: 'Нед',
438		dateFormat: 'dd-mm-yy',
439		maxDate: "0D",
440		firstDay: 1,
441		isRTL: false,
442		showMonthAfterYear: false,
443		yearSuffix: ''
444	};
445	
446	$.datepicker.setDefaults($.datepicker.regional['ru']);	
447});
448
449
450function loadingData(o) {
451	
452	if(o.data('type') == 'html') {
453		$.post('/' + page + '/showAnimals', {'page' : o.data('page')}, function(html) {
454			o.parent().remove();
455			$('#content-data div[data-layer="' + o.data('container') + '"]').append(html);	
456		});
457	
458	} else if(o.data('type') == 'json') {
459		
460		var request = 'page='+o.data('page') +'&';
461		
462		if($('#' + o.data('container')).length > 0) {
463			request += $('#' + o.data('container')).serialize();
464		}
465				
466		$.post('/' + page + '/showAnimals', request, function(data) {
467			if(!DefineErrors(data)) {return;}
468			o.parent().remove();
469			
470			$('#' + o.data('container') + '-list').append(data.html);	
471			
472			  if($('.animal-icon a').length > 0) {
473				  $('.fancybox').fancybox({
474					protect: true,
475					buttons : ['close'],
476					thumbs : {
477						autoStart : true
478					}
479				});	
480			  }	
481			
482		}, 'json');
483	}
484}
485
486function PopUpMessage(status, message) {
487	
488	// Close current Window
489	$('#window').dialog('destroy').remove();
490	
491	var icon;
492	
493	if(status == 'ok') {
494		message = (message == undefined) ? 'Данные успешно сохранены.' : message;
495		icon = 'ok';
496	} else if(status == 'error') {
497		message = (message == undefined) ? 'Ошибка при сохранении данных.' : message;
498		icon = 'warning';
499	}
500	
501	var result =  '<div class="info"> \
502						<div class="text"> \
503							<svg class="icon-small"> \
504                            	<use xlink:href="/i/svg/icons.svg#' + icon + '-white"></use> \
505                            </svg> \
506							' + message + ' \
507						</div> \
508					</div>';
509	
510	$('#window').dialog('destroy').remove();
511	$('<div id="window" />').dialog(optDialog, 'open').html(result)	
512	.parents('.ui-dialog').delay(2000).effect('drop', {'direction' : 'up'}, 'slow', function() {
513		$('#window').dialog('destroy').remove();
514	});	
515	$('#window').dialog('option', 'position', {my: 'center', at: 'center', of: window, collision: 'fit'});			
516}
517
518function DefineErrors(data) {
519	
520	$('.block-error').remove();
521	
522	if(data == null || data.status == 'ok' || data.status == 'error') { return true; }
523	
524	var i = 0, typeForm = 'popup';
525	
526	$.each(data, function(field, error) {
527		
528		if(device == 'mobile') {
529			
530			var errorBlock = $('<div class="block-error">' + error + '</div>');		
531			
532			if($('#' + field).parents('.slideOne').length > 0) {		
533				$('#' + field).parents('.slideOne').parent().append(errorBlock);
534				errorBlock.hide().fadeIn(function() {
535				//	$('#window').dialog('option', 'position', {my: 'center', at: 'center', of: window, collision: 'fit'});
536				});
537			
538			} else if($("#" + field).parents('.phone-block').length > 0) {
539				
540				var parent = $('#' + field).parent();
541					
542				errorBlock.insertAfter(parent);
543				
544				errorBlock.hide().fadeIn(function() {
545				//	$('#window').dialog('option', 'position', {my: 'center', at: 'center', of: window, collision: 'fit'});
546				});
547			} else {
548				errorBlock.insertAfter(('#' + field)).hide().fadeIn(function() {
549				//	$('#window').dialog('option', 'position', {my: 'center', at: 'center', of: window, collision: 'fit'});
550				});
551			}
552			
553			
554			if($('#' + field).parents('.content-form-shop').length > 0) {
555				$('body, html').animate({
556					scrollTop: $('.content-form-shop .block-error:first').offset().top - 100
557				}, 800);
558			}
559			
560			//$('form').find('.block-error').first().focus();
561		
562		} else {
563			
564			// Common Forms
565			if(
566                $('#' + field).parents('.content-form').length         ||
567                $('#' + field).parents('.content-form-shop').length 
568            ) 
569            
570            {
571
572				typeForm = 'common';		
573				
574				var errorBlock = $('<div class="block-error">' + error + '</div>');
575				
576				// IF phone-block
577				if($("#" + field).parents('.phone-block').length == 1 || $("#" + field).parents('.agreement').length == 1) {
578					var parent = $('#' + field).parent();
579					errorBlock.insertAfter(parent).hide().fadeIn();
580				}
581
582				else {
583
584					if(field == 'delivery') {
585						errorBlock.insertAfter(('#' + field + '-field')).hide().fadeIn();
586					}
587
588					else {
589						errorBlock.insertAfter(('#' + field)).hide().fadeIn();
590					}
591
592
593				}
594				
595			// PopUp Forms
596			} else {
597	                
598				if(reposition == true) {
599					$('#window').dialog('option', 'position', {my: 'center', at: 'center', of: window, collision: 'fit'});
600				}
601				
602				var errorBlock = $('<div class="block-error">' + error + '</div>');
603				
604				// IF we have hidden field
605				if(field == 'region' || field == 'color' || field == 'breed' || field == 'company') {
606					field = field + 'Title';
607				}
608				
609				// IF slider
610				if($("#" + field).parent().parent().hasClass('slideOne')) {
611					var position = $("#" + field).parent().parent().offset();		
612				} else {
613					var position = $("#" + field).offset();	
614				}
615
616				$('body').append(errorBlock);
617				
618				var positionForm = $("#" + field).parents('form').parent().offset();
619
620				// Double Form
621				if($("#" + field).parents('form').hasClass('double')) {
622									
623					var offset = $("#" + field).parent().position();
624					
625					// right side	
626					if(offset.left > 30) {
627						errorBlock.offset({top:position.top + 6, left:positionForm.left + $("#" + field).parents('form').parent().width()}) 
628						.css('text-align', 'left').addClass('block-error-right');
629					// left side
630					} else	{				
631						errorBlock.offset({top:position.top + 6, left:positionForm.left - errorBlock.width() - 29}) 
632						.css('text-align', 'right').addClass('block-error-left');
633					}
634					
635				// Single Form
636				}
637
638				else {
639				    
640                    if($("#" + field).attr('type') != 'hidden') {
641                    
642                        // left side
643                        if(i % 2 == 0)	 {
644                            errorBlock.offset({top:position.top + 6, left:positionForm.left - errorBlock.width() - 29}) 
645                            .css('text-align', 'right').addClass('block-error-left');
646                        }
647
648                        // right side
649                        else { 
650                            errorBlock.offset({top:position.top  + 6, left:positionForm.left + $("#" + field).parents('form').parent().width()}) 
651                            .css('text-align', 'left').addClass('block-error-right');
652                        }
653                    
654                    }
655				}
656                
657				
658				errorBlock.hide().fadeIn();
659			}
660		
661		}
662		
663		i++;
664	});
665	
666	// Only For Commons Forms	
667	if(typeForm == 'common') {
668        
669		// When animation finished
670		$('.block-error').promise().done(function() {
671			var o = $('.content-form .block-error:first, .content-form-shop .block-error:first');
672			
673            if(o.parents('.content-form')) {
674                extra = o.prev().outerHeight() + 55;
675            } else {
676                extra = 0;
677            }
678            
679            if(InViewport(o, $('#top-header').outerHeight()) === false) {
680				$([document.documentElement, document.body]).animate({
681					scrollTop: $('.content-form .block-error:first, .content-form-shop .block-error:first').offset().top - $('#top-header').outerHeight() - extra
682				}, 800);	
683			}
684		});
685	}
686
687	return false;	
688}
689
690function SetNotification (value) {
691    
692	$('div[data-notification="' + value + '"]').remove();
693    
694	if($('#notifications-list > div').length == 0) {
695		$('#notifications-count').remove();
696		if(value.indexOf('move-') + 1) {
697			$('#window').dialog('destroy').remove();
698		}
699	}
700}
701
702function AnimalsCount(action) {
703	if($('#animals-count').data('count') == 0 && action < 0) { return; }
704	$('#animals-count').data('count', $('#animals-count').data('count') + action);
705	$('#animals-count').text($('#animals-count').data('count').toLocaleStr
705ing());
706}
707
708function inputHint() {
709
710    $('input[data-masked="true"]').each(function() {
711
712		if($(this).data('pattern')) {
713			$(this).mask($(this).data('pattern'));
714		}
715
716	});
717    
718	if(device == 'mobile') { return; } 
719	
720	$('input, textarea, select').each(function() {
721		
722		var hint;
723
724		// After submit empty field
725		if($(this).prev('.hint').length > 0 && $(this).val() == '') {
726			hint = $(this).prev('.hint');
727			$(this).attr('placeholder', hint.text()).css('padding-top', '0');
728			$(this).next().css('padding-top', '0');
729			hint.remove();
730		}
731		
732		if($(this).hasClass('no-hint') || $(this).prev('.hint').length > 0 || ($(this).val() == '' && $(this).is(':not(:focus)')) || $(this).attr('type') == 'hidden' || $(this).attr('type') == 'checkbox') { return; }
733
734		hint = ($(this).get(0).tagName == 'SELECT') ? $('<div class="hint">' + $(this).find("option:first").text() + '</div>') : $('<div class="hint">' + $(this).attr('placeholder') + '</div>');
735
736		hint.insertBefore(this);
737
738		if($(this).is('textarea')) {
739			$(this).css('padding-top', '24px');
740		}
741		else {
742			$(this).css('padding-top', '17px');
743		}
744
745    });
746
747}
748
749function InViewport ($ele, ExtraHeight) {
750        
751    var lBound = $(window).scrollTop() + ExtraHeight,
752        uBound = lBound + $(window).height(),
753        top = $ele.offset().top,
754        bottom = top + $ele.outerHeight(true);
755
756    return (top > lBound && top < uBound)
757        || (bottom > lBound && bottom < uBound)
758        || (lBound >= top && lBound <= bottom)
759        || (uBound >= top && uBound <= bottom);
760}

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.