PageSourceSearch

https://tamga.ru/bitrix/cache/js/s1/tamga_bootstrap/page_0fdb991a7…ee4d9373aba94b01d0b78_v1.js?174194605880737

js tamga.ru collected 2026-10-07 16:36:30 UTC 80,737 bytes, 2,444 lines download raw bytes

1
2; /* Start:"a:4:{s:4:"full";s:116:"/local/templates/tamga_bootstrap/components/bitrix/sale.basket.basket/new_style/js/action-pool.min.js?17065845564358";s:6:"source";s:97:"/local/templates/tamga_bootstrap/components/bitrix/sale.basket.basket/new_style/js/action-pool.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
3(function(){"use strict";BX.namespace("BX.Sale.BasketActionPool");BX.Sale.BasketActionPool=function(t){this.component=t;this.requestProcessing=false;this.updateTimer=null;this.isBasketRefreshed=this.component.params.DEFERRED_REFRESH!=="Y";this.needFullRecalculation=this.component.params.DEFERRED_REFRESH==="Y";this.pool={};this.lastActualPool={};this.approvedAction=["QUANTITY","DELETE","RESTORE","DELAY","OFFER","MERGE_OFFER"];this.switchTimer()};BX.Sale.BasketActionPool.prototype.setRefreshStatus=function(t){this.isBasketRefreshed=!!t};BX.Sale.BasketActionPool.prototype.getRefreshStatus=function(){return this.isBasketRefreshed};BX.Sale.BasketActionPool.prototype.isItemInPool=function(t){return!!this.pool[t]};BX.Sale.BasketActionPool.prototype.clearLastActualQuantityPool=function(t){this.lastActualPool[t]&&delete this.lastActualPool[t].QUANTITY};BX.Sale.BasketActionPool.prototype.checkItemPoolBefore=function(t){if(!t)return;this.pool[t]=this.pool[t]||{}};BX.Sale.BasketActionPool.prototype.checkItemPoolAfter=function(t){if(!t||!this.pool[t])return;if(Object.keys(this.pool[t]).length===0){delete this.pool[t]}};BX.Sale.BasketActionPool.prototype.addCoupon=function(t){this.pool.COUPON=t;this.switchTimer()};BX.Sale.BasketActionPool.prototype.removeCoupon=function(t){this.checkItemPoolBefore("REMOVE_COUPON");this.pool.REMOVE_COUPON[t]=t;this.switchTimer()};BX.Sale.BasketActionPool.prototype.changeQuantity=function(t,o,e){this.checkItemPoolBefore(t);if(this.lastActualPool[t]&&this.lastActualPool[t].QUANTITY!==o||!this.lastActualPool[t]&&o!==e){this.pool[t].QUANTITY=o}else{this.pool[t]&&delete this.pool[t].QUANTITY}this.checkItemPoolAfter(t);this.switchTimer()};BX.Sale.BasketActionPool.prototype.deleteItem=function(t){this.checkItemPoolBefore(t);if(this.pool[t].RESTORE){delete this.pool[t].RESTORE}else{this.pool[t].DELETE="Y"}this.checkItemPoolAfter(t);this.switchTimer()};BX.Sale.BasketActionPool.prototype.restoreItem=function(t,o){this.checkItemPoolBefore(t);if(this.pool[t].DELETE==="Y"){delete this.pool[t].DELETE}else{this.pool[t].RESTORE=o}this.checkItemPoolAfter(t);this.switchTimer()};BX.Sale.BasketActionPool.prototype.addDelayed=function(t){this.checkItemPoolBefore(t);this.pool[t].DELAY="Y";this.checkItemPoolAfter(t);this.switchTimer()};BX.Sale.BasketActionPool.prototype.removeDelayed=function(t){this.checkItemPoolBefore(t);this.pool[t].DELAY="N";this.checkItemPoolAfter(t);this.switchTimer()};BX.Sale.BasketActionPool.prototype.changeSku=function(t,o,e){if(JSON.stringify(o)!==JSON.stringify(e)){this.checkItemPoolBefore(t);this.pool[t].OFFER=o}else{this.pool[t]&&delete this.pool[t].OFFER;this.checkItemPoolAfter(t)}this.switchTimer()};BX.Sale.BasketActionPool.prototype.mergeSku=function(t){this.checkItemPoolBefore(t);this.pool[t].MERGE_OFFER="Y";this.switchTimer()};BX.Sale.BasketActionPool.prototype.switchTimer=function(){clearTimeout(this.updateTimer);if(this.isProcessing()){return}if(this.isPoolEmpty()){this.component.editPostponedBasketItems();this.component.fireCustomEvents()}if(!this.isPoolEmpty()){this.updateTimer=setTimeout(BX.proxy(this.trySendPool,this),300)}else if(!this.getRefreshStatus()){this.trySendPool()}};BX.Sale.BasketActionPool.prototype.trySendPool=function(){if(this.isPoolEmpty()&&this.getRefreshStatus()){return}this.doProcessing(true);if(!this.isPoolEmpty()){this.component.sendRequest("recalculateAjax",{basket:this.getPoolData()});this.lastActualPool=this.pool;this.pool={}}else if(!this.getRefreshStatus()){this.component.sendRequest("refreshAjax",{fullRecalculation:this.needFullRecalculation?"Y":"N"});this.needFullRecalculation=false}};BX.Sale.BasketActionPool.prototype.getPoolData=function(){var t={},o=this.pool;if(o.COUPON){t.coupon=o.COUPON;delete o.COUPON}if(o.REMOVE_COUPON){t.delete_coupon=o.REMOVE_COUPON;delete o.REMOVE_COUPON}for(var e in o){if(o.hasOwnProperty(e)){for(var i in o[e]){if(o[e].hasOwnProperty(i)&&BX.util.in_array(i,this.approvedAction)){t[i+"_"+e]=o[e][i]}}}}return t};BX.Sale.BasketActionPool.prototype.isPoolEmpty=function(){return Object.keys(this.pool).length===0};BX.Sale.BasketActionPool.prototype.doProcessing=function(t){this.requestProcessing=t===true;if(this.requestProcessing){this.component.startLoader()}else{this.component.endLoader()}};BX.Sale.BasketActionPool.prototype.isProcessing=function(){return this.requestProcessing===true}})();
4/* End */
5;
6; /* Start:"a:4:{s:4:"full";s:112:"/local/templates/tamga_bootstrap/components/bitrix/sale.basket.basket/new_style/js/filter.min.js?170658455610511";s:6:"source";s:92:"/local/templates/tamga_bootstrap/components/bitrix/sale.basket.basket/new_style/js/filter.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
7(function(){"use strict";BX.namespace("BX.Sale.BasketFilter");BX.Sale.BasketFilter=function(t){this.component=t;this.activeFilterMode=false;this.filterTimer=null;this.mouseOverClearFilter=false;this.realShownItems=[];this.realSortedItems=[];this.realScrollTop=0;this.lastShownItemsHash="";this.currentFilter={query:"",similarHash:"",warning:false,notAvailable:false,delayed:false};if(this.component.useItemsFilter){this.bindEvents()}};BX.Sale.BasketFilter.prototype.bindEvents=function(){var t;var e=this.component.getEntity(this.component.getCacheNode(this.component.ids.itemListWrapper),"basket-filter");t=this.component.getEntity(e,"basket-filter-input");if(BX.type.isDomNode(t)){BX.bind(t,"focus",function(){e.style.flex=3});BX.bind(t,"blur",BX.delegate(function(){if(!this.mouseOverClearFilter){e.style.flex=""}},this));BX.bind(t,"keyup",BX.proxy(this.onFilterInput,this));BX.bind(t,"cut",BX.proxy(this.onFilterInput,this));BX.bind(t,"paste",BX.proxy(this.onFilterInput,this))}t=this.component.getEntity(e,"basket-filter-clear-btn");if(BX.type.isDomNode(t)){BX.bind(t,"mouseenter",BX.delegate(function(){this.mouseOverClearFilter=true},this));BX.bind(t,"mouseout",BX.delegate(function(){this.mouseOverClearFilter=false},this));BX.bind(t,"click",BX.delegate(function(){if(!this.filterInputEmpty()){this.clearFilterInput();this.onFilterChange()}e.style.flex=""},this))}};BX.Sale.BasketFilter.prototype.isActive=function(){return this.activeFilterMode};BX.Sale.BasketFilter.prototype.showFilterByName=function(t){if(!t)return;switch(t){case"not-available":this.showNotAvailableItemsFilter();break;case"delayed":this.showDelayItemsFilter();break;case"warning":this.showWarningItemsFilter();break;case"similar":this.showSimilarItemsFilter();break;case"all":default:this.clearAllFiltersExcept([]);this.onFilterChange()}};BX.Sale.BasketFilter.prototype.onFilterInput=function(){var t=BX.type.isDomNode(BX.proxy_context)?BX.util.trim(BX.proxy_context.value).toLowerCase():"";if(this.currentFilter.query!==t){this.currentFilter.query=t;this.onFilterChange()}};BX.Sale.BasketFilter.prototype.clearAllFiltersExcept=function(t){if(!t||!BX.type.isArray(t))return;!BX.util.in_array("input",t)&&this.clearFilterInput();!BX.util.in_array("warning",t)&&this.clearWarningItemsFilter();!BX.util.in_array("delayed",t)&&this.clearDelayItemsFilter();!BX.util.in_array("not-available",t)&&this.clearNotAvailableItemsFilter();if(!BX.util.in_array("similar",t)){this.clearSimilarItemsFilter();this.component.showSimilarCount(false)}};BX.Sale.BasketFilter.prototype.filterInputEmpty=function(){return this.currentFilter.query.length===0};BX.Sale.BasketFilter.prototype.clearFilterInput=function(){this.currentFilter.query="";var t=this.component.getEntity(this.component.getCacheNode(this.component.ids.itemListWrapper),"basket-filter-input");if(BX.type.isDomNode(t)){t.value=""}};BX.Sale.BasketFilter.prototype.addWarningItemsFilter=function(){this.currentFilter.warning=true};BX.Sale.BasketFilter.prototype.clearWarningItemsFilter=function(){this.currentFilter.warning=false};BX.Sale.BasketFilter.prototype.showWarningItemsFilter=function(){if(!this.currentFilter.warning){this.clearAllFiltersExcept(["warning"]);this.addWarningItemsFilter();this.onFilterChange()}};BX.Sale.BasketFilter.prototype.addDelayItemsFilter=function(){this.currentFilter.delayed=true};BX.Sale.BasketFilter.prototype.clearDelayItemsFilter=function(){this.currentFilter.delayed=false};BX.Sale.BasketFilter.prototype.showDelayItemsFilter=function(){if(!this.currentFilter.delayed){this.clearAllFiltersExcept(["delayed"]);this.addDelayItemsFilter();this.onFilterChange()}};BX.Sale.BasketFilter.prototype.addNotAvailableItemsFilter=function(){this.currentFilter.notAvailable=true};BX.Sale.BasketFilter.prototype.clearNotAvailableItemsFilter=function(){this.currentFilter.notAvailable=false};BX.Sale.BasketFilter.prototype.showNotAvailableItemsFilter=function(){if(!this.currentFilter.notAvailable){this.clearAllFiltersExcept(["not-available"]);this.addNotAvailableItemsFilter();this.onFilterChange()}};BX.Sale.BasketFilter.prototype.addSimilarItemsFilter=function(t){this.currentFilter.similarHash=t.HASH};BX.Sale.BasketFilter.prototype.clearSimilarItemsFilter=function(){this.currentFilter.similarHash=""};BX.Sale.BasketFilter.prototype.showSimilarItemsFilter=function(){var t=this.component.getItemDataByTarget(BX.proxy_context);if(this.currentFilter.similarHash!==t.HASH){this.clearAllFiltersExcept(["similar"]);this.addSimilarItemsFilter(t);this.onFilterChange()}};BX.Sale.BasketFilter.prototype.getTimeoutDuration=function(){return this.component.duration.filterTimer};BX.Sale.BasketFilter.prototype.onFilterChange=function(){this.component.showItemsOverlay();if(this.currentFilter.query.length||this.currentFilter.similarHash.length||this.currentFilter.warning||this.currentFilter.notAvailable||this.currentFilter.delayed){clearTimeout(this.filterTimer);this.filterTimer=setTimeout(BX.proxy(this.enableFilterMode,this),this.getTimeoutDuration())}else{this.disableFilterMode()}};BX.Sale.BasketFilter.prototype.enableFilterMode=function(){var t;if(!this.activeFilterMode){this.activeFilterMode=true;this.realShownItems=BX.util.array_values(this.component.shownItems);this.realSortedItems=BX.util.array_values(this.component.sortedItems);this.realScrollTop=this.component.getDocumentScrollTop()}this.component.scrollToFirstItem();this.component.sortedItems=this.searchItems();t=JSON.stringify(this.component.sortedItems);if(this.lastShownItemsHash!==t){this.lastShownItemsHash=t;this.component.deleteBasketItems(BX.util.array_values(this.component.shownItems),false);
7if(this.component.sortedItems.length){this.component.initializeBasketItems();this.hideEmptyFilterResult()}else{this.showEmptyFilterResult()}if(this.currentFilter.similarHash.length){this.component.showSimilarCount(true)}}else{this.highlightFoundItems()}this.component.hideItemsOverlay()};BX.Sale.BasketFilter.prototype.disableFilterMode=function(){clearTimeout(this.filterTimer);this.lastShownItemsHash="";if(this.activeFilterMode){this.activeFilterMode=false;this.component.sortedItems=BX.util.array_values(this.realSortedItems);this.component.deleteBasketItems(BX.util.array_values(this.component.shownItems),false);this.hideEmptyFilterResult();this.component.editBasketItems(BX.util.array_values(this.realShownItems));window.scrollTo(0,this.realScrollTop)}this.component.hideItemsOverlay()};BX.Sale.BasketFilter.prototype.searchItems=function(){var t=[];for(var e=0;e<this.realSortedItems.length;e++){var i=this.component.items[this.realSortedItems[e]];if(i&&this.searchItemMatch(i)){t.push(i.ID)}}return t};BX.Sale.BasketFilter.prototype.highlightFoundItems=function(){if(!this.activeFilterMode)return;for(var t in this.component.shownItems){if(this.component.shownItems.hasOwnProperty(t)){this.highlightSearchMatch(this.component.items[this.component.shownItems[t]])}}};BX.Sale.BasketFilter.prototype.searchItemMatch=function(t){var e=false,i=false;if(this.currentFilter.notAvailable){i=!!t.NOT_AVAILABLE;if(!i){return e}}else if(this.currentFilter.delayed){i=!!t.DELAYED;if(!i){return e}}else if(this.currentFilter.warning){i=BX.util.in_array(t.ID,this.component.warningItems);if(!i){return e}}else if(BX.type.isNotEmptyString(this.currentFilter.similarHash)){i=this.currentFilter.similarHash===t.HASH;if(!i){return e}}if(BX.type.isNotEmptyString(this.currentFilter.query)){if(t.NAME.toLowerCase().indexOf(this.currentFilter.query)!==-1){e="NAME"}if(!e){var r=parseFloat(this.currentFilter.query);if(!isNaN(r)){if(parseFloat(t.PRICE)===r){e="PRICE"}else if(parseFloat(t.SUM_PRICE)===r){e="SUM_PRICE"}}}if(!e&&this.currentFilter.query.length>=3){if(t.PRICE_FORMATED.toLowerCase().indexOf(this.currentFilter.query)!==-1){e="PRICE"}else if(t.SUM_PRICE_FORMATED.toLowerCase().indexOf(this.currentFilter.query)!==-1){e="SUM_PRICE"}}var s,l;if(!e&&t.PROPS.length){for(s in t.PROPS){if(t.PROPS.hasOwnProperty(s)&&BX.type.isNotEmptyString(t.PROPS[s].VALUE)){l=t.PROPS[s].VALUE.toLowerCase();if(l===this.currentFilter.query||this.currentFilter.query.length>=3&&l.indexOf(this.currentFilter.query)!==-1){e="PROPS";break}}}}if(!e&&t.COLUMN_LIST.length){for(s in t.COLUMN_LIST){if(t.COLUMN_LIST.hasOwnProperty(s)&&BX.type.isNotEmptyString(t.COLUMN_LIST[s].VALUE)){l=t.COLUMN_LIST[s].VALUE.toLowerCase();if(l===this.currentFilter.query||this.currentFilter.query.length>=3&&l.indexOf(this.currentFilter.query)!==-1){e="COLUMNS";break}}}}}else if(i){e=true}return e};BX.Sale.BasketFilter.prototype.highlightSearchMatch=function(t){var e=this.searchItemMatch(t);if(e){var i,r,s,l;switch(e){case"NAME":i=this.component.getEntity(BX(this.component.ids.item+t.ID),"basket-item-name");if(BX.type.isDomNode(i)){i.innerHTML=t.NAME.replace(new RegExp("(.*)("+this.currentFilter.query.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")+")(.*)","gi"),function(t,e,i,r){return BX.util.htmlspecialchars(e)+'<span class="basket-item-highlighted">'+BX.util.htmlspecialchars(i)+"</span>"+BX.util.htmlspecialchars(r)})}break;case"PRICE":i=BX(this.component.ids.price+t.ID);BX.addClass(i,"basket-item-highlighted");break;case"SUM_PRICE":i=BX(this.component.ids.sumPrice+t.ID);BX.addClass(i,"basket-item-highlighted");break;case"PROPS":i=this.component.getEntities(BX(this.component.ids.item+t.ID),"basket-item-property-value");for(r=0;r<i.length;r++){l=i[r].getAttribute("data-property-code");for(s in t.PROPS){if(t.PROPS.hasOwnProperty(s)&&t.PROPS[s].CODE===l){i[r].innerHTML=t.PROPS[s].VALUE.replace(new RegExp("("+this.currentFilter.query+")","gi"),'<span class="basket-item-highlighted">$1</span>')}}}break;case"COLUMNS":i=this.component.getEntities(BX(this.component.ids.item+t.ID),"basket-item-property-column-value");for(r=0;r<i.length;r++){l=i[r].getAttribute("data-column-property-code");for(s in t.COLUMN_LIST){if(t.COLUMN_LIST.hasOwnProperty(s)&&t.COLUMN_LIST[s].CODE===l){i[r].innerHTML=t.COLUMN_LIST[s].VALUE.replace(new RegExp("("+this.currentFilter.query+")","gi"),'<span class="basket-item-highlighted">$1</span>')}}}break}}};BX.Sale.BasketFilter.prototype.showEmptyFilterResult=function(){var t=this.component.getCacheNode(this.component.ids.itemList);if(BX.type.isDomNode(t)&&t.clientHeight>=500){var e=this.component.getCacheNode(this.component.ids.itemListEmptyResult);
7if(BX.type.isDomNode(e)){e.style.display=""}}};BX.Sale.BasketFilter.prototype.hideEmptyFilterResult=function(){var t=this.component.getCacheNode(this.component.ids.itemListEmptyResult);if(BX.type.isDomNode(t)){t.style.display="none"}}})();
8/* End */
9;
10; /* Start:"a:4:{s:4:"full";s:111:"/local/templates/tamga_bootstrap/components/bitrix/sale.basket.basket/new_style/js/component.js?173079250664552";s:6:"source";s:95:"/local/templates/tamga_bootstrap/components/bitrix/sale.basket.basket/new_style/js/component.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
11;(function() {
12	'use strict';
13
14	BX.namespace('BX.Sale.BasketComponent');
15
16	BX.Sale.BasketComponent = {
17		maxItemsShowCount: 30,
18		precisionFactor: Math.pow(10, 6),
19		stickyHeaderOffset: 0,
20
21		duration: {
22			priceAnimation: 300,
23			filterTimer: 300
24		},
25
26		ids: {
27			item: 'basket-item-',
28			quantity: 'basket-item-quantity-',
29			price: 'basket-item-price-',
30			sumPrice: 'basket-item-sum-price-',
31			sumPriceOld: 'basket-item-sum-price-old-',
32			sumPriceDiff: 'basket-item-sum-price-difference-',
33			itemHeightAligner: 'basket-item-height-aligner-',
34			total: 'basket-total-price',
35			basketRoot: 'basket-root',
36			itemListWrapper: 'basket-items-list-wrapper',
37			itemListContainer: 'basket-items-list-container',
38			itemList: 'basket-item-list',
39			itemListTable: 'basket-item-table',
40			itemListEmptyResult: 'basket-item-list-empty-result',
41			itemListOverlay: 'basket-items-list-overlay',
42			warning: 'basket-warning'
43		},
44
45		initializePrimaryFields: function()
46		{
47			this.templates = {};
48			this.nodes = {};
49
50			/** Object of all basket items (itemId => itemArray) */
51			this.items = {};
52
53			/** Array of all basket items to show sorted by field SORT */
54			this.sortedItems = [];
55
56			/** Array of basket items showed on screen */
57			this.shownItems = [];
58
59			/** Array of basket items changed since last request */
60			this.changedItems = [];
61
62			/** Array of basket items postponed by pool to edit */
63			this.postponedItems = [];
64
65			/** Array of basket items with warnings */
66			this.warningItems = [];
67
68			this.isMobile = BX.browser.IsMobile();
69			this.isTouch = BX.hasClass(document.documentElement, 'bx-touch');
70
71			this.lastAction = 'initialLoad';
72			this.coupons = null;
73
74			this.imagePopup = null;
75			this.loadingScreen = null;
76
77			this.quantityDelay = null;
78			this.quantityTimer = null;
79		},
80
81		init: function(parameters)
82		{
83			this.initializePrimaryFields();
84
85			this.params = parameters.params || {};
86			this.template = parameters.template || '';
87			this.signedParamsString = parameters.signedParamsString || '';
88			this.siteId = parameters.siteId || '';
89			this.siteTemplateId = parameters.siteTemplateId || '';
90			this.ajaxUrl = this.params.AJAX_PATH || '';
91			this.templateFolder = parameters.templateFolder || '';
92
93			this.useDynamicScroll = this.params.USE_DYNAMIC_SCROLL === 'Y';
94			this.useItemsFilter = this.params.SHOW_FILTER === 'Y' && !this.isMobile;
95
96			this.initializeFilter();
97			this.applyBasketResult(parameters.result);
98			this.initializeActionPool();
99
100			if (this.useItemsFilter)
101			{
102				this.checkHeaderDisplay();
103				this.bindHeaderEvents();
104			}
105
106			this.initializeBasketItems();
107			this.editTotal();
108			this.editWarnings();
109
110			this.getCacheNode(this.ids.basketRoot).style.opacity = 1;
111
112			this.bindInitialEvents();
113		},
114
115		getTemplate: function(templateName)
116		{
117			if (!this.templates.hasOwnProperty(templateName))
118			{
119				var template = BX(templateName);
120				this.templates[templateName] = BX.type.isDomNode(template) ? template.innerHTML : '';
121			}
122
123			return this.templates[templateName];
124		},
125
126		getCacheNode: function(id)
127		{
128			if (!this.nodes.hasOwnProperty(id))
129			{
130				this.nodes[id] = BX(id);
131			}
132
133			return this.nodes[id];
134		},
135
136		getEntity: function(parent, entity, additionalFilter)
137		{
138			if (!parent || !entity)
139				return null;
140
141			additionalFilter = additionalFilter || '';
142
143			return parent.querySelector(additionalFilter + '[data-entity="' + entity + '"]');
144		},
145
146		getEntities: function(parent, entity, additionalFilter)
147		{
148			if (!parent || !entity)
149				return {length: 0};
150
151			additionalFilter = additionalFilter || '';
152
153			return parent.querySelectorAll(additionalFilter + '[data-entity="' + entity + '"]');
154		},
155
156		bindInitialEvents: function()
157		{
158			this.bindWarningEvents();
159
160			BX.bind(window, 'scroll', BX.proxy(this.checkStickyHeaders, this));
161			BX.bind(window, 'scroll', BX.proxy(this.lazyLoad, this));
162
163			BX.bind(window, 'resize', BX.throttle(this.checkStickyHeaders, 20, this));
164		},
165
166		bindWarningEvents: function()
167		{
168			var showItemsNode = this.getEntity(BX(this.ids.warning), 'basket-items-warning-count');
169
170			if (BX.type.isDomNode(showItemsNode))
171			{
172				showItemsNode.style.display = '';
173				BX.bind(showItemsNode, 'click', BX.delegate(function() {this.toggleFilter('warning');}, this));
174			}
175
176			BX.bind(
177				this.getEntity(BX(this.ids.warning), 'basket-items-warning-notification-close'),
178				'click',
179				BX.proxy(this.removeAllWarnings, this)
180			);
181		},
182
183		toggleFilter: function(event)
184		{
185			var target = BX.type.isNotEmptyString(event) ?
186				this.getEntity(
187					this.getCacheNode(this.ids.itemListWrapper),
188					'basket-items-count',
189					'[data-filter="' + event + '"]'
190				)
191				: BX.getEventTarget(event);
192
193			if (!BX.type.isDomNode(target) || BX.hasClass(target, 'active'))
194				return;
195
196			var entityName = target.getAttribute('data-filter');
197			var entities = target.parentNode.querySelectorAll('[data-filter]');
198
199			for (var i = 0; i < entities.length; i++)
200			{
201				if (entities[i].getAttribute('data-filter') === entityName)
202				{
203					BX.addClass(entities[i], 'active');
204				}
205				else if (BX.hasClass(entities[i], 'active'))
206				{
207					BX.removeClass(entities[i], 'active');
208				}
209			}
210
211			this.filter.showFilterByName(entityName);
212		},
213
214		scrollToFirstItem: function()
215		{
216			var headerNode = this.getEntity(this.getCacheNode(this.ids.itemListWrapper), 'basket-items-list-header');
217
218			if (BX.type.isDomNode(headerNode))
219			{
220				var itemListTopPosition = BX.pos(this.getCacheNode(this.ids.itemListContainer)).top;
221				var headerBottomPosition = BX.pos(headerNode).bottom;
222
223				if (itemListTopPosition < headerBottomPosition)
224				{
225					window.scrollTo(0, itemListTopPosition - this.stickyHeaderOffset);
226				}
227			}
228		},
229
230		showItemsOverlay: function()
231		{
232			var overlay = this.getCacheNode(this.ids.itemListOverlay);
233
234			if (BX.type.isDomNode(overlay))
235			{
236				overlay.style.display = '';
237			}
238		},
239
240		hideItemsOverlay: function()
241		{
242			var overlay = this.getCacheNode(this.ids.itemListOverlay);
243
244			if (BX.type.isDomNode(overlay))
245			{
246				overlay.style.display = 'none';
247			}
248		},
249
250		checkHeaderDisplay: function()
251		{
252			var header = this.getCacheNode(this.ids.itemListWrapper);
253
254			if (BX.type.isDomNode(header))
255			{
256				BX.removeClass(header, 'basket-items-list-wrapper-light');
257			}
258		},
259
260		bindHeaderEvents: function()
261		{
262			var entities = this.getEntities(this.getCacheNode(this.ids.itemListWrapper), 'basket-items-count');
263
264			for (var i = 0; i < entities.length; i++)
265			{
266				BX.bind(entities[i], 'click', BX.proxy(this.toggleFilter, this));
267			}
268		},
269
270		checkStickyHeaders: function()
271		{
272			if (this.isMobile)
273				return;
274
275			var node, position;
276			var border = 2, offset = 0;
277			var scrollTop = this.getDocumentScrollTop();
278			var basketPosition = BX.pos(this.getCacheNode(this.ids.basketRoot));
279			var basketScrolledToEnd = scrollTop + 200 >= basketPosition.bottom;
280
281			if (BX.util.in_array('top', this.params.TOTAL_BLOCK_DISPLAY))
282			{
283				var totalBlockNode = this.getEntity(this.getCacheNode(this.ids.basketRoot), 'basket-total-block');
284				if (BX.type.isDomNode(totalBlockNode))
285				{
286					node = this.getEntity(totalBlockNode, 'basket-checkout-aligner');
287					if (BX.type.isDomNode(node))
288					{
289						position = BX.pos(totalBlockNode);
290
291						if (scrollTop >= position.top)
292						{
293							offset += node.clientHeight;
294
295							if (!BX.hasClass(node, 'basket-checkout-container-fixed'))
296							{
297								totalBlockNode.style.height = position.height + 'px';
298
299								node.style.width = node.clientWidth + border + 'px';
300								BX.addClass(node, 'basket-checkout-container-fixed');
301							}
302						}
303						else if (BX.hasClass(node, 'basket-checkout-container-fixed'))
304						{
305							totalBlockNode.style.height = '';
306
307							node.style.width = '';
308							BX.removeClass(node, 'basket-checkout-container-fixed');
309						}
310
311						if (basketScrolledToEnd)
312						{
313							if (!BX.hasClass(node, 'basket-checkout-container-fixed-hide'))
314							{
315								BX.addClass(node, 'basket-checkout-container-fixed-hide');
316							}
317						}
318						else if (BX.hasClass(node, 'basket-checkout-container-fixed-hide'))
319						{
320							BX.removeClass(node, 'basket-checkout-container-fixed-hide');
321						}
322					}
323				}
324			}
325
326			if (this.useItemsFilter)
327			{
328				var itemWrapperNode = this.getCacheNode(this.ids.itemListWrapper);
329
330				node = this.getEntity(itemWrapperNode, 'basket-items-list-header');
331				if (BX.type.isDomNode(node))
332				{
333					position = BX.pos(itemWrapperNode);
334
335					if ((scrollTop + offset >= position.top) && !basketScrolledToEnd)
336					{
337						if (!BX.hasClass(node, 'basket-items-list-header-fixed'))
338						{
339							node.style.width = node.clientWidth + border + 'px';
340
341							itemWrapperNode.style.paddingTop = node.clientHeight + 'px';
342
343							BX.addClass(node, 'basket-items-list-header-fixed');
344						}
345
346						if (offset)
347						{
348							node.style.top = offset + 'px';
349						}
350
351						offset += node.clientHeight;
352					}
353					else if (BX.hasClass(node, 'basket-items-list-header-fixed'))
354					{
355						itemWrapperNode.style.paddingTop = '';
356
357						node.style.width = '';
358						node.style.top = '';
359
360						BX.removeClass(node, 'basket-items-list-header-fixed');
361					}
362				}
363			}
364
365			this.stickyHeaderOffset = offset;
366		},
367
368		getDocumentScrollTop: function()
369		{
370			return window.scrollY
371				|| window.pageYOffset
372				|| document.body.scrollTop + (document.documentElement && document.documentElement.scrollTop || 0);
373		},
374
375		lazyLoad: function()
376		{
377			var itemsNodePosition = BX.pos(this.getCacheNode(this.ids.itemListContainer));
378
379			if (this.getDocumentScrollTop() + window.innerHeight >= itemsNodePosition.bottom - 400)
380			{
381				var itemIds = this.getItemsAfter();
382				if (itemIds.length)
383				{
384					this.editBasketItems(itemIds);
385				}
386			}
387		},
388
389		fireCustomEvents: function()
390		{
391			if (this.result.EVENT_ONCHANGE_ON_START === 'Y')
392			{
393				BX.onCustomEvent('OnBasketChange');
394			}
395
396			if (this.params.HIDE_COUPON !== 'Y')
397			{
398				if (this.coupons !== null && this.coupons !== this.result.COUPON_LIST)
399				{
400					BX.onCustomEvent('OnCouponApply');
401				}
402
403				this.coupons = this.result.COUPON_LIST;
404			}
405		},
406
407		editTotal: function()
408		{
409			this.fillTotalBlocks();
410			this.showItemsCount();
411			this.showWarningItemsCount();
412			this.showNotAvailableItemsCount();
413			this.showDelayedItemsCount();
414		},
415
416		fillTotalBlocks: function()
417		{
418			var totalNodes = this.getEntities(this.getCacheNode(this.ids.basketRoot), 'basket-total-block');
419
420			if (totalNodes && totalNodes.length)
421			{
422				var totalTemplate = this.getTemplate('basket-total-template');
423				if (totalTemplate)
424				{
425					var totalRender = this.render(totalTemplate, this.result.TOTAL_RENDER_DATA);
426
427					for (var i in totalNodes)
428					{
429						if (totalNodes.hasOwnProperty(i) && BX.type.isDomNode(totalNodes[i])
429)
430						{
431							totalNodes[i].innerHTML = totalRender;
432
433							this.bindTotalEvents(totalNodes[i]);
434						}
435					}
436				}
437			}
438
439			this.checkStickyHeaders();
440		},
441
442		showItemsCount: function()
443		{
444			var itemCountNode = this.getEntity(
445				this.getCacheNode(this.ids.itemListWrapper),
446				'basket-items-count',
447				'[data-filter="all"]'
448			);
449
450			if (BX.type.isDomNode(itemCountNode))
451			{
452				itemCountNode.innerHTML = BX.message('SBB_IN_BASKET') + ' ' + this.result.BASKET_ITEMS_COUNT + ' ' + this.getGoodsMessage(this.result.BASKET_ITEMS_COUNT);
453				itemCountNode.style.display = '';
454			}
455		},
456
457		showSimilarCount: function(state)
458		{
459			var itemCountNode = this.getEntity(
460				this.getCacheNode(this.ids.itemListWrapper),
461				'basket-items-count',
462				'[data-filter="similar"]'
463			);
464
465			if (BX.type.isDomNode(itemCountNode))
466			{
467				if (state)
468				{
469					itemCountNode.innerHTML = this.sortedItems.length + ' '
470						+ this.getGoodsMessage(this.result.BASKET_ITEMS_COUNT, 'SBB_SIMILAR_ITEM');
471					itemCountNode.style.display = '';
472				}
473				else
474				{
475					itemCountNode.style.display = 'none';
476				}
477			}
478		},
479
480		showWarningItemsCount: function()
481		{
482			var itemCountNode = this.getEntity(
483				this.getCacheNode(this.ids.itemListWrapper),
484				'basket-items-count',
485				'[data-filter="warning"]'
486			);
487
488			if (BX.type.isDomNode(itemCountNode))
489			{
490				if (this.warningItems.length)
491				{
492					itemCountNode.innerHTML = this.warningItems.length + ' ' + BX.message('SBB_BASKET_ITEMS_WARNING');
493					itemCountNode.style.display = '';
494				}
495				else
496				{
497					itemCountNode.style.display = 'none';
498				}
499			}
500		},
501
502		showNotAvailableItemsCount: function()
503		{
504			var itemCountNode = this.getEntity(
505				this.getCacheNode(this.ids.itemListWrapper),
506				'basket-items-count',
507				'[data-filter="not-available"]'
508			);
509
510			if (BX.type.isDomNode(itemCountNode))
511			{
512				if (parseInt(this.result.NOT_AVAILABLE_BASKET_ITEMS_COUNT))
513				{
514					itemCountNode.innerHTML = this.result.NOT_AVAILABLE_BASKET_ITEMS_COUNT + ' '
515						+ this.getGoodsMessage(this.result.NOT_AVAILABLE_BASKET_ITEMS_COUNT, 'SBB_NOT_AVAILABLE_ITEM');
516					itemCountNode.style.display = '';
517				}
518				else
519				{
520					itemCountNode.style.display = 'none';
521				}
522			}
523		},
524
525		showDelayedItemsCount: function()
526		{
527			var itemCountNode = this.getEntity(
528				this.getCacheNode(this.ids.itemListWrapper),
529				'basket-items-count',
530				'[data-filter="delayed"]'
531			);
532
533			if (BX.type.isDomNode(itemCountNode))
534			{
535				if (parseInt(this.result.DELAYED_BASKET_ITEMS_COUNT))
536				{
537					itemCountNode.innerHTML = this.result.DELAYED_BASKET_ITEMS_COUNT + ' '
538						+ this.getGoodsMessage(this.result.DELAYED_BASKET_ITEMS_COUNT, 'SBB_DELAYED_ITEM');
539					itemCountNode.style.display = '';
540				}
541				else
542				{
543					itemCountNode.style.display = 'none';
544				}
545			}
546		},
547
548		getGoodsMessage: function(count, customMessage)
549		{
550			var mesCode;
551			var countReminder = (count > 10 && count < 20) ? 0 : count % 10;
552
553			if (countReminder === 1)
554			{
555				mesCode = customMessage || 'SBB_GOOD';
556			}
557			else if (countReminder >= 2 && countReminder <= 4)
558			{
559				mesCode = customMessage ? customMessage + '_2' : 'SBB_GOOD_2';
560			}
561			else
562			{
563				mesCode = customMessage ? customMessage + 'S' : 'SBB_GOODS';
564			}
565
566			return BX.message(mesCode);
567		},
568
569		bindTotalEvents: function(node)
570		{
571			if (!this.result.TOTAL_RENDER_DATA.DISABLE_CHECKOUT)
572			{
573				BX.bind(this.getEntity(node, 'basket-checkout-button'), 'click', BX.proxy(this.checkOutAction, this));
574			}
575
576			BX.bind(this.getEntity(node, 'basket-coupon-input'), 'change', BX.proxy(this.addCouponAction, this));
577			BX.bind(this.getEntity(node, 'basket-coupon-input'), 'paste', BX.proxy(this.pasteCouponAction, this));
578
579			var couponNodes = this.getEntities(node, 'basket-coupon-delete');
580			for (var i = 0, l = couponNodes.length; i < l; i++)
581			{
582				BX.bind(couponNodes[i], 'click', BX.proxy(this.removeCouponAction, this));
583			}
584
585		},
586
587		checkOutAction: function()
588		{
589			document.location.href = this.params.PATH_TO_ORDER;
590		},
591
592		addCouponAction: function(event)
593		{
594			var target = BX.getEventTarget(event);
595			if (target && target.value)
596			{
597				this.actionPool.addCoupon(target.value);
598				target.disabled = true;
599			}
600		},
601
602		pasteCouponAction: function(event)
603		{
604			setTimeout(BX.delegate(function() {
605				this.addCouponAction(event);
606			}, this), 10);
607		},
608
609		removeCouponAction: function()
610		{
611			var value = BX.proxy_context && BX.util.trim(BX.proxy_context.getAttribute('data-coupon'));
612			if (value)
613			{
614				this.actionPool.removeCoupon(value);
615			}
616		},
617
618		initializeActionPool: function()
619		{
620			this.actionPool = new BX.Sale.BasketActionPool(this);
621		},
622
623		initializeFilter: function()
624		{
625			this.filter = new BX.Sale.BasketFilter(this);
626		},
627
628		/**
629		 * Send ajax request with basket data and executes callback by action
630		 */
631		sendRequest: function(action, data)
632		{
633			this.lastAction = action;
634
635			if (this.lastAction === 'recalculateAjax')
636			{
637				// we use it to reload all items if applied discounts changed
638				data.lastAppliedDiscounts = BX.util.array_keys(this.result.FULL_DISCOUNT_LIST).join(',');
639
640				if (this.params.USE_ENHANCED_ECOMMERCE === 'Y')
641				{
642					this.checkAnalytics(data);
643				}
644			}
645
646			BX.ajax({
647				method: 'POST',
648				dataType: 'json',
649				url: this.ajaxUrl,
650				data: this.getData(data),
651				onsuccess: BX.delegate(function(result) {
652					this.actionPool.doProcessing(false);
653
654					if (!BX.type.isPlainObject(result))
655						return;
656
657					this.actionPool.setRefreshStatus(result.BASKET_REFRESHED);
658
659					if (result.RESTORED_BASKET_ITEMS)
660					{
661						this.restoreBasketItems(result.RESTORED_BASKET_ITEMS);
662					}
663
664					if (result.DELETED_BASKET_ITEMS)
665					{
666						this.deleteBasketItems(result.DELETED_BASKET_ITEMS, this.params.SHOW_RESTORE === 'Y');
667					}
668
669					if (result.MERGED_BASKET_ITEMS)
670					{
671						this.deleteBasketItems(result.MERGED_BASKET_ITEMS, false, true);
672					}
673
674					this.applyBasketResult(result.BASKET_DATA);
675					this.editBasketItems(this.getItemsToEdit());
676					this.editTotal();
677
678					this.applyPriceAnimation();
679					this.editWarnings();
680
681					this.actionPool.switchTimer();
682
683					if (this.isBasketIntegrated() && this.isBasketChanged())
684					{
685						BX.Sale.OrderAjaxComponent.sendRequest();
686					}
687				}, this),
688				onfailure: BX.delegate(function() {
689					this.actionPool.doProcessing(false);
690				}, this)
691			});
692		},
693
694		isBasketIntegrated: function()
695		{
696			return this.params.BASKET_WITH_ORDER_INTEGRATION === 'Y';
697		},
698
699		isBasketChanged: function()
700		{
701			return this.changedItems.length;
702		},
703
704		addPriceAnimationData: function(nodeId, start, finish, currency)
705		{
706			if (!BX.type.isPlainObject(this.priceAnimationData))
707			{
708				this.clearPriceAnimationData();
709			}
710
711			this.priceAnimationData.start[nodeId] = parseFloat(start);
712			this.priceAnimationData.finish[nodeId] = parseFloat(finish);
713			this.priceAnimationData.currency[nodeId] = currency;
714			this.priceAnimationData.int[nodeId] = (parseFloat(start) === parseInt(start)) && (parseFloat(finish) === parseInt(finish));
715		},
716
717		clearPriceAnimationData: function()
718		{
719			this.priceAnimationData = {
720				start: {},
721				finish: {},
722				currency: {},
723				int: {}
724			};
725		},
726
727		applyBasketResult: function(result)
728		{
729			this.changedItems = [];
730			this.clearPriceAnimationData();
731
732			if (!BX.type.isPlainObject(result))
733			{
734				return;
735			}
736
737			if (result.BASKET_ITEM_RENDER_DATA)
738			{
739				var i, newData;
740
741				for (i in result.BASKET_ITEM_RENDER_DATA)
742				{
743					if (result.BASKET_ITEM_RENDER_DATA.hasOwnProperty(i))
744					{
745						newData = result.BASKET_ITEM_RENDER_DATA[i];
746						newData.WARNINGS = this.checkBasketItemWarnings(newData, result.WARNING_MESSAGE_WITH_CODE);
747
748						if (this.items[newData.ID])
749						{
750							if (JSON.stringify(this.items[newData.ID]) === JSON.stringify(newData))
751							{
752								continue;
753							}
754						}
755						else
756						{
757							this.addSortedItem(newData.ID, true);
758						}
759
760						this.changedItems.push(newData.ID);
761
762						newData = this.checkBasketItemsAnimation(newData);
763						this.items[newData.ID] = newData;
764					}
765				}
766
767				this.changedItems = BX.util.array_unique(this.changedItems.concat(this.getChangedSimilarOffers()));
768
769				if (this.isBasketChanged())
770				{
771					this.sortSortedItems(true);
772				}
773			}
774
775			if (result.TOTAL_RENDER_DATA)
776			{
777				result.TOTAL_RENDER_DATA = this.checkTotalAnimation(result.TOTAL_RENDER_DATA);
778			}
779
780			this.result = result;
781		},
782
783		itemSortFunction: function(a, b)
784		{
785			if (!this.items.hasOwnProperty(a) || !this.items.hasOwnProperty(b))
786			{
787				return 0;
788			}
789
790			return parseFloat(this.items[a].SORT) - parseFloat(this.items[b].SORT);
791		},
792
793		getChangedSimilarOffers: function()
794		{
795			var changedSimilarOffers = [];
796
797			var otherSimilarItemsQuantity, totalSimilarItemsQuantity;
798			var hashMap = this.getHashMap();
799
800			for (var hash in hashMap)
801			{
802				if (hashMap.hasOwnProperty(hash))
803				{
804					if (hashMap[hash].length > 1)
805					{
806						for (var i = 0; i < hashMap[hash].length; i++)
807						{
808							otherSimilarItemsQuantity = 0;
809							totalSimilarItemsQuantity = 0;
810
811							for (var k = 0; k < hashMap[hash].length; k ++)
812							{
813								if (hashMap[hash][k] != hashMap[hash][i])
814								{
815									otherSimilarItemsQuantity += parseFloat(this.items[hashMap[hash][k]].QUANTITY);
816								}
817
818								totalSimilarItemsQuantity += parseFloat(this.items[hashMap[hash][k]].QUANTITY);
819							}
820
821							if (
822								!this.items[hashMap[hash][i]].HAS_SIMILAR_ITEMS
823								|| this.items[hashMap[hash][i]].SIMILAR_ITEMS_QUANTITY != otherSimilarItemsQuantity
824								|| this.items[hashMap[hash][i]].TOTAL_SIMILAR_ITEMS_QUANTITY != totalSimilarItemsQuantity
825							)
826							{
827								changedSimilarOffers.push(hashMap[hash][i]);
828
829								this.items[hashMap[hash][i]].HAS_SIMILAR_ITEMS = true;
830								this.items[hashMap[hash][i]].SIMILAR_ITEMS_QUANTITY = otherSimilarItemsQuantity;
831								this.items[hashMap[hash][i]].TOTAL_SIMILAR_ITEMS_QUANTITY = totalSimilarItemsQuantity;
832
833								this.items[hashMap[hash][i]].ALL_AVAILABLE_QUANTITY = this.items[hashMap[hash][i]].AVAILABLE_QUANTITY;
834								this.items[hashMap[hash][i]].AVAILABLE_QUANTITY = this.items[hashMap[hash][i]].ALL_AVAILABLE_QUANTITY - otherSimilarItemsQuantity;
835							}
836						}
837					}
838					else if (hashMap[hash][0] && this.items[hashMap[hash][0]].HAS_SIMILAR_ITEMS)
839					{
840						changedSimilarOffers.push(hashMap[hash][0]);
841
842						delete this.items[hashMap[hash][0]].HAS_SIMILAR_ITEMS;
843						delete this.items[hashMap[hash][0]].SIMILAR_ITEMS_QUANTITY;
844						delete this.items[hashMap[hash][0]].TOTAL_SIMILAR_ITEMS_QUANTITY;
845
846						this.items[hashMap[hash][0]].AVAILABLE_QUANTITY = this.items[hashMap[hash][0]].ALL_AVAILABLE_QUANTITY;
847						delete this.items[hashMap[hash][0]].ALL_AVAILABLE_QUANTITY;
848					}
849				}
850			}
851
852			return changedSimilarOffers;
853		},
854
855		getHashMap: function()
856		{
857			var hashMap = {};
858
859			for (var id in this.items)
860			{
861				if (this.items.hasOwnProperty(id) && this.isItemAvailable(id))
862				{
863					if (!hashMap.hasOwnProperty(this.items[id].HASH))
864					{
865						hashMap[this.items[id].HASH] = [];
866					}
867
868					hashMap[this.items[id].HASH].push(id);
869				}
870			}
871
872			return hashMap;
873		},
874
875		isItemAvailable: function(itemId)
876		{
877			var sortedItems = this.filter.isActive() ? this.filter.realSortedItems : this.sortedItems;
878
879			return !this.items[itemId].NOT_AVAILABLE
880				&& !this.items[itemId].SHOW_RESTORE
881				&& BX.util.in_array(itemId, sortedItems);
882		},
883
884		checkTotalAnimation: function(totalData)
885		{
886			if (this.result && this.result.TOTAL_RENDER_DATA && parseFloat(this.result.TOTAL_RENDER_DATA.PRICE) > parseFloat(totalData.PRICE))
887			{
888				totalData.PRICE_NEW = totalData.PRICE;
889				totalData.PRICE = this.result.TOTAL_RENDER_DATA.PRICE;
890
891				totalData.PRICE_FORMATED_NEW = totalData.PRICE_FORMATED;
892				totalData.PRICE_FORMATED = this.result.TOTAL_RENDER_DATA.PRICE_FORMATED;
893
894				this.addPriceAnimationData(this.ids.total, totalData.PRICE, totalData.PRICE_NEW, totalData.CURRENCY);
895			}
896
897			return totalData;
898		},
899
900		checkBasketItemsAnimation: function(itemData)
901		{
902			var itemId = itemData.ID;
903
904			if (this.items[itemId])
905			{
906				var quantityNode = BX(this.ids.quantity + itemId);
907				if (
908					BX.type.isDomNode(quantityNode)
909					&& !this.actionPool.isItemInPool(itemId)
910					&& parseFloat(quantityNode.value) !== parseFloat(itemData.QUANTITY)
911				)
912				{
913					itemData.QUANTITY_ANIMATION = true;
914					this.actionPool.clearLastActualQuantityPool(itemId);
915				}
916
917				if (parseFloat(this.items[itemId].PRICE) > parseFloat(itemData.PRICE))
918				{
919					itemData.PRICE_NEW = itemData.PRICE;
920					itemData.PRICE = this.items[itemId].PRICE;
921
922					itemData.PRICE_FORMATED_NEW = itemData.PRICE_FORMATED;
923					itemData.PRICE_FORMATED = this.items[itemId].PRICE_FORMATED;
924
925					this.addPriceAnimationData(this.ids.price + itemId, itemData.PRICE, itemData.PRICE_NEW, itemData.CURRENCY);
926				}
927
928				if (
929					BX.util.in_array('SUM', this.params.COLUMNS_LIST)
930					&& parseFloat(this.items[itemId].SUM_PRICE) > parseFloat(itemData.SUM_PRICE)
931					&& parseFloat(this.items[itemId].QUANTITY) === parseFloat(itemData.QUANTITY)
932				)
933				{
934					itemData.SUM_PRICE_NEW = itemData.SUM_PRICE;
935					itemData.SUM_PRICE = this.items[itemId].SUM_PRICE;
936
937					itemData.SUM_PRICE_FORMATED_NEW = itemData.SUM_PRICE_FORMATED;
938					itemData.SUM_PRICE_FORMATED = this.items[itemId].SUM_PRICE_FORMATED;
939
940					this.addPriceAnimationData(this.ids.sumPrice + itemId, itemData.SUM_PRICE, itemData.SUM_PRICE_NEW, itemData.CURRENCY);
941				}
942			}
943
944			return itemData;
945		},
946
947		getData: function(data)
948		{
949			data = data || {};
950
951			data[this.params.ACTION_VARIABLE] = this.lastAction;
952			data.via_ajax = 'Y';
953			data.site_id = this.siteId;
954			data.site_template_id = this.siteTemplateId;
955			data.sessid = BX.bitrix_sessid();
956			data.template = this.template;
957			data.signedParamsString = this.signedParamsString;
958
959			return data;
960		},
961
962		startLoader: function()
963		{
964			// if (!this.loadingScreen)
965			// {
966			// 	this.loadingScreen = new BX.PopupWindow('loading_screen', null, {
967			// 		events: {
968			// 			onAfterPopupShow: BX.delegate(function() {
969			// 				BX.cleanNode(this.loadingScreen.popupContainer);
970			// 				BX.removeClass(this.loadingScreen.popupContainer, 'popup-window');
971			// 				this.loadingScreen.popupContainer.appendChild(
972			// 					BX.create('IMG', {props: {src: this.templateFolder + '/images/loader.gif'}})
973			// 				);
974			// 				this.loadingScreen.popupContainer.removeAttribute('style');
975			// 				this.loadingScreen.popupContainer.style.display = 'block';
976			// 			}, this)
977			// 		}
978			// 	});
979			// 	BX.addClass(this.loadingScreen.popupContainer, 'bx-step-opacity');
980			// }
981			//
982			// this.loadingScreen.show();
983		},
984
985		/**
986		 * Hiding loader image with overlay.
987		 */
988		endLoader: function()
989		{
990			// if (this.loadingScreen && this.loadingScreen.isShown())
991			// {
992			// 	this.loadingScreen.close();
993			// }
994		},
995
996		editWarnings: function()
997		{
998			this.editGeneralWarnings();
999			this.editBasketItemWarnings();
1000			this.toggleWarningBlock();
1001			this.showWarningItemsCount();
1002		},
1003
1004		editGeneralWarnings: function()
1005		{
1006			var warningsNode = this.getEntity(this.getCacheNode(this.ids.warning), 'basket-general-warnings');
1007
1008			if (BX.type.isDomNode(warningsNode))
1009			{
1010				var generalWarningText = warningsNode.innerHTML;
1011
1012				if (this.result.WARNING_MESSAGE_WITH_CODE)
1013				{
1014					for (var code in this.result.WARNING_MESSAGE_WITH_CODE)
1015					{
1016						if (this.result.WARNING_MESSAGE_WITH_CODE.hasOwnProperty(code))
1017						{
1018							if (
1019								!this.items[code]
1020								&& generalWarningText.indexOf(this.result.WARNING_MESSAGE_WITH_CODE[code]) === -1
1021							)
1022							{
1023								generalWarningText += this.result.WARNING_MESSAGE_WITH_CODE[code] + '<br/>';
1024							}
1025						}
1026					}
1027				}
1028
1029				if (generalWarningText)
1030				{
1031					warningsNode.innerHTML = generalWarningText;
1032					warningsNode.style.display = '';
1033				}
1034				else
1035				{
1036					warningsNode.style.display = 'none';
1037					warningsNode.innerHTML = '';
1038				}
1039			}
1040		},
1041
1042		editBasketItemWarnings: function()
1043		{
1044			var itemsWarningsNode = this.getEntity(this.getCacheNode(this.ids.warning), 'basket-item-warnings');
1045
1046			if (BX.type.isDomNode(itemsWarningsNode))
1047			{
1048				if (this.warningItems.length)
1049				{
1050					var warningCount = this.getEntity(itemsWarningsNode, 'basket-items-warning-count');
1051					if (BX.type.isDomNode(warningCount))
1052					{
1053						warningCount.innerHTML = this.warningItems.length + ' ' + this.getGoodsMessage(this.warningItems.length);
1054					}
1055
1056					itemsWarningsNode.style.display = '';
1057				}
1058				else if (itemsWarningsNode.style.display !== 'none')
1059				{
1060					itemsWarningsNode.style.display = 'none';
1061
1062					if (this.filter.isActive())
1063					{
1064						this.toggleFilter('all');
1065					}
1066				}
1067			}
1068		},
1069
1070		toggleWarningBlock: function()
1071		{
1072			var warningNode = this.getCacheNode(this.ids.warning);
1073
1074			if (BX.type.isDomNode(warningNode))
1075			{
1076				var generalWarningNode = this.getEntity(warningNode, 'basket-general-warnings');
1077				var itemsWarningsNode = this.getEntity(warningNode, 'basket-item-warnings');
1078
1079				if (
1080					(!BX.type.isDomNode(generalWarningNode) || generalWarningNode.style.display === 'none')
1081					&& (!BX.type.isDomNode(itemsWarningsNode) || itemsWarningsNode.style.display === 'none')
1082				)
1083				{
1084					warningNode.style.display = 'none';
1085				}
1086				else
1087				{
1088					warningNode.style.display = '';
1089				}
1090			}
1091		},
1092
1093		checkBasketItemWarnings: function(itemData, warnings)
1094		{
1095			if (!itemData)
1096				return;
1097
1098			var itemWarnings;
1099
1100			if (this.items[itemData.ID] && this.lastAction === 'refreshAjax')
1101			{
1102				itemWarnings = this.items[itemData.ID].WARNINGS;
1103			}
1104			else
1105			{
1106				itemWarnings = [];
1107			}
1108
1109			if (BX.type.isArray(warnings[itemData.ID]) && warnings[itemData.ID].length)
1110			{
1111				for (var i in warnings[itemData.ID])
1112				{
1113					if (warnings[itemData.ID].hasOwnProperty(i) && !BX.util.in_array(warnings[itemData.ID][i], itemWarnings))
1114					{
1115						itemWarnings.push(warnings[itemData.ID][i]);
1116					}
1117				}
1118			}
1119
1120			if (itemWarnings.length)
1121			{
1122				if (!BX.util.in_array(itemData.ID, this.warningItems))
1123				{
1124					this.warningItems.push(itemData.ID);
1125				}
1126			}
1127			else if (BX.util.in_array(itemData.ID, this.warningItems))
1128			{
1129				this.warningItems.splice(BX.util.array_search(itemData.ID, this.warningItems), 1);
1130			}
1131
1132			return itemWarnings;
1133		},
1134
1135		removeAllWarnings: function(event)
1136		{
1137			this.clearGeneralWarnings();
1138			this.clearBasketItemsWarnings();
1139
1140			this.editWarnings();
1141
1142			event && event.preventDefault();
1143		},
1144
1145		clearGeneralWarnings: function()
1146		{
1147			this.result.WARNING_MESSAGE_WITH_CODE = {};
1148
1149			var generalWarningNode = this.getEntity(this.getCacheNode(this.ids.warning), 'basket-general-warnings');
1150
1151			if (BX.type.isDomNode(generalWarningNode))
1152			{
1153				generalWarningNode.innerHTML = '';
1154			}
1155		},
1156
1157		clearBasketItemsWarnings: function()
1158		{
1159			var itemsToEdit = [];
1160
1161			for (var i in this.warningItems)
1162			{
1163				if (this.warningItems.hasOwnProperty(i))
1164				{
1165					this.items[this.warningItems[i]].WARNINGS = [];
1166
1167					if (this.isItemShown(this.warningItems[i]))
1168					{
1169						itemsToEdit.push(this.warningItems[i]);
1170					}
1171				}
1172			}
1173
1174			this.warningItems = [];
1175			this.editBasketItems(itemsToEdit);
1176		},
1177
1178		isItemShown: function(itemId)
1179		{
1180			return BX.util.in_array(itemId, this.shownItems);
1181		},
1182
1183		initializeBasketItems: function()
1184		{
1185			if (Object.keys(this.items).length === 0)
1186				return;
1187
1188			for (var i = 0; i < this.sortedItems.length; i++)
1189			{
1190				if (this.useDynamicScroll && this.shownItems.length >= this.maxItemsShowCount)
1191				{
1192					break;
1193				}
1194
1195				this.createBasketItem(this.sortedItems[i]);
1196			}
1197		},
1198
1199		createBasketItem: function(itemId)
1200		{
1201			if (!this.items[itemId])
1202			{
1203				return;
1204			}
1205
1206			var basketItemTemplate = this.getTemplate('basket-item-template');
1207			if (basketItemTemplate)
1208			{
1209				var basketItemHtml = this.renderBasketItem(basketItemTemplate, this.items[itemId]);
1210				var sortIndex = BX.util.array_search(itemId, this.sortedItems);
1211
1212				if (this.shownItems.length && sortIndex >= 0)
1213				{
1214					if (sortIndex < BX.util.array_search(this.shownItems[0], this.sortedItems))
1215					{
1216						// insert before
1217						BX(this.ids.item + this.shownItems[0]).insertAdjacentHTML('beforebegin', basketItemHtml);
1218						this.shownItems.unshift(itemId);
1219					}
1220					else if (sortIndex > BX.util.array_search(this.shownItems[this.shownItems.length - 1], this.sortedItems))
1221					{
1222						// insert after
1223						BX(this.ids.item + this.shownItems[this.shownItems.length - 1]).insertAdjacentHTML('afterend', basketItemHtml);
1224						this.shownItems.push(itemId);
1225					}
1226					else
1227					{
1228						// insert between
1229						BX(this.ids.item + this.sortedItems[sortIndex + 1]).insertAdjacentHTML('beforebegin', basketItemHtml);
1230						this.shownItems.splice(sortIndex + 1, 0, itemId);
1231					}
1232				}
1233				else
1234				{
1235					this.getCacheNode(this.ids.itemListTable).insertAdjacentHTML('beforeend', basketItemHtml);
1236					this.shownItems.push(itemId);
1237				}
1238
1239				this.bindBasketItemEvents(this.items[itemId]);
1240
1241				if (this.filter.isActive())
1242				{
1243					this.filter.highlightSearchMatch(this.items[itemId]);
1244				}
1245			}
1246		},
1247
1248		getItemsToEdit: function()
1249		{
1250			var itemIds = [];
1251
1252			if (this.isBasketChanged())
1253			{
1254				for (var i in this.changedItems)
1255				{
1256					if (this.changedItems.hasOwnProperty(i) && this.isItemShown(this.changedItems[i]))
1257					{
1258						itemIds.push(this.changedItems[i]);
1259					}
1260				}
1261			}
1262
1263			return itemIds;
1264		},
1265
1266		getItemsAfter: function()
1267		{
1268			var itemIdsAfter = [];
1269
1270			if (this.useDynamicScroll)
1271			{
1272				var lastShownItemId = this.shownItems[this.shownItems.length - 1] || false;
1273
1274				if (lastShownItemId)
1275				{
1276					var i = 0;
1277					var index = BX.util.array_search(lastShownItemId, this.sortedItems);
1278
1279					while (this.sortedItems[++index] && i++ < this.maxItemsShowCount)
1280					{
1281						itemIdsAfter.push(this.sortedItems[index]);
1282					}
1283				}
1284			}
1285
1286			return itemIdsAfter;
1287		},
1288
1289		editBasketItems: function(itemIds)
1290		{
1291			if (!itemIds || itemIds.length === 0)
1292			{
1293				return;
1294			}
1295
1296			var i, item;
1297
1298			for (i in itemIds)
1299			{
1300				if (!itemIds.hasOwnProperty(i) || !BX.type.isPlainObject(this.items[itemIds[i]]))
1301				{
1302					continue;
1303				}
1304
1305				item = this.items[itemIds[i]];
1306
1307				if (this.actionPool.isItemInPool(item.ID))
1308				{
1309					if (!BX.util.in_array(item.ID, this.postponedItems))
1310					{
1311						this.postponedItems.push(item.ID);
1312					}
1313
1314					continue;
1315				}
1316
1317				if (BX.type.isDomNode(BX(this.ids.item + item.ID)))
1318				{
1319					this.redrawBasketItemNode(item.ID);
1320					this.applyQuantityAnimation(item.ID);
1321				}
1322				else
1323				{
1324					this.createBasketItem(item.ID);
1325				}
1326			}
1327		},
1328
1329		editPostponedBasketItems: function()
1330		{
1331			if (!this.postponedItems.length)
1332				return;
1333
1334			var itemsToEdit = [];
1335
1336			for (var i in this.postponedItems)
1337			{
1338				if (this.postponedItems.hasOwnProperty(i) && this.isItemShown(this.postponedItems[i]))
1339				{
1340					itemsToEdit.push(this.postponedItems[i]);
1341				}
1342			}
1343
1344			this.postponedItems = [];
1345			this.editBasketItems(itemsToEdit);
1346		},
1347
1348		applyQuantityAnimation: function(itemId)
1349		{
1350			var basketItemNode = BX(this.ids.item + itemId);
1351
1352			if (BX.type.isDomNode(basketItemNode) && this.items[itemId])
1353			{
1354				if (this.items[itemId].QUANTITY_ANIMATION)
1355				{
1356					BX.addClass(BX(this.ids.quantity + itemId), 'basket-updated');
1357				}
1358			}
1359		},
1360
1361		applyPriceAnimation: function()
1362		{
1363			if (!this.priceAnimationData || Object.keys(this.priceAnimationData.start).length === 0)
1364				return;
1365
1366			var animationData = this.priceAnimationData,
1367				nodeCache = {};
1368
1369			new BX.easing({
1370				duration: this.params.USE_PRICE_ANIMATION === 'Y' ? this.duration.priceAnimation : 1,
1371				start: animationData.start,
1372				finish: animationData.finish,
1373				transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
1374				step: BX.delegate(function(state){
1375					for (var nodeId in animationData.start)
1376					{
1377						if (animationData.start.hasOwnProperty(nodeId))
1378						{
1379							if (!nodeCache[nodeId])
1380							{
1381								if (nodeId === this.ids.total)
1382								{
1383									nodeCache[nodeId] = this.getEntities(this.getCacheNode(this.ids.basketRoot), this.ids.total);
1384								}
1385								else
1386								{
1387									var node = BX(nodeId);
1388									nodeCache[nodeId] = node ? [node] : [];
1389								}
1390							}
1391
1392							if (!animationData.int[nodeId])
1393							{
1394								// fix price blinking
1395								state[nodeId] = (state[nodeId] + (state[nodeId] % 1000) / 1000).toFixed(5);
1396							}
1397
1398							for (var i = 0; i < nodeCache[nodeId].length; i++)
1399							{
1400								nodeCache[nodeId][i].innerHTML = this.getFormatPrice(state[nodeId], animationData.currency[nodeId]);
1401							}
1402						}
1403					}
1404				}, this),
1405				complete: BX.delegate(function() {
1406					var nodeId, formattedPrice, itemId, type;
1407
1408					for (nodeId in animationData.start)
1409					{
1410						if (animationData.start.hasOwnProperty(nodeId))
1411						{
1412							formattedPrice = this.getFormatPrice(animationData.finish[nodeId], animationData.currency[nodeId]);
1413
1414							for (var i = 0; i < nodeCache[nodeId].length; i++)
1415							{
1416								nodeCache[nodeId][i].innerHTML = formattedPrice;
1417							}
1418
1419							if (nodeId.indexOf(this.ids.sumPrice) !== -1)
1420							{
1421								type = 'SUM_PRICE';
1422								itemId = nodeId.substr(this.ids.sumPrice.length);
1423							}
1424							else if (nodeId.indexOf(this.ids.price) !== -1)
1425							{
1426								type = 'PRICE';
1427								itemId = nodeId.substr(this.ids.price.length);
1428							}
1429							else if (nodeId.indexOf(this.ids.total) !== -1)
1430							{
1431								type = 'TOTAL';
1432								itemId = '';
1433							}
1434							else
1435							{
1436								itemId = '';
1437								type = '';
1438							}
1439
1440							if (BX.type.isNotEmptyString(type))
1441							{
1442								if (itemId)
1443								{
1444									this.items[itemId][type] = animationData.finish[nodeId];
1445									delete this.items[itemId][type + '_NEW'];
1446									this.items[itemId][type + '_FORMATED'] = formattedPrice;
1447									delete this.items[itemId][type + '_FORMATED_NEW'];
1448								}
1449								else if (type === 'TOTAL')
1450								{
1451									this.result.TOTAL_RENDER_DATA.PRICE = animationData.finish[nodeId];
1452									delete this.result.TOTAL_RENDER_DATA.PRICE_NEW;
1453									this.result.TOTAL_RENDER_DATA.PRICE_FORMATED = formattedPrice;
1454									delete this.result.TOTAL_RENDER_DATA.PRICE_FORMATED_NEW;
1455								}
1456							}
1457						}
1458					}
1459
1460					this.filter.highlightFoundItems();
1461				}, this)
1462			}).animate();
1463		},
1464
1465		getFormatPrice: function(price, currency)
1466		{
1467			return BX.Currency.currencyFormat(price, currency, true);
1468		},
1469
1470		deleteBasketItems: function(items, restore, final)
1471		{
1472			if (!items || !items.length)
1473			{
1474				return;
1475			}
1476
1477			for (var i in items)
1478			{
1479				if (items.hasOwnProperty(i))
1480				{
1481					this.deleteBasketItem(items[i], restore, final);
1482				}
1483			}
1484		},
1485
1486		deleteBasketItem: function(itemId, restore, final)
1487		{
1488			// delete not available item with no chance to restore
1489			if (this.items[itemId].NOT_AVAILABLE && restore)
1490			{
1491				restore = false;
1492				final = true;
1493			}
1494
1495			if (restore)
1496			{
1497				this.items[itemId].SHOW_RESTORE = true;
1498				this.items[itemId].SHOW_LOADING = false;
1499				this.redrawBasketItemNode(itemId);
1500			}
1501			else
1502			{
1503				this.changeShownItem(itemId);
1504				BX.remove(BX(this.ids.item + itemId));
1505			}
1506
1507			if (final)
1508			{
1509				this.changeSortedItem(itemId, false, true);
1510				this.changeShownItem(itemId, false, true);
1511			}
1512		},
1513
1514		addSortedItem: function(itemId, all)
1515		{
1516			this.sortedItems.push(itemId.toString());
1517
1518			if (all && this.filter.isActive())
1519			{
1520				this.filter.realSortedItems.push(itemId.toString());
1521			}
1522		},
1523
1524		changeSortedItem: function(itemId, newItemId, all)
1525		{
1526			var index = BX.util.array_search(itemId, this.sortedItems);
1527
1528			if (index >= 0)
1529			{
1530				if (newItemId)
1531				{
1532					this.sortedItems.splice(index, 1, newItemId.toString());
1533				}
1534				else
1535				{
1536					this.sortedItems.splice(index, 1);
1537				}
1538			}
1539
1540			if (all && this.filter.isActive())
1541			{
1542				index = BX.util.array_search(itemId, this.filter.realSortedItems);
1543
1544				if (index >= 0)
1545				{
1546					if (newItemId)
1547					{
1548						this.filter.realSortedItems.splice(index, 1, newItemId.toString());
1549					}
1550					else
1551					{
1552						this.filter.realSortedItems.splice(index, 1);
1553					}
1554				}
1555			}
1556		},
1557
1558		sortSortedItems: function(all)
1559		{
1560			this.sortedItems.sort(BX.proxy(this.itemSortFunction, this));
1561
1562			if (all && this.filter.isActive())
1563			{
1564				this.filter.realSortedItems.sort(BX.proxy(this.itemSortFunction, this));
1565			}
1566		},
1567
1568		changeShownItem: function(itemId, newItemId, all)
1569		{
1570			var index = BX.util.array_search(itemId, this.shownItems);
1571
1572			if (index >= 0)
1573			{
1574				if (newItemId)
1575				{
1576					this.shownItems.splice(index, 1, newItemId.toString());
1577				}
1578				else
1579				{
1580					this.shownItems.splice(index, 1);
1581				}
1582			}
1583
1584			if (all && this.filter.isActive())
1585			{
1586				index = BX.util.array_search(itemId, this.filter.realShownItems);
1587
1588				if (index >= 0)
1589				{
1590					if (newItemId)
1591					{
1592						this.filter.realShownItems.splice(index, 1, newItemId.toString());
1593					}
1594					else
1595					{
1596						this.filter.realShownItems.splice(index, 1);
1597					}
1598				}
1599			}
1600		},
1601
1602		redrawBasketItemNode: function(itemId)
1603		{
1604			var basketItemNode = BX(this.ids.item + itemId);
1605
1606			if (!this.items[itemId] || !BX.type.isDomNode(basketItemNode))
1607				return;
1608
1609			var basketItemTemplate = this.getTemplate('basket-item-template');
1610			if (basketItemTemplate)
1611			{
1612				var nodeAligner = BX(this.ids.itemHeightAligner + itemId),
1613					oldHeight;
1614
1615				if (BX.type.isDomNode(nodeAligner))
1616				{
1617					oldHeight = nodeAligner.clientHeight;
1618				}
1619
1620				var basketItemHtml = this.renderBasketItem(basketItemTemplate, this.items[itemId]);
1621				basketItemNode.insertAdjacentHTML('beforebegin', basketItemHtml);
1622				BX.remove(basketItemNode);
1623
1624				if (oldHeight)
1625				{
1626					nodeAligner = BX(this.ids.itemHeightAligner + itemId);
1627
1628					if (BX.type.isDomNode(nodeAligner) && nodeAligner.clientHeight < oldHeight)
1629					{
1630						nodeAligner.style.minHeight = oldHeight + 'px';
1631						setTimeout(function(){nodeAligner.style.minHeight = '0px';}, 1);
1632					}
1633				}
1634
1635				this.bindBasketItemEvents(this.items[itemId]);
1636
1637				if (this.filter.isActive())
1638				{
1639					this.filter.highlightSearchMatch(this.items[itemId]);
1640				}
1641			}
1642		},
1643
1644		restoreBasketItems: function(items)
1645		{
1646			if (!items || Object.keys(items).length === 0)
1647			{
1648				return;
1649			}
1650
1651			var oldItemId, newItemId, basketItemNode;
1652
1653			for (oldItemId in items)
1654			{
1655				if (items.hasOwnProperty(oldItemId))
1656				{
1657					newItemId = items[oldItemId];
1658
1659					if (this.isItemShown(oldItemId))
1660					{
1661						this.changeShownItem(oldItemId, newItemId, true);
1662
1663						basketItemNode = BX(this.ids.item + oldItemId);
1664						if (BX.type.isDomNode(basketItemNode))
1665						{
1666							basketItemNode.id = this.ids.item + newItemId;
1667							basketItemNode.setAttribute('data-id', newItemId);
1668						}
1669					}
1670
1671					this.changeSortedItem(oldItemId, false, true);
1672				}
1673			}
1674		},
1675
1676		bindBasketItemEvents: function(itemData)
1677		{
1678			if (!itemData)
1679				return;
1680
1681			var itemNode = BX(this.ids.item + itemData.ID);
1682			if (BX.type.isDomNode(itemNode))
1683			{
1684				this.bindQuantityEvents(itemNode, itemData);
1685				this.bindSkuEvents(itemNode, itemData);
1686				this.bindImageEvents(itemNode, itemData);
1687				this.bindActionEvents(itemNode, itemData);
1688				this.bindRestoreAction(itemNode, itemData);
1689				this.bindItemWarningEvents(itemNode, itemData);
1690			}
1691		},
1692
1693		bindQuantityEvents: function(node, data)
1694		{
1695			if (!node || !data || !this.isItemAvailable(data.ID))
1696				return;
1697
1698			var entity;
1699
1700			var block = this.getEntity(node, 'basket-item-quantity-block');
1701			if (block)
1702			{
1703				var startEventName = this.isTouch ? 'touchstart' : 'mousedown';
1704				var endEventName = this.isTouch ? 'touchend' : 'mouseup';
1705
1706				entity = this.getEntity(block, 'basket-item-quantity-minus');
1707				BX.bind(entity, startEventName, BX.proxy(this.startQuantityInterval, this));
1708				BX.bind(entity, endEventName, BX.proxy(this.clearQuantityInterval, this));
1709				BX.bind(entity, 'mouseout', BX.proxy(this.clearQuantityInterval, this));
1710				BX.bind(entity, 'click', BX.proxy(this.quantityMinus, this));
1711
1712				entity = this.getEntity(block, 'basket-item-quantity-plus');
1713				BX.bind(entity, startEventName, BX.proxy(this.startQuantityInterval, this));
1714				BX.bind(entity, endEventName, BX.proxy(this.clearQuantityInterval, this));
1715				BX.bind(entity, 'mouseout', BX.proxy(this.clearQuantityInterval, this));
1716				BX.bind(entity, 'click', BX.proxy(this.quantityPlus, this));
1717
1718				entity = this.getEntity(block, 'basket-item-quantity-field');
1719				BX.bind(entity, 'change', BX.proxy(this.quantityChange, this));
1720			}
1721		},
1722
1723		startQuantityInterval: function()
1724		{
1725			var target = BX.proxy_context;
1726			var func = target.getAttribute('data-entity') === 'basket-item-quantity-minus'
1727				? BX.proxy(this.quantityMinus, this)
1728				: BX.proxy(this.quantityPlus, this);
1729
1730			this.quantityDelay = setTimeout(
1731				BX.delegate(function() {
1732					this.quantityTimer = setInterval(function(){func(target);}, 150);
1733				}, this),
1734				300
1735			);
1736		},
1737
1738		clearQuantityInterval: function()
1739		{
1740			clearTimeout(this.quantityDelay);
1741			clearInterval(this.quantityTimer);
1742		},
1743
1744		quantityPlus: function(target)
1745		{
1746			if (!BX.type.isDomNode(target))
1747			{
1748				target = BX.proxy_context;
1749				this.clearQuantityInterval();
1750			}
1751
1752			var itemData = this.getItemDataByTarget(target);
1753			if (itemData)
1754			{
1755				var quantityField = BX(this.ids.quantity + itemData.ID);
1756				var isQuantityFloat = this.isQuantityFloat(itemData);
1757
1758				var currentQuantity = isQuantityFloat ? parseFloat(quantityField.value) : Math.round(quantityField.value);
1759				var measureRatio = isQuantityFloat ? parseFloat(itemData.MEASURE_RATIO) : parseInt(itemData.MEASURE_RATIO);
1760
1761				var quantity = parseFloat((currentQuantity + measureRatio).toFixed(5));
1762				quantity = this.getCorrectQuantity(itemData, quantity);
1763
1764				this.setQuantity(itemData, quantity);
1765			}
1766		},
1767
1768		quantityMinus: function(target)
1769		{
1770			target = BX.type.isDomNode(target) ? target : BX.proxy_context;
1771
1772			var itemData = this.getItemDataByTarget(target);
1773			if (itemData)
1774			{
1775				var quantityField = BX(this.ids.quantity + itemData.ID);
1776				var isQuantityFloat = this.isQuantityFloat(itemData);
1777
1778				var currentQuantity = isQuantityFloat ? parseFloat(quantityField.value) : Math.round(quantityField.value);
1779				var measureRatio = isQuantityFloat ? parseFloat(itemData.MEASURE_RATIO) : parseInt(itemData.MEASURE_RATIO);
1780
1781				var quantity = parseFloat((currentQuantity - measureRatio).toFixed(5));
1782				quantity = this.getCorrectQuantity(itemData, quantity);
1783
1784				this.setQuantity(itemData, quantity);
1785			}
1786		},
1787
1788		quantityChange: function()
1789		{
1790			var itemData = this.getItemDataByTarget(BX.proxy_context);
1791			if (itemData)
1792			{
1793				var quantityField, quantity;
1794
1795				quantityField = BX(this.ids.quantity + itemData.ID);
1796				quantity = this.getCorrectQuantity(itemData, quantityField.value);
1797
1798				this.setQuantity(itemData, quantity);
1799			}
1800		},
1801
1802		isQuantityFloat: function(item)
1803		{
1804			return this.params.QUANTITY_FLOAT === 'Y' || (parseInt(item.MEASURE_RATIO) !== parseFloat(item.MEASURE_RATIO));
1805		},
1806
1807		getCorrectQuantity: function(itemData, quantity)
1808		{
1809			var isQuantityFloat = this.isQuantityFloat(itemData),
1810				measureRatio = isQuantityFloat ? parseFloat(itemData.MEASURE_RATIO) : parseInt(itemData.MEASURE_RATIO),
1811				availableQuantity = 0;
1812
1813			quantity = (isQuantityFloat ? parseFloat(quantity) : parseInt(quantity, 10)) || 0;
1814			if (quantity < 0)
1815			{
1816				quantity = 0;
1817			}
1818
1819			if (measureRatio > 0 && quantity < measureRatio)
1820			{
1821				quantity = measureRatio;
1822			}
1823
1824			if (itemData.CHECK_MAX_QUANTITY === 'Y')
1825			{
1826				availableQuantity = isQuantityFloat ? parseFloat(itemData.AVAILABLE_QUANTITY) : parseInt(itemData.AVAILABLE_QUANTITY);
1827				if (availableQuantity > 0 && quantity > availableQuantity)
1828				{
1829					quantity = availableQuantity;
1830				}
1831			}
1832
1833			var reminder = (quantity / measureRatio - ((quantity / measureRatio).toFixed(0))).toFixed(5),
1834				remain;
1835
1836			if (parseFloat(reminder) === 0)
1837			{
1838				return quantity;
1839			}
1840
1841			if (measureRatio !== 0 && measureRatio !== 1)
1842			{
1843				remain = (quantity * this.precisionFactor) % (measureRatio * this.precisionFactor) / this.precisionFactor;
1844
1845				if (measureRatio > 0 && remain > 0)
1846				{
1847					if (
1848						remain >= measureRatio / 2
1849						&& (
1850							availableQuantity === 0
1851							|| (quantity + measureRatio - remain) <= availableQuantity
1852						)
1853					)
1854					{
1855						quantity += (measureRatio - remain);
1856					}
1857					else
1858					{
1859						quantity -= remain;
1860					}
1861				}
1862			}
1863
1864			quantity = isQuantityFloat ? parseFloat(quantity) : parseInt(quantity, 10);
1865
1866			return quantity;
1867		},
1868
1869		setQuantity: function(itemData, quantity)
1870		{
1871			var quantityField = BX(this.ids.quantity + itemData.ID),
1872				currentQuantity;
1873
1874			if (quantityField)
1875			{
1876				quantity = parseFloat(quantity);
1877				currentQuantity = parseFloat(quantityField.getAttribute('data-value'));
1878
1879				quantityField.value = quantity;
1880
1881				if (parseFloat(itemData.QUANTITY) !== parseFloat(quantity))
1882				{
1883					this.animatePriceByQuantity(itemData, quantity);
1884					this.actionPool.changeQuantity(itemData.ID, quantity, currentQuantity);
1885				}
1886			}
1887		},
1888
1889		animatePriceByQuantity: function(itemData, quantity)
1890		{
1891			var priceNode = BX(this.ids.sumPrice + itemData.ID);
1892			if (!BX.type.isDomNode(priceNode))
1893				return;
1894
1895			var quantityMultiplier = quantity / parseFloat(itemData.MEASURE_RATIO);
1896
1897			var startPrice = parseFloat(itemData.SUM_PRICE),
1898				finalPrice = parseFloat(itemData.PRICE) * quantityMultiplier,
1899				isInt = parseInt(startPrice) === parseFloat(startPrice)
1900					&& parseInt(finalPrice) === parseFloat(finalPrice);
1901
1902			if (startPrice !== finalPrice)
1903			{
1904				this.items[itemData.ID].QUANTITY = quantity;
1905				this.items[itemData.ID].SUM_PRICE = finalPrice;
1906
1907				new BX.easing({
1908					duration: this.params.USE_PRICE_ANIMATION === 'Y' ? this.duration.priceAnimation : 1,
1909					start: {price: startPrice},
1910					finish: {price: finalPrice},
1911					transition: BX.easing.makeEaseOut(BX.easing.transitions.quad),
1912					step: BX.delegate(function(state){
1913						if (!isInt)
1914						{
1915							// fix price blinking
1916							state.price = (state.price + (state.price % 1000) / 1000).toFixed(5);
1917						}
1918
1919						priceNode.innerHTML = this.getFormatPrice(state.price, itemData.CURRENCY);
1920					}, this),
1921					complete: BX.delegate(function() {
1922						var node, price;
1923
1924						priceNode.innerHTML = this.getFormatPrice(finalPrice, itemData.CURRENCY);
1925
1926						node = BX(this.ids.sumPriceOld + itemData.ID);
1927						if (BX.type.isDomNode(node))
1928						{
1929							price = parseFloat(itemData.FULL_PRICE) * quantityMultiplier;
1930							node.innerHTML = this.getFormatPrice(price, itemData.CURRENCY);
1931						}
1932
1933						node = BX(this.ids.sumPriceDiff + itemData.ID);
1934						if (BX.type.isDomNode(node))
1935						{
1936							price = parseFloat(itemData.DISCOUNT_PRICE) * quantityMultiplier;
1937							node.innerHTML = this.getFormatPrice(price, itemData.CURRENCY);
1938						}
1939					}, this)
1940				}).animate();
1941			}
1942		},
1943
1944		getItemDataByTarget: function(target)
1945		{
1946			var data = false;
1947			var id;
1948
1949			var itemNode = BX.findParent(target, {attrs: {'data-entity': 'basket-item'}});
1950			if (itemNode)
1951			{
1952				id = itemNode.getAttribute('data-id');
1953				data = this.items[id];
1954			}
1955
1956			return data;
1957		},
1958
1959		bindSkuEvents: function(node, data)
1960		{
1961			if (!node || !data)
1962				return;
1963
1964			var blocks = this.getEntities(node, 'basket-item-sku-block');
1965			var blockEntities, i, l, ii, ll;
1966
1967			for (i = 0, l = blocks.length; i < l; i++)
1968			{
1969				blockEntities = this.getEntities(blocks[i], 'basket-item-sku-field');
1970
1971				for (ii = 0, ll = blockEntities.length; ii < ll; ii++)
1972				{
1973					BX.bind(blockEntities[ii], 'click', BX.proxy(this.changeSku, this));
1974				}
1975			}
1976		},
1977
1978		changeSku: function()
1979		{
1980			var i, l;
1981
1982			var target = BX.proxy_context;
1983
1984			if (BX.hasClass(target, 'selected'))
1985				return;
1986
1987			var itemData = this.getItemDataByTarget(target);
1988			if (itemData)
1989			{
1990				var basketItemNode = BX(this.ids.item + itemData.ID);
1991				if (basketItemNode)
1992				{
1993					var currentSkuListNodes = this.getEntities(target.parentNode, 'basket-item-sku-field');
1994					for (i = 0, l = currentSkuListNodes.length; i < l; i++)
1995					{
1996						if (currentSkuListNodes[i].isEqualNode(target))
1997						{
1998							BX.addClass(currentSkuListNodes[i], 'selected');
1999						}
2000						else
2001						{
2002							BX.removeClass(currentSkuListNodes[i], 'selected');
2003						}
2004					}
2005
2006					this.actionPool.changeSku(
2007						itemData.ID,
2008						this.getSkuPropertyValues(basketItemNode),
2009						this.getInitialSkuPropertyValues(basketItemNode)
2010					);
2011				}
2012			}
2013		},
2014
2015		getSkuPropertyValues: function(basketItemNode)
2016		{
2017			var propertyValues = {};
2018
2019			var propNodes = this.getEntities(basketItemNode, 'basket-item-sku-field', '.selected');
2020			for (var i = 0, l = propNodes.length; i < l; i++)
2021			{
2022				propertyValues[propNodes[i].getAttribute('data-property')] = BX.util.htmlspecialcharsback(propNodes[i].getAttribute('data-value-id'));
2023			}
2024
2025			return propertyValues;
2026		},
2027
2028		getInitialSkuPropertyValues: function(basketItemNode)
2029		{
2030			var propertyValues = {};
2031
2032			var propNodes = this.getEntities(basketItemNode, 'basket-item-sku-field', '[data-initial="true"]');
2033			for (var i = 0, l = propNodes.length; i < l; i++)
2034			{
2035				propertyValues[propNodes[i].getAttribute('data-property')] = BX.util.htmlspecialcharsback(propNodes[i].getAttribute('data-value-id'));
2036			}
2037
2038			return propertyValues;
2039		},
2040
2041		bindImageEvents: function(node, data)
2042		{
2043			if (!node || !data)
2044				return;
2045
2046			var images = node.querySelectorAll('.basket-item-custom-block-photo-item');
2047			for (var i = 0, l = images.length; i < l; i++)
2048			{
2049				BX.bind(images[i], 'click', BX.proxy(this.showPropertyImagePopup, this));
2050			}
2051		},
2052
2053		showPropertyImagePopup: function()
2054		{
2055			var target, propertyCode, imageIndex, item, imageSrc, i;
2056
2057			target = BX.proxy_context;
2058			item = this.getItemDataByTarget(target);
2059
2060			propertyCode = target.getAttribute('data-column-property-code');
2061			imageIndex = target.getAttribute('data-image-index');
2062
2063			if (item && item.COLUMN_LIST)
2064			{
2065				for (i in item.COLUMN_LIST)
2066				{
2067					if (
2068						item.COLUMN_LIST.hasOwnProperty(i)
2069						&& item.COLUMN_LIST[i].CODE === propertyCode
2070						&& item.COLUMN_LIST[i].VALUE[imageIndex]
2071					)
2072					{
2073						imageSrc = item.COLUMN_LIST[i].VALUE[imageIndex].IMAGE_SRC_ORIGINAL;
2074						break;
2075					}
2076				}
2077			}
2078
2079			if (!imageSrc)
2080			{
2081				return;
2082			}
2083
2084			if (this.imagePopup)
2085			{
2086				this.imagePopup.destroy();
2087			}
2088
2089			var imageId = 'bx-soa-image-popup-content';
2090			var that = this;
2091
2092			this.imagePopup = new BX.PopupWindow('bx-soa-image-popup', null, {
2093				lightShadow: true,
2094				offsetTop: 0,
2095				offsetLeft: 0,
2096				closeIcon: {top: '3px', right: '10px'},
2097				autoHide: true,
2098				bindOptions: {position: 'bottom'},
2099				closeByEsc: true,
2100				zIndex: 100,
2101				events: {
2102					onPopupShow: function() {
2103						BX.create('IMG', {
2104							props: {src: imageSrc},
2105							events: {
2106								load: function() {
2107									var content = BX(imageId);
2108									if (content)
2109									{
2110										var windowSize = BX.GetWindowInnerSize(),
2111											ratio = that.isMobile ? 0.5 : 0.9,
2112											contentHeight, contentWidth;
2113
2114										BX.cleanNode(content);
2115										content.appendChild(this);
2116
2117										contentHeight = content.offsetHeight;
2118										contentWidth = content.offsetWidth;
2119
2120										if (contentHeight >
2120 windowSize.innerHeight * ratio)
2121										{
2122											content.style.height = windowSize.innerHeight * ratio + 'px';
2123											content.style.width = contentWidth * (windowSize.innerHeight * ratio / contentHeight) + 'px';
2124											contentHeight = content.offsetHeight;
2125											contentWidth = content.offsetWidth;
2126										}
2127
2128										if (contentWidth > windowSize.innerWidth * ratio)
2129										{
2130											content.style.width = windowSize.innerWidth * ratio + 'px';
2131											content.style.height = contentHeight * (windowSize.innerWidth * ratio / contentWidth) + 'px';
2132										}
2133
2134										content.style.height = content.offsetHeight + 'px';
2135										content.style.width = content.offsetWidth + 'px';
2136
2137										that.imagePopup.adjustPosition();
2138									}
2139								}
2140							}
2141						});
2142					},
2143					onPopupClose: function() {
2144						this.destroy();
2145					}
2146				},
2147				content: BX.create('DIV', {props: {id: imageId}})
2148			});
2149			this.imagePopup.show();
2150		},
2151
2152		bindActionEvents: function(node, data)
2153		{
2154			if (!node || !data)
2155				return;
2156
2157			var entity;
2158
2159			if (BX.util.in_array('DELETE', this.params.COLUMNS_LIST))
2160			{
2161				entity = this.getEntities(node, 'basket-item-delete');
2162				for (var i = 0, l = entity.length; i < l; i++)
2163				{
2164					BX.bind(entity[i], 'click', BX.proxy(this.deleteAction, this));
2165				}
2166			}
2167
2168			if (BX.util.in_array('DELAY', this.params.COLUMNS_LIST))
2169			{
2170				entity = this.getEntity(node, 'basket-item-add-delayed');
2171				BX.bind(entity, 'click', BX.proxy(this.addDelayedAction, this));
2172			}
2173
2174			entity = this.getEntity(node, 'basket-item-remove-delayed');
2175			BX.bind(entity, 'click', BX.proxy(this.removeDelayedAction, this));
2176
2177			entity = this.getEntity(node, 'basket-item-merge-sku-link');
2178			BX.bind(entity, 'click', BX.proxy(this.mergeAction, this));
2179
2180			entity = this.getEntity(node, 'basket-item-show-similar-link');
2181			BX.bind(entity, 'click', BX.delegate(function() {this.toggleFilter('similar');}, this));
2182		},
2183
2184		deleteAction: function()
2185		{
2186			var itemData = this.getItemDataByTarget(BX.proxy_context);
2187			if (itemData)
2188			{
2189				this.actionPool.deleteItem(itemData.ID);
2190
2191				this.items[itemData.ID].SHOW_LOADING = true;
2192
2193				if (this.params.SHOW_RESTORE === 'Y' && this.isItemAvailable(itemData.ID))
2194				{
2195					this.items[itemData.ID].SHOW_RESTORE = true;
2196				}
2197
2198				this.redrawBasketItemNode(itemData.ID);
2199			}
2200		},
2201
2202		addDelayedAction: function()
2203		{
2204			var itemData = this.getItemDataByTarget(BX.proxy_context);
2205			if (itemData)
2206			{
2207				this.actionPool.addDelayed(itemData.ID);
2208
2209				this.items[itemData.ID].SHOW_LOADING = true;
2210				this.redrawBasketItemNode(itemData.ID);
2211			}
2212		},
2213
2214		removeDelayedAction: function()
2215		{
2216			var itemData = this.getItemDataByTarget(BX.proxy_context);
2217			if (itemData)
2218			{
2219				this.actionPool.removeDelayed(itemData.ID);
2220
2221				this.items[itemData.ID].SHOW_LOADING = true;
2222				this.redrawBasketItemNode(itemData.ID);
2223			}
2224		},
2225
2226		mergeAction: function()
2227		{
2228			var itemData = this.getItemDataByTarget(BX.proxy_context);
2229			if (itemData)
2230			{
2231				this.actionPool.mergeSku(itemData.ID);
2232			}
2233		},
2234
2235		bindRestoreAction: function(node, itemData)
2236		{
2237			if (!node || !itemData || this.params.SHOW_RESTORE !== 'Y')
2238				return;
2239
2240			BX.bind(
2241				this.getEntity(node, 'basket-item-restore-button'),
2242				'click',
2243				BX.delegate(function() {
2244					this.actionPool.restoreItem(itemData.ID, {
2245						PRODUCT_ID: itemData.PRODUCT_ID,
2246						QUANTITY: itemData.QUANTITY,
2247						PROPS: itemData.PROPS_ALL,
2248						SORT: itemData.SORT,
2249						MODULE: itemData.MODULE,
2250						PRODUCT_PROVIDER_CLASS: itemData.PRODUCT_PROVIDER_CLASS
2251					});
2252
2253					this.items[itemData.ID].SHOW_RESTORE = false;
2254					this.items[itemData.ID].SHOW_LOADING = true;
2255					this.redrawBasketItemNode(itemData.ID);
2256				}, this)
2257			);
2258			BX.bind(
2259				this.getEntity(node, 'basket-item-close-restore-button'),
2260				'click',
2261				BX.delegate(function() {
2262					this.deleteBasketItem(itemData.ID, false, true);
2263				}, this)
2264			);
2265		},
2266
2267		bindItemWarningEvents: function(node, data)
2268		{
2269			if (!node || !data)
2270				return;
2271
2272			BX.bind(
2273				this.getEntity(BX(this.ids.item + data.ID), 'basket-item-warning-close'),
2274				'click',
2275				BX.proxy(this.closeItemWarnings, this)
2276			);
2277		},
2278
2279		closeItemWarnings: function()
2280		{
2281			var target = BX.proxy_context;
2282
2283			if (BX.type.isDomNode(target))
2284			{
2285				var itemData = this.getItemDataByTarget(target);
2286
2287				this.items[itemData.ID].WARNINGS = [];
2288				this.warningItems.splice(BX.util.array_search(itemData.ID, this.warningItems), 1);
2289
2290				this.redrawBasketItemNode(itemData.ID);
2291				this.editWarnings();
2292			}
2293		},
2294
2295		renderBasketItem: function(template, data)
2296		{
2297			var clonedData = BX.clone(data);
2298
2299			if (BX.type.isPlainObject(clonedData))
2300			{
2301				clonedData.USE_FILTER = this.useItemsFilter
2302					&& !this.filter.currentFilter.similarHash.length;
2303			}
2304
2305			return Mustache.render(template, clonedData);
2306		},
2307
2308		render: function(template, data)
2309		{
2310			return Mustache.render(template, data);
2311		},
2312
2313		checkAnalytics: function(data)
2314		{
2315			if (!data || !data.basket)
2316				return;
2317
2318			var itemId, itemsDiff = {};
2319
2320			for (var i in data.basket)
2321			{
2322				if (data.basket.hasOwnProperty(i))
2323				{
2324					if (i.indexOf('QUANTITY_') >= 0)
2325					{
2326						itemId = i.substr(9);
2327
2328						if (this.items[itemId])
2329						{
2330							itemsDiff[itemId] = parseFloat(data.basket[i]) - parseFloat(BX(this.ids.quantity + itemId).getAttribute('data-value'));
2331						}
2332					}
2333					else if (i.indexOf('DELETE_') >= 0)
2334					{
2335						itemId = i.substr(7);
2336
2337						if (this.items[itemId])
2338						{
2339							itemsDiff[itemId] = -parseFloat(this.items[itemId].QUANTITY);
2340						}
2341					}
2342					else if (i.indexOf('RESTORE_') >= 0)
2343					{
2344						itemId = i.substr(8);
2345
2346						if (this.items[itemId])
2347						{
2348							itemsDiff[itemId] = parseFloat(this.items[itemId].QUANTITY);
2349						}
2350					}
2351				}
2352			}
2353
2354			this.setAnalyticsDataLayer(itemsDiff);
2355		},
2356
2357		setAnalyticsDataLayer: function(itemsDiff)
2358		{
2359			if (!itemsDiff || Object.keys(itemsDiff).length === 0)
2360				return;
2361
2362			window[this.params.DATA_LAYER_NAME] = window[this.params.DATA_LAYER_NAME] || [];
2363
2364			var plus = [], minus = [];
2365
2366			for (var itemId in itemsDiff)
2367			{
2368				if (itemsDiff.hasOwnProperty(itemId))
2369				{
2370					if (itemsDiff[itemId] > 0)
2371					{
2372						plus.push(this.getItemAnalyticsInfo(itemId, itemsDiff[itemId]));
2373					}
2374					else if (itemsDiff[itemId] < 0)
2375					{
2376						minus.push(this.getItemAnalyticsInfo(itemId, itemsDiff[itemId]));
2377					}
2378				}
2379			}
2380
2381			if (plus.length)
2382			{
2383				window[this.params.DATA_LAYER_NAME].push({
2384					//event: 'addToCart',
2385					ecommerce: {
2386						currencyCode: this.items[itemId].CURRENCY || '',
2387						add: {
2388							products: plus
2389						}
2390					},
2391					'event': 'gtm-ee-event',
2392					'gtm-ee-event-category': 'Enhanced Ecommerce',
2393					'gtm-ee-event-action': 'Add to Cart',
2394					'gtm-ee-event-non-interaction': 'False',
2395				});
2396			}
2397
2398			if (minus.length)
2399			{
2400				window[this.params.DATA_LAYER_NAME].push({
2401					//event: 'removeFromCart',
2402					ecommerce: {
2403						currencyCode: this.items[itemId].CURRENCY || '',
2404						remove: {
2405							products: minus
2406						}
2407					},
2408					'event': 'gtm-ee-event',
2409					'gtm-ee-event-category': 'Enhanced Ecommerce',
2410					'gtm-ee-event-action': 'Remove from Cart',
2411					'gtm-ee-event-non-interaction': 'False',
2412				});
2413			}
2414		},
2415
2416		getItemAnalyticsInfo: function(itemId, diff)
2417		{
2418			if (!this.items[itemId])
2419				return {};
2420
2421			var brand = (this.items[itemId].BRAND || '').split(',  ').join('/');
2422			var variants = [];
2423
2424			var selectedSku = this.getEntities(BX(this.ids.item + itemId), 'basket-item-sku-field', '.selected');
2425			for (var i = 0, l = selectedSku.length; i < l; i++)
2426			{
2427				variants.push(selectedSku[i].getAttribute('data-sku-name'));
2428			}
2429
2430			return {
2431				'name': this.items[itemId].NAME || '',
2432				'id': this.items[itemId].PRODUCT_ID || '',
2433				'price': this.items[itemId].PRICE || 0,
2434				'brand': brand || 'Tamga',
2435				'variant': variants.join('/') || 'N/A',
2436				'quantity': Math.abs(diff)
2437			};
2438		}
2439	};
2440})();
2441/* End */
2442;; /* /local/templates/tamga_bootstrap/components/bitrix/sale.basket.basket/new_style/js/action-pool.min.js?17065845564358*/
2443; /* /local/templates/tamga_bootstrap/components/bitrix/sale.basket.basket/new_style/js/filter.min.js?170658455610511*/
2444; /* /local/templates/tamga_bootstrap/components/bitrix/sale.basket.basket/new_style/js/component.js?173079250664552*/

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.