PageSourceSearch

https://www.casaativa.com/frontend/js/vitrine.js

js casaativa.com collected 2026-09-28 16:05:00 UTC 24,186 bytes, 682 lines download raw bytes

1$(function () {
2	const searchParams = new URLSearchParams(window.location.search);
3	const addToCartSuccess = searchParams.get('addToCartSuccess');
4
5	let pluginMessageCarregado = setInterval(function () {
6		if ($.message) {
7			if (addToCartSuccess) {
8				$.message.show('success', { vars: { title: 'Produto adicionado com sucesso!' }, idleTime: 4000 });
9			}
10			clearInterval(pluginMessageCarregado);
11		}
12	}, 1000);
13
14	//Inicia cache e define imagens padrões
15	ProductModel.init();
16
17	//Evento que controla marcação de checkboxes por produtos
18	$(document).on('click', '.product-combination-item', function (e) {
19
20		e.preventDefault();
21
22		$(this).find('.product-comb-attribute').prop('checked', true);
23
24		var value = $(this).find('.product-comb-attribute').val();
25		var prodClass = '.' + this.className.split(' ').pop();
26		var combClass = this.className.split(' ').shift();
27
28		$(this).closest('.product-combination-list').find('.product-comb-attribute[value="' + value + '"]').prop('checked', true).parent().addClass('product-combination-active');
29		$(this).closest('.product-combination-list').find('.product-comb-attribute[value!="' + value + '"]').prop('checked', false).parent().removeClass('product-combination-active');
30		$(this).closest('.wrapper-product-combination').addClass('product-combination-loading');
31
32		if ($(this).find('.product-comb-attribute').hasClass('active-combination')) {
33			active_combination($(this));
34		} else {
35			non_active_combination($(this));
36		}
37	});
38
39	$(document).on('click', '.btn-disabled', function () {
40		return false;
41	});
42
43	$(document).on('click', '.btn-buy', function (e) {
44		const element = $(this);
45		const productListItem = element.closest('.product-list-item');
46
47
48		//Caso o produto seja composto por variações e esteja em um carrousel, redireciona para o produto
49		const isCarrousel = element.closest('.bx-viewport').length > 0;
50		const isProductCoumpounded = element.closest('.product-compounded').length > 0;
51		if (isCarrousel && isProductCoumpounded) {
52			console.warn("Produtos com variações em carrousel vão direto para o produto.");
53			const hrefProduct = element.closest('.product-compounded').find(".product-link").attr('href');
54			window.location = hrefProduct;
55			return;
56		}
57
58		//Verifica se o produto tem condição de venda
59		const conditionalData = productListItem.data('conditional');
60		const conditionalProduct = conditionalData == 1;
61		if (conditionalProduct) {
62			showModalConditionalProduct(productListItem);
63			return;
64		}
65
66		addToCart($(this));
67	});
68
69	$(document).on('click', '.btn-tell-me', function (e) {
70		var element = $(this),
71			btnText = element.children('.btn-text'),
72			produto = element.closest('.product-list-item');
73		ProductModel.id = produto.data('id');
74		var comb = get_comb_by_product(produto);
75		var perguntasArray = new Array();
76		var checked = ProductModel.getChecked(comb),
77			combsCount = get_comb_by_product(produto).length;
78		var produtoId = $(this).closest('.product-list-item').data('id');
79		var produtoImg = $(this).closest('.product-list-item-inner').find('.product-image img').first().attr('src');
80		var produtoNome = $(this).closest('.product-list-item-inner').find('.product-name').children('a').html();
81		var produtoSku = $(this).closest('.product-list-item').data('sku');
82
83		var modalImg = $('.modal-product-image').children('img');
84		var modalNome = $('.modal-product-info').children('.product-name');
85		var modalSku = $('.modal-product-info').children('.product-price');
86
87		modalImg.attr('src', produtoImg);
88		modalNome.html(produtoNome);
89		modalSku.html(produtoSku);
90
91		$('#tellme-sku').val(produtoSku);
92		$('#tellme-produto-id').val(produtoId);
93
94		if (combsCount == checked.length) {
95			$.modal.show(null, 'modal-tell-me');
96		} else {
97			$.message.show('error', { vars: { title: 'Você precisa selecionar todas as combinações.' }, idleTime: 4000 });
98		}
99	});
100
101	$(document).on('click', '.btn-budget', function () {
102		var form = $('#form-budget'),
103			produtoInner = $(this).closest('.product-list-item-inner'),
104			produtoId = $(this).closest('.product-list-item').data('id'),
105			produtoEstoque = $(this).closest('.product-list-item').data('sku'),
106			modalImg = $('.modal-product-image').children('img'),
107			modalNome = $('.modal-product-info').children('.product-name'),
108			produtoImg = produtoInner.find('.product-image').children('a').children('img').attr('src'),
109			produtoNome = produtoInner.find('.product-name').children('a').html();
110
111		form.find('#CotacaoProdutoId').val(produtoId);
112		form.find('#CotacaoEstoqueId').val(produtoEstoque);
113		modalImg.attr('src', produtoImg);
114		modalNome.html(produtoNome);
115
116		$.modal.show(null, 'modal-budget');
117	});
118
119	$(document).on('click', '#budget-btn', function () {
120		var valid = $('#form-budget').valid();
121		if (valid) {
122
123			var reCaptcha = $('#g-recaptcha-response').val();
124			if (reCaptcha.length > 0) {
125
126				var cotacao = {};
127				var route = WsRouter.generateRoute(null, 'produto', 'cotacaoProduto', null);
128
129				cotacao = {
130					clienteNome: $('#CotacaoNome').val(),
131					clienteEmail: $('#CotacaoEmail').val(),
132					clienteTelefone: $('#CotacaoTelefone').val(),
133					clienteObservacao: $('#CotacaoObservacao').val(),
134					clienteLogradouro: $('#CotacaoLogradouro').val(),
135					clienteNumero: $('#CotacaoNumero').val(),
136					clienteComplemento: $('#CotacaoComplemento').val(),
137					clienteBairro: $('#CotacaoBairro').val(),
138					clienteCidade: $('#CotacaoCidade').val(),
139					clienteEstado: $('#CotacaoEstado').val(),
140					clienteCep: $('#CotacaoCep').val(),
141					produtoId: $('#CotacaoProdutoId').val(),
142					produtoEstoqueId: $('#CotacaoEstoqueId').val(),
143					quantidade: $('#CotacaoQuantidade').val(),
144					recaptcha_response: reCaptcha
145				};
146
147				WsDispatcher.postRequest(route, { 'VendaCotacao': JSON.stringify(cotacao) }, null, function (data) {
148					if (data.status == 1) {
149						$.modal.hide('fadeInUp', 'modal-budget');
150						$.message.show('success', { vars: { title: data.message }, idleTime: 4000 });
151					} else {
152						$.message.show('error', { vars: { title: data.message }, idleTime: 4000 });
153					}
154				});
155
156			} else {
157				var error = '<label id="g-recaptcha-response-error" class="error" for="g-recaptcha-response">Você precisa completar o Captcha de segurança.</label>';
158				$('#g-recaptcha-response-error').remove();
159				$('#div-captcha-budget').append(error);
160			}
161		}
162	});
163
164	function get_comb_by_product(prod) {
165		return prod.children('.product-list-item-inner').children('.wrapper-product-combination').find('.product-combination-list');
166	}
167
168	function show_product_add_message() {
169		$.message.show('product-add');
170	};
171
172	function active_combination(self, label_comprar) {
173
174		// Botão Buy ou Tellme
175		var btn = self.closest('.product-list-item').find('.wrapper-btn-product');
176
177		//Recolhe os dados necessários para as operações no Model do produto
178		var prod = self.closest('.product-list-item');
179		var divImg = self.closest('.product-list-item-inner').find('.product-image');
180
181		//Define o estado do model (produto em questão)
182		ProductModel.id = prod.data('id');
183
184		//Busca atributos selecionados
185		var attributes = ProductModel.getChecked(get_comb_by_product(prod));
186
187		if (self.find('.product-comb-attribute').prop('checked')) {
188
189			//Busca dados do web service
190			ProductModel.find(attributes,
191				function () {
192					//Before Send
193				},
194				//Success
195				function (data) {
196
197					update_unavailable_product(self, 0, divImg);
198					var img = divImg.children('a');
199
200					if (data.id !== null) {
201
202						update_product_original_price(self, data);
203						update_tag_progressive_discount(self, data);
204						update_product_price(self, data['valor_venda_unitario']);
205						update_product_parcelled(self, data['parcelas'], data['valor_parcelado']);
206						update_price_off(self, data['desconto_avista'], data['valor_avista']);
207
208						update_combinations(self, data['combinacoes']);
209						update_tellme_price(self, null, 0);
210						update_button_tellme(btn, self, 0, data);
211
212						$(data['img']).css('opacity', 1);
213
214						if (data['disponivel'] !== true) {
215							update_unavailable_product(self, 1, divImg);
216							update_tellme_price(self, data, 1);
217							update_button_tellme(btn, self, 1, data);
218							$(data['img']).css('opacity', 0.5);
219						}
220
221						$(data['img']).fadeIn(500);
222						img.children('img').remove();
223						img.append(data['img']);
224
225						if (data['imgsec'] != false) {
226							img.children('img:first-child').addClass('image-main');
227
228							var imgsec = document.createElement('img');
229							imgsec.src = base_url_image + '/sku/thumb_' + data['imgsec'];
230							imgsec.style.cssText = 'display:none;';
231							imgsec.setAttribute("class", "image-over");
232							img.append(imgsec);
233						}
234
235					} else {
236						update_unavailable_product(self, 1, divImg);
237						update_tellme_price(self, data, 1);
238						update_button_tellme(btn, self, 1, data);
239					}
240				}
241			);
242		}
243	}
244
245	function non_active_combination(self, label_comprar) {
246
247		var btn = self.closest('.product-list-item').find('.wrapper-btn-product');
248
249		//Recolhe os dados necessários para as operações no Model do produto
250		var prod = self.closest('.product-list-item'),
251			divImg = $(prod).find('.product-image'),
252			img = divImg.children('a').children('img');
253
254		ProductModel.id = prod.data('id');
255
256		//Busca atributos selecionados
257		var attributes = ProductModel.getChecked(get_comb_by_product(prod));
258
259		if (self.find('.product-comb-attribute').prop('checked')) {
260
261			//Busca dados do web service
262			ProductModel.find(
263				attributes,
264				null,
265				//Success
266				function (data) {
267
268					update_unavailable_product(self, 0, divImg);
269
270					if (data.id !== null) {
271
272						update_product_original_price(self, data);
273						update_tag_progressive_discount(self, data);
274						update_product_price(self, data['valor_venda_unitario']);
275						update_product_parcelled(self, data['parcelas'], data['valor_parcelado']);
276						update_price_off(self, data['desconto_avista'], data['valor_avista']);
277
278						update_combinations(self, data['combinacoes']);
279						update_unavailable_product(self, 0, divImg);
280						update_tellme_price(self, null, 0);
281						update_button_tellme(btn, self, 0, data);
282
283						if (data['disponivel'] !== true) {
284							update_unavailable_product(self, 1, divImg);
285							update_tellme_price(self, data, 1);
286							update_button_tellme(btn, self, 1, data);
287							$(data['img']).css('opacity', 0.5);
288						}
289
290					} else {
291						update_unavailable_product(self, 1, divImg);
292						update_tellme_price(self, data, 1);
293						update_button_tellme(btn, self, 1, data);
294						$(prod).addClass('comb-unavailable');
295					}
296				}
297			);
298		}
299	}
300
301	function update_product_original_price(self, product) {
302
303		var wrapper = self.closest('.product-list-item-inner'),
304			oldPrice = wrapper.find('.product-old-price'),
305			labelPromo = self.closest('.product-list-item-inner').find('.label-promo');
306
307		if (product['promocao'] && product['valor_original'] !== null) {
308			oldPrice.show();
309			labelPromo.html(product['percentual_promocao']);
310			labelPromo.show();
311			oldPrice.removeClass('product-price');
312			oldPrice.children('span:nth-child(1)').html('de ');
313			oldPrice.children('span:nth-child(2)').html(accounting.formatMoney(product['valor_original']));
314			oldPrice.children('span:nth-child(2)').attr('class', 'product-strikethrough-price');
315		} else {
316			oldPrice.find('span').html('');
317			labelPromo.hide();
318			oldPrice.hide();
319		}
320	}
321
322	function update_product_price(self, valor_venda) {
323
324
325		var wrapper = self.closest('.product-list-item-inner');
326		var price = wrapper.find('.product-sell-price');
327
328		price.children('span:nth-child(1)').html('Por ');
329		price.children('span:nth-child(2)').html('');
330		price.children('span:nth-child(2)').html(accounting.formatMoney(valor_venda));
331		price.children('span:nth-child(2)').attr('class', 'product-big-price');
332	}
333
334	function update_product_parcelled(self, parcelas, valor_parcelado) {
335
336		var wrapper = self.closest('.product-list-item-inner');
337		var parcelled = wrapper.find('.product-parcelled-price');
338
339		parcelled.children('.product-number-parcels').html('');
340		parcelled.children('.product-number-parcels').html(parcelas + 'x');
341		parcelled.children('.product-big-price').html('');
342		parcelled.children('.product-big-price').html(accounting.formatMoney(valor_parcelado));
343	}
344
345	function update_price_off(self, desconto, valor_avista) {
346		if (desconto > 0) {
347
348			var wrapper = self.closest('.product-list-item-inner');
349			var cash = wrapper.find('.product-cash-price');
350
351			cash.children('.product-big-price').html('');
352			cash.children('.product-big-price').html(accounting.formatMoney(valor_avista));
353
354			cash.children('.product-price-off').html('');
355			cash.children('.product-price-off').html(desconto + '%');
356		}
357	}
358
359	function update_combinations(self, combinacoes) {
360
361		var wrapper = $(self).closest('.wrapper-product-combination');
362		wrapper.html('');
363
364		var html_combinacoes = '';
365
366		$.each(combinacoes, function (idx, combinacao) {
367
368			html_combinacoes +=
369				'<span class="product-combination-title">' + combinacao.label + '</span>' +
370				'<ul class="product-combination-list">';
371
372			$.each(combinacao.CombinacaoAtributo, function (idx2, atributo) {
373
374				var disponivel = ((atributo.disponivel == true) ? '' : ' product-combination-unavailable'),
375					selecionado = ((atributo.selecionado == true) ? ' product-combination-active' : ''),
376					atributo_ativo = ((combinacao.mostra_vitrine == true) ? ' active-combination' : ''),
377					selected = ((atributo.selecionado == true) ? ' checked="checked" ' : ''),
378					atributo_tipo = __update_combinations_type(atributo);
379
380				html_combinacoes +=
381					'<li class="product-combination-item' + disponivel + selecionado + ' ' + combinacao.classes_adicionais + '">' +
382					'<label for="CatalogoCombinacaoAtributoId' + combinacao.produto_id + combinacao.id + atributo.id + '" title="' + atributo.nome + '">' +
383					atributo_tipo +
384					'</label>' +
385					((atributo.disponivel == true) ? '' : '<span class="label-product-combination-unavailable">x</span>') +
386					'<input type="hidden" name="data[CatalogoCombinacaoAtributo][id][' + combinacao.produto_id + '][' + combinacao.id + '][' + atributo.id + ']" id="CatalogoCombinacaoAtributoId' + combinacao.produto_id + combinacao.id + atributo.id + '_" value="0">' +
387					'<input type="checkbox" name="data[CatalogoCombinacaoAtributo][id][' + combinacao.produto_id + '][' + combinacao.id + '][' + atributo.id + ']" value="' + atributo.id + '"' + selected + 'class="comb-' + combinacao.id + ' product-comb-attribute' + atributo_ativo + ' prod-' + combinacao.produto_id + '" data-order="' + combinacao.ordem + '" id="CatalogoCombinacaoAtributoId' + combinacao.produto_id + combinacao.id + atributo.id + '">' +
388					'</li>';
389
390			});
391
392			html_combinacoes +=
393				'</ul>';
394
395		});
396
397		wrapper.html(html_combinacoes);
398		wrapper.removeClass('product-combination-loading');
399	}
400
401	function update_tag_progressive_discount(self, product) {
402		var wrapper = self.closest('.product-list-item-inner');
403		if (product['progressive_discount_message'] == "") {
404			wrapper.find('.product-tag-progressiveDiscount').addClass('tag-hidden');
405		} else {
406			wrapper.find('.product-tag-progressiveDiscount').removeClass('tag-hidden');
407		}
408	}
409
410	function update_button_tellme(btn, self, opt, data) {
411		if (opt == 1) {
412			var btn_html =
413				'<div class="wrapper-btn-buy">' +
414				'<a href="javascript:;" class="btn btn-tell-me">' +
415				'<span class="icon-buy icon-tell-me btn-icon"></span>' +
416				'<span class="btn-text">' + data['msg_aviseme'] + '</span>' +
417				'</a>' +
418				'</div>';
419		} else if (opt == 0) {
420			var btn_html =
421				'<div class="wrapper-btn-buy">' +
422				'<a href="javascript:;" class="btn btn-buy">' +
423				'<span class="icon-buy btn-icon"></span>' +
424				'<span class="btn-text">' + data['label_comprar'] + '</span>' +
425				'</a>' +
426				'</div>';
427		}
428
429		btn.html(btn_html);
430	}
431
432	function update_tellme_price(self, data, opt) {
433		if (opt == 1) {
434			if (data['exibe_preco_aviseme'] == '0')
435				__clear_price(self);
436
437			var modalSku = $('.modal-product-info').children('.product-price');
438			modalSku.html(data['sku']);
439			$('#tellme-sku').val(data['id']);
440			self.closest('.product-list-item').attr('data-sku', $('#tellme-sku').val());
441
442		} else if (opt == 0) {
443			var price_info = $(self).closest('.product-list-item-inner').children('.product-info');
444			price_info.find('p').show();
445			price_info.find('.product-sku').hide();
446		}
447	}
448
449	function update_available_product(self) {
450		var inner_div = $(self).parent().parent().parent().parent();
451	}
452
453	function update_unavailable_product(self, opt, divImg) {
454		var link = divImg.children('a').attr('href');
455		var html_unavailable = '<a class="label-product label-unavailable" href="' + link + '">Produto Indisponível</a>';
456
457		if (opt == 1) {
458			divImg.find('.label-unavailable').remove();
459			$(divImg).append(html_unavailable);
460		} else if (opt == 0) {
461			divImg.find('.label-unavailable').remove();
462		}
463	}
464
465	function uncheckedatrributesLabels(self) {
466		var labelMessage = new Array();
467		var label = '';
468
469		self.closest('.product-list-item').find('.product-combination-list').each(function () {
470			label = $(this).prev().text();
471			labelMessage[labelMessage.length] = label;
472		});
473
474		return labelMessage;
475	}
476
477	function __clear_price(self) {
478		var price_info = $(self).closest('.product-list-item-inner').children('.product-info');
479		price_info.find('p').hide();
480		price_info.find('.product-name').show();
481	}
482
483	function __update_combinations_type(atributo) {
484		var atributo_tipo = '';
485
486		if (atributo.tipo_capa == 'imagem') {
487			atributo_tipo = '<div class="combination-image"><img src="' + base_url_image + '/combinacao_atributo/thumb_' + atributo.name + '" alt=""></div>';
488		} else if (atributo.tipo_capa == 'cor') {
489			atributo_tipo = '<div style="background-color:#' + atributo.cor_primaria.replace('#', '') + '" >';
490
491			if (atributo.cor_secundaria != null && atributo.cor_secundaria != '')
492				atributo_tipo += '<span style="border-color:#' + atributo.cor_secundaria.replace('#', '') + '"></span>';
493
494			atributo_tipo += '</div>';
495		} else {
496			atributo_tipo = '<div>' + atributo.nome + '</div>';
497		}
498
499		return atributo_tipo;
500	}
501
502	function showModalConditionalProduct(product) {
503		const preSaleDateShipping = $(product).data('pre-sale-shipping');
504		const preSaleDateFormat = (new Date(preSaleDateShipping)).toLocaleDateString('pt-br', { month: 'numeric', day: 'numeric' });
505		const productName = $(product).find('.product-name').text();
506		const modal = $('#modal-conditions-add');
507		const modalElements = {
508			title: $('#modal-conditions-add .modal-header-title'),
509			conditionTitle: $('#modal-conditions-add .condition-title'),
510			conditionDesc: $('#modal-conditions-add .condition-description'),
511		};
512		const btnAddToCart = modal.find('.msg-link-cart');
513		const btnContinueBuy = modal.find('.msg-link-close');
514
515		let conditionCheckbox = modal.find('#condition-accept');
516		let conditionalTitle = $(product).data('conditional-title');
517		let conditionalDesc = $(product).data('conditional-desc');
518
519		modalElements.title.text('Comprar ' + productName);
520		modalElements.conditionTitle.html(conditionalTitle);
521		modalElements.conditionDesc.html(conditionalDesc);
522
523		if (preSaleDateShipping) {
524			let conditionalTitleReplaced = conditionalTitle.replace('%prazo_envio%', `${preSaleDateFormat}`);
525			let conditionalDescReplaced = conditionalDesc.replace('%prazo_envio%', `${preSaleDateFormat}`);
526
527			modalElements.conditionTitle.html(conditionalTitleReplaced);
528			modalElements.conditionDesc.html(conditionalDescReplaced);
529		}
530
531		conditionCheckbox.prop('checked', false);
532		$.modal.show('fadeInDown', 'modal-conditions-add');
533
534		conditionCheckbox.on('change', function () {
535			if ($(this).is(':checked')) {
536				modal.find('.msg-link-cart').attr('disabled', false);
537				modal.find('.msg-link-close').attr('disabled', false);
538				return;
539			}
540
541			modal.find('.msg-link-cart').attr('disabled', true);
542			modal.find('.msg-link-close').attr('disabled', true);
543		});
544
545		conditionCheckbox.trigger('change');
546
547		btnAddToCart.click(function () {
548			addToCart(product, 'goToCheckout');
549		});
550
551		btnContinueBuy.click(function () {
552			addToCart(product, 'continueShopping');
553		});
554	}
555
556	function addToCart(product, action) {
557		var element = product,
558			btnText = element.children('.btn-text'),
559			produto = element.closest('.product-list-item');
560		ProductModel.id = produto.data('id');
561
562		const conditionalData = produto.data('conditional');
563		const conditionalProduct = conditionalData == 1;
564
565		let btnContinueBuyData = produto.data('btn-continue-buy');
566
567		var comb = get_comb_by_product(produto);
568		var perguntasArray = new Array();
569		var checked = ProductModel.getChecked(comb),
570			combsCount = get_comb_by_product(produto).length;
571
572		if (combsCount == checked.length) {
573			var self = this;
574
575			// Previne clique duplo (soh libera o botao depois de executar o ajax)
576			if (!element.hasClass('btn-disabled')) {
577
578				element.addClass('btn-disabled');
579				btnText.addClass('loading-button');
580				$('.loading-page').show();
581
582				ProductModel.cartCreateProduct(checked, perguntasArray,
583					function () {
584						//beforeSave
585					},
586					function (cart) {
587						if (!cart['alerta_quantidade']) {
588							var el = $('.shopping-cart-total-price'),
589								img = produto.find('.product-image img:eq(0)');
590
591							if (cart.acao_comprar == '3' || cart.acao_comprar == '4' || action == 'goToCheckout') {
592								var uri = base_url + 'carrinho';
593								$(location).attr("href", uri);
594							} else {
595								if (action == 'continueShopping' && btnContinueBuyData == '1') {
596									const urlContinueBuy = base_url + '?addToCartSuccess=1';
597									$(location).attr("href", urlContinueBuy);
598									return;
599								}
600
601								$('.loading-page').hide();
602								btnText.removeClass('loading-button');
603								if (conditionalProduct) {
604									$.modal.hide('fadeOutUp', 'modal-conditions-add');
605									$.message.show('success', { vars: { title: 'Produto adicionado com sucesso!' }, idleTime: 4000 });
606								} else {
607									$.message.show(cart.continuar_comprando);
608								}
609							}
610
611							App.refreshCartIcon(cart);
612							App.addProductIcon(cart, img);
613
614						} else if (cart['alerta_quantidade'] == true) {
615
616							$('.loading-page').hide();
617							btnText.removeClass('loading-button');
618							$.message.show('error', { vars: { title: 'Produto indisponível' }, idleTime: 4000 });
619
620						} else {
621
622							$('.loading-page').hide();
623							btnText.removeClass('loading-button');
624							$.message.show('error', { vars: { title: cart['alerta_quantidade'].replace(".", ",") }, idleTime: 4000 });
625						}
626
627						setTimeout(function () {
628							element.removeClass('btn-disabled');
629						}, 1100);
630					}
631				);
632			}
633
634		} else {
635			var labelMessage = uncheckedatrributesLabels(element);
636			$.message.show('error', { vars: { title: 'Você precisa selecionar as combinações:<br/>' + labelMessage.join(", ") }, idleTime: 4000 });
637		}
638	}
639});
640
641let executedTellMeShop = false;
642
643function submitTellMeShop(token) {
644	const siteKey = $('#tellme-btn').data('site-key');
645	const loading = $('#modal-tell-me').find('.modal-loading');
646
647	if (!executedTellMeShop) {
648		executedTellMeShop = true;
649
650		loading.show();
651
652		grecaptcha.enterprise.ready(function () {
653			grecaptcha.enterprise.execute(siteKey, { action: 'submit' }).then(function (tokenRecaptcha) {
654				$.ajax({
655					url: base_url + 'produto/aviseme/add2',
656					data: {
657						'nome': $('#tellme-nome').val(),
658						'email': $('#tellme-email').val(),
659						'produto_id': $('#tellme-produto-id').val(),
660						'produto_estoque_id': $('#tellme-sku').val(),
661						'g-recaptcha-response': tokenRecaptcha,
662					},
663					dataType: 'json',
664					type: 'POST',
665					success: function (data) {
666						$('#tellme-btn').find('.btn-text').removeClass('loading-button');
667						if (data['id'] == -1) {
668							$.message.show('error', { vars: { title: data['mensagem'] }, idleTime: 3500 });
669						} else {
670							$('.modal-mask').hide();
671							$('.modal').hide();
672							$.message.show('success', { vars: { title: 'Aviso cadastrado com sucesso!', idleTime: 3500 } });
673						}
674
675						loading.hide();
676						executedTellMeShop = false;
677					}
678				});
679			});
680		});
681	}
682}

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.