PageSourceSearch

https://kotel-kv.ru/includes/modules/filter2/js/filter2.js

js kotel-kv.ru collected 2026-10-08 20:34:08 UTC 25,614 bytes, 697 lines download raw bytes

1var filterCallback = {};
2
3function getFloatParam($filterForm) {
4    var items_float = [];
5
6    $filterForm.find('.rbm_js_filter2_float_block').each(function () {
7        var id = $(this).data('id'),
8            name = $(this).data('parameter'),
9            min = $(this).find('.rbm_js_filter2_input_min_' + name).val(),
10            max = $(this).find('.rbm_js_filter2_input_max_' + name).val();
11        if (max !== '' || min !== '') {
12            items_float.push({
13                id: id,
14                name: name,
15                min: min,
16                max: max
17            });
18        }
19    });
20    return items_float;
21}
22
23function getStringParam($filterForm) {
24    var items_string = [];
25    $filterForm.find('.rbm_js_filter2_string_block').each(function () {
26        var values = [];
27        $(this).find('.rbm_js_filter2_input_string').each(function () {
28            if (this.tagName == "SELECT") {
29                if ($(this).val() != 0) {
30                    values.push($(this).val());
31                }
32            } else if (this.tagName == "INPUT") {
33                if ($(this).prop("checked")) {
34                    values.push($(this).val());
35                }
36            } else if ($(this).hasClass('active')) {
37                values.push($(this).data('value'));
38            }
39        });
40        if (values.length) {
41            items_string.push({
42                id: $(this).data('id'),
43                name: $(this).data('parameter'),
44                values: values
45            });
46        }
47    });
48    return items_string;
49}
50
51let inputTimer = false;
52
53////// инициализация слайдеров у фильтра
54function sliderInit() {
55	$(".rangeslider-string").each(function(){
56		let $this = $(this);
57		let map = new Map();
58		
59		$this.parent().find('.custom-checkbox').each(function(){
60			map.set($(this).find('.custom-control-label').html().trim(), $(this).find('input'));
61		});
62		
63		
64		$this.ionRangeSlider({
65			type: "double",
66			values:  Array.from(map.keys()),
67			onFinish: function(data){
68					
69				let start = null;
70				let end = null;
71
72				let flag = false;
73				map.forEach((value, key, map) => {
74					if(start === null){
75						start = key;
76					}
77					
78					end = key;
79					
80					if(key.toString() == data.from_value.toString()){
81						 flag = true;
82					}
83					
84					value.prop('checked', flag);
85					
86					if(key.toString() == data.to_value.toString()){
87						 flag = false;
88					}
89				
90				});
91				
92				if(start.toString() === data.from_value.toString() && data.to_value.toString() === end && map.size > 1){
93					$this.parent().find('input').prop('checked', false);
94				}
95				
96				map.get(data.from_value.toString()).trigger('change');
97				
98			}
99		});
100	});
101
102    $('.rbm_filter2_slider_ui').each(function () {
103        var tmp = 0.01;
104        if (parseFloat($(this).data('max')) > 1000) {
105            tmp = 1;
106        }else if(parseFloat($(this).data('max')) > 100){
107			tmp = 0.1;
108		}
109        var $this = $(this);
110        var parameterName = $(this).data('parameter'),
111            IdOutMin = '.rbm_js_filter2_input_min_' + parameterName,
112            IdOutMax = '.rbm_js_filter2_input_max_' + parameterName,
113            SlName = '.rbm_filter2_slider_helper_' + parameterName,
114            myMin = parseFloat($(this).data('min')),
115            myMax = parseFloat($(this).data('max')),
116            step = tmp;
117		var thisParID = $this.data('id');
118        ////////// инициализация слайдера
119        $(SlName).ionRangeSlider({
120            min: myMin,
121            max: (myMax * 100) / 100,
122            step: step,
123            type: "double",
124			grid: true,
125            from: $(IdOutMin).val().trim().length ? +$(IdOutMin).val() : myMin,
126            to: $(IdOutMax).val().trim().length ? +$(IdOutMax).val() : myMax,
127            onChange: function (ui) {
128                $(IdOutMin).val(parseFloat(ui.from));
129                $(IdOutMax).val(parseFloat(ui.to));
130
131                if (parseFloat(myMin) === parseFloat(ui.from)) {
132                    $(IdOutMin).val('');
133                }
134                if (parseFloat(myMax) === parseFloat(ui.to)) {
135                    $(IdOutMax).val('');
136                }
137                
138            },
139			onFinish: function(data) {
140				search_disable($this, thisParID);
141				data.input.parents('.rbm_js_filter2_float_block').find('.rbm_js_filter2_clean_values').removeClass('invisible');
142			}
143        });
144
145        let inputs = $this.closest('.rbm_js_filter2_float_block').find('.rbm_js_filter2_input_float');
146
147        ////// обратная связь
148        inputs.on('input', function () {
149			let $this = $(this);
150			clearTimeout(inputTimer);
151			inputTimer = setTimeout(function(){
152				console.log(1);
153				$this.trigger('blur');
154			}, 1500);
155        });
156		
157		$(IdOutMin).on('blur', function(){
158				clearTimeout(inputTimer);
159                let max = $(IdOutMax).val().trim().length ? +$(IdOutMax).val() : myMax;
160                let currentValue = $(this).val().replace(/[^0-9\.]+/, '');
161
162                if(currentValue.length){
163                    currentValue = parseFloat(currentValue);
164                    if(currentValue > myMax){
165                        currentValue = myMax;
166                        $(IdOutMax).val(currentValue);
167                    }else if(currentValue > max){
168                        $(IdOutMax).val(currentValue);
169                    }else if(currentValue < myMin){
170                        currentValue = myMin;
171                    }
172                    $(this).val(currentValue);
173                }
174				let slider = $this.data("ionRangeSlider");
175				slider.update({from: $(IdOutMin).val(), to: $(IdOutMax).val()});
176				search_disable($this, thisParID);
177				$(this).closest('.rbm_js_filter2_float_block').find('.rbm_js_filter2_clean_values').removeClass('invisible');
178            });
179
180            $(IdOutMax).on('blur', function(){
181				clearTimeout(inputTimer);
182                let min = $(IdOutMin).val().trim().length ? +$(IdOutMin).val() : myMin;
183                let currentValue = $(this).val().replace(/[^0-9\.]+/, '');
184
185                if(currentValue.length){
186                    currentValue = parseFloat(currentValue);
187                    if(currentValue < myMin){
188                        currentValue = myMin;
189                        $(IdOutMin).val(currentValue);
190                    }else if(currentValue < min){
191                        $(IdOutMin).val(currentValue);
192                    }else if(currentValue > myMax){
193                        currentValue = myMax;
194                    }
195                    $(this).val(currentValue);
196                }
197				
198				let slider = $this.data("ionRangeSlider");
199				slider.update({from: $(IdOutMin).val(), to: $(IdOutMax).val()});
200				search_disable($this, thisParID);
201				$(this).closest('.rbm_js_filter2_float_block').find('.rbm_js_filter2_clean_values').removeClass('invisible');
202            });
203    });
204}
205
206function URL2GET() {
207    var preParams = document.location.search.substr(1).split('&'),
208        params = {},
209        oneParam;
210    if (preParams.length) {
211        preParams.forEach(function (item) {
212            oneParam = item.split('=');
213            if (oneParam[0] !== undefined && oneParam[0] != '' && oneParam[1] !== undefined) {
214                params[oneParam[0]] = oneParam[1];
215            }
216        });
217    }
218    return params;
219}
220
221function GET2URL(newParams, deleteParams) {
222    var oldParams = URL2GET(),
223        params,
224        URL = '';
225    for (var param in oldParams) {
226        if (oldParams.hasOwnProperty(param)) {
227            if (param.split('_')[0] == 'param' || ~deleteParams.indexOf(param)) {
228                delete oldParams[param];
229            }
230        }
231    }
232    params = $.extend({}, oldParams, newParams);
233    for (param in params) {
234        if (params.hasOwnProperty(param) && params[param] !== undefined) {
235            URL += '&' + param + '=' + params[param];
236        }
237    }
238    return (URL.length !== 0) ? '?' + URL.substr(1) : "";
239}
240
241function changeParamsURL(params, order, page, category, group, where) {
242    var preparedParams = {},
243        deletedParams = [];
244
245    params.forEach(function (item) {
246        if (item.values !== undefined) {
247            preparedParams[item.name] = item.values;
248        } else if (item.min !== undefined || item.max !== undefined) {
249            preparedParams[item.name] = [item.min, item.max];
250        }
251    });
252    for (var param in preparedParams) {
253        if (preparedParams.hasOwnProperty(param)) {
254            preparedParams['param_' + param] = preparedParams[param].join(';');
255            delete preparedParams[param];
256        }
257    }
258
259
260    if (group !== undefined && group !== '') {
261        preparedParams.group = group;
262    } else {
263        deletedParams.push('group');
264    }
265
266    if (where !== undefined && where !== '') {
267        preparedParams.where = where;
268    } else {
269        deletedParams.push('where');
270    }
271    if (order !== undefined && order !== '') {
272        preparedParams.order = order;
273    } else {
274        deletedParams.push('order');
275    }
276
277    if (page !== undefined && page !== 1) {
278        preparedParams.page = page;
279    } else {
280        deletedParams.push('page');
281    }
282
283    if (category !== undefined && category != 0) {
284        preparedParams.category = category;
285    } else {
286        deletedParams.push('category');
287    }
288    history.pushState({filter2: '1.0'}, 'Результаты поиска', document.location.pathname + GET2URL(preparedParams, deletedParams));
289    $('.tab_url').each(function () {
290        var $this = $(this);
291        $this.attr('href', document.location.href + $this.data('path'));
292    });
293}
294
295function filterSearch($filterForm, parameters, $btn_changed) {
296    parameters.category = (parameters.category !== undefined) ? parameters.category : 0;
297    parameters.page = (parameters.page !== undefined) ? parameters.page : 1;
298    parameters.order = (parameters.order !== undefined) ? parameters.order : "";
299    var jsonString;
300    if (typeof (parameters) == "object") {
301        jsonString = JSON.stringify(parameters);
302    } else if (typeof (parameters) == "string") {
303        jsonString = parameters;
304    } else {
305        return;
306    }
307    $('body').addClass('preloader');
308    $.ajax({
309        dataType: 'json',
310        type: 'POST',
311        url: 'includes/modules/filter2/filter2.php',
312        data: {'data': jsonString},
313        success: function (msg) {
314            $('body').removeClass('preloader');
315            filterCallback[parameters.type](msg, $filterForm, parameters, $btn_changed);
316
317        },
318        error: function () {
319            $('body').removeClass('preloader');
320        }
321    });
322}
323
324/**
325 * Обычный поиск с постраничной навигацией
326 * @param {object} msg
327 * @param {object} $filterForm
328 * @param {object} parameters
329 * @param {string} msg.paginate
330 * @param {string} msg.data
331 * @param {string} msg.msg
332 * @param {number} msg.start
333 * @param {number} msg.end
334 * @param {number} msg.total
335 */
336filterCallback.search = function (msg, $filterForm, parameters, $btn_changed) {
337
338    if (!parameters.string.length && !parameters.float.length) {
339        changeParamsURL([], parameters.order, parameters.page, parameters.category, parameters.group, parameters.where);
340    } else {
341        changeParamsURL([].concat(parameters.string, parameters.float), parameters.order, parameters.page, parameters.category, parameters.group, parameters.where);
342    }
343    if (msg.status === 'ok') {
344        // Вывод данных с постраничной навигацией
345        if ($btn_changed.hasClass('rbm_js_filter_load_more_button')) {
346            filterCallback.load_more(msg, $filterForm);
347        } else {
348            $filterForm.find('.rbm_js_filter_result').html(msg.data);
349            if (msg.total == msg.end) {
350                $filterForm.find('.rbm_js_filter_load_more_button').hide();
351            } else {
352                $filterForm.find('.rbm_js_filter_load_more_button').show();
353                $filterForm.find('.rbm_js_filter_load_more_button').data('page', parameters.page + 1);
354            }
355        }
356
357        $filterForm.find('.rbm_js_filter2_paginate').html(msg.paginate);
358        $filterForm.find('.rbm_js_filter_product_count').html("<div>Показаны товары с " + msg.start + " по " + msg.end + " из " + msg.total + " найденых</div>");
359        $("input[type='number']").niceNumber();
360
361        if ($('.change-view').hasClass('table-view')) {
362            $filterForm.find('.rbm_js_filter_result').find('.product-card-mini').removeClass('list-view').addClass('table-view');
363        } else {
364            $filterForm.find('.rbm_js_filter_result').find('.product-card-mini').removeClass('table-view').addClass('list-view');
365        }
366        $(".spinner").spinner({
367		  icons: {
368			down: "icon icon-minus",
369			up: "icon icon-plus"
370		  },
371		});
372
373		RBM.initForm();
374    } else if (msg.status == 'no_result') {
375        $filterForm.find('.rbm_js_filter_result').html('<p class=\'msg-no-filter-result\'>Результат поиска пуст.</p>');
376        $filterForm.find('.rbm_js_filter2_paginate').empty();
377        $filterForm.find('.rbm_js_filter_product_count').empty();
378    } else {
379        $.jGrowl(msg.msg, {theme: 'ui-state-error'});
380    }
381
382};
383
384/**
385 * Поиск с дозагрузкой товаров на страницу
386 * @param {object} msg
387 * @param {object} $filterForm
388 * @param {string} msg.paginate
389 * @param {string} msg.data
390 * @param {string} msg.msg
391 * @param {number} msg.start
392 * @param {number} msg.end
393 * @param {number} msg.total
394 */
395filterCallback.load_more = function (msg, $filterForm) {
396    if (msg.status == 'ok') {
397        var offset_block = $('.rbm_js_filter_result .rbm_js_product_item').last();
398        //$("html, body").animate({"scrollTop":  offset_block.offset().top + offset_block.outerHeight()}, "slow");
399        $filterForm.find('.rbm_js_filter_result').append(msg.data);
400        if (msg.total == msg.end) {
401            $filterForm.find('.rbm_js_filter_load_more_button').hide();
402        } else {
403            $filterForm.find('.rbm_js_filter_load_more_button').data('page', $filterForm.find('.rbm_js_filter_load_more_button').data('page') + 1);
404        }
405    }
406};
407
408/**
409 * Поиск с дозагрузкой товаров на страницу
410 * @param {object} msg
411 * @param {object} $filterForm
412 * @param {string} msg.paginate
413 * @param {string} msg.data
414 * @param {string} msg.msg
415 * @param {number} msg.start
416 * @param {number} msg.end
417 * @param {number} msg.total
418 */
419filterCallback.map_page = function (msg, $filterForm) {
420    if (msg.status == 'ok') {
421        // Вывод данных с постраничной навигацией
422        $filterForm.find('.rbm_js_filter_result').html(msg.data);
423        $filterForm.find('.rbm_js_filter2_paginate').html(msg.paginate);
424        $filterForm.find('.rbm_js_filter_product_count').html("<div>Показаны товары с " + msg.start + " по " + msg.end + " из " + msg.total + " найденых</div>");
425    } else if (msg.status == 'no_result') {
426        $filterForm.find('.rbm_js_filter_result').html('<p class=\'msg-no-filter-result\'>Результат поиска пуст.</p>');
427        $filterForm.find('.rbm_js_filter2_paginate').empty();
428        $filterForm.find('.rbm_js_filter_product_count').empty();
429    } else {
430        $.jGrowl(msg.msg, {theme: 'ui-state-error'});
431    }
432    showPreloader(false, ['.rbm_js_filter2_button']);
433};
434
435function searchStart() {
436    var $this = $(this);
437    var type = $(this).data('type'),
438        action = $(this).data('action'),
439        $filterForm = $(this).parents('.rbm_js_filter_form');
440    var output = {
441        data_view: $('.change-view').find('.active').data('view'),
442        action: (action !== undefined) ? action : 'search_filter',
443        type: (type !== undefined) ? type : 'search',
444        category: $filterForm.find('.rbm_js_filter_category').val(),
445        page: $(this).data('page'),
446        order: $filterForm.find('.rbm_js_filter_order').val() != 0 ? $filterForm.find('.rbm_js_filter_order').val() : '',
447        types: $filterForm.find('.rbm_js_filter_types').val(),
448        limit: $filterForm.find('.rbm_js_filter_limit').val(),
449        float: getFloatParam($filterForm),
450        string: getStringParam($filterForm),
451        group: $filterForm.find('.rbm_js_filter_group').val() != 0 ? $filterForm.find('.rbm_js_filter_group').val() : '',
452        where: $filterForm.find('.rbm_js_filter_where').val() != 0 ? $filterForm.find('.rbm_js_filter_where').val() : ''
453    };
454    filterSearch($filterForm, output, $this);
455}
456
457/////////////////////// поиск с помощью фильтра
458$(document).on('click', '.rbm_js_filter2_paginate_page, .rbm_js_filter2_button, .rbm_js_filter_load_more_button', function (e) {
459    e.preventDefault();
460    e.stopPropagation();
461    searchStart.call(this);
462    return false;
463
464});
465
466////////////////////Снятие одного выбранного параметра фильтра
467$(document).on('click', '.rbm_del_select_element_filter', function () {
468    searchStart.call(this);
469});
470
471////////////////////Снятие всех параметров фильтра
472$(document).on('click', '.rbm_js_clear_all_param', function () {
473
474    $('.rbm_js_filter2_input_float').each(function () {
475        var $this = $(this).closest('.rbm_js_filter2_float_block').find('.rbm_filter2_slider_ui');
476        let slider = $this.data("ionRangeSlider");
477        slider.update({from: $this.data('min'), to: $this.data('max')});
478        $('.rbm_js_filter2_input_min_' + $this.data('parameter')).prop('placeholder', $this.data('min'));
479        $('.rbm_js_filter2_input_max_' + $this.data('parameter')).prop('placeholder', $this.data('max'));
480        $(this).val('');
481
482    });
483	
484	$(".rangeslider-string").each(function(){
485		let slider = $(this).data("ionRangeSlider");
486		slider.reset();
487	});
488	
489	
490    $('.rbm_js_filter2_input_string').each(function () {
491        $(this).closest('label').removeClass('rbm_css_value_disable');
492        if (this.tagName === "SELECT") {
493            if ($(this).val() != 0) {
494                $(this).val('');
495            }
496        } else if (this.tagName === "INPUT") {
497            if ($(this).prop("checked")) {
498                $(this).prop('checked', false);
499            }
500            $(this).prop('disabled', false);
501        } else if ($(this).hasClass('active')) {
502            $(this).removeClass('active');
503        }
504    });
505    searchStart.call(this);
506    sliderInit();
507    /* $('.rbm_js_filter2_input_float').each(function () {
508         $(this).val($(this).attr('placeholder'));
509     });*/
510});
511
512
513////////////////////Эмуляция нажатия кнопки поиска при смене вида сортировки
514$(document).on('change', '.rbm_js_filter_order, .rbm_js_filter_category, .rbm_js_filter_group, .rbm_js_filter_where', function () {
515    searchStart.call(this);
516});
517
518
519$(document).on("click", ".filter-button", function () {
520    searchStart.call($('.rbm_js_filter2_button'));
521});
522
523
524// ---------- / Show filter button ---------- //
525
526$(document).ready(function () {
527    sliderInit();
528    $('.rbm_filter2_helper').tooltip();
529/////////////////////Навигация по истории /////////////////////////////////////
530// (setTimeout для сафари, чтобы событие не срабатывало при загрузке страницы)
531    setTimeout(function () {
532        $(window).on('popstate', function () {
533            window.history.go(0);
534            return false;
535        });
536    }, 0);
537});
538
539
540$(document).on('change', '.rbm_js_filter2_input_string', function (e) {
541    var thisParID = $(this).closest('.rbm_js_filter2_string_block').data('id');
542    search_disable($(this), thisParID);
543
544});
545
546function search_disable($this, thisParID) {
547
548    var type = $this.data('type'),
549        action = $this.data('action'),
550        $filterForm = $this.closest('.rbm_js_filter_form');
551    var output = {
552        action: 'search_disable',
553        type: (type !== undefined) ? type : 'search',
554        category: $filterForm.find('.rbm_js_filter_category').val(),
555        page: $this.data('page'),
556        order: $filterForm.find('.rbm_js_filter_order').val(),
557        types: $filterForm.find('.rbm_js_filter_types').val(),
558        limit: $filterForm.find('.rbm_js_filter_limit').val(),
559        float: getFloatParam($filterForm),
560        string: getStringParam($filterForm)
561    };
562    output.category = (output.category !== undefined) ? output.category : 0;
563    output.page = (output.page !== undefined) ? output.page : 1;
564    output.order = (output.order !== undefined) ? output.order : "";
565    var jsonString;
566    if (typeof (output) == "object") {
567        jsonString = JSON.stringify(output);
568    } else if (typeof (output) == "string") {
569        jsonString = output;
570    } else {
571        return;
572    }
573    $.ajax({
574        dataType: 'json',
575        type: 'POST',
576        url: 'includes/modules/filter2/filter2.php',
577        data: {'data': jsonString},
578        success: function (msg) {
579            $('.rbm_js_filter2_string_block').each(function () {
580                if ($(this).data('id') != thisParID) {
581                    $(this).find('.rbm_js_filter2_input_string').prop('disabled', true);
582
583                    $(this).find('.rbm_js_filter2_input_string').each(function () {
584                        if (msg.id_value.indexOf($(this).val()) != -1) {
585                            $(this).prop('disabled', false);
586                        }
587                    });
588                } else {
589                    $(this).find('.rbm_js_filter2_input_string').each(function () {
590						
591                        if (msg.id_value.indexOf($(this).val()) != -1) {
592                            $(this).prop('disabled', false);
593                        }
594                    });
595                }
596            });
597
598            for (key in msg.int_value) {
599                if ($('.rbm_js_filter2_input_min_' + key).length && $('.rbm_js_filter2_input_min_' + key).val().length) {
600                    msg.int_value[key][0] = $('.rbm_js_filter2_input_min_' + key).val();
601                }
602
603                if ($('.rbm_js_filter2_input_max_' + key).length && $('.rbm_js_filter2_input_max_' + key).val().length) {
604                    msg.int_value[key][1] = $('.rbm_js_filter2_input_max_' + key).val();
605                }
606
607
608
609                let slider = $('.rbm_filter2_slider_helper_' + key).data("ionRangeSlider");
610				if(slider){
611					slider.update({
612						from: msg.int_value[key][0], to: msg.int_value[key][1]
613					});
614
615					$('.rbm_js_filter2_input_min_' + key).prop('placeholder', msg.int_value[key][0]);
616					$('.rbm_js_filter2_input_max_' + key).prop('placeholder', msg.int_value[key][1]);
617				}
618                
619            }
620			
621			searchStart.call($('.rbm_js_filter2_button'));
622			
623        },
624        error: function () {
625            //showPreloader(false, ['.rbm_js_filter2_button']);
626            $('body').removeClass('preloader');
627        }
628    });
629}
630
631$(document).on('click', '.rbm_js_filter2_clean_values', function() {
632
633	var $this = $(this).closest('.rbm_js_filter2_float_block').find('.rbm_filter2_slider_ui');
634	let slider = $this.data("ionRangeSlider");
635	slider.update({from: $this.data('min'), to: $this.data('max')});
636	$('.rbm_js_filter2_input_min_' + $this.data('parameter')).prop('placeholder', $this.data('min')).val('');
637	$('.rbm_js_filter2_input_max_' + $this.data('parameter')).prop('placeholder', $this.data('max')).val('');
638
639	var thisParID = $(this).closest('.rbm_js_filter2_string_block').data('id');
640	$(this).addClass('invisible');
641
642	search_disable($(this), thisParID);
643});
644
645$(document).on('click', '.rbm_js_filter_select_btn', function() {
646  var dataValuesString = [];
647  var dataValuesInt = [];
648  var thisPar = $(this);
649  $('.rbm_js_filter_select').each(function() {
650    if ($(this).data('type') == 'int') {
651      dataValuesInt.push({
652        id: $(this).data('parameter_id'),
653        name: $(this).data('alias'),
654        min: $(this).val(),
655        max: $(this).val()
656      });
657    } else if ($(this).data('type') == 'string') {
658      dataValuesString.push({
659        id: $(this).data('parameter_id'),
660        name: $(this).data('alias'),
661        values: [$(this).val()]
662
663
664      });
665    }
666  })
667
668  var output = {
669
670    action: 'search_filter_select',
671    type: 'search',
672    category: $('.rbm_js_filter_category').val(),
673    page: '1',
674    order: 'types',
675    limit: '5',
676    string: dataValuesString,
677    float: dataValuesInt
678  };
679
680  var jsonString = JSON.stringify(output);
681  $.ajax({
682    dataType: 'json',
683    type: 'POST',
684    url: 'includes/modules/filter2/filter2.php',
685    data: {
686      'data': jsonString
687    },
688    success: function(msg) {
689      $('.rbm_js_filter_select_result').html(msg.msg);
690
691    },
692    error: function() {
693      //showPreloader(false, ['.rbm_js_filter2_button']);
694      $('body').removeClass('preloader');
695    }
696  });
697});

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.