PageSourceSearch

https://gardenwood.ru/g/shop2/shop2custom.js

js gardenwood.ru collected 2026-10-05 00:06:43 UTC 61,664 bytes, 2,409 lines download raw bytes

1shop2.delivery = {
2	deligate: false,
3	shop2_old: false,
4	ymapsMap : null,
5    ymapsData : [],
6    ymapsIconsData: {
7      'default' : '/g/shop2v2/default/images/map-pin.svg',
8      'spsr' : '/g/shop2v2/default/images/map-pin-red.svg',
9      'dellin' : '/g/shop2v2/default/images/map-pin-purple.svg',
10      'edostavka' : '/g/shop2v2/default/images/map-pin-green.svg',
11      'pickpoint' : '/g/shop2v2/default/images/map-pin.svg',
12      'boxberry' : '/g/shop2v2/default/images/map-pin-boxberry.svg',
13      'delica' : '/g/shop2v2/default/images/map-pin.svg',
14    },
15    select: function(id, block_class) {
16        $('.' + block_class).hide();
17        $('.' + block_class + ' :input').attr('disabled', true);
18        $('#' + block_class + '-' + id + ' :input').attr('disabled', false);
19        $('#' + block_class + '-' + id).show();
20        return false
21    },
22    onload: function(delivery_radio, block_class) {
23        var self = this;
24        widgets.addOnloadEvent(function() {
25            var id = $('.' + delivery_radio + ':checked').val();
26            self.select(id, block_class)
27        })
28    },
29    calc: function() {
30        if (arguments.length < 4) {
31            throw 'Invalid arguments'
32        }
33        var func = arguments[4];
34        $.getJSON('/-/shop2-api/?cmd=deliveryCalc', {
35            hash: arguments[0],
36            ver_id: arguments[1],
37            attach_id: arguments[2],
38            params: arguments[3]
39        }, function(d) {
40            if (d.errstr == '') {
41                if (typeof (func) == "function") {
42                    func(d.data)
43                } else {
44                    $('#' + func).text(d.data.cost)
45                }
46            } else {
47                alert(d.errstr[0])
48            }
49        });
50        return false
51    }
52};
53shop2.delivery.changeDeliveryPoint = function(obj, service_code) {
54  var $this = $(obj),
55      option = $this.parents('.option-details:first');
56      
57  if (shop2.delivery.ymapsMap) {
58  	  shop2.delivery.ymapsMap.destroy();
59  	  shop2.delivery.ymapsMap = null;
60  }
61  
62  option.find('.map-select select option:first').prop('selected', true);
63  option.find('.map-select select').trigger('refresh');
64  option.find('.deligate_points_fields .fields').empty();
65  option.removeClass('selected');
66  $('html, body').scrollTop(option.parent().offset().top - 60);
67  shop2.delivery.YmapsInit(service_code);
68  return false;
69}
70shop2.delivery.selectSuggestion = function(value, enter) {
71  var name = value;
72  $.ajax({
73    url : '/-/x-api/v1/public/?method=deligate/suggestAddress',
74    type : 'POST',
75    dataType: 'json',
76    data : JSON.stringify({query:name, count:1}),
77    success : function(suggestion) {
78      if (suggestion.result.suggestions) {
79        suggestion.result.suggestions[0].data.source = name;
80      }
81      if (enter) {
82        $('#shop2-deligate-calc').trigger('click');
83      } else {
84        $("#dadata").val(JSON.stringify(suggestion.result.suggestions[0].data));
85        $("#address").val(name);
86        $('#shop2-deligate-calc').trigger('click');
87      }
88    }
89  });
90}
91shop2.delivery.YmapsInit = function(service_code) {
92  var obj = Object.keys(shop2.delivery.ymapsData).length,
93    localize_text_div = $('.baloon-content-localize'),
94    localize_text = {
95      'point' : localize_text_div.data('point-text'),
96      'term' : localize_text_div.data('term-text'),
97      'price' : localize_text_div.data('price-text'),
98      'address' : localize_text_div.data('address-text'),
99      'phone' : localize_text_div.data('phone-text'),
100      'worktime' : localize_text_div.data('worktime-text'),
101      'url' : localize_text_div.data('url-text'),
102      'more' : localize_text_div.data('more-text'),
103      'choose' : localize_text_div.data('choose-text'),
104    };
105  if (!obj) {
106    $('.shop2-delivery--item__tab.points').addClass('disabled');
107    return false;
108  }
109  var dadataJson   = $.parseJSON($('#dadata').val()),
110    coordsCenter = [dadataJson.geo_lat, dadataJson.geo_lon],
111    options      = {
112      id: service_code,
113      center: coordsCenter,
114      zoom: 11,
115    };
116
117  ymaps.ready(function() {
118    shop2.delivery.ymapsMap = new ymaps.Map(options.id, {
119      center: options.center,
120      zoom: options.zoom,
121      controls:[]
122    });
123    var MyBalloonContentLayoutClass = ymaps.templateLayoutFactory.createClass(
124      '<div class="delivery-baloon-content">' +
125      '<h3>$[properties.address]</h3>' +
126      '<div class="buttons"><button type="button" class="shop2-btn" id="balloon-select">'+localize_text.choose+'</button>[if properties.site]<a target="_blank" class="shop2-btn" href="$[properties.site]">'+localize_text.more+'</a>[endif]</div>' +
127      '<div class="note-block"> <p><span>'+localize_text.term+':</span><strong class="term">$[properties.term]</strong></p> <p>$[properties.cost]</p> </div>' +
128      '[if properties.phone]<div class="phone"><span>'+localize_text.phone+':</span>$[properties.phone]</div>[endif]' +
129      '[if properties.worktime]<div class="worktime"><span>'+localize_text.worktime+':</span>$[properties.worktime]</div>[endif]' +
130      '[if properties.desc]<div class="desc"><span>'+localize_text.url+':</span>$[properties.desc]</div>[endif]' +
131      '<form data-attach_id="$[properties.attach_id]"><input type="hidden" name="delivery_type" value="$[properties.delivery_type]">
131<input class="point-address" type="hidden" name="$[properties.attach_id][0]" value="$[properties.address]"><input type="hidden" name="$[properties.attach_id][deligate][tarif]" class="tariff" value="$[properties.tariff_hash]"><input type="hidden" name="$[properties.attach_id][deligate][terminal]" value="$[properties.id]"></form>'+
132      '</div>', {
133        build: function () {
134          MyBalloonContentLayoutClass.superclass.build.call(this);
135          $('#balloon-select').bind('click', this.onCounterClick);
136        },
137        clear: function () {
138          $('#balloon-select').unbind('click', this.onCounterClick);
139          MyBalloonContentLayoutClass.superclass.clear.call(this);
140        },
141        onCounterClick: function (e) {
142          e.preventDefault();
143          var balloonContent = $(this).parents('.delivery-baloon-content:first'),
144            form           = balloonContent.find('form'),
145            pointName	   = balloonContent.find('h3').text(),
146            pointCostInp   = balloonContent.find('label.cost input:checked'),
147            pointCost	   = pointCostInp.parent().data('cost'),
148            pointTerm	   = balloonContent.find('.term').text(),
149            attach_id      = form.data("attach_id"),
150            deliveryBlock  = $('#shop2-order-delivery'),
151            options        = deliveryBlock.find('.option-label'),
152            groups		   = deliveryBlock.find('.option-type'),
153            details        = deliveryBlock.find('.option-details'),
154            pointTab	   = deliveryBlock.find('.shop2-delivery--item__tab.points'),
155            pointFields    = $(shop2.delivery.ymapsMap.container._parentElement).next(),
156            pointAddress   = form.find('input.point-address').val(),
157            option         = $(shop2.delivery.ymapsMap.container._parentElement).parents('.option-details:first');
158
159          $("#delivery_id_deligate").val(attach_id);
160          form.find('input.tariff').val(pointCostInp.val());
161          pointFields.find('.fields').html(form.html());
162          pointFields.find('.point-name').html(pointName);
163          pointFields.find('.point-cost').html(pointCost);
164          pointFields.find('.point-term').html(pointTerm);
165          pointFields.find('.point-address').html(pointAddress);
166          option.addClass('selected');
167          $('html, body').scrollTop(option.parent().offset().top - 60);
168          //pointFields.show();
169          shop2.delivery.ymapsMap.balloon.close();
170        }
171      }
172    );
173
174    var myCollection = new ymaps.GeoObjectCollection();
175
176    $.each(shop2.delivery.ymapsData[service_code], function(key, item) {
177          var iconPic = shop2.delivery.ymapsIconsData[service_code] || shop2.delivery.ymapsIconsData['default'];
178          if (item.service_code == service_code) {
179	          myCollection.add(new ymaps.Placemark(
180	            item.coords,
181	            item,
182	            {
183	              balloonContentLayout: MyBalloonContentLayoutClass,
184	              iconLayout: 'default#image',
185	              iconImageHref: iconPic,
186	              iconImageSize: [26, 36], // размеры картинки
187	              iconImageOffset: [-13, -36], // смещение картинки
188	              balloonMaxWidth: 530,
189	              balloonPanelMaxMapArea: 'Infinity',
190	              balloonMinHeight: 330,
191	              balloonshadow: false,
192	
193	            }
194	          ));
195          }
196        });
197
198        shop2.delivery.ymapsMap.geoObjects.add(myCollection);
199        shop2.delivery.ymapsMap.container.fitToViewport();
200        shop2.delivery.ymapsMap.behaviors.disable('multiTouch');
201  });
202}
203shop2.delivery.edost = function(attach_id) {
204
205	function find(name) {
206		var selector = '[name=' + name.replace(/([\[\]])/g, '\\$1') + ']';
207		return $(selector);
208	}
209
210	var btn = $('#shop2-edost-calc'),
211		address = find(attach_id + '[address]');
212
213
214	function setAddress(office) {
215		var text = $.trim(office.text()).replace(/\s*\n\s*/g, '\n').split('\n').splice(1).join('\n');
216		address.val(text).prop('readonly', true);
217	}
218
219	find(attach_id + '[edost][office]').on('click', function() {
220		var $this = $(this),
221			wrap = $this.closest('.shop2-edost-office');
222
223		setAddress(wrap);
224		$this.prop('checked', true);
225	});
226
227	find(attach_id + '[edost][tarif]').on('click', function() {
228		var $this = $(this),
229			wrap = $this.closest('.shop2-edost-variant'),
230			siblings = wrap.siblings(),
231			office = wrap.find('.shop2-edost-office'),
232			checked;
233
234		siblings.find('.shop2-edost-office input, .shop2-edost-pickpointmap input').prop({
235			disabled: true,
236			checked: false
237		});
238
239		var radio = wrap.find('.shop2-edost-office input, .shop2-edost-pickpointmap input').prop({
240			disabled: false
241		}).filter(':radio');
242
243		checked = radio.filter(':checked');
244
245		if (radio.get(0)) {
246
247			if (checked.get(0)) {
248				checked.trigger('click');
249			} else {
250				radio.eq(0).trigger('click');
251			}
252
253		} else {
254
255			if (office.length == 1) {
256				setAddress(office);
257			} else if (address.prop('readonly')) {
258				address.prop('readonly', false).val('');
259			}
260
261		}
262
263	}).filter(':checked').trigger('click');
264
265
266	$('.shop2-edost-pickpointmap a').on('click', function() {
267		var $this = $(this),
268			span = $this.children(),
269			city = $this.data('city');
270
271		$this.closest('.shop2-edost-variant').find('> label input').trigger('click');
272
273		function cb(data) {
274			var res = {};
275			$.each(['name', 'address', 'id'], function(i, k) {
276				res[k] = data[k];
277			});
278			$this.next().val(JSON.stringify(res));
279			span.html(': ' + res.name);
280
281			address.val(res.name + ',\n' + res.address).prop('readonly', true);
282		}
283
284		PickPoint.open(cb, {
285			city: city,
286			ids: null
287		});
288
289		return false;
290	});
291
292};
293
294shop2.delivery.calc = function(hash, ver_id, attach_id) {
295
296
297	var to = $('select[name=' + attach_id + '\\[to\\]]');
298	var	zip = $('input[name=' + attach_id + '\\[zip\\]]');
299	var order_value = $('input[name=' + attach_id + '\\[order_value\\]]');
300
301	to = to.length ? to.val() : '';
302	zip = zip.length ? zip.val() : '';
303	order_value = order_value.prop("checked") ? 'on' : '';
304
305	$.getJSON('/-/shop2-api/?cmd=deliveryCalc', {
306
307		hash: hash,
308		ver_id: ver_id,
309		attach_id: attach_id,
310		params: 'to=' + to + '&zip=' + zip + '&order_value=' + order_value
311
312	}, function(d) {
313
314		if (!d.data && d.errstr) {
315
316			alert(d.errstr);
317			$('#delivery-' + attach_id + '-cost').html(0);
318
319		} else {
320
321			$('#delivery-' + attach_id + '-cost').html(d.data.cost);
322
323			if (d.data.html) {
324
325				$('#delivery-' + attach_id + '-html').html(d.data.html);
326				shop2.delivery.edost(attach_id);
327
328			}
329
330		}
331
332	});
333
334	return false;
335};
336
337shop2.user = {
338  activate: function(user_id, target) {
339    var $target = $(target);
340    
341    $target.attr('disabled', true);
342
343    $.post('/-/x-api/v1/public/?method=user/reactivation', {
344      'user_id': user_id,
345    }, function() {
346      var $parent = $target.parent(),
347          $message = $('<div>').addClass('shop2-info').html(window._s3Lang.ACTIVATION_MAIL_SENT);
348    
349      $target.hide();
350      $parent.append($message);
351    });
352  },
353};
354
355shop2.orderCancelling = {
356  alert : function() {
357    var linkButton = $('.order-cancelling'),
358      attrToLinkOrder = linkButton.data('href'),
359      attrLinkTitle = linkButton.data('cancellingTitle'),
360      attrLinkButtonTitle = linkButton.data('cancellingButtonTitle'),
361      attrLinkButtonClose = linkButton.data('cancellingClose'),
362
363      html = '<div class="order-cancel-title">'+ attrLinkTitle +'</div>' +
364        '<div class="order-cancel-buttons">' +
365        '<a class="shop2-btn" href="' + attrToLinkOrder + '">'+ attrLinkButtonTitle +'</a>' +
366        '<a class="shop2-alert-close" onclick="shopClient.alert.hide(); return false;" href="#">
366'+ attrLinkButtonClose +'</a>' +
367        '</div>';
368
369    shopClient.alert(html, '', 'shop2-alert--warning order-cancel');
370  }
371};
372
373shop2.orderCancelling;
374
375$(document).on('click', '.order-cancelling', function(e){
376  e.preventDefault();
377  shop2.orderCancelling.alert();
378});
379
380shop2.facets = {
381    enabled: false,
382    aggs: null,
383    _data: {},
384    emptyClass: 'empty-val',
385
386    mask: '[data-name^="s[field]"][data-value="key"],' +
387    '[name="s[parentField][parentKey]"] [value="key"],' +
388    '[name="s[field]"] [value="key"],' +
389    '[data-name="s[field][index]"],' +
390    '[data-name="s[field][key]"],' +
391    '[name="s[field][key]"]',
392
393    filter: {
394        wrapper: '.shop2-filter, #shop2-color-ext-list',
395        items: '[data-name], [name], [name] [value]'
396    },
397
398    search: {
399        wrapper: '.shop2-block.search-form form, #shop2-color-ext-select',
400        items: '[data-name], [name], [name] [value]'
401    },
402
403    ignoreClear: function($item) {
404        this._data.attrName = $item.attr('name') ? $item.attr('name') : $item.parent().attr('name');
405        return /s\[(folder_id|products_per_page)\]/i.test(this._data.attrName);
406    },
407
408    set: function(mod /* module filter, search */) {
409        var module = shop2.facets[mod];
410
411        if (! module) {
412            return;
413        }
414
415        var $wrapper = $(module.wrapper);
416        var $items   = $wrapper.find(module.items);
417
418        this._data.$wrapper = $wrapper;
419
420        this.clearItems($items);
421        this.insertData(this.aggs);
422
423        var eventName = 'afterFacets' + mod.charAt(0).toUpperCase() + mod.slice(1);
424
425        shopClient.trigger(eventName, this.aggs);
426    },
427
428    searchSetup: function() {
429        if (! this.search) {
430            return;
431        }
432
433        var $form  = $(this.search.wrapper);
434
435        if (!$form.length) {
436            return;
437        }
438
439        var $items = $form.find(this.search.items);
440        var self = this;
441        var url = '/-/shop2-api/?cmd=getSearchMatches&hash=' +
442                shop2.product.apiHash.getSearchMatches +
443                '&ver_id=' + shop2.product.verId + '&',
444            fullUrl = url + $form.serialize();
445
446        this.getDataSearch(fullUrl);
447
448        $(document).on('change', $items, function(e) {
449            if (e.target.name == "s[products_per_page]") {
450                return;
451            }
452
453            fullUrl = url + $form.serialize()
454
455            self.getDataSearch(fullUrl);
456        });
457    },
458
459    getDataSearch: function(url) {
460        $.get(
461            url,
462            function(d, status) {
463                if (status == 'success') {
464                    if ($.type(d) === 'string') {
465                        d = $.parseJSON(d);
466                    }
467
468                    shop2.facets.aggregation(d);
469                    shop2.facets.set('search');
470                }
471            }
472        );
473    },
474
475    clearItems: function ($items) {
476        var emptyClass = this.emptyClass;
477        var self = this;
478        var $item, nodeName;
479
480        $items.each(function(index, item) {
481            $item = $(item);
482
483            if ( self.ignoreClear($item) ) {
484                return true;
485            }
486
487            nodeName = $item.prop('tagName').toLowerCase();
488
489            switch (nodeName) {
490                case 'select':
491                    break;
492                case 'input':
493                    $item.attr('placeholder', '');
494                    break;
495                case 'option':
496                    if ( $item.attr('value')) {
497                        $item.attr('disabled', 'disabled');
498                    }
499                    break;
500            }
501
502            $item.attr('data-param-val', '0');
503            $item.addClass(emptyClass);
504        });
505    },
506
507    aggregation: function(d) {
508        if (typeof d === 'object' && d.data.aggs) {
509            this.aggs = this.dataSetup(d.data.aggs);
510        }
511
512        return this.aggs;
513    },
514
515    dataSetup: function(aggs) {
516        var cf = aggs.cf;
517        var key, field;
518
519        for (key in cf) {
520            field = cf[key];
521
522            if ($.isArray(field) && !field.length) {
523                delete cf[key];
524            }
525        }
526
527        return aggs;
528    },
529
530    insertData: function(aggs, field) {
531        $.each(aggs, $.proxy(function(key, value) {
532            if (typeof value === "object") {
533                this.insertData(value, key);
534            } else {
535                this._data.$item = this.getItem(field, key);
536
537                if (!this._data.$item.length || ! value) {
538                    return true;
539                }
540
541                switch (this._data.$item.prop('tagName').toLowerCase()) {
542                    case 'input':
543                        this._data.$item.attr('placeholder', value);
544                        break;
545                    case 'option':
546                        this._data.$item.removeAttr('disabled');
547                        break;
548                }
549
550                this._data.$item.attr('data-param-val', value);
551                this._data.$item.removeClass(this.emptyClass);
552            }
553        }, this));
554    },
555
556    getItem: function(field, key) {
557        this._data.selector = this.mask.replace(/field/g, field).replace(/key/g, key);
558
559        return this._data.$wrapper.find(this._data.selector);
560    },
561
562    setMask: function(mask) {
563        this.mask = mask;
564    },
565
566    setEmptyClass: function(emptyClassName) {
567        this.emptyClass = emptyClassName;
568    },
569
570    setContainers: function(module, obj) {
571        this[module] = obj;
572    }
573};
574
575(function() {
576
577	$.fn.s3center = function() {
578
579		return this.each( function() {
580			var $this = $(this),
581				isVisible = $this.is(':visible');
582
583			if (!isVisible) {
584				$this.show();
585			}
586
587			$this.css({
588				marginLeft: -$this.outerWidth() / 2,
589				marginTop: -$this.outerHeight() / 2
590			});
591
592			if (!isVisible) {
593				$this.hide();
594			}
595		});
596	};
597
598	$.fn.caret = function(begin, end) {
599		var range;
600
601		if (this.length === 0 || this.is(":hidden")) {
602			return;
603		}
604
605		if (typeof begin == 'number') {
606			end = (typeof end === 'number') ? end : begin;
607			return this.each(function() {
608				if (this.setSelectionRange) {
609					this.setSelectionRange(begin, end);
610				} else if (this.createTextRange) {
611					range = this.createTextRange();
612					range.collapse(true);
613					range.moveEnd('character', end);
614					range.moveStart('character', begin);
615					range.select();
616				}
617			});
618		} else {
619			if (this[0].setSelectionRange) {
620				begin = this[0].selectionStart;
621				end = this[0].selectionEnd;
622			} else if (document.selection && document.selection.createRange) {
623				range = document.selection.createRange();
624				begin = 0 - range.duplicate().moveStart('character', -100000);
625				end = begin + range.text.length;
626			}
627			return {
628				begin: begin,
629				end: end
630			};
631		}
632	};
633
634	$.fn.keyFilter = function(def, type, callback) {
635		return this.each(function() {
636			var obj = $(this);
637			obj.keypress(function(e) {
638				var caret = obj.caret();
639				if (e.shiftKey || e.ctrlKey) return false;
640				if (e.which == 0) return true;
641				var isDigit = e.which >= 48 && e.which <= 57;
642				var isPoint = e.which == 46 || e.which == 44;
643				var isBack = e.which == 8;
644				if (type == 'int' && isPoint) return false;
645				if (!isDigit && !isPoint && !isBack) return false;
646				obj.val(obj.val().replace(',', '.'));
647				obj.caret(caret.begin, caret.end);
648
649				if (isPoint && obj.val().indexOf('.') != -1) return false;
650			}).keyup(function(e) {
651				var max = obj.attr('max');
652				if (max) {
653					max = Number(max);
654					if (obj.val() > max) {
655						obj.val(max);
656						widgets.msg("В наличии только " + max, obj.get(0));
657					}
658				}
659				if (callback) callback(obj);
660			}).blur(function() {
661				if (obj.val() == '' || obj.getVal() == 0) {
662					obj.val(def);
663					if (callback) callback(obj);
664				}
665			});
666		});
667	};
668
669	$.fn.getVal = function() {
670		var v = $(this).val();
671		v = parseFloat(v);
672		if (v) return v;
673		return 0;
674	};
675
676
677	$.fn.s3tooltip = function(settings) {
678
679		settings = $.extend({
680			data: function() {
681				return this.alt || '';
682			},
683
684			cls: 'tooltip-1',
685			slide: true,
686			dir: 'bottom'
687
688		}, settings);
689
690		var tooltip = $('#shop2-tooltip');
691
692		if (!tooltip.get(0)) {
693			tooltip = $('<div id="shop2-tooltip"></div>');
694			$('body').append(tooltip);
695		}
696
697		var selector = this.selector;
698
699		var win = {
700				$el: $(window)
701			},
702			width,
703			height;
704
705		$(document).on({
706
707			mouseenter: function(e) {
708				var html = settings.data.call(this);
709
710				if (!html) {
711					return;
712				}
713
714				win.width = win.$el.width();
715				win.height = win.$el.height();
716
717				tooltip.html(html);
718				tooltip.addClass(settings.cls);
719				tooltip.show();
720
721				width = tooltip.outerWidth(true);
722				height = tooltip.outerHeight(true);
723			},
724
725			mouseleave: function(e) {
726				tooltip.hide();
727				tooltip.removeClass(settings.cls);
728			},
729
730			mousemove: function(e) {
731
732				var left = e.pageX,
733					top = e.pageY,
734					scrollTop = $(document).scrollTop();
735
736				if (left + width > win.width) {
737					left -= width;
738				}
739
740				if (settings.dir == 'top') {
741					top -= height;
742
743					if (top < scrollTop) {
744
745						if (settings.slide) {
746
747							top = scrollTop;
748
749						} else {
750
751							top += height;
752						}
753
754					}
755
756				} else {
757
758					if (top + height > win.height + scrollTop) {
759
760						if (settings.slide) {
761
762							top = win.height + scrollTop - height;
763
764						} else {
765
766							top -= height;
767
768						}
769
770					}
771
772				}
773
774				tooltip.css({
775					left: left,
776					top: top
777				});
778
779			}
780		}, selector);
781
782	};
783
784})(jQuery);
785
786shop2.product.reload = function (node, pageType, cb) {
787	var nodeData, paramName, paramValue, form, productId, curKindId, refs,
788		kindId, meta, i, d, p, v;
789
790	nodeData   = this.getNodeData(node, true);
791	paramName  = this.getNodeData(node, false, 'data-name');
792	paramValue = this.getNodeData(node, false, 'data-value');
793
794	if (!nodeData) {
795		throw 'Node data is empty';
796	}
797	if (paramName == undefined || paramValue == undefined) {
798		throw "data-name and data-value attributes required";
799	}
800
801	form = $(node).closest('form');
802
803	if (!form.length) {
804		throw 'Failed getting form node';
805	}
806
807	form = form.get(0);
808
809	if (form.elements['meta'] != undefined) {
810		meta = JSON.parse(form.elements['meta'].value);
811	}
812
813	form.submit.disabled = true;
814
815	productId   = Number(form.product_id.value);
816	curKindId   = Number(form.kind_id.value);
817	refs        = shop2.product.productRefs[productId];
818	kindId      = 0;
819	matches     = 0;
820	lastMatches = 0;
821
822	// Find the best matching kind ID
823
824	if (nodeData.length == 1) {
825		kindId = nodeData[0];
826	} else {
827		for (i = 0; i < nodeData.length; ++i) {
828			// d - one of kind IDs having selected value
829			d = Number(nodeData[i]);
830
831			matches = 0;
832
833			for (p in refs) {
834				// p - control name
835				for (v in refs[p]) {
836					if (p == paramName) {
837						if (v == paramValue) {
838							++matches;
839						}
840					} else {
841						// v - control value
842						if (String(refs[p][v]).indexOf(d) == -1) {
843							continue;
844						}
845
846						//++matches;
847
848						if (shop2.product.checkMetaItemValue) {
849							if (meta && shop2.product.checkMetaItemValue(meta, p, v)) {
850								++matches;
851							}
852						} else {
853							if (meta && shop2.product.getMetaItemValue(meta, p) == v) {
854								++matches;
855							}
856						}
857					}
858				}
859			}
860
861			// Searching for kind ID with best matches
862			if (matches > lastMatches) {
863				kindId = d;
864				lastMatches = matches;
865			}
866		}
867	}
868
869	// Reload all in case of product page
870	if (pageType == 'product') {
871		var uri = shopClient.uri;
872		if (uri) {
873			if (uri.slice(-1) == '/') {
874				uri = uri.slice(0, -1);
875			}
876			document.location.href = uri + '/product/' + kindId;
877		} else {
878			document.location.href = document.location.href.replace(/\/product\/.+/, '/product/' + kindId);
879		}
880		return;
881	} else {
882		shop2.showPreloader(node);
883	}
884
885	// Request the kind for rendering via AJAX
886	var url = '/-/shop2-api/?cmd=getProductListItem&hash=' + this.apiHash['getProductListItem']
887		+ '&ver_id=' + this.verId;
888	if (pageType != undefined) {
889		url += '&page_type=' + pageType;
890	}
891	$.post(url, {
892		'kind_id'    : kindId,
893		'product_id' : productId
894	}, function(d, textStatus) {
895		try {
896			if (textStatus == 'success') {
897				if (typeof d == 'string') {
898					d = jQuery.parseJSON(d);
899				}
900
901				if (typeof d.errstr != "undefined" && d.errstr) {
902					widgets.msg(window._s3Lang['JS_HTTP_ERROR'] + ': ' + d.errstr, node, 'msg-ajax-error');
903				}
904
905				// Replace product element div
906				var $cont = $(node).closest('.shop2-product-item');
907				$cont.hide();
908				var $newCont = $(d.data.body).insertBefore($cont);
909				$cont.remove();
910				shop2.product.disableUnusedFields($newCont, nodeData);
911
912
913				if (typeof d.data.params != "undefined") {
914					$('.shop2-product-item-params').html(d.data.params);
915				}
916			} else {
917				// HTTP error code
918				widgets.msg(window._s3Lang['JS_HTTP_ERROR'] + ': ' + d.errstr, 'msg-ajax-error');
919			}
920
921			shop2.hidePreloader();
922		} catch (e) {
923			widgets.msg(e.message);
924			shop2.hidePreloader();
925		}
926		if (typeof cb == "function") {
927			cb(d);
928		}
929	});
930
931	form.submit.disabled = false;
932};
933
934shop2.options = {
935	amountDefaultValue: 1,
936	amountDefaultInc: 1,
937	amountType: 'int',
938	msgTime: 1500,
939	printCSS: '/g/shop2v2/default/css/print.less.css'
940};
941
942var shopClient = {
943	reloadProduct: function(obj) {
944		shop2.product.reloadProduct(obj);
945	},
946	addItem: function(obj, hash, ver_id, kind_id, amount, submit_btn, type) {
947		createCookie("cart_opened", 1, 90);
948		amount = Number(amount);
949		if (!amount) amount = 1;
950		shop2.cart.addItem(obj, hash, ver_id, kind_id, amount, submit_btn, type);
951	}
952};
953
954shopClient.callbacks = {};
955
956shopClient.on = function(type, func) {
957	var _this = this;
958
959	$.each(type.split(','), function(index, type) {
960		type = $.trim(type);
961
962		if (!_this.callbacks[type]) {
963			_this.callbacks[type] = $.Callbacks();
964		}
965
966		_this.callbacks[type].add(func);
967	});
968};
969
970shopClient.off = function(type, func) {
971	if (this.callbacks[type]) {
972		func ? this.callbacks[type].remove(func) : this.callbacks[type].empty();
973	}
974};
975
976shopClient.trigger = function(type) {
977	if (this.callbacks[type]) {
978		this.callbacks[type].fireWith(self, [].slice.call(arguments, 1));
979	}
980};
981
982shopClient.defaults = {
983	minAmount: 1,
984	unitType: 'int',
985	amountDefaultInc: 1
986};
987
988shopClient.locale = {
989	inCard: 'Товар добавлен в корзину. <br /><a href="">Оформить заказ</a>',
990	hideParams: 'Скрыть параметры',
991	allParams: 'Все параметры'
992};
993
994shopClient.msg = {
995	win: null,
996	close: null,
997	content: null,
998	o: null,
999	init: function() {
1000		var html = '<div id="shop2-msg">' +
1001			'<div id="shop2-msg-close">x</div>' +
1002			'<div id="shop2-msg-text"></div>'
1003		'</div>';
1004		$('body').append(html);
1005		this.win = $('#shop2-msg');
1006		this.close = $('#shop2-msg-close');
1007		this.content = $('#shop2-msg-text');
1008
1009		$(window).resize(function() {
1010			shopClient.msg.setPosition();
1011		});
1012		this.close.click(function() {
1013			shopClient.msg.win.hide();
1014		});
1015	},
1016	show: function(text, obj) {
1017		var ww, wh;
1018		if (!this.win) {
1019			this.init();
1020		}
1021
1022		text = shopClient.locale.inCard;
1023
1024		this.content.html(text);
1025		this.o = $(obj);
1026		this.win.show();
1027		this.setPosition();
1028	},
1029	setPosition: function() {
1030		var ww, wh, mw, mh, ow, oh, pos, left, top, visible;
1031
1032		visible = this.win.is(':visible');
1033		if (!visible) return;
1034
1035
1036		this.win.hide();
1037
1038		ww = $(document).width() - 15;
1039		wh = $(document).height();
1040
1041		this.win.show();
1042
1043		mw = this.win.outerWidth(true);
1044		mh = this.win.outerHeight(true);
1045		ow = this.o.width();
1046		oh = this.o.height();
1047
1048		pos = this.o.offset();
1049
1050
1051		left = pos.left + ow + 15;
1052		top = pos.top - (mh - oh) / 2;
1053
1054		if (left + mw > ww) {
1055			left = pos.left - mw - 15;
1056		}
1057
1058		if (top + mh > wh) {
1059			top = wh - mh;
1060		}
1061
1062		this.win.css({
1063			left: left,
1064			top: top
1065		});
1066	}
1067};
1068
1069$(function() {
1070	if (document.location.search.indexOf('test') != -1) {
1071		widgets.msg = function(text, obj) {
1072			shopClient.msg.show(text, obj);
1073		}
1074	}
1075});
1076
1077//shop2.cart.addItem(this, '324eabfdc402491d8ab1d9f080f1d325', '26909', this.kind_id.value, this.amount.value,this.elements.submit, 'shop2-cart-preview'); return false;
1078
1079shopClient.Cart = {
1080	check: function() {
1081		var amount = $('#cart_total_amount'),
1082			pre = $('#cart_pre_amount'),
1083			cart = $('.shop-cart'),
1084			empty = $('.shop-cart-in .shop-cart-empty'),
1085			full = $('.shop-cart-in .shop-cart-full');
1086
1087		if (amount.get(0) || pre.get(0)) {
1088			if (parseFloat(amount.html()) > 0 || pre.html() > 0) {
1089				cart.addClass('cart-added');
1090				empty.hide();
1091				full.show();
1092			} else {
1093				cart.removeClass('cart-added');
1094				empty.show();
1095				full.hide();
1096			}
1097		}
1098	}
1099};
1100
1101shopClient.PriceList = {
1102	addToCart: function(el, hash, ver_id, kind_id) {
1103		var amount = $('#amount_' + kind_id).val(),
1104			obj = $(el);
1105		if (!obj.hasClass('shop2-button-disabled') && amount > 0) {
1106			shopClient.addItem(el, hash, ver_id, kind_id, amount, el, 'shop2-cart-preview');
1107		}
1108		return void(0);
1109	}
1110};
1111
1112shopClient.Product = {
1113	setBigImage: function(srcObj, imageUrl, thumbUrl) {
1114		var e = document.getElementById('shop2-product-image'),
1115			src = $(srcObj).attr('src');
1116		if (e && e.tagName == 'IMG') {
1117			e.src = thumbUrl;
1118			$('div.product-thumbnails-wrap li').removeClass('activ-img');
1119			$(srcObj).parent('li').addClass('activ-img');
1120			$(e).closest('a.highslide').attr('href', imageUrl);
1121		}
1122	}
1123};
1124
1125shopClient.Search = {
1126	getFolderParams: function(self, hash, ver_id) {
1127		var v = self.options[self.selectedIndex].value,
1128			wrap = document.getElementById('shop2_search_custom_fields'),
1129			url,
1130			options = shopClient.Filter.getUrlParams(),
1131			search = [],
1132			i;
1133
1134		shopClient.trigger('beforeGetFolderCustomFields');
1135
1136		if (wrap) {
1137
1138
1139			if (v > 0) {
1140				url = '/-/shop2-api/?cmd=getFolderCustomFields' + '&hash=' + hash + '&ver_id=' + ver_id + '&folder_id=' + v;
1141
1142				for (i in options) {
1143					if (options.hasOwnProperty(i) && options[i]) {
1144						search.push(i + '=' + options[i]);
1145					}
1146				}
1147				search = search.join('&');
1148				if (search) {
1149					url = url + '&' + search;
1150				}
1151
1152				jQuery.getJSON(url, function(d, status) {
1153
1154					shopClient.trigger('afterGetFolderCustomFields', d, status);
1155
1156					if (!d || d.error) {
1157						widgets.msg(d.error, self);
1158						return;
1159					}
1160
1161					wrap.innerHTML = d.data;
1162				});
1163			} else {
1164				wrap.innerHTML = '';
1165			}
1166		}
1167	}
1168};
1169
1170
1171shopClient.Filter = {
1172	_get: null,
1173	_sort: null,
1174	_folder: "",
1175	Folder: function(key, value) {
1176		this._folder = '&' + key + '=' + value;
1177	},
1178	getUrlParams: function() {
1179		var search = window.decodeURIComponent(document.location.search),
1180			params = {},
1181			param,
1182			i, j,
1183			parts;
1184		if (this._get === null) {
1185			search = search.slice(1).split('&');
1186			for (i = 0; i < search.length; i++) {
1187				param = search[i].split('=');
1188				if (param.length == 2) {
1189					params[param[0]] = [];
1190					parts = param[1].split('|');
1191					for (j = 0; j < parts.length; j++) {
1192						if (parts[j] != '') {
1193							params[param[0]].push(parts[j]);
1194						}
1195					}
1196				}
1197			}
1198			this._get = params;
1199		}
1200		return this._get;
1201	},
1202	findOption: function(array, value) {
1203		var i;
1204		for (i = 0; i < array.length; i++) {
1205			if (array[i] == value) {
1206				return i;
1207			}
1208		}
1209		return -1;
1210	},
1211	replaceParam: function(key, value) {
1212		var params = this.getUrlParams();
1213		params[key] = [value];
1214		this._get = params;
1215		this.getCount();
1216	},
1217	addParam: function(key, value, obj) {
1218		var params = this.getUrlParams(),
1219			i, position;
1220
1221		value = window.encodeURIComponent(value);
1222
1223		if (typeof params[key] === 'undefined') {
1224			params[key] = [value];
1225		} else {
1226			position = this.findOption(params[key], value);
1227			if (position != -1) {
1228				params[key].splice(position, 1);
1229			} else {
1230				params[key].push(value);
1231			}
1232		}
1233
1234		$(obj).toggleClass('shop-filter-param-val-active');
1235
1236		this._get = params;
1237		this.getCount();
1238		return void(0);
1239
1240	},
1241	getCount: function() {
1242		var url = this.getUrl(true);
1243
1244		shopClient.trigger('beforeGetSearchMatches');
1245
1246		$.get('/-/shop2-api/?cmd=getSearchMatches&hash=' + shop2.product.apiHash.getSearchMatches + '&ver_id=' + shop2.product.verId + '&' + url + this._folder, function(d, textStatus) {
1247
1248			shopClient.trigger('afterGetSearchMatches', d, textStatus);
1249
1250			if (textStatus == 'success') {
1251				if (typeof d == 'string') {
1252					d = jQuery.parseJSON(d);
1253				}
1254
1255                if (shop2.facets.enabled) {
1256                    shop2.facets.aggregation(d);
1257                    shop2.facets.set('filter');
1258                }
1259			}
1260			$('span.filter-result').removeClass('filter-result-hide');
1261			if (d.data.total_found == 0) {
1262				$('span.filter-result').addClass('no-filter-result')
1263			} else {
1264				$('span.filter-result').removeClass('no-filter-result')
1265			}
1266			$('#filter-result').html(d.data.total_found);
1267		});
1268	},
1269	getUrl: function(fromCount) {
1270		var i, params = [],
1271			j, options = this._get;
1272
1273		for (i in options) {
1274			if (options.hasOwnProperty(i) && options[i]) {
1275				if (options[i].length > 0) {
1276					params.push(i + '=' + options[i].join('|'));
1277				}
1278			}
1279		}
1280		params = params.join('&');
1281		if (fromCount) {
1282			return params;
1283		}
1284		if (params) {
1285			params = '?' + params;
1286		}
1287		return document.location.pathname.replace(/\/p\/\d*/g, '') + params;
1288	},
1289	goToUrl: function(key, value) {
1290		if (key) {
1291			this._get[key] = [value];
1292		}
1293		document.location = this.getUrl();
1294		return void(0);
1295	},
1296	getSortParams: function() {
1297		var sort_by = this.getUrlParams()['s[sort_by]'],
1298			options = {},
1299			option,
1300			i;
1301		if (this._sort === null) {
1302			if (sort_by) {
1303				sort_by = sort_by[0].split(',');
1304				for (i = 0; i < sort_by.length; i++) {
1305					option = sort_by[i].split(' ');
1306					if (option.length == 2) {
1307						options[option[0]] = option[1];
1308					}
1309				}
1310			}
1311			this._sort = options;
1312		}
1313		return this._sort;
1314	},
1315	sortBy: function(name) {
1316		var params = this.getSortParams(),
1317			i,
1318			sort_by = [];
1319		if (typeof params[name] == 'undefined' || params[name] == '' || params[name] == 'asc') {
1320			params[name] = 'desc';
1321		} else {
1322			params[name] = 'asc';
1323		}
1324
1325		for (i in params) {
1326			if (params.hasOwnProperty(i) && params[i]) {
1327				sort_by.push(i + ' ' + params[i]);
1328			}
1329		}
1330
1331		sort_by = sort_by.join(',');
1332
1333		this._get['s[sort_by]'] = [sort_by];
1334		return this.goToUrl();
1335	},
1336	resetSort: function() {
1337		this._get['s[sort_by]'] = [];
1338		return this.goToUrl();
1339	},
1340	init: function() {
1341		var params = this.getSortParams(),
1342			i, j, value;
1343
1344		for (i in params) {
1345			if (params.hasOwnProperty(i) && params[i]) {
1346				$('#shop2-sorting-' + i).addClass('shop2-sorting-param-' + params[i]);
1347			}
1348		}
1349
1350		var timeout = {};
1351		$('form.shop2-filter input:text').keyup(function(i) {
1352			var o = $(this),
1353				name = o.attr('name'),
1354				value = o.val();
1355			if (timeout[name]) {
1356				window.clearTimeout(timeout[name]);
1357			}
1358
1359			timeout[name] = window.setTimeout(function() {
1360				shopClient.Filter.replaceParam(name, value);
1361			}, 500);
1362
1363		});
1364	}
1365};
1366
1367
1368shopClient.Compare = {
1369	add: function(kind_id, callback) {
1370		this.action('add', kind_id, callback);
1371	},
1372	remove: function(kind_id, callback) {
1373		this.action('del', kind_id, callback);
1374	},
1375	clear: function(callback) {
1376		this.action('clear', null, callback);
1377	},
1378	action: function(action, kind_id, func) {
1379
1380		var eventName = $.camelCase('Compare-' + action);
1381
1382		shopClient.trigger('before' + eventName);
1383
1384
1385		$.post(
1386			'/-/shop2-api/?cmd=compare', {
1387				hash: shop2.product.apiHash.compare,
1388				ver_id: shop2.product.verId,
1389				kind_id: kind_id,
1390				action: action
1391			}, function(d, status) {
1392
1393				shopClient.trigger('after' + eventName, d, status);
1394
1395				if (func) func(d, status);
1396
1397			}
1398		);
1399	}
1400};
1401
1402
1403shopClient.back = function () {
1404	var url;
1405	if (window.sessionStorage) {
1406		url = sessionStorage.getItem('shop2_back_url');
1407		if (url === 'null') {
1408			url = '/';
1409		}
1410	} else {
1411		url = document.referrer;
1412	}
1413	document.location = url || '/';
1414	return false;
1415};
1416
1417
1418(function () {
1419	try {
1420		if (window.sessionStorage) {
1421			var current = sessionStorage.getItem('shop2_current_url');
1422			var url = location.pathname + location.search;
1423			if (current != url) {
1424				sessionStorage.setItem('shop2_back_url', current);
1425			}
1426			sessionStorage.setItem('shop2_current_url', url);
1427		}
1428	} catch (e) {}
1429})();
1430
1431
1432$(function() {
1433
1434	(function() {
1435		$(document).on('click', '.js-shop2-cart-auth__expand', function(e) {
1436			e.preventDefault();
1437			$('.js-shop2-cart-auth__form').toggle();
1438		});
1439
1440		$('#order-print').on('click', function() {
1441			s3.printMe('shop2-order-table', {
1442				stylesheet: shop2.options.printCSS
1443			});
1444
1445			return false;
1446		});
1447	})();
1448
1449	// Кнопка купить
1450	/*(function() {
1451		if ($.browser.msie) {
1452			$(".product-buy").mousedown(function() {
1453				$(this).addClass('active-ie');
1454			}).mouseup(function() {
1455				$(this).removeClass('active-ie');
1456			}).mouseout(function() {
1457				$(this).removeClass('active-ie');
1458			});
1459		}
1460	})();*/
1461
1462	// Плюс и минус
1463
1464	$(document).on('click', 'span.p-plus, span.product-amount-button-add', function() {
1465		var o = $(this),
1466			product_amount, max
1467		if (o.hasClass('disabled')) {
1468			return false;
1469		}
1470		product_amount = o.parent().find('input:text');
1471
1472		var value = product_amount.getVal() + shopClient.defaults.amountDefaultInc;
1473
1474		product_amount.val(value);
1475		max = product_amount.attr('max');
1476		if (max) {
1477			max = Number(max);
1478			if (value > max) {
1479				product_amount.val(max);
1480				widgets.msg(_s3Lang.JS_AVAILABLE_ONLY + ' ' + max, this);
1481			}
1482		}
1483	});
1484
1485	$(document).on('click', 'span.p-minus, span.product-amount-button-remove', function() {
1486		var o = $(this),
1487			product_amount;
1488		if (o.hasClass('disabled')) {
1489			return false;
1490		}
1491		product_amount = o.parent().find('input:text');
1492
1493		var value = product_amount.getVal() - shopClient.defaults.amountDefaultInc;
1494
1495		if (value > shopClient.defaults.minAmount) {
1496			product_amount.val(value);
1497		} else {
1498			product_amount.val(shopClient.defaults.minAmount);
1499		}
1500	});
1501
1502
1503	//Корзинка
1504	(function() {
1505		$(document).on('click', '.shop-cart-title', function() {
1506			var shop_cart_in = $('.shop-cart-in'),
1507				shop_cart = $('.shop-cart');
1508			if (shop_cart_in.is(':hidden')) {
1509				shop_cart_in.show();
1510				shop_cart.addClass('cart-opened');
1511				createCookie("cart_opened", 1, 90);
1512				//$.cookie("full_cart", 1, {path : "/"});
1513			} else {
1514				shop_cart_in.hide();
1515				shop_cart.removeClass('cart-opened');
1516				createCookie("cart_opened", 0, 90);
1517				//$.cookie("full_cart", 0, {path : "/"});
1518			}
1519		});
1520	})();
1521
1522
1523	//Поиск
1524	(function() {
1525		var shop_search_title = $('.shop-search-title'),
1526			shop_search_wrap = $('.shop-search-wrap'),
1527			ss = readCookie("search_state") /*$.cookie("search_state")*/ ;
1528
1529		shop_search_title.click(function() {
1530			var o = $(this);
1531			if (shop_search_wrap.is(':hidden')) {
1532				shop_search_wrap.slideDown(500);
1533				o.addClass('opened');
1534				createCookie("search_state", 1, 90);
1535				//$.cookie("search_state", 1, {path: "/"});
1536			} else {
1537				shop_search_wrap.slideUp(500);
1538				o.removeClass('opened');
1539				createCookie("search_state", 0, 90);
1540				//$.cookie("search_state", 0, {path: "/"});
1541			}
1542		});
1543
1544		if (ss == 1) {
1545			shop_search_wrap.show();
1546			shop_search_title.addClass('opened');
1547		}
1548	})();
1549
1550
1551	//Кабинет
1552	(function() {
1553		var cabinet = 0;
1554
1555		$('div.shop2-login-header').click(function() {
1556			var o = $(this).parent(),
1557				visible = 0;
1558
1559			if ($('div.shop2-login-body').is(':hidden')) {
1560				visible = 1;
1561			} else {
1562				visible = 0;
1563			}
1564			o.toggleClass('shop2-login-close');
1565			createCookie("cabinet", visible, 90);
1566			//$.cookie("cabinet", visible, {path : "/"});
1567		});
1568
1569		cabinet = readCookie("cabinet") /*$.cookie("cabinet")*/ ;
1570		if (cabinet == 1) {
1571			$('div.shop2-login').removeClass('shop2-login-close');
1572		}
1573	})();
1574
1575
1576	//Табы
1577	(function() {
1578		var active = 'shop-tab-active';
1579
1580		$(document).on('click', '.shop-tabs .shop-tabs-nav li a', function() {
1581			var o = $(this),
1582				current = o.attr('href');
1583
1584			$('.shop-tabs .shop-tabs-nav li').removeClass(active);
1585			o.parent().addClass(active);
1586			$('.shop-tabs .shop-tab').hide().removeClass('shop-tabs-active');
1587			$(current).show().addClass('shop-tabs-active');
1588			return false;
1589		});
1590
1591		$('.shop-tabs .shop-tab').hide().eq(0).show().addClass('shop-tabs-active');
1592		$('.shop-tabs .shop-tabs-nav li').eq(0).addClass(active);
1593	})();
1594
1595	//Скидки, подсказки
1596	(function() {
1597		var info;
1598		$('#shop2-cart').append('<div id="discount-info"></div>');
1599		info = $('#discount-info');
1600		$('a.discount-info').hover(function() {
1601			var o = $(this),
1602				pos = o.position(),
1603				text = '',
1604				href = o.attr('href');
1605
1606			if (o.attr('href') == '#') {
1607				text = o.attr('title');
1608			} else {
1609				text = $(href).html();
1610			}
1611
1612			info.html(text).show();
1613
1614			info.css({
1615				top: pos.top - info.outerHeight(true) - 5,
1616				left: pos.left + 20
1617			});
1618
1619		}, function() {
1620			info.hide();
1621		});
1622	})();
1623
1624	//Доставка
1625  (function() {
1626    var deliveries = $('div.delivery-type');
1627    deliveries.click(function() {
1628      deliveries.removeClass('delivery-type-current');
1629      $(this).addClass('delivery-type-current');
1630    });
1631    $('#shop2-order-delivery').find('.delivery-items').each(function() {
1632	 	var $this = $(this);
1633	 	if ($.trim($this.text()) == "") {
1634	 		$this.parents('.shop2-delivery--item__tab:first').addClass('disabled');
1635	 	}
1636	});
1637	$(document).on('change', '.map-select select', function() {
1638		var $this = $(this),
1639			index = $this.find('option:selected').index(),
1640		    pos   = $this.find('option:selected').text(),
1641		    id    = $this.val();
1642		    
1643		if (index == 0) {
1644			shop2.delivery.ymapsMap.balloon.close();
1645			return;
1646		}
1647            
1648        var it = shop2.delivery.ymapsMap.geoObjects.getIterator(),
1649        	ss;
1650        while (ss = it.getNext()) {
1651        	for(var i = 0, len = ss.getLength(); i < len; i++) {
1652                var placemark = ss.get(i);
1653                if(placemark.properties.get('id') === id) {
1654                    if(placemark.balloon.isOpen()) {
1655                        placemark.balloon.close();
1656                    }
1657                    else {
1658                    	placemark.balloon.open();
1659                    }
1660                    return;
1661                }
1662            }
1663        }
1664            
1665	});
1666    $(document).on('click', '.option-label', function(e) {
1667      var options = $(document).find('.option-label'),
1668      	  groups  = $(document).find('.option-type'),
1669      	  details = options.next();
1670
1671    	var $this = $(this),
1672      		index = $this.parent().index();
1673      		
1674      	if (e.target.nodeName != 'INPUT' && shop2.delivery.deligate) {
1675      		e.preventDefault();
1676      	}
1677    
1678        if (shop2.delivery.ymapsMap) {
1679	      	shop2.delivery.ymapsMap.destroy();
1680	      	shop2.delivery.ymapsMap = null;
1681	    }
1682
1683    	groups.removeClass('active-type');
1684    	$this.parent().addClass('active-type');
1685    	details.find('input, textarea, select').prop('disabled', true);
1686    	$this.next().find('input, textarea, select').prop('disabled', false);
1687    	if (shop2.delivery.deligate) {
1688    		$this.find('input:first').prop('checked', true);
1689    	}
1690    	
1691    	if ($this.hasClass('ymap')) {
1692			shop2.delivery.YmapsInit($this.data('service-code'));
1693		}
1694
1695    });
1696    $(document).on('click', '.shop2-delivery--item__tab .tab-label', function() {
1697      var groups = $(document).find('.shop2-delivery--item__tab'),
1698      	  $this  =  $(this),
1699      	  parent = $this.parents('.shop2-delivery--item__tab:first'),
1700      	  index  = parent.index();
1701
1702    	if (parent.hasClass('disabled')) return false;
1703    	if (parent.hasClass('active-tab')) {
1704      		parent.removeClass('active-tab');
1705      		return;
1706    	}
1707
1708    	groups.removeClass('active-tab').eq(index).addClass('active-tab');
1709    });
1710
1711    $(document).on("click", ".option-label", function() {
1712      var $this = $(this),
1713        attach_id = $this.data("attach_id"),
1714        siblings = $this.parent().siblings(".option-type"),
1715        tabsSib  = $this.parents('.shop2-delivery--item__tab:first').siblings();
1716      $("#delivery_id_deligate").val(attach_id);
1717      $("#deligate_points_fields .fields").empty();
1718      $("#deligate_points_fields").hide();
1719      tabsSib.find('.option-type input').prop('checked', false);
1720      tabsSib.removeClass('point');
1721      siblings.find('input').prop('checked', false);
1722
1723      //$('#form_g-anketa .text-right button').prop('disabled', false).removeClass('g-button--disabled');
1724    });
1725    $('#shop2-deligate-calc').on('click', function(e) {
1726        var data         = {},
1727            delivery     = $('#shop2-order-delivery'),
1728            tabs         = delivery.find('.shop2-delivery--item__tab'),
1729            deligate_url = '/-/x-api/v1/public/?method=deligate/calc&param[get_vars][]';
1730            
1731        if (shop2.delivery.shop2_old) {
1732        	deligate_url += '&param[get_vars][ver_id]='+shop2.product.verId+'&param[get_vars][is_old]=1';
1733        }
1734
1735        $('#shop2-perfect-form').find('input, textearea, select').each(function() {
1736          var $this = $(this);
1737          if (this.tagName === 'INPUT' && this.type === 'checkbox') {
1738            if (this.checked) {
1739              data[this.name] = 'on';
1740            }
1741          } else {
1742            data[this.name] = $(this).val();
1743          }
1744        });
1745
1746        e.preventDefault();
1747        tabs.removeClass('active-tab');
1748        tabs.removeClass('point');
1749        delivery.addClass('preloader');
1750        $('#shop2-delivery-wait').show();
1751        $('input#address').blur();
1752        $('#shop2-deligate-calc').hide();
1753        //$('#form_g-anketa .text-right button').prop('disabled', true).addClass('g-button--disabled');
1754
1755        $.ajax({
1756          url: deligate_url,
1757          type: 'post',
1758          dataType: 'json',
1759          data: data,
1760          success: function(result) {
1761            delivery.removeClass('preloader');
1762            $('#shop2-delivery-wait').hide();
1763            $('#shop2-order-delivery').html(result.result.html);
1764	        $('#shop2-order-delivery').append('<div class="preloader"><div class="spinner"></div></div>');
1765	        $('#shop2-order-delivery').find('.delivery-items').each(function() {
1766			 	var $this = $(this);
1767			 	if ($.trim($this.text()) == "") {
1768			 		$this.parents('.shop2-delivery--item__tab:first').addClass('disabled');
1769			 	}
1770			});
1771            if (result.result.error) {
1772              shop2.alert(result.result.error);
1773            } else {
1774
1775              var dadataJson = $.parseJSON($('#dadata').val()),
1776                coordsCenter = [dadataJson.geo_lat, dadataJson.geo_lon];
1777              $('#shop2-deligate-calc').hide();
1778            }
1779          }
1780        });
1781      });
1782  })();
1783
1784	//Оплата
1785	(function() {
1786		var payments = $('div.payment-type');
1787		payments.find('label').click(function() {
1788			payments.removeClass('payment-type-current');
1789			$(this).parent().addClass('payment-type-current');
1790		});
1791	})();
1792
1793	(function() {
1794		var btn = $('a.shop2-filter-show'),
1795			tr = $('tr.shop2-filter-custom-fields');
1796
1797		var alt = btn.data('alt') || shopClient.locale.hideParams,
1798			text = btn.html() || shopClient.locale.allParams;
1799
1800		btn.click(function() {
1801			if (tr.is(':visible')) {
1802				tr.hide();
1803				btn.html(text);
1804				createCookie('custom-fields', 0, 90);
1805			} else {
1806				tr.show();
1807				btn.html(alt);
1808				createCookie('custom-fields', 1, 90);
1809			}
1810			return false;
1811		});
1812
1813		var flag = readCookie('custom-fields');
1814		if (flag == 1) {
1815			tr.show();
1816			btn.html(alt);
1817			createCookie('custom-fields', 1, 90);
1818		} else {
1819			tr.hide();
1820			btn.html(text);
1821			createCookie('custom-fields', 0, 90);
1822		}
1823	})();
1824
1825	//Выравнивание по высоте в списке
1826	(function() {
1827
1828		function getMaxHeight(group_heads, group_foots) {
1829			var max = 0;
1830			group_heads.each(function(i) {
1831				var o = $(this),
1832					height;
1833				o.css('min-height', 10);
1834				height = o.height() + group_foots.eq(i).outerHeight(true);
1835				if (height > max) {
1836					max = height;
1837				}
1838			});
1839			return max;
1840		}
1841
1842		var setHeights = shop2._setHeights = function() {
1843			var wrap = $('div.tpl-product-list-v');
1844
1845			wrap.each(function() {
1846				var wrap = $(this),
1847					items = wrap.find('div.product-item'),
1848					heads = wrap.find('div.product-top'),
1849					foots = wrap.find('div.product-bot'),
1850					inRow = 0,
1851					left, right, group_heads, group_foots, max = 0;
1852
1853				if (wrap.get(0) && items.get(0)) {
1854					var marginRight = parseInt(items.eq(0).css('margin-right'));
1855					var width = wrap.width();
1856					var itemWidth = items.eq(0).outerWidth(true);
1857					inRow = Math.floor(width / itemWidth);
1858
1859					if (width % itemWidth >= itemWidth - marginRight) {
1860						inRow++;
1861					}
1862
1863					if (inRow > 1) {
1864						for (var i = 0; i < heads.length; i += inRow) {
1865							left = i;
1866							right = i + inRow;
1867							if (right > heads.length) {
1868								right = heads.length;
1869							}
1870							group_heads = heads.slice(left, right);
1871							group_foots = foots.slice(left, right);
1872							max = getMaxHeight(group_heads, group_foots);
1873
1874							group_heads.each(function(i) {
1875								$(this).css('min-height', max - group_foots.eq(i).outerHeight(true));
1876							});
1877						}
1878					}
1879				}
1880			});
1881		};
1882
1883		setHeights();
1884
1885		$(window).resize(setHeights).load(setHeights);
1886
1887		if (shop2 && shop2.product && shop2.product.reload) {
1888			var reload = shop2.product.reload;
1889
1890			shop2.product.reload = function(node, pageType, cb) {
1891				if (pageType == 'product') {
1892					reload.call(this, node, 'product', cb);
1893				} else {
1894					if (!cb) {
1895						cb = setHeights;
1896					}
1897					reload.call(this, node, null, cb);
1898				}
1899			}
1900		}
1901	})();
1902
1903	//Фильтруем ввод
1904	$('table.tpl-product-list-p input:text, input[name=amount]').keyFilter(shopClient.defaults.minAmount, shopClient.defaults.unitType);
1905
1906	$('td.shop2-cart-amount input:text').keyFilter(0, shopClient.defaults.unitType, function() {
1907		$('#recount-button').show();
1908	});
1909
1910	//Проверяем корзинку
1911	shopClient.Cart.check();
1912
1913	//Инициализация фильтра
1914	shopClient.Filter.init();
1915
1916	if (shopClient.defaults.minAmount != 1) {
1917		$('table.tpl-product-list-p input:text, input[name=amount]').val(shopClient.defaults.minAmount);
1918	}
1919
1920	$('form .tpl-stars').each(function() {
1921		var $this = $(this),
1922			selected = null,
1923			stars = $this.children('span'),
1924			input = $this.children('input');
1925
1926		function choose(elem) {
1927			elem = $(elem);
1928			stars.removeClass('tpl-active');
1929			elem.addClass('tpl-active').prevAll().addClass('tpl-active');
1930		}
1931
1932		$this.on({
1933			click: function(e) {
1934				selected = e.target;
1935				input.val($(selected).index() + 1);
1936			},
1937			mousemove: function(e) {
1938				choose(e.target);
1939			},
1940			mouseleave: function(e) {
1941				choose(selected);
1942			}
1943		});
1944
1945	});
1946
1947
1948	(function() {
1949
1950		var $document = $(document);
1951
1952		function update(el, res) {
1953
1954			// el.closest('.product-compare').replaceWith(res.data);
1955			$('input[type=checkbox][value=' + el.val() + ']').closest('.product-compare').replaceWith(res.data);
1956
1957			$('.product-compare-added a span').html('(' + res.count + ')');
1958
1959			if (res.panel) {
1960				$('#shop2-panel').replaceWith(res.panel);
1961			}
1962
1963		}
1964
1965		$document.on('click', '.product-compare input:checkbox', function() {
1966			var $this = $(this),
1967				action = !$this.prop('checked') ? 'del' : 'add';
1968
1969			shopClient.Compare.action(action, $this.val(), function(res, status) {
1970				if (status == 'success') {
1971
1972					if (res.errstr) {
1973						alert(res.errstr);
1974						$this.prop('checked', false);
1975					} else {
1976						update($this, res);
1977					}
1978				}
1979			});
1980
1981			return false;
1982		});
1983
1984	})();
1985
1986	(function($) {
1987
1988		$.s3escape = function(text) {
1989			return $('<div>').text(text).html();
1990		};
1991
1992		var maps = shopClient.maps = {};
1993
1994		maps.alert = function(type, params) {
1995			shopClient.alert('<div id="shop2-alert-map"></div>', 'Закрыть', 'shop2-alert--map');
1996			maps[type].ready(function() {
1997				maps[type].draw('shop2-alert-map', params);
1998			});
1999		};
2000
2001		maps.getCenter = function(arr) {
2002			var x = 0;
2003			var y = 0;
2004			$.each(arr, function() {
2005				x += this.x;
2006				y += this.y;
2007			});
2008
2009		};
2010
2011		maps.yandex = {
2012			ymaps: window.ymaps,
2013			_loading: $.Deferred(),
2014			_loading_init: false,
2015			_loading_callback: function(ymaps) {
2016				this.ymaps = ymaps;
2017				this._loading.resolve(ymaps);
2018			},
2019			ready: function(callback) {
2020				this._loading.done(callback);
2021				if (this.ymaps) {
2022					this._loading.resolve(this.ymaps);
2023					return;
2024				}
2025				if (!this._loading_init) {
2026					$('head').append('<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&onload=shopClient.maps.yandex._loading_callback" type="text/javascript">');
2027					this._loading_init = true;
2028				}
2029			},
2030			draw: function(id, point) {
2031				point = $.extend({}, point);
2032				point.title = $.s3escape(point.title);
2033				point.text = $.s3escape(point.text);
2034
2035				var map = new this.ymaps.Map(id, {
2036					zoom: point.z,
2037					center: [point.x, point.y],
2038					behaviors: ['drag', 'rightMouseButtonMagnifier', 'scrollZoom']
2039				});
2040
2041				var MyBalloonContentLayoutClass = this.ymaps.templateLayoutFactory.createClass(
2042					'<div class="shop2-map-baloon-content">' +
2043					'<h3>$[properties.title]</h3>' +
2044					'$[properties.text]' +
2045					'</div>'
2046				);
2047				var placemark = new self.ymaps.Placemark([point.x, point.y], point, {balloonContentLayout: MyBalloonContentLayoutClass});
2048				map.geoObjects.add(placemark);
2049			}
2050		};
2051
2052		maps.google = {
2053			gmaps: window.google && window.google.maps ? window.google.maps : false,
2054			_loading: $.Deferred(),
2055			_loading_init: false,
2056			_loading_callback: function() {
2057				try {
2058					this.gmaps = window.google.maps;
2059					this._loading.resolve(this.gmaps);
2060				} catch (e) {
2061					console.log(e);
2062				}
2063			},
2064			ready: function(callback) {
2065				this._loading.done(callback);
2066				if (this.gmaps) {
2067					this._loading.resolve(this.gmaps);
2068					return;
2069				}
2070				if (!this._loading_init) {
2071					$('head').append('<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&callback=shopClient.maps.google._loading_callback" type="text/javascript">');
2072					this._loading_init = true;
2073				}
2074			},
2075			draw: function(id, point) {
2076				var map = new this.gmaps.Map(document.getElementById(id), {
2077					zoom: Number(point.z),
2078					center: new google.maps.LatLng(point.x, point.y)
2079				});
2080				var marker = new google.maps.Marker({
2081					position: new google.maps.LatLng(point.x, point.y),
2082					map: map,
2083					title: point.title
2084				});
2085				var infowindow = new google.maps.InfoWindow({
2086					content: '<div class="shop2-map-baloon-content">' +
2087					'<h3>' + $.s3escape(point.title) + '</h3>' +
2088					$.s3escape(point.text) +
2089					'</div>'
2090				});
2091				this.gmaps.event.addListener(marker, 'click', function() {
2092					infowindow.open(map, marker);
2093				});
2094			}
2095		};
2096
2097		$(document).on('click', '.shop2-map-link', function(e) {
2098			e.preventDefault();
2099			var $this = $(this);
2100			var data = $this.data();
2101			var map = data.map;
2102			if (!map.title) {
2103				map.title = $this.text();
2104			}
2105			shopClient.maps.alert(data.mapType, map);
2106		});
2107	})(jQuery);
2108
2109	(function() {
2110
2111		var tpl = [
2112				'<div id="shop2-alert">',
2113					'<div id="shop2-alert-body"></div>',
2114					'<a href="#" id="shop2-alert-ok" class="shop2-btn"></a>',
2115				'</div>',
2116				'<div id="shop2-alert-overlay"></div>'
2117			].join('\n'),
2118
2119			win,
2120			overlay,
2121			body,
2122			ok,
2123			cls;
2124
2125		$(document.body).append(tpl);
2126
2127		win = $('#shop2-alert');
2128		overlay = $('#shop2-alert-overlay');
2129		body = $('#shop2-alert-body');
2130		ok = $('#shop2-alert-ok');
2131
2132		function hide() {
2133			overlay.hide();
2134			win.hide();
2135			win.removeAttr('class');
2136			cls = '';
2137			shopClient.trigger('alertHide', win);
2138			return false;
2139		}
2140
2141		function show() {
2142			overlay.show();
2143			win.attr('class', cls);
2144			win.show().s3center();
2145			shopClient.trigger('alertShow', win);
2146		}
2147
2148		overlay.on('click', hide);
2149		ok.on('click', hide);
2150
2151		shopClient.alert = function(msg, btn, c) {
2152			ok.html(btn || 'Ok');
2153			body.html(msg);
2154			cls = c || '';
2155			show();
2156		};
2157
2158		shopClient.alert.hide = hide;
2159
2160	})();
2161
2162
2163	(function() {
2164
2165		var edost = $('[id^=delivery][id$=html]');
2166		if (!edost.get(0)) return;
2167		var id = edost.attr('id');
2168		if (!id) return;
2169		var attach_id = id.replace(/[^\d]/g, '');
2170		if (!attach_id) return;
2171
2172		shop2.delivery.edost(attach_id);
2173
2174	})();
2175
2176	(function() {
2177
2178		$('.shop2-color-ext-list li').s3tooltip({
2179
2180			cls: 'shop2-color-ext-tooltip',
2181			dir: 'top',
2182			data: function() {
2183				return $(this).children('div').html();
2184			}
2185
2186		});
2187
2188		$('.shop2-color-ext-multi').s3tooltip({
2189
2190			cls: 'shop2-color-ext-tooltip',
2191			dir: 'top',
2192			data: function() {
2193				var ul = this.getElementsByTagName('ul');
2194				if (ul.length) {
2195					return ul[0].outerHTML;
2196				}
2197			}
2198
2199		});
2200
2201	})();
2202
2203
2204	(function() {
2205
2206		var popup = $('<div id="shop2-color-ext-popup"></div>');
2207		var close = $('<div id="shop2-color-ext-close"></div>');
2208		var list = $('<ul id="shop2-color-ext-list" class="shop2-color-ext-list"></ul>');
2209		var colors = null;
2210
2211		popup.append(close);
2212		popup.append(list);
2213		$(document.body).append(popup);
2214
2215		$(document).on('click', '.shop2-color-ext-caption', function() {
2216				var caption = $(this);
2217				var wrap = caption.closest('.shop2-color-ext-popup');
2218				var ul = wrap.find('.shop2-color-ext-list');
2219				var offset = caption.offset();
2220
2221				colors = ul.children('li');
2222				list.html(ul.html());
2223
2224				popup.css(offset).show();
2225
2226				return false;
2227		});
2228
2229		$(document).on('click touchstart', '.shop2-color-ext-list li', function() {
2230			var $this = $(this);
2231			var data = $this.data();
2232			var input = $this.parent().find('input.additional-cart-params');
2233
2234			if (typeof data.kinds !== 'undefined' || input.length) {
2235
2236				$this.addClass('shop2-color-ext-selected').siblings().removeClass('shop2-color-ext-selected');
2237
2238				if (input.length) {
2239					input.val(data.value);
2240				} else {
2241					$this.attr('data', data.kinds);
2242					shop2.product.reload(this, shopClient.mode);
2243				}
2244
2245			} else {
2246
2247				var index = $this.index();
2248				$this.toggleClass('shop2-color-ext-selected');
2249				colors.eq(index).toggleClass('shop2-color-ext-selected');
2250				shopClient.Filter.addParam(data.name, data.value, this);
2251
2252			}
2253		});
2254
2255		$(document).on('click', function(e) {
2256			var target = $(e.target);
2257			var wrap = target.closest('#shop2-color-ext-popup');
2258
2259			if (!wrap.get(0) || e.target == close.get(0)) {
2260				popup.hide();
2261			}
2262		});
2263
2264	})();
2265
2266
2267	(function() {
2268
2269		var select = $('<div id="shop2-color-ext-select"><ins></ins></div>');
2270		var colors = null;
2271		var input = null;
2272		$(document.body).append(select);
2273
2274		function hide() {
2275			if (select.is(':visible')) {
2276				select.hide();
2277				return true;
2278			}
2279		}
2280
2281		$(document).on('click', hide);
2282
2283		$(document).on('click', '.shop2-color-ext-select', function() {
2284
2285			if (hide()) {
2286				return;
2287			}
2288
2289			var wrap = $(this);
2290			var ul = wrap.find('.shop2-color-ext-options');
2291			var offset = wrap.offset();
2292
2293			var html =
2294				'<div class="baron-wrapper">' +
2295				'	<div class="baron-scroller">' +
2296				'		<div class="baron-container">' +
2297				'			<div class="shop2-color-ext-options">' +
2298								ul.html() +
2299				'			</div>' +
2300				'		</div>' +
2301				'		<div class="baron-scroller-bar"></div>' +
2302				'	</div>' +
2303				'</div>';
2304
2305			colors = ul.children('li');
2306			input = wrap.find('input');
2307
2308			select.html(html)
2309			select.show();
2310
2311			var wrapWidth = wrap.width();
2312			var selectWidth = select.data('width') || (function() {
2313				var width = select.width();
2314				select.data('width', width);
2315				return width;
2316			})();
2317
2318			if (wrapWidth > selectWidth) {
2319				select.css('width', wrapWidth);
2320			} else {
2321				select.css('width', selectWidth);
2322			}
2323
2324			baron(select, {
2325				scroller: '.baron-scroller',
2326				container: '.baron-container',
2327				bar: '.baron-scroller-bar'
2328			});
2329
2330			select.css(offset);
2331
2332			return false;
2333
2334		});
2335
2336		$(document).on('click', '#shop2-color-ext-select li:not(.shop2-color-ext-selected)', function() {
2337			var $this = $(this);
2338			var index = $this.index();
2339			var data = $this.data();
2340			var item = colors.eq(index);
2341
2342			$this.addClass('shop2-color-ext-selected').siblings().removeClass('shop2-color-ext-selected');
2343			colors.removeClass('shop2-color-ext-selected');
2344			item.addClass('shop2-color-ext-selected');
2345
2346			if (data.kinds) {
2347				item.attr('data', data.kinds);
2348				shop2.product.reload(item.get(0), shopClient.mode);
2349			} else {
2350				input.val(data.value);
2351			}
2352
2353		});
2354
2355	})();
2356
2357
2358	(function() {
2359
2360		var custom = $('#shop2_search_custom_fields'),
2361			global = $('#shop2_search_global_fields'),
2362			folders = $('#s\\[folder_id\\]');
2363
2364		folders.change(function() {
2365			var folder_id = folders.val();
2366
2367			if (!folder_id) {
2368				custom.html('');
2369				global.find('input, select').prop('disabled', false);
2370				global.show();
2371			}
2372
2373		});
2374
2375		shopClient.on('afterGetFolderCustomFields', function(d) {
2376			var folder_id = folders.val();
2377
2378			if (folder_id) {
2379
2380				custom.html(d.data);
2381				global.find('input, select').prop('disabled', true);
2382				global.hide();
2383
2384			}
2385
2386		});
2387
2388		folders.trigger('change');
2389
2390	})();
2391
2392
2393	(function() {
2394
2395		var $form = $('form#order-form');
2396		var $submit = $form.find('[type=submit]');
2397
2398		$form.on('submit', function() {
2399			$submit.prop('disabled', true);
2400			setTimeout(function() {
2401				$submit.prop('disabled', false);
2402			}, 1000);
2403		});
2404
2405	})();
2406
2407
2408
2409});

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.