PageSourceSearch

https://inesbe.com/wp-content/plugins/customer-reviews-woocommerce/js/frontend.js?ver=5.119.0

js inesbe.com collected 2026-10-05 00:59:26 UTC 95,487 bytes, 1,994 lines download raw bytes

1(function() {
2	jQuery(document).ready(function($) {
3		// initial resize of [cusrev_reviews_grid] and Trust Badges
4		crResizeAllGridItems();
5		crResizeTrustBadges();
6		//enable attachment of images to comments
7		jQuery("form#commentform").attr( "enctype", "multipart/form-data" ).attr( "encoding", "multipart/form-data" );
8		//prevent review submission if captcha is not solved
9		jQuery("#commentform").on( "submit", function(event) {
10			if( ! crCaptchaEnabled() ) {
11				return;
12			}
13			const commentForm = jQuery( this );
14			if( crCaptcha.isInvisible() ) {
15				if( commentForm.data( "crCaptchaToken" ) ) {
16					commentForm.data( "crCaptchaToken", false );
17					return;
18				}
19				event.preventDefault();
20				crCaptcha.execute( commentForm, function( token ) {
21					if( ! token ) {
22						alert( crCaptcha.errorText() );
23						return;
24					}
25					commentForm.data( "crCaptchaToken", true );
26					const submitButton = commentForm.find( "[type='submit']" ).first();
27					if( submitButton.length ) {
28						submitButton[0].click();
29					} else {
30						HTMLFormElement.prototype.submit.call( commentForm[0] );
31					}
32				} );
33			} else if( "" === crCaptcha.getResponse( commentForm ) ) {
34				event.preventDefault();
35				alert( crCaptcha.errorText() );
36			}
37		} );
38		//show lightbox when click on images attached to reviews
39		jQuery("ol.commentlist").on("click", ".cr-comment-a", function(t) {
40			if(cr_ajax_object.disable_lightbox === '0') {
41				//only if lightbox is not disabled in settings of the plugin
42				t.preventDefault();
43				const oo = jQuery(".pswp");
44				if ( 0 < oo.length ) {
45					const o = oo[0];
46					var pics = jQuery(this).parent().parent().find(".cr-comment-a img");
47					var this_pic = jQuery(this).find("img");
48					var inx = 0;
49					if (pics.length > 0 && this_pic.length > 0) {
50						var a = [];
51						for (i = 0; i < pics.length; i++) {
52							a.push({
53								src: pics[i].src,
54								w: pics[i].naturalWidth,
55								h: pics[i].naturalHeight,
56								title: pics[i].alt
57							});
58							if (this_pic[0].src == pics[i].src) {
59								inx = i;
60							}
61						}
62						var r = {
63							index: inx
64						};
65						new PhotoSwipe(o, PhotoSwipeUI_Default, a, r).init();
66					}
67				}
68			}
69		});
70		// play a video when a user clicks on it in the reviews grid
71		jQuery(".cr-reviews-grid").on("click", ".image-row-vid, .cr-comment-videoicon", function(t) {
72			if( ! jQuery(this).closest(".image-row").hasClass( "cr-vid-playing" ) ) {
73				jQuery(this).closest(".image-row").addClass( "cr-vid-playing" );
74				jQuery(this).closest(".image-row").find(".image-row-vid").prop( "controls", true );
75				jQuery(this).closest(".image-row").find(".image-row-vid").get(0).play();
76			} else {
77				jQuery(this).closest(".image-row").find(".image-row-vid").get(0).pause();
78				jQuery(this).closest(".image-row").find(".image-row-vid").prop( "controls", false );
79				jQuery(this).closest(".image-row").removeClass( "cr-vid-playing" );
80			}
81			return false;
82		} );
83		// play a video when a user clicks on it in the media pop-up window
84		jQuery(".cr-ajax-reviews-cus-images-modal").on("click", ".cr-ajax-reviews-video, .cr-ajax-reviews-video .cr-comment-videoicon", function(t) {
85			if( ! jQuery(this).closest(".cr-ajax-reviews-video").hasClass( "cr-vid-playing" ) ) {
86				jQuery(this).closest(".cr-ajax-reviews-video").addClass( "cr-vid-playing" );
87				jQuery(this).closest(".cr-ajax-reviews-video").find("video").prop( "controls", true );
88				jQuery(this).closest(".cr-ajax-reviews-video").find("video").get(0).play();
89			} else {
90				jQuery(this).closest(".cr-ajax-reviews-video").find("video").get(0).pause();
91				jQuery(this).closest(".cr-ajax-reviews-video").find("video").prop( "controls", false );
92				jQuery(this).closest(".cr-ajax-reviews-video").removeClass( "cr-vid-playing" );
93			}
94			return false;
95		} );
96		// open a gallery with media files in the reviews grid
97		jQuery(".cr-reviews-grid").on("click", ".media-row-count", function(t) {
98			if ( cr_ajax_object.disable_lightbox === '0' ) {
99				// only if lightbox is not disabled in settings of the plugin
100				t.preventDefault();
101				const oo = jQuery(".pswp");
102				let media = jQuery(this).parent().find(".image-row-vid,.image-row-img"),
103					this_media = jQuery(this),
104					inx = 0;
105				if (media.length > 0 && this_media.length > 0) {
106					const o = oo[0];
107					var a = [];
108					for (i = 0; i < media.length; i++) {
109						if ( "vid" === media[i].dataset.crmedia ) {
110							a.push({
111								html: '<div class="cr-video-wrapper"><video class="cr-media-video" src="' + media[i].src + '" controls></video></div>',
112								title: media[i].dataset.crtitle
113							});
114						} else {
115							a.push({
116								src: media[i].src,
117								w: media[i].naturalWidth,
118								h: media[i].naturalHeight,
119								title: media[i].alt
120							});
121						}
122						if (this_media[0].src == media[i].src) {
123							inx = i;
124						}
125					}
126					var r = {
127						index: inx
128					};
129					new PhotoSwipe(o, PhotoSwipeUI_Default, a, r).init();
130				}
131			}
132		} );
133		// play or pause a video in the gallery
134		jQuery(document).on("click", ".cr-video-wrapper .cr-media-video", function(t) {
135			const vid = jQuery(this).get(0);
136			if ( vid ) {
137				const isVideoPlaying = !!( vid.currentTime > 0 && !vid.paused && !vid.ended && vid.readyState > 2 );
138				if ( isVideoPlaying ) {
139					vid.pause();
140				} else {
141					vid.play();
142				}
143			}
144			return false;
145		} );
146		// show a lightbox when a user clicks on images in the reviews grid
147		jQuery(".cr-reviews-grid").on("click", ".image-row-img, .image-row-count", function(t) {
148			if(cr_ajax_object.disable_lightbox === '0') {
149				// only if lightbox is not disabled in settings of the plugin
150				t.preventDefault();
151				const oo = jQuery(".pswp");
152				if ( 0 < oo.length ) {
153					const o = oo[0];
154					var pics = jQuery(this).parent().find("img.image-row-img");
155					var this_pic = jQuery(this);
156					var inx = 0;
157					if (pics.length > 0 && this_pic.length > 0) {
158						var a = [];
159						for (i = 0; i < pics.length; i++) {
160							a.push({
161								src: pics[i].src,
162								w: pics[i].naturalWidth,
163								h: pics[i].naturalHeight,
164								title: pics[i].alt
165							});
166							if (this_pic[0].src == pics[i].src) {
167								inx = i;
168							}
169						}
170						var r = {
171							index: inx
172						};
173						new PhotoSwipe(o, PhotoSwipeUI_Default, a, r).init();
174					}
175				}
176			}
177		});
178		//register a listener for votes on for reviews
179		initVoteClick("ol.commentlist", ".cr-voting-a", "cr_vote_review");
180		//register a listener for the voting buttons on modal
181		initVoteClick(".cr-ajax-reviews-cus-images-modal", ".cr-voting-a", "cr_vote_review");
182		//register a listener for the voting buttons on Q & A
183		initVoteClick(".cr-qna-block .cr-qna-list-block", ".cr-voting-a", "cr_vote_question");
184
185		//show a lightbox when click on videos attached to reviews
186		jQuery("ol.commentlist").on("click", ".cr-video-a, .cr-comment-videoicon", function(t) {
187			if( ! jQuery(this).closest(".cr-comment-videos").hasClass( "cr-comment-videos-modal" ) ) {
188				let tt = jQuery(this).closest("[class*='cr-comment-video-']");
189				jQuery(this).closest(".cr-comment-videos").addClass( "cr-comment-videos-modal" );
190				tt.addClass( "cr-comment-video-modal" );
191				tt.find( "video" ).prop( "controls", true );
192				tt.find( ".cr-comment-videoicon" ).hide();
193				tt.find( "video" ).get(0).play();
194				return false;
195			}
196			return false;
197		} );
198		//close a video lightbox
199		jQuery("ol.commentlist").on( "click", ".cr-comment-videos", function(t) {
200			if( jQuery(this).hasClass( "cr-comment-videos-modal" ) ) {
201				jQuery(this).removeClass( "cr-comment-videos-modal" );
202				jQuery(this).find("[class*='cr-comment-video-']").each(function(index, element){
203					if( jQuery(element).hasClass( "cr-comment-video-modal" ) ) {
204						jQuery(element).removeClass( "cr-comment-video-modal" );
205						jQuery(element).find( "video").get(0).pause();
206						jQuery(element).find( "video" ).prop( "controls", false );
207						jQuery(element).find( ".cr-comment-videoicon" ).show();
208						jQuery(element).removeAttr("style");
209					}
210				});
211				return false;
212			}
213		} );
214		//show more ajax reviews
215		jQuery(".cr-show-more-reviews-prd").on( "click", function(t) {
216			t.preventDefault();
217			crShowMoreReviewsPrd( jQuery(this) );
218		} );
219
220		// ajax sorting of reviews
221		jQuery(".cr-ajax-reviews-sort").on( "change", function(t) {
222			t.preventDefault();
223
224			if ( jQuery(this).parents(".cr-all-reviews-shortcode").length ) {
225				// sorting in the all reviews block
226				cr_filter_all_reviews( jQuery(this) );
227			} else {
228				// sorting on a product page
229				var cr_product_id = jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").attr("data-product");
230				var cr_sort = jQuery(this).children("option:selected").val();
231				var cr_rating = jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax .ivole-histogramRow.ivole-histogramRow-s .cr-histogram-a").attr("data-rating");
232				if(!cr_rating){
233					cr_rating = 0;
234				}
235				var cr_data = {
236					"action": "cr_sort_reviews",
237					"productID": cr_product_id,
238					"sort": cr_sort,
239					"rating": cr_rating
240				};
241				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-search-no-reviews").hide();
242				jQuery(this).parents(".cr-reviews-ajax-comments").find('.cr-ajax-search input').val("").trigger("change");
243				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").hide();
244				jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").hide();
245				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-review-spinner").show();
246				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax").addClass("cr-summaryBar-updating");
247				jQuery(this).addClass("cr-sort-updating");
248				jQuery.post( {
249					url: cr_ajax_object.ajax_url,
250					data: cr_data,
251					context: this,
252					success: function(response) {
253						jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-review-spinner").hide();
254						jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax").removeClass("cr-summaryBar-updating");
255						jQuery(this).removeClass("cr-sort-updating");
256						if(response.page > 0){
257							jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").empty();
258							jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").append(response.html);
259							jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").show();
260							jQuery(this).parents(".cr-reviews-ajax-comments").attr("data-page",response.page);
261							if( response.show_more_label ) {
262								jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").text( response.show_more_label );
263							}
264							if ( response.count_row ) {
265								jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-count-row .cr-count-row-count").html( response.count_row );
266							}
267							if(!response.last_page){
268								jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").show();
269							}
270						}
271					},
272					dataType: "json"
273				} );
274			}
275		} );
276		// non-ajax filtering of reviews
277		jQuery(".cr-noAjax").on( "click", ".cr-histogram-a", function (t) {
278			t.preventDefault();
279			const parser = new URL(window.location);
280			parser.searchParams.set(cr_ajax_object.rating_filter, jQuery(this).data("rating"));
281			parser.hash = cr_ajax_object.reviews_tab;
282			window.location = parser.href;
283		} );
284		// ajax filtering of reviews
285		jQuery(".cr-reviews-ajax-comments").on("click", ".cr-histogram-a, .cr-seeAllReviews", function(t){
286			t.preventDefault();
287			let tmpParent = jQuery(this).parents(".cr-reviews-ajax-comments");
288			let cr_product_id = tmpParent.find(".commentlist.cr-ajax-reviews-list").attr("data-product");
289			let cr_nonce = tmpParent.find(".cr-summaryBox-ajax").attr("data-nonce");
290			let cr_rating = jQuery(this).attr("data-rating");
291			let cr_sort = tmpParent.find(".cr-ajax-reviews-sort").children("option:selected").val();
292			let cr_data = {
293				"action": "cr_filter_reviews",
294				"productID": cr_product_id,
295				"rating": cr_rating,
296				"sort": cr_sort,
297				"security": cr_nonce
298			};
299			tmpParent.find(".cr-summaryBox-ajax .ivole-histogramRow.ivole-histogramRow-s").removeClass("ivole-histogramRow-s");
300			if( cr_rating > 0 ) {
301				jQuery(this).closest(".ivole-histogramRow").addClass("ivole-histogramRow-s");
302			}
303			tmpParent.find(".cr-search-no-reviews").hide();
304			tmpParent.find('.cr-ajax-search input').val("").trigger("change");
305			tmpParent.find(".cr-show-more-reviews-prd").hide();
306			tmpParent.find(".commentlist.cr-ajax-reviews-list").hide();
307			tmpParent.find(".cr-show-more-review-spinner").show();
308			tmpParent.find(".cr-summaryBox-ajax").addClass("cr-summaryBar-updating");
309			tmpParent.find(".cr-ajax-reviews-sort").addClass("cr-sort-updating");
310			jQuery.post( {
311				url: cr_ajax_object.ajax_url,
312				data: cr_data,
313				context: tmpParent,
314				success: function(response) {
315					this.find(".cr-show-more-review-spinner").hide();
316					this.find(".cr-summaryBox-ajax").removeClass("cr-summaryBar-updating");
317					this.find(".cr-ajax-reviews-sort").removeClass("cr-sort-updating");
318					if(response.page > 0) {
319						this.find(".commentlist.cr-ajax-reviews-list").empty();
320						this.find(".commentlist.cr-ajax-reviews-list").append(response.html);
321						this.find(".commentlist.cr-ajax-reviews-list").show();
322						this.attr("data-page",response.page);
323						if( response.show_more_label ) {
324							this.find( ".cr-show-more-reviews-prd" ).text( response.show_more_label );
325						}
326						if ( response.count_row ) {
327							this.find(".cr-count-row .cr-count-row-count").html( response.count_row );
328						}
329						if(!response.last_page){
330							this.find(".cr-show-more-reviews-prd").show();
331						}
332					}
333				},
334				dataType: "json"
335			} );
336		} );
337		// ajax search typing
338		jQuery('.cr-ajax-search input').on("keyup", function(e){
339			if(e.keyCode == 13){
340				jQuery(this).parents(".cr-ajax-search").find("button").trigger("click");
341			}
342			// show clear icon
343			if(jQuery(this).val() !== "") {
344				jQuery(this).parents(".cr-ajax-search").find(".cr-clear-input").css("display", "inline-block");
345			} else {
346				jQuery(this).parents(".cr-ajax-search").find(".cr-clear-input").css("display", "none");
347			}
348		}).on("change", function(){
349			if(jQuery(this).val() === "") jQuery(this).parents(".cr-ajax-search").find(".cr-clear-input").hide();
350		});
351		//
352		jQuery('.cr-reviews-ajax-reviews .cr-ajax-search input').on( 'keyup', crDebounce(
353			( ref ) => {
354				jQuery(ref.target).parents(".cr-reviews-ajax-comments").attr("data-page", 0);
355				jQuery(ref.target).parents(".cr-reviews-ajax-reviews").find(".cr-ajax-reviews-list").empty();
356				crShowMoreReviewsPrd( jQuery(ref.target) );
357			},
358			1000
359		) );
360		// clear search field
361		jQuery(".cr-ajax-search .cr-clear-input").on("click", function () {
362			jQuery(this).prev("input").val("");
363			jQuery(this).parents(".cr-ajax-search").find(".cr-clear-input").hide();
364			jQuery(this).parents(".cr-ajax-search").find("button").trigger("click");
365			//
366			if( jQuery(this).parents(".cr-reviews-ajax-reviews").length ) {
367				// clear search in the case of product pages
368				jQuery(this).parents(".cr-reviews-ajax-comments").attr("data-page", 0);
369				jQuery(this).parents(".cr-reviews-ajax-reviews").find(".cr-ajax-reviews-list").empty();
370				crShowMoreReviewsPrd( jQuery(this) );
371			}
372		});
373		// ajax search of reviews
374		jQuery(".cr-ajax-search button").on("click", function (e) {
375			e.preventDefault();
376
377			//search in the all reviews block
378			if( jQuery(this).parents(".cr-all-reviews-shortcode").length ){
379				// search in ajax version of the All Reviews block / shortcode
380				cr_filter_all_reviews( jQuery(this) );
381			} else {
382				jQuery(this).parents(".cr-reviews-ajax-comments").attr("data-page", 0);
383				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-ajax-reviews-list").empty();
384				crShowMoreReviewsPrd( jQuery(this) );
385			}
386		});
387		jQuery(".cr-ajax-reviews-add-review, .cr-nosummary-add").on( "click", function(t) {
388			t.preventDefault();
389			var parent = jQuery(this).closest(".cr-reviews-ajax-reviews");
390			parent.find(".cr-reviews-ajax-comments").hide();
391			var reviewForm = parent.find(".cr-ajax-reviews-review-form");
392			reviewForm.show();
393			reviewForm.find( ".cr-review-form-wrap" ).first().trigger( "focus" );
394
395			// If captcha script is loaded, reset and render the widget after the form becomes visible.
396			if ( window.crCaptcha && typeof window.crCaptcha.render === 'function' ) {
397				// small delay to allow layout/visibility changes to take effect
398				window.setTimeout( function() {
399					try {
400						if ( typeof window.crCaptcha.reset === 'function' ) {
401							window.crCaptcha.reset( reviewForm );
402						}
403						window.crCaptcha.render( reviewForm );
404					} catch ( e ) {
405						// ignore errors
406					}
407				}, 50 );
408			}
409		} );
410		// click to filter reviews by tags
411		jQuery(".cr-review-tags-filter span.cr-tags-filter").on( "click", function (e) {
412			e.preventDefault();
413			if(jQuery(this).hasClass("cr-tag-selected")) {
414				jQuery(this).removeClass("cr-tag-selected");
415			} else {
416				jQuery(this).addClass("cr-tag-selected");
417			}
418			if ( jQuery(this).parents(".cr-all-reviews-shortcode").length ) {
419				// tags filtering in the all reviews shortcode
420				cr_filter_all_reviews( jQuery(this) );
421			} else {
422				// tags filtering on a product page
423				jQuery(this).parents(".cr-reviews-ajax-comments").attr("data-page", 0);
424				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-ajax-reviews-list").empty();
425				crShowMoreReviewsPrd( jQuery(this) );
426			}
427		} );
428		//open popup window with pictures
429		jQuery(".cr-comment-image-top .cr-comment-image-top-item").on( "click", function(t) {
430			t.preventDefault();
431			jQuery("body").addClass("cr-noscroll");
432			let slide_no = jQuery(this).data("slide");
433			let imgParent = jQuery(this).closest(".cr-ajax-reviews-cus-images-div").parent();
434			imgParent.find(".cr-ajax-reviews-cus-images-modal-cont").addClass("cr-mask-active");
435			imgParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-main").slickk('setPosition');
436			imgParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-nav").slickk('setPosition');
437			if ( typeof slide_no !== 'undefined' ) {
438				imgParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-main").slickk('slickGoTo', slide_no, true);
439				imgParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-nav").slickk('slickGoTo', slide_no, true);
440			}
441		} );
442		jQuery(".cr-comment-image-top .cr-comment-videoicon").on( "click", function(t) {
443			jQuery(this).closest( ".cr-comment-image-top" ).find( ".cr-comment-image-top-item" ).trigger( "click" );
444		} );
445		//close popup window with pictures
446		jQuery(".cr-ajax-reviews-cus-images-modal-cont, .cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-close").on( "click", function(t) {
447			t.preventDefault();
448			let closeParent = jQuery(this).closest(".cr-ajax-reviews-cus-images-modal-cont.cr-mask-active");
449			closeParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-main").slickk('slickGoTo',0,true);
450			closeParent.find(".cr-ajax-reviews-cus-images-modal .cr-ajax-reviews-cus-images-slider-nav").slickk('slickGoTo',0,true);
451			closeParent.removeClass("cr-mask-active");
452			jQuery("body").removeClass("cr-noscroll");
453		} );
454		jQuery(".cr-ajax-reviews-cus-images-modal-cont .cr-ajax-reviews-cus-images-modal").on( "click", function(t) {
455			t.stopPropagation();
456		} );
457		//Product variations
458		jQuery(".single_variation_wrap").on( "show_variation", function ( event, variation ) {
459			if(jQuery(".cr_gtin").length){
460				jQuery(".cr_gtin_val").text(variation._cr_gtin);
461			}
462			if(jQuery(".cr_mpn").length){
463				jQuery(".cr_mpn_val").text(variation._cr_mpn);
464			}
465			if(jQuery(".cr_brand").length){
466				jQuery(".cr_brand_val").text(variation._cr_brand);
467			}
468		});
469		//Reset Product variations
470		jQuery(document).on('reset_data', function () {
471			var cr_gtin = jQuery(".cr_gtin"),
472			cr_mpn = jQuery(".cr_mpn"),
473			cr_brand = jQuery(".cr_brand");
474
475			if(cr_gtin.length){
476				jQuery(".cr_gtin_val").text(cr_gtin.data("o_content"));
477			}
478			if(cr_mpn.length){
479				jQuery(".cr_mpn_val").text(cr_mpn.data("o_content"));
480			}
481			if(cr_brand.length){
482				jQuery(".cr_brand_val").text(cr_brand.data("o_content"));
483			}
484		});
485		// show more ajax reviews in the all reviews block
486		jQuery('.cr-all-reviews-shortcode .cr-show-more-button').on("click", function (e) {
487			e.preventDefault();
488			cr_filter_all_reviews( jQuery(this), true );
489		});
490		jQuery('.cr-all-reviews-shortcode').on("click", ".cr-page-numbers-a", function (e) {
491			e.preventDefault();
492			cr_filter_all_reviews( jQuery(this), true );
493		});
494		// filter ajax reviews in the all reviews block
495		jQuery(".cr-all-reviews-shortcode").on("click", ".cr-histogram-a, .cr-seeAllReviews", function(t){
496			t.preventDefault();
497			let cr_rating = jQuery(this).data("rating");
498			jQuery("div.ivole-summaryBox .ivole-histogramRow.ivole-histogramRow-s").removeClass("ivole-histogramRow-s");
499			if ( cr_rating > 0 ) {
500				jQuery(this).closest(".ivole-histogramRow").addClass("ivole-histogramRow-s");
501			}
502			jQuery(this).parents(".cr-all-reviews-shortcode").find(".cr-review-tags-filter .cr-tag-selected").removeClass("cr-tag-selected");
503			cr_filter_all_reviews( jQuery(this) );
504		});
505
506		// show more ajax reviews in the grid
507		jQuery( ".cr-reviews-grid .cr-show-more-button" ).on( "click", function (e) {
508			e.preventDefault();
509
510			let $this = jQuery(this),
511			$spinner =  $this.next(".cr-show-more-spinner"),
512			cr_rating = $this.parents(".cr-reviews-grid").find(".ivole-summaryBox.cr-grid-reviews-ajax .ivole-histogramRow.ivole-histogramRow-s .cr-histogram-a").attr("data-rating"),
513			attributes = $this.parents(".cr-reviews-grid").data("attributes");
514
515			attributes.comment__not_in = $this.parents(".cr-reviews-grid").find(".cr-review-card.cr-card-product").map( function() {
516				return jQuery(this).data("reviewid");
517			} ).get();
518			attributes.comment__not_in = attributes.comment__not_in.concat(
519				$this.parents(".cr-reviews-grid").find(".cr-review-card.cr-card-shop").map(function(){
520					return jQuery(this).data("reviewid");
521				}).get() );
522
523			var grid_data = {
524				'action': "ivole_show_more_grid_reviews",
525				'rating': cr_rating,
526				'attributes': attributes
527			};
528
529			$this.hide();
530			$spinner.show();
531
532			jQuery.post(cr_ajax_object.ajax_url, grid_data, function(response) {
533				$spinner.hide();
534				$reviews = jQuery(response.html).find(".cr-review-card");
535				let showMoreBtn = jQuery(response.html).find(".cr-show-more-button");
536				if ( $reviews.length ) {
537					$this.parents(".cr-reviews-grid").find(".cr-reviews-grid-inner").colcade("append", $reviews);
538					if ( showMoreBtn.length ) {
539						$this.text( showMoreBtn.text() );
540						$this.show();
541					} else {
542						$this.hide();
543					}
544				} else {
545					$this.hide();
546				}
547			}).fail(function(response) {
548				$spinner.hide();
549				$this.show();
550				$this.parent().append('<div style="color:#cd2653;text-align:center;display:block;">'+response.responseText+'</div>');
551			});
552		});
553
554		jQuery(".cr-reviews-grid .cr-summaryBox-wrap").on("click", ".cr-histogram-a, .cr-seeAllReviews", function(e){
555			e.preventDefault();
556
557			let $this = jQuery(this),
558			$grid =  $this.parents(".cr-reviews-grid"),
559			$spinner =  $grid.find(".cr-show-more-spinner"),
560			cr_rating = $this.attr("data-rating"),
561			attributes = $grid.data("attributes");
562
563			attributes.show_more = attributes.count + attributes.count_shop_reviews;
564			attributes.comment__not_in = [];
565
566			if(!cr_rating) cr_rating = 0;
567
568			var grid_data = {
569				'action': "ivole_show_more_grid_reviews",
570				'rating': cr_rating,
571				'attributes': attributes
572			};
573
574			$grid.find("div.ivole-summaryBox .ivole-histogramRow.ivole-histogramRow-s").removeClass("ivole-histogramRow-s");
575			if( cr_rating > 0 ) {
576				$this.closest(".ivole-histogramRow").addClass("ivole-histogramRow-s");
577			}
578			$grid.find(".cr-reviews-grid-inner").hide();
579			$grid.find(".cr-show-more-button").hide();
580			$spinner.show();
581			$grid.find("div.ivole-summaryBox").addClass("cr-summaryBar-updating");
582
583			jQuery.post(cr_ajax_object.ajax_url, grid_data, function(response) {
584				$spinner.hide();
585				$grid.find(".cr-show-more-button").show();
586				$grid.find(".cr-summaryBox-wrap .cr-count-filtered-reviews").empty();
587				$reviews = jQuery(response.html).find(".cr-review-card");
588				if($reviews.length){
589					$grid.find(".cr-reviews-grid-inner").colcade("empty");
590					$grid.find(".cr-reviews-grid-inner").show();
591					$grid.find(".cr-reviews-grid-inner").colcade("append", $reviews);
592					$grid.find("div.ivole-summaryBox").removeClass("cr-summaryBar-updating");
593					$grid.find(".cr-summaryBox-wrap .cr-count-filtered-reviews").append(jQuery(response.html).find(".cr-count-filtered-reviews").html());
594				}
595			}).fail(function(response) {
596				$spinner.hide();
597				$this.parent().append('<div style="color: #cd2653;text-align: center;display: block;">'+response.responseText+'</div>');
598			});
599
600		});
601		jQuery('#cr_floatingtrustbadge').on( "click", function() {
602			if( !jQuery(this).hasClass( 'cr-floatingbadge-big' ) ) {
603				jQuery(this).find('div.cr-badge.badge_size_compact').hide();
604				jQuery(this).find('div.cr-badge.badge--wide-mobile').css( 'display', 'block' );
605				jQuery(this).find('div.cr-floatingbadge-close').css( 'display', 'block' );
606				jQuery(this).addClass( 'cr-floatingbadge-big' );
607				//update colors
608				var crcolors = jQuery(this).data('crcolors');
609				if (typeof crcolors !== 'undefined') {
610					jQuery(this).css( 'border-color', crcolors['big']['border'] );
611					jQuery(this).find('div.cr-floatingbadge-background-top').css( 'background-color', crcolors['big']['top'] );
612					jQuery(this).find('div.cr-floatingbadge-background-middle').
612css( 'background-color', crcolors['big']['middle'] );
613					jQuery(this).find('div.cr-floatingbadge-background-bottom').css( 'background-color', crcolors['big']['bottom'] );
614					jQuery(this).find('div.cr-floatingbadge-background-bottom').css( 'border-color', crcolors['big']['border'] );
615				}
616			}
617		} );
618		jQuery('#cr_floatingtrustbadge .cr-floatingbadge-close').on( "click", function(event) {
619			if( jQuery('#cr_floatingtrustbadge').hasClass( 'cr-floatingbadge-big' ) ) {
620				jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-badge.badge--wide-mobile').hide();
621				jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-badge.badge_size_compact').css( 'display', 'block' );
622				jQuery(this).closest('#cr_floatingtrustbadge').removeClass( 'cr-floatingbadge-big' );
623				//update colors
624				var crcolors = jQuery(this).closest('#cr_floatingtrustbadge').data('crcolors');
625				if (typeof crcolors !== 'undefined') {
626					jQuery(this).closest('#cr_floatingtrustbadge').css( 'border-color', crcolors['small']['border'] );
627					jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-floatingbadge-background-top').css( 'background-color', crcolors['small']['top'] );
628					jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-floatingbadge-background-middle').css( 'background-color', crcolors['small']['middle'] );
629					jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-floatingbadge-background-bottom').css( 'background-color', crcolors['small']['bottom'] );
630					jQuery(this).closest('#cr_floatingtrustbadge').find('div.cr-floatingbadge-background-bottom').css( 'border-color', crcolors['small']['border'] );
631				}
632			} else {
633				jQuery('#cr_floatingtrustbadge').hide();
634				document.cookie = 'cr_hide_trustbadge=true; path=/; max-age='+60*60*24+';';
635			}
636			event.stopPropagation();
637		} );
638		jQuery( '.cr-reviews-slider' ).on( 'click', '.cr-slider-read-more a', function (e) {
639			e.preventDefault();
640			let parent = jQuery(this).parents(".review-text");
641			parent.find(".cr-slider-read-more").hide();
642			parent.find(".cr-slider-details").css("display", "inline");
643			jQuery(this).parents(".cr-reviews-slider").slickk('setPosition');
644		} );
645		jQuery( '.cr-reviews-slider' ).on( 'click', '.cr-slider-read-less a', function (e) {
646			e.preventDefault();
647			let parent = jQuery(this).parents(".review-text");
648			parent.find(".cr-slider-details").hide();
649			parent.find(".cr-slider-read-more").css("display", "inline");
650			jQuery(this).parents(".cr-reviews-slider").slickk('setPosition');
651		} );
652		jQuery( '.cr-reviews-grid' ).on( 'click', '.cr-grid-read-more a', function (e) {
653			e.preventDefault();
654			let parent = jQuery(this).parents(".review-content");
655			if ( 0 === parent.length ) {
656				parent = jQuery(this).parents(".cr-grid-reply-content");
657			}
658			parent.find(".cr-grid-read-more").hide();
659			parent.find(".cr-grid-details").css("display", "inline");
660		} );
661		jQuery( '.cr-reviews-grid' ).on( 'click', '.cr-grid-read-less a', function (e) {
662			e.preventDefault();
663			let parent = jQuery(this).parents(".review-content");
664			if ( 0 === parent.length ) {
665				parent = jQuery(this).parents(".cr-grid-reply-content");
666			}
667			parent.find(".cr-grid-details").hide();
668			parent.find(".cr-grid-read-more").css("display", "inline");
669		} );
670		jQuery('.cr-qna-block .cr-qna-search-block .cr-qna-ask-button').on( 'click', function (e) {
671			e.preventDefault();
672			jQuery( this ).closest( '.cr-qna-block' ).addClass( 'cr-qna-new-q-form-open' );
673		} );
674		jQuery(".cr-qna-block .cr-qna-list-block").on( "click", ".cr-qna-ans-button", function (e) {
675			e.preventDefault();
676
677			let nameField = jQuery( this ).closest( '.cr-qna-block' ).find( ".cr-qna-new-q-form .cr-review-form-name" );
678			let nameValue = nameField.find( ".cr-review-form-txt" ).data("defval");
679			jQuery( this ).closest( '.cr-qna-list-q-b' ).find( ".cr-qna-list-inl-answ .cr-review-form-name .cr-review-form-txt" ).val( nameValue );
680
681			let emailField = jQuery( this ).closest( '.cr-qna-block' ).find( ".cr-qna-new-q-form .cr-review-form-email" );
682			let emailValue = emailField.find( ".cr-review-form-txt" ).data("defval");
683			jQuery( this ).closest( '.cr-qna-list-q-b' ).find( ".cr-qna-list-inl-answ .cr-review-form-email .cr-review-form-txt" ).val( emailValue );
684
685			jQuery( this ).closest( '.cr-qna-list-q-b' ).addClass( 'cr-qna-ans-form-open' );
686		} );
687		//show more questions and answers
688		jQuery(".cr-qna-block").on( "click", ".cr-show-more-que", function(t) {
689			t.preventDefault();
690			let qna_block = jQuery(this).parents(".cr-qna-block").eq(0);
691			let cr_product_id = jQuery(this).attr("data-product");
692			let cr_page = jQuery(this).attr("data-page");
693			let cr_attributes = qna_block.data("attributes");
694			let cr_search = qna_block.find(".cr-ajax-qna-search input").val();
695			let cr_permalink = jQuery(this).attr("data-permalink");
696			let cr_data = {
697				"action": "cr_show_more_qna",
698				"productID": cr_product_id,
699				"page": cr_page,
700				"permalink": cr_permalink,
701				"search": cr_search,
702				"cr_attributes": cr_attributes
703			};
704			qna_block.find(".cr-search-no-qna").hide();
705			jQuery(this).hide();
706			qna_block.find("#cr-show-more-q-spinner").show();
707			jQuery.post(cr_ajax_object.ajax_url, cr_data, function(response) {
708				jQuery(".cr-qna-block #cr-show-more-q-spinner").hide();
709				if(response.page >= 0){
710					jQuery(".cr-qna-block .cr-qna-list-block .cr-qna-list-block-inner").append(response.html);
711					jQuery(".cr-qna-block #cr-show-more-q-id").attr("data-page",response.page);
712					if(!response.last_page){
713						jQuery(".cr-qna-block #cr-show-more-q-id").show();
714					}
715				}
716				if(response.html === "" && response.page === 0){
717					jQuery(".cr-qna-block .cr-search-no-qna").show();
718				}
719			}, "json");
720		} );
721		//search questions and answers
722		jQuery(".cr-qna-block .cr-ajax-qna-search input").on("keyup", cr_keyup_delay(function(e) {
723			// do nothing if it's an arrow key
724			var code = (e.keyCode || e.which);
725			if(code == 37 || code == 38 || code == 39 || code == 40) {
726				return;
727			}
728			jQuery(".cr-qna-block #cr-show-more-q-id").attr("data-page", -1);
729			jQuery(".cr-qna-block .cr-qna-list-block .cr-qna-list-block-inner").empty();
730			jQuery(".cr-qna-block #cr-show-more-q-id").trigger("click");
731		}, 500));
732		jQuery(".cr-qna-block .cr-ajax-qna-search input").on("keyup", function(e){
733			//show clear icon
734			if(jQuery(this).val() !== "") {
735				jQuery(".cr-qna-block .cr-ajax-qna-search .cr-clear-input").css("display", "inline-block");
736			} else {
737				if(jQuery(this).val() === "") jQuery(".cr-qna-block .cr-ajax-qna-search .cr-clear-input").hide();
738			}
739		}).on("change", function(){
740			if(jQuery(this).val() === "") jQuery(".cr-qna-block .cr-ajax-qna-search .cr-clear-input").hide();
741		});
742		jQuery(".cr-qna-block .cr-ajax-qna-search .cr-clear-input").on("click", function () {
743			jQuery(this).prev("input").val("");
744			jQuery(".cr-qna-block .cr-ajax-qna-search .cr-clear-input").hide();
745			jQuery(".cr-qna-block #cr-show-more-q-id").attr("data-page", -1);
746			jQuery(".cr-qna-block .cr-qna-list-block .cr-qna-list-block-inner").empty();
747			jQuery(".cr-qna-block #cr-show-more-q-id").trigger("click");
748		});
749		//show QnA tab
750		jQuery("body").on("click", "a.cr-qna-link", function () {
751			const cr_qna_tab = jQuery( '.cr_qna_tab a' );
752			if( cr_qna_tab.length ) {
753				cr_qna_tab.trigger( "click" );
754			} else {
755				jQuery( '.cr-qna-block' ).parents( ':hidden' ).show();
756			}
757			return true;
758		});
759		// show Reviews tab
760		jQuery("body").on("click", ".cr-review-link", function () {
761			const wc_reviews_tab = jQuery( '.reviews_tab a' );
762			if( wc_reviews_tab.length ) {
763				wc_reviews_tab.trigger( "click" );
764				return true;
765			}
766		});
767
768		// upload images with a review
769		jQuery("#cr_review_image").on("change", function () {
770			jQuery(".cr-upload-images-status").removeClass("cr-upload-images-status-error");
771			jQuery(".cr-upload-images-status").text(cr_ajax_object.cr_upload_initial);
772			let allowedTypes = ['image/jpeg', 'image/png', 'image/jpg', 'image/gif', 'video/mp4', 'video/mpeg', 'video/ogg', 'video/webm', 'video/quicktime', 'video/x-msvideo'];
773			let uploadFiles = jQuery("#cr_review_image");
774			let countFiles = uploadFiles[0].files.length;
775			let countUploaded = jQuery(".cr-upload-images-preview .cr-upload-images-containers").length;
776			let lastIndex = 1;
777			if(jQuery(this).attr("data-lastindex")) {
778				lastIndex = parseInt(jQuery(this).attr("data-lastindex"));
779			}
780			if( countFiles + countUploaded > cr_ajax_object.cr_images_upload_limit ) {
781				jQuery(".cr-upload-images-status").addClass("cr-upload-images-status-error");
782				jQuery(".cr-upload-images-status").text(cr_ajax_object.cr_upload_error_too_many);
783				jQuery(".cr-upload-images-preview .cr-upload-images-containers").not(".cr-upload-ok").remove();
784				uploadFiles.val("");
785				return;
786			}
787			for(let i = 0; i < countFiles; i++) {
788				if(!allowedTypes.includes(uploadFiles[0].files[i].type) ) {
789					jQuery(".cr-upload-images-status").addClass("cr-upload-images-status-error");
790					jQuery(".cr-upload-images-status").text(cr_ajax_object.cr_upload_error_file_type);
791					jQuery(".cr-upload-images-preview .cr-upload-images-containers").not(".cr-upload-ok").remove();
792					uploadFiles.val("");
793					return;
794				} else if(uploadFiles[0].files[i].size && uploadFiles[0].files[i].size > cr_ajax_object.cr_images_upload_max_size) {
795					jQuery(".cr-upload-images-status").addClass("cr-upload-images-status-error");
796					jQuery(".cr-upload-images-status").text(cr_ajax_object.cr_upload_error_file_size);
797					jQuery(".cr-upload-images-preview .cr-upload-images-containers").not(".cr-upload-ok").remove();
798					uploadFiles.val("");
799					return;
800				} else {
801					let container = jQuery("<div/>", {class:"cr-upload-images-containers cr-upload-images-container-" + (lastIndex + i)});
802					let progressBar = jQuery("<div/>", {class:"cr-upload-images-pbar"});
803					progressBar.append(
804						jQuery("<div/>", {class:"cr-upload-images-pbarin"})
805					);
806					if( -1 === uploadFiles[0].files[i].type.indexOf( 'image' ) ) {
807						container.append(
808							jQuery( "<svg class='cr-upload-video-thumbnail' viewBox='0 0 576 512'>
808<path d='M336.2 64H47.8C21.4 64 0 85.4 0 111.8v288.4C0 426.6 21.4 448 47.8 448h288.4c26.4 0 47.8-21.4 47.8-47.8V111.8c0-26.4-21.4-47.8-47.8-47.8zm189.4 37.7L416 177.3v157.4l109.6 75.5c21.2 14.6 50.4-.3 50.4-25.8V127.5c0-25.4-29.1-40.4-50.4-25.8z'></path></svg>" )
809						);
810					} else{
811						container.append(
812							jQuery("<img>", {class:"cr-upload-images-thumbnail",src:URL.createObjectURL(uploadFiles[0].files[i])})
813						);
814					}
815					container.append(
816						progressBar
817					);
818					let removeButton = jQuery("<button/>", {class:"cr-upload-images-delete"});
819					removeButton.append(
820						'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path class="cr-no-icon" d="M12.12 10l3.53 3.53-2.12 2.12L10 12.12l-3.54 3.54-2.12-2.12L7.88 10 4.34 6.46l2.12-2.12L10 7.88l3.54-3.53 2.12 2.12z"/></g></svg>'
821					);
822					container.append(
823						removeButton
824					);
825					container.append(
826						jQuery("<input>", {name:"cr-upload-images-ids[]",type:"hidden",value:""})
827					);
828					container.append(
829						jQuery("<span/>", {class:"cr-upload-images-delete-spinner"})
830					);
831					jQuery(".cr-upload-images-preview").append(container);
832				}
833			}
834
835			let filesToUpload = [];
836			for(let i = 0; i < countFiles; i++) {
837				filesToUpload.push(uploadFiles[0].files[i]);
838			}
839			const uploadField = jQuery(this);
840			const crUploadFiles = function( cr_captcha ) {
841				for(let i = 0; i < countFiles; i++) {
842					let formData = new FormData();
843					formData.append("action", "cr_upload_local_images_frontend");
844					formData.append("cr_nonce", uploadField.attr("data-nonce"));
845					formData.append("cr_postid", uploadField.attr("data-postid"));
846					formData.append("cr_file", filesToUpload[i]);
847					formData.append("cr_captcha", cr_captcha);
848					jQuery.ajax({
849						url: cr_ajax_object.ajax_url,
850						data: formData,
851						processData: false,
852						contentType: false,
853						dataType: "json",
854						type: "POST",
855						beforeSend: function() {
856						},
857						xhr: function() {
858							var myXhr = jQuery.ajaxSettings.xhr();
859							if ( myXhr.upload ) {
860								myXhr.upload.addEventListener( 'progress', function(e) {
861									if ( e.lengthComputable ) {
862										let perc = ( e.loaded / e.total ) * 100;
863										perc = perc.toFixed(0);
864										jQuery(".cr-upload-images-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i) + " .cr-upload-images-pbar .cr-upload-images-pbarin").width(perc + "%");
865									}
866								}, false );
867							}
868							return myXhr;
869						},
870						success: function(response) {
871							if(200 === response["code"]) {
872								let idkey = JSON.stringify({ id: response["attachment"]["id"], key: response["attachment"]["key"] });
873								jQuery(".cr-upload-images-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i) + " input").val(idkey);
874								jQuery(".cr-upload-images-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i)).addClass("cr-upload-ok");
875								jQuery(".cr-upload-images-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i) + " button").attr("data-delnonce",response["attachment"]["nonce"]);
876							} else if(500 <= response["code"]) {
877								jQuery(".cr-upload-images-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i)).remove();
878								jQuery(".cr-upload-images-status").addClass("cr-upload-images-status-error");
879								jQuery(".cr-upload-images-status").text(response["message"]);
880							}
881						}
882					});
883				}
884			};
885			if( crCaptchaEnabled() ) {
886				crCaptcha.consume( uploadField.closest( "form" ), crUploadFiles );
887			} else {
888				crUploadFiles( "" );
889			}
890			jQuery(this).attr("data-lastindex", lastIndex + countFiles);
891			uploadFiles.val("");
892		});
893
894		// delete uploaded image
895		jQuery(".cr-upload-images-preview").on("click", ".cr-upload-images-delete", function (e) {
896			e.preventDefault();
897			jQuery(".cr-upload-images-status").removeClass("cr-upload-images-status-error");
898			jQuery(".cr-upload-images-status").text(cr_ajax_object.cr_upload_initial);
899			let classList = jQuery(this).parent().eq(0).attr("class").split(/\s+/);
900			let classes = "";
901			jQuery.each(classList, function(index, item) {
902				classes += "." + item;
903			});
904			let ajaxData = {
905				"action": "cr_delete_local_images_frontend",
906				"cr_nonce": jQuery(this).attr("data-delnonce"),
907				"image": jQuery(this).parent().children("input").eq(0).val(),
908				"class": classes
909			}
910			jQuery(this).parent().addClass("cr-upload-delete-pending");
911			jQuery.post(cr_ajax_object.ajax_url, ajaxData, function(response) {
912				if(200 === response["code"] && response["class"]) {
913					jQuery(".cr-upload-images-preview " + response["class"]).remove();
914				}
915				jQuery(".cr-upload-images-preview " + response["class"]).removeClass("cr-upload-delete-pending");
916			}, "json");
917		});
918
919		// update star rating on an add-a-review form hover
920		jQuery( ".cr-review-form-rating .cr-review-form-rating-inner" ).on(
921			"mouseenter",
922			function() {
923				let rating = parseInt( jQuery( this ).data( "rating" ) );
924				let ratingActv = parseInt( jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-actv" ).data( "rating" ) );
925				if( isNaN( ratingActv ) ) {
926					ratingActv = 0;
927				}
928				for( r = 1; r < 6; r++ ) {
929					if( r > rating && r > ratingActv ) {
930						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).hide();
931						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).show();
932					} else {
933						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).hide();
934						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).show();
935					}
936				}
937				jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-nbr" ).text( rating + "/5" );
938			}
939		).on(
940			"mouseleave",
941			function() {
942				let ratingActv = parseInt( jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-actv" ).data( "rating" ) );
943				if( isNaN( ratingActv ) ) {
944					ratingActv = 0;
945				}
946				for( r = 1; r < 6; r++ ) {
947					if( r > ratingActv ) {
948						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).hide();
949						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).show();
950					} else {
951						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).hide();
952						jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).show();
953					}
954				}
955				jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-nbr" ).text( ratingActv + "/5" );
956			}
957		);
958
959		// update star rating on an add-a-review form click
960		jQuery( ".cr-review-form-rating .cr-review-form-rating-inner" ).on( "click", function( e ) {
961			e.preventDefault();
962			let rating = parseInt( jQuery( this ).data( "rating" ) );
963			jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner" ).removeClass( "cr-review-form-rating-actv" );
964			jQuery( this ).addClass( "cr-review-form-rating-actv" );
965			for( r = 1; r < 6; r++ ) {
966				if( r > rating ) {
967					jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).hide();
968					jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).show();
969				} else {
970					jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-deact" ).hide();
971					jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-inner[data-rating=" + r + "] .cr-rating-act" ).show();
972				}
973			}
974			jQuery( this ).closest( ".cr-review-form-rating-cont" ).find( ".cr-review-form-rating-nbr" ).text( rating + "/5" );
975			jQuery( this ).closest( ".cr-review-form-rating" ).find( ".cr-review-form-rating-inp" ).val( rating );
976			jQuery( this ).closest( ".cr-review-form-rating" ).removeClass( "cr-review-form-error" );
977		} );
978
979		// close the review form
980		jQuery( ".cr-all-reviews-shortcode .cr-nav-left svg, .cr-all-reviews-shortcode .cr-nav-right svg, .cr-all-reviews-shortcode .cr-review-form-cancel" ).on( "click", function( e ) {
981			jQuery( this ).closest( ".cr-all-reviews-shortcode" ).removeClass( "cr-all-reviews-new-review" );
982			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
983			cr_reset_review_form( jQuery( this ) );
984		} );
985		jQuery( ".cr-all-reviews-shortcode .cr-review-form-wrap" ).on( "click", ".cr-review-form-success", function( e ) {
986			jQuery( this ).closest( ".cr-all-reviews-shortcode" ).removeClass( "cr-all-reviews-new-review" );
987			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
988			cr_reset_review_form( jQuery( this ) );
989			// reload the page
990			window.location.reload();
991		} );
992		jQuery( ".cr-review-form-wrap" ).on( "click", ".cr-review-form-error", function( e ) {
993			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
994		} );
995		jQuery( ".cr-ajax-reviews-review-form .cr-nav-left svg, .cr-ajax-reviews-review-form .cr-nav-right svg, .cr-ajax-reviews-review-form .cr-review-form-cancel" ).on( "click", function( e ) {
996			jQuery(this).closest(".cr-reviews-ajax-reviews").find(".cr-reviews-ajax-comments").show();
997			jQuery(this).closest(".cr-reviews-ajax-reviews").find(".cr-ajax-reviews-review-form").hide();
998			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
999			cr_reset_review_form( jQuery( this ) );
1000		} );
1001		jQuery( ".cr-ajax-reviews-review-form .cr-review-form-wrap" ).on( "click", ".cr-review-form-success", function( e ) {
1002			jQuery(this).closest(".cr-reviews-ajax-reviews").find(".cr-reviews-ajax-comments").show();
1003			jQuery(this).closest(".cr-reviews-ajax-reviews").find(".cr-ajax-reviews-review-form").hide();
1004			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
1005			cr_reset_review_form( jQuery( this ) );
1006			// reload the page
1007			if ( window.location.hash !== '#reviews' ) {
1008				window.location.href = window.location.pathname + '#reviews';
1009			}
1010			window.location.reload();
1011		} );
1012		jQuery( ".cr-reviews-grid .cr-nav-left svg, .cr-reviews-grid .cr-nav-right svg, .cr-reviews-grid .cr-review-form-cancel" ).on( "click", function( e ) {
1013			jQuery( this ).closest( ".cr-reviews-grid" ).removeClass( "cr-reviews-grid-new-review" );
1014			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
1015			cr_reset_review_form( jQuery( this ) );
1016		} );
1017		jQuery( ".cr-reviews-grid .cr-review-form-wrap" ).on( "click", ".cr-review-form-success", function( e ) {
1018			jQuery( this ).closest( ".cr-reviews-grid" ).removeClass( "cr-reviews-grid-new-review" );
1019			jQuery( this ).closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-res" );
1020			cr_reset_review_form( jQuery( this ) );
1021			// reload the page
1022			window.location.reload();
1023		} );
1024		// close the qna form
1025		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-new-q-form .cr-nav-left svg, .cr-qna-new-q-form .cr-nav-right svg, .cr-qna-new-q-form .cr-review-form-cancel", function( e ) {
1026			jQuery( this ).closest( ".cr-qna-block" ).removeClass( "cr-qna-new-q-form-open" );
1027			jQuery( this ).closest( ".cr-qna-new-q-form" ).removeClass( "cr-review-form-res" );
1028			cr_reset_qna_form( jQuery( this ) );
1029		} );
1030		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-new-q-form .cr-review-form-success", function( e ) {
1031			jQuery( this ).closest( ".cr-qna-block" ).removeClass( "cr-qna-new-q-form-open" );
1032			jQuery( this ).closest( ".cr-qna-new-q-form" ).removeClass( "cr-review-form-res" );
1033			cr_reset_qna_form( jQuery( this ) );
1034		} );
1035		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-new-q-form .cr-review-form-error", function( e ) {
1036			jQuery( this ).closest( ".cr-qna-new-q-form" ).removeClass( "cr-review-form-res" );
1037		} );
1038		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-list-inl-answ .cr-nav-left svg, .cr-qna-list-inl-answ .cr-nav-right svg, .cr-qna-list-inl-answ .cr-review-form-cancel", function( e ) {
1039			jQuery( this ).closest( ".cr-qna-list-q-b" ).removeClass( "cr-qna-ans-form-open" );
1040			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).removeClass( "cr-review-form-res" );
1041			cr_reset_ans_form( jQuery( this ) );
1042		} );
1043		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-list-inl-answ .cr-review-form-success", function( e ) {
1044			jQuery( this ).closest( ".cr-qna-list-q-b" ).removeClass( "cr-qna-ans-form-open" );
1045			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).removeClass( "cr-review-form-res" );
1046			cr_reset_ans_form( jQuery( this ) );
1047		} );
1048		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-list-inl-answ .cr-review-form-error", function( e ) {
1049			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).removeClass( "cr-review-form-res" );
1050		} );
1051
1052		// submit the review form
1053		jQuery( ".cr-review-form-wrap .cr-review-form-submit" ).on( "click", function( e ) {
1054			// check if media upload is in progress
1055			if ( 0 < jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media-preview .cr-upload-images-containers:not(.cr-upload-ok)" ).length ) {
1056				return false;
1057			}
1058			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating" ).removeClass( "cr-review-form-error" );
1059			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1060			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name" ).removeClass( "cr-review-form-error" );
1061			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email" ).removeClass( "cr-review-form-error" );
1062			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-onsite-question" ).removeClass( "cr-review-form-error" );
1063			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media" ).removeClass( "cr-review-form-error" );
1064			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-captcha" ).removeClass( "cr-review-form-error" );
1065			jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1066			if( cr_validate_review_form( jQuery( this ) ) ) {
1067				// add custom onsite questions and ratings to the ajax call
1068				let onsiteQuestions = {};
1069				jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating input[type='hidden']" ).each(
1070					function() {
1071						onsiteQuestions[jQuery( this ).attr( 'name' )] = jQuery( this ).val();
1072					}
1073				)
1074				jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-onsite-question input" ).each(
1075					function() {
1076						onsiteQuestions[jQuery( this ).attr( 'name' )] = jQuery( this ).val();
1077					}
1078				)
1079				// submit the form if the validation is successful
1080				let cr_data = {
1081					"action": "cr_submit_review",
1082					"rating": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-overall .cr-review-form-rating-inp" ).val(),
1083					"review": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment-txt" ).val().trim(),
1084					"name": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim(),
1085					"id": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-item-id" ).val(),
1086					"email": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim(),
1087					"onsiteQuestions": onsiteQuestions,
1088					"cr-upload-images-ids": jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media .cr-upload-images-containers input" ).map( function() {
1089						return jQuery( this ).val();
1090					} ).get()
1091				};
1092				jQuery( this ).closest( ".cr-review-form-wrap" ).addClass( "cr-review-form-submitting" );
1093				jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-success" );
1094				jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-error" );
1095				//
1096				const postReview = ( token, data, ref ) => {
1097					data.cr_captcha_response = token;
1098					jQuery.post(
1099						{
1100							url: cr_ajax_object.ajax_url,
1101							data: data,
1102							context: jQuery( ref ),
1103							success: function( response ) {
1104								if ( ! Object.hasOwn( response, 'button' ) ) {
1105									response.button = 'OK';
1106								}
1107								if ( ! Object.hasOwn( response, 'description' ) ) {
1108									response.description = 'An unexpected error that could be caused by a third-party plugin';
1109								}
1110								this.closest( ".cr-review-form-wrap" ).removeClass( "cr-review-form-submitting" );
1111								this.closest( ".cr-review-form-wrap" ).addClass( "cr-review-form-res" );
1112								this.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-result span" ).html( response.description );
1113								this.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-continue" ).html( response.button );
1114								if( 0 === response.code ) {
1115									this.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-success" );
1116								} else {
1117									this.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-error" );
1118								}
1119							},
1120							dataType: "json"
1121						}
1122					);
1123				};
1124				//
1125				const reviewForm = jQuery( this ).closest( ".cr-review-form-wrap" );
1126				const submitRef = this;
1127				if ( crCaptchaEnabled() ) {
1128					crCaptcha.execute( reviewForm, function( token ) {
1129						postReview( token, cr_data, submitRef );
1130					} );
1131				} else {
1132					postReview( '', cr_data, submitRef );
1133				}
1134			};
1135		} );
1136
1137		// submit a new question
1138		jQuery( ".cr-qna-block .cr-qna-new-q-form" ).on( "click", ".cr-review-form-submit", function( e ) {
1139			jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1140			jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-name" ).removeClass( "cr-review-form-error" );
1141			jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-email" ).removeClass( "cr-review-form-error" );
1142			jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1143			if( cr_validate_qna( jQuery( this ) ) ) {
1144				// submit the form if the validation is successful
1145				let cr_data = {
1146					"action": "cr_new_qna",
1147					"crNonce": jQuery( this ).closest( ".cr-qna-block" ).data( "nonce" ),
1148					"currentPostID": jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-item-id" ).val(),
1149					"text": jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment-txt" ).val().trim(),
1150					"name": jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim(),
1151					"email": jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim()
1152				};
1153				jQuery( this ).closest( ".cr-qna-new-q-form" ).addClass( "cr-review-form-submitting" );
1154				jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-success" );
1155				jQuery( this ).closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-error" );
1156				//
1157				const postQuestion = ( token, data, ref ) => {
1158					data.cptcha = token;
1159					jQuery.post(
1160						{
1161							url: cr_ajax_object.ajax_url,
1162							data: data,
1163							context: jQuery( ref ),
1164							success: function( response ) {
1165								this.closest( ".cr-qna-new-q-form" ).removeClass( "cr-review-form-submitting" );
1166								this.closest( ".cr-qna-new-q-form" ).addClass( "cr-review-form-res" );
1167								this.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-result span" ).html( response.description );
1168								this.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-continue" ).html( response.button );
1169								if( 0 === response.code ) {
1170									this.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-success" );
1171								} else {
1172									this.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-error" );
1173								}
1174							},
1175							dataType: "json"
1176						}
1177					);
1178				};
1179				//
1180				let cr_cptcha = jQuery(this).attr("data-crcptcha");
1181				var rf = this;
1182				if ( cr_cptcha && cr_cptcha.length > 0 ) {
1183					grecaptcha.ready(function() {
1184						grecaptcha.execute( cr_cptcha, {action: 'submit'} ).then( function(token) {
1185							postQuestion( token, cr_data, rf )
1186						} );
1187					} );
1188				} else {
1189					postQuestion( '', cr_data, rf );
1190				}
1191			};
1192		} );
1193
1194		// submit a new answer
1195		jQuery( ".cr-qna-block" ).on( "click", ".cr-qna-list-inl-answ .cr-review-form-submit", function( e ) {
1196			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1197			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-name" ).removeClass( "cr-review-form-error" );
1198			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-email" ).removeClass( "cr-review-form-error" );
1199			jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1200			if( cr_validate_ans( jQuery( this ) ) ) {
1201				// submit the form if the validation is successful
1202				let cr_data = {
1203					"action": "cr_new_qna",
1204					"crNonce": jQuery( this ).closest( ".cr-qna-block" ).data( "nonce" ),
1205					"currentPostID": jQuery( this ).closest( ".cr-qna-block" ).find( ".cr-review-form-item-id" ).val(),
1206					"questionID": jQuery( this ).closest( ".cr-qna-list-q-b" ).data( "question" ),
1207					"productID": jQuery( this ).closest( ".cr-qna-list-q-b" ).data( "post" ),
1208					"text": jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment-txt" ).val().trim(),
1209					"name": jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim(),
1210					"email": jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim()
1211				};
1212				jQuery( this ).closest( ".cr-qna-list-inl-answ" ).addClass( "cr-review-form-submitting" );
1213				jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-success" );
1214				jQuery( this ).closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-continue" ).removeClass( "cr-review-form-error" );
1215				//
1216				const postQuestion = ( token, data, ref ) => {
1217					data.cptcha = token;
1218					jQuery.post(
1219						{
1220							url: cr_ajax_object.ajax_url,
1221							data: data,
1222							context: jQuery( ref ),
1223							success: function( response ) {
1224								this.closest( ".cr-qna-list-inl-answ" ).removeClass( "cr-review-form-submitting" );
1225								this.closest( ".cr-qna-list-inl-answ" ).addClass( "cr-review-form-res" );
1226								this.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-result span" ).html( response.description );
1227								this.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-continue" ).html( response.button );
1228								if( 0 === response.code ) {
1229									this.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-success" );
1230								} else {
1231									this.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-continue" ).addClass( "cr-review-form-error" );
1232								}
1233							},
1234							dataType: "json"
1235						}
1236					);
1237				};
1238				//
1239				let cr_cptcha = jQuery(this).attr("data-crcptcha");
1240				var rf = this;
1241				if ( cr_cptcha && cr_cptcha.length > 0 && grecaptcha ) {
1242					grecaptcha.ready(function() {
1243						grecaptcha.execute( cr_cptcha, {action: 'submit'} ).then( function(token) {
1244							postQuestion( token, cr_data, rf )
1245						} );
1246					} );
1247				} else {
1248					postQuestion( '', cr_data, rf );
1249				}
1250			};
1251		} );
1252
1253		// validate custom questions and ratings on submission of a review form on a product page
1254		jQuery( ".cr-single-product-review" ).on( "click", ".cr-single-product-rev-submit", function(t) {
1255			let validationResult = true;
1256			let reviewForm = jQuery( this ).closest( ".cr-single-product-review" );
1257
1258			// validate ratings
1259			reviewForm.find( ".cr-review-form-rating-cont.cr-review-form-rating-req" ).each( function( index ) {
1260				if( 1 > jQuery( this ).find( ".cr-review-form-rating-actv" ).length ) {
1261					jQuery( this ).closest( ".cr-review-form-rating" ).addClass( "cr-review-form-error" );
1262					validationResult = false;
1263				}
1264			} );
1265
1266			// validate custom questions
1267			reviewForm.find( ".cr-onsite-question.cr-review-form-que-req" ).each( function( index ) {
1268				if( 1 > jQuery( this ).find( "input[type=text]" ).val().trim().length ) {
1269					jQuery( this ).closest( ".cr-onsite-question" ).addClass( "cr-review-form-error" );
1270					validationResult = false;
1271				} else {
1272					jQuery( this ).closest( ".cr-onsite-question" ).removeClass( "cr-review-form-error" );
1273				}
1274			} );
1275
1276			// validate the comment field
1277			reviewForm.find( ".cr-review-form-textbox" ).each( function( index ) {
1278				if( 1 > jQuery( this ).val().trim().length ) {
1279					jQuery( this ).addClass( "cr-review-form-error" );
1280					validationResult = false;
1281				} else {
1282					jQuery( this ).removeClass( "cr-review-form-error" );
1283				}
1284			} );
1285
1286			// validate the terms checkbox
1287			if ( 0 < reviewForm.find( '.cr-review-form-terms' ).length ) {
1288				if ( ! reviewForm.find( '.cr-review-form-terms .cr-review-form-checkbox' ).is(':checked') ) {
1289					alert( 'Please tick the checkbox to proceed' );
1290					validationResult = false;
1291				}
1292			}
1293
1294			if( ! validationResult ) {
1295				t.preventDefault();
1296			}
1297		} );
1298
1299		// open the review form
1300		jQuery( ".cr-all-reviews-add-review" ).on( "click", function(t) {
1301			t.preventDefault();
1302			if ( 0 < jQuery( this ).closest( ".cr-all-reviews-shortcode" ).length ) {
1303				jQuery( this ).closest( ".cr-all-reviews-shortcode" ).addClass( "cr-all-reviews-new-review" );
1304			}
1305			if ( 0 < jQuery( this ).closest( ".cr-reviews-grid" ).length ) {
1306				jQuery( this ).closest( ".cr-reviews-grid" ).addClass( "cr-reviews-grid-new-review" );
1307			}
1308		} );
1309
1310		// upload media trigger
1311		jQuery( ".cr-review-form-wrap .cr-form-item-media-none" ).on( "click", function( t ) {
1312			jQuery( this ).parent().find( "input.cr-form-item-media-file" ).trigger( "click" );
1313		} );
1314		jQuery( ".cr-review-form-wrap .cr-form-item-media-none" ).on( "keydown", function( e ) {
1315			if ( "Enter" === e.key || " " === e.key ) {
1316				e.preventDefault();
1317				jQuery( this ).trigger( "click" );
1318			}
1319		} );
1320
1321		// upload media trigger
1322		jQuery( ".cr-review-form-wrap .cr-form-item-media-preview" ).on( "click", ".cr-form-item-media-add", function( t ) {
1323			jQuery( this ).parents( ".cr-form-item-media" ).find( "input.cr-form-item-media-file" ).trigger( "click" );
1324		} );
1325
1326		// upload media
1327		jQuery( ".cr-review-form-wrap .cr-form-item-media .cr-form-item-media-file" ).on( "change", function () {
1328			let allowedTypes = ['image/jpeg', 'image/png', 'image/jpg', 'image/gif', 'video/mp4', 'video/mpeg', 'video/ogg', 'video/webm', 'video/quicktime', 'video/x-msvideo'],
1329			uploadFiles = jQuery( this ),
1330			countFiles = uploadFiles[0].files.length,
1331			lastIndex = 1,
1332			mediaPreview = jQuery( this ).parent().find( ".cr-form-item-media-preview" ),
1333			countUploaded = mediaPreview.children( ".cr-upload-images-containers" ).length;
1334			jQuery(this).closest(".cr-form-item-media").removeClass("cr-review-form-error");
1335			if( jQuery(this).attr("data-lastindex") ) {
1336				lastIndex = parseInt( jQuery( this ).attr( "data-lastindex" ) );
1337			}
1338			if( countFiles + countUploaded > cr_ajax_object.cr_images_upload_limit ) {
1339				jQuery(this).closest(".cr-form-item-media").addClass("cr-review-form-error");
1340				jQuery(this).closest(".cr-form-item-media").find(".cr-review-form-field-error").text(cr_ajax_object.cr_upload_error_too_many);
1341				uploadFiles.val("");
1342				return;
1343			}
1344			for(let i = 0; i < countFiles; i++) {
1345				if(!allowedTypes.includes(uploadFiles[0].files[i].type) ) {
1346					jQuery(this).closest(".cr-form-item-media").addClass("cr-review-form-error");
1347					jQuery(this).closest(".cr-form-item-media").find(".cr-review-form-field-error").text(cr_ajax_object.cr_upload_error_file_type);
1348					uploadFiles.val("");
1349					return;
1350				} else if( uploadFiles[0].files[i].size && uploadFiles[0].files[i].size > cr_ajax_object.cr_images_upload_max_size * 100 ) {
1351					jQuery(this).closest(".cr-form-item-media").addClass("cr-review-form-error");
1352					jQuery(this).closest(".cr-form-item-media").find(".cr-review-form-field-error").text(cr_ajax_object.cr_upload_error_file_size);
1353					uploadFiles.val("");
1354					return;
1355				} else {
1356					let container = jQuery( "<div/>", {class:"cr-upload-images-containers cr-upload-images-container-" + (lastIndex + i)} );
1357					let progressBar = jQuery( "<div/>", {class:"cr-upload-images-pbar"} );
1358					progressBar.append(
1359						jQuery( "<div/>", {class:"cr-upload-images-pbarin"} )
1360					);
1361					if( -1 === uploadFiles[0].files[i].type.indexOf( 'image' ) ) {
1362						container.append(
1363							jQuery( "<svg class='cr-upload-video-thumbnail' viewBox='0 0 576 512'>
1363<path d='M336.2 64H47.8C21.4 64 0 85.4 0 111.8v288.4C0 426.6 21.4 448 47.8 448h288.4c26.4 0 47.8-21.4 47.8-47.8V111.8c0-26.4-21.4-47.8-47.8-47.8zm189.4 37.7L416 177.3v157.4l109.6 75.5c21.2 14.6 50.4-.3 50.4-25.8V127.5c0-25.4-29.1-40.4-50.4-25.8z'></path></svg>" )
1364						);
1365					} else {
1366						container.append(
1367							jQuery( "<img>", {class:"cr-upload-images-thumbnail", src:URL.createObjectURL(uploadFiles[0].files[i])} )
1368						);
1369					}
1370					container.append(
1371						progressBar
1372					);
1373					let removeButton = jQuery( "<button/>", {class:"cr-upload-images-delete"} );
1374					removeButton.append(
1375						'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><rect x="0" fill="none" width="20" height="20"/><g><path class="cr-no-icon" d="M12.12 10l3.53 3.53-2.12 2.12L10 12.12l-3.54 3.54-2.12-2.12L7.88 10 4.34 6.46l2.12-2.12L10 7.88l3.54-3.53 2.12 2.12z"/></g></svg>'
1376					);
1377					container.append(
1378						removeButton
1379					);
1380					container.append(
1381						jQuery( "<input>", {name:"cr-upload-images-ids[]",type:"hidden",value:""} )
1382					);
1383					container.append(
1384						jQuery( "<span/>", {class:"cr-upload-images-delete-spinner"} )
1385					);
1386					mediaPreview.find( ".cr-form-item-media-add" ).remove();
1387					mediaPreview.append( container );
1388					if( countFiles + countUploaded < cr_ajax_object.cr_images_upload_limit ) {
1389						mediaPreview.append(
1390							jQuery( "<div class='cr-form-item-media-add'>+</div>" )
1391						);
1392					}
1393				}
1394			}
1395			if( 0 < mediaPreview.children( ".cr-upload-images-containers" ).length && ! mediaPreview.hasClass( "cr-form-visible" ) ) {
1396				mediaPreview.parents( ".cr-form-item-subcontainer" ).addClass( "cr-form-visible" );
1397			}
1398			for(let i = 0; i < countFiles; i++) {
1399				let formData = new FormData();
1400				formData.append( "action", "cr_upload_media" );
1401				formData.append( "cr_file", uploadFiles[0].files[i] );
1402				formData.append( "cr_item", jQuery( this ).closest( ".cr-review-form-wrap" ).find( ".cr-review-form-item-id" ).val() );
1403				formData.append( "cr_nonce", jQuery( this ).closest( ".cr-review-form-wrap" ).data( "nonce" ) );
1404				var currentFileInput = jQuery( this );
1405				jQuery.ajax({
1406					url: cr_ajax_object.ajax_url,
1407					data: formData,
1408					processData: false,
1409					contentType: false,
1410					dataType: "json",
1411					type: "POST",
1412					context: this,
1413					beforeSend: function() {
1414					},
1415					xhr: function() {
1416						var myXhr = jQuery.ajaxSettings.xhr();
1417						if ( myXhr.upload ) {
1418							myXhr.upload.addEventListener( 'progress', function(e) {
1419								if ( e.lengthComputable ) {
1420									let perc = ( e.loaded / e.total ) * 100;
1421									perc = perc.toFixed(0);
1422									currentFileInput.parent().find( ".cr-form-item-media-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i) + " .cr-upload-images-pbar .cr-upload-images-pbarin" ).width(perc + "%");
1423								}
1424							}, false );
1425						}
1426						return myXhr;
1427					},
1428					success: function(response) {
1429						if(200 === response["code"]) {
1430							let idkey = JSON.stringify( { "id": response["attachment"]["id"], "key": response["attachment"]["key"] } );
1431							currentFileInput.parent().find( ".cr-form-item-media-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i) + " input").val(idkey);
1432							currentFileInput.parent().find( ".cr-form-item-media-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i)).addClass("cr-upload-ok");
1433						} else if(500 <= response["code"]) {
1434							currentFileInput.parent().find( ".cr-form-item-media-preview .cr-upload-images-containers.cr-upload-images-container-" + (lastIndex + i)).remove();
1435							let mediaPreview = jQuery(this).closest(".cr-form-item-media").find(".cr-form-item-media-preview");
1436							let countUploaded = mediaPreview.find( ".cr-upload-images-containers" ).length;
1437							if( 0 < countUploaded ) {
1438								if( 0 === mediaPreview.children( ".cr-form-item-media-add" ).length ) {
1439									mediaPreview.append(
1440										jQuery( "<div class='cr-form-item-media-add'>+</div>" )
1441									);
1442								}
1443							} else {
1444								mediaPreview.removeClass( "cr-form-visible" );
1445								mediaPreview.parents( ".cr-form-item-subcontainer" ).removeClass( "cr-form-visible" );
1446							}
1447							jQuery(this).closest(".cr-form-item-media").addClass("cr-review-form-error");
1448							jQuery(this).closest(".cr-form-item-media").find(".cr-review-form-field-error").text(response["message"]);
1449						}
1450					}
1451				});
1452			}
1453			jQuery(this).attr("data-lastindex", lastIndex + countFiles);
1454			uploadFiles.val("");
1455		} );
1456
1457		// delete uploaded image
1458		jQuery(".cr-review-form-wrap .cr-form-item-media-preview").on("click", ".cr-upload-images-delete", function (e) {
1459			e.preventDefault();
1460			let imgContainer = jQuery(this).parent(),
1461			mediaPreview = imgContainer.parent();
1462			let ajaxData = {
1463				"action": "cr_delete_media",
1464				"image": jQuery( this ).parent().children( "input" ).eq( 0 ).val()
1465			}
1466			imgContainer.addClass( "cr-upload-delete-pending" );
1467			jQuery.post( cr_ajax_object.ajax_url, ajaxData, function(response) {
1468				imgContainer.removeClass( "cr-upload-delete-pending" );
1469				if( 200 === response["code"] ) {
1470					imgContainer.remove();
1471					let countUploaded = mediaPreview.children( ".cr-upload-images-containers" ).length;
1472					if( 0 < countUploaded ) {
1473						if( 0 === mediaPreview.children( ".cr-form-item-media-add" ).length ) {
1474							mediaPreview.append(
1475								jQuery( "<div class='cr-form-item-media-add'>+</div>" )
1476							);
1477						}
1478					} else {
1479						mediaPreview.removeClass( "cr-form-visible" );
1480						mediaPreview.parents( ".cr-form-item-subcontainer" ).removeClass( "cr-form-visible" );
1481					}
1482				}
1483			}, "json" );
1484		} );
1485
1486		cr_maybe_download_media_frontend();
1487
1488		if( "object" === typeof elementorFrontend && "hooks" in elementorFrontend ) {
1489			elementorFrontend.hooks.addAction( "frontend/element_ready/widget", function( $scope ) {
1490				if( -1 !== $scope.data( "widget_type" ).indexOf( "shortcode" ) ) {
1491					if( 0 < $scope.find( ".cr-reviews-grid-inner" ).length ) {
1492						crResizeAllGridItems();
1493					}
1494				}
1495			} );
1496		}
1497
1498	} );
1499
1500	const crValidateEmail = (email) => {
1501		return email.match(
1502			/^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
1503		);
1504	};
1505
1506	function initVoteClick(sel1, sel2, action) {
1507		jQuery(sel1).on("click", sel2, function(e) {
1508			e.preventDefault();
1509
1510			let reviewIDhtml = jQuery(this).data("vote");
1511			let parent = jQuery(this).parents(".cr-voting-cont-uni");
1512
1513			if(reviewIDhtml != null) {
1514				let reviewID = reviewIDhtml;
1515				let data = {
1516					"action": action,
1517					"reviewID": reviewID,
1518					"upvote": jQuery(this).data("upvote")
1519				};
1520
1521				parent.find(".cr-voting-a").removeClass("cr-voting-active");
1522				parent.find(".cr-voting-a").addClass("cr-voting-update");
1523				jQuery.post(cr_ajax_object.ajax_url, data, function(response) {
1524					parent.find(".cr-voting-a").removeClass("cr-voting-update");
1525					if( response.code === 0 ) {
1526						if( response.votes ) {
1527							parent.find(".cr-voting-upvote-count").text("(" +  response.votes.upvotes + ")");
1528							parent.find(".cr-voting-downvote-count").text("(" +  response.votes.downvotes + ")");
1529						}
1530						if( 0 !== response.votes.current ) {
1531							if( 0 < response.votes.current ) {
1532								parent.find(".cr-voting-upvote").addClass("cr-voting-active");
1533							} else {
1534								parent.find(".cr-voting-downvote").addClass("cr-voting-active");
1535							}
1536						}
1537					}
1538				}, "json");
1539			}
1540		});
1541	}
1542
1543	function cr_keyup_delay(fn, ms) {
1544		let timer = 0;
1545		return function(...args) {
1546			clearTimeout(timer);
1547			timer = setTimeout(fn.bind(this, ...args), ms || 0);
1548		};
1549	}
1550
1551	function cr_filter_all_reviews( refElement, show_more = false ) {
1552		let attributes = refElement.parents(".cr-all-reviews-shortcode").data("attributes"),
1553		cr_rating = refElement.parents(".cr-all-reviews-shortcode").find(".ivole-summaryBox .ivole-histogramRow.ivole-histogramRow-s .cr-histogram-a").attr("data-rating"),
1554		cr_search = refElement.parents(".cr-all-reviews-shortcode").find(".cr-ajax-search input").val(),
1555		cr_sort = refElement.parents(".cr-all-reviews-shortcode").find(".cr-ajax-reviews-sort").children("option:selected").val();
1556		let cr_tags = [];
1557		refElement.parents(".cr-all-reviews-shortcode").find(".cr-review-tags-filter .cr-tags-filter.cr-tag-selected").each(
1558			function() {
1559				cr_tags.push( jQuery(this).attr("data-crtagid") );
1560			}
1561		);
1562		let cr_data = {
1563			"action": "cr_show_more_all_reviews",
1564			"attributes": attributes,
1565			"rating": cr_rating,
1566			"page": 0,
1567			"search": cr_search,
1568			"sort": cr_sort,
1569			"tags": cr_tags
1570		};
1571		//
1572		if( show_more ) {
1573			cr_data.page = refElement.data( "page" );
1574			// click on 'show more' button
1575			jQuery(".cr-search-no-reviews").hide();
1576			jQuery('.cr-show-more-button').hide();
1577
1578			// dim the list of comments when dealing with the pagination
1579			if ( refElement.hasClass( "cr-page-numbers-a" ) ) {
1580				refElement.closest( ".cr-all-reviews-shortcode" ).find( ".commentlist" ).addClass( "cr-pagination-load" );
1581				refElement.closest( ".cr-all-reviews-shortcode" ).find( ".cr-all-reviews-pagination" ).addClass( "cr-pagination-load" );
1582			} else {
1583				refElement.closest( ".cr-all-reviews-shortcode" ).find( ".cr-show-more-review-spinner" ).show();
1584			}
1585
1586			jQuery.post(
1587				{
1588					url: cr_ajax_object.ajax_url,
1589					data: cr_data,
1590					context: refElement,
1591					success: function(response) {
1592						let shcode = jQuery(this).closest( ".cr-all-reviews-shortcode" );
1593						shcode.find( ".cr-show-more-review-spinner" ).hide();
1594						if( response.html !== "" ) {
1595							if ( jQuery(this).hasClass( "cr-page-numbers-a" ) ) {
1596								shcode.find(".commentlist").find("*").not(".cr-pagination-review-spinner").remove();
1597								shcode.find(".commentlist").prepend(response.html);
1598							} else {
1599								shcode.find(".commentlist").append(response.html);
1600							}
1601							if( ! response.last_page ) {
1602								shcode.find(".cr-show-more-button").text( response.show_more_label );
1603								shcode.find(".cr-show-more-button").show();
1604							}
1605							shcode.find(".cr-show-more-button").data( "page", response.page );
1606							shcode.find(".cr-count-row .cr-count-row-count").html( response.count_row );
1607							if ( response.pagination !== "" ) {
1608								shcode.find(".cr-all-reviews-pagination").html(response.pagination);
1609							}
1610						} else {
1611							shcode.find(".cr-show-more-button").hide();
1612						}
1613						if( response.html == "" && response.page === 1 ){
1614							shcode.find( ".cr-search-no-reviews" ).show();
1615						}
1616						shcode.find( ".commentlist" ).removeClass( "cr-pagination-load" );
1617						shcode.find( ".cr-all-reviews-pagination" ).removeClass( "cr-pagination-load" );
1618					},
1619					dataType: "json"
1620				}
1621			);
1622		} else {
1623			// click on 'search' button
1624			refElement.closest(".cr-all-reviews-shortcode").find(".cr-search-no-reviews").hide();
1625			refElement.closest(".cr-all-reviews-shortcode").find(".cr-show-more-button").hide();
1626			refElement.closest(".cr-all-reviews-shortcode").find(".commentlist").hide();
1627			refElement.closest(".cr-all-reviews-shortcode").find(".cr-show-more-review-spinner").show();
1628			refElement.closest(".cr-all-reviews-shortcode").find(".ivole-summaryBox").addClass("cr-summaryBar-updating");
1629			refElement.closest(".cr-all-reviews-shortcode").find(".cr-seeAllReviews").addClass("cr-seeAll-updating");
1630			refElement.closest(".cr-all-reviews-shortcode").find(".cr-ajax-reviews-sort").addClass("cr-sort-updating");
1631			refElement.closest(".cr-all-reviews-shortcode").find(".cr-review-tags-filter").addClass("cr-tags-updating");
1632			refElement.closest(".cr-all-reviews-shortcode").find(".cr-all-reviews-pagination").hide();
1633			jQuery.post(
1634				{
1635					url: cr_ajax_object.ajax_url,
1636					data: cr_data,
1637					context: refElement,
1638					success: function(response) {
1639						let shcode = jQuery(this).closest( ".cr-all-reviews-shortcode" );
1640						shcode.find( ".cr-show-more-review-spinner" ).hide();
1641						shcode.find(".ivole-summaryBox").removeClass("cr-summaryBar-updating");
1642						shcode.find(".cr-seeAllReviews").removeClass("cr-seeAll-updating");
1643						shcode.find(".cr-ajax-reviews-sort").removeClass("cr-sort-updating");
1644						shcode.find(".cr-review-tags-filter").removeClass("cr-tags-updating");
1645						if(response.html !== ""){
1646							shcode.find(".commentlist").empty();
1647							shcode.find(".commentlist").append(response.html);
1648							shcode.find(".commentlist").show();
1649							shcode.find(".cr-show-more-button").data("page",response.page);
1650							if( !response.last_page ){
1651								shcode.find(".cr-show-more-button").text( response.show_more_label );
1652								shcode.find(".cr-show-more-button").show();
1653							}
1654						} else {
1655							shcode.find(".cr-search-no-reviews").show();
1656						}
1657						shcode.find(".cr-count-row .cr-count-row-count").html( response.count_row );
1658						shcode.find(".cr-all-reviews-pagination").html(response.pagination);
1659						shcode.find(".cr-all-reviews-pagination").show();
1660					},
1661					dataType: "json"
1662				}
1663			);
1664		}
1665	}
1666
1667	function cr_maybe_download_media_frontend() {
1668		jQuery(".cr-comment-image-ext,.cr-comment-video-ext").each(function() {
1669			let ajaxData = {
1670				"action": "cr_auto_download_media_frontend",
1671				"reviewID": jQuery(this).data("reviewid")
1672			}
1673			jQuery.post(cr_ajax_object.ajax_url, ajaxData, function(response) {
1674				// do nothing
1675			}, "json");
1676			return false;
1677		});
1678	}
1679
1680	function crCaptchaEnabled() {
1681		return "undefined" !== typeof crCaptcha && crCaptcha.isEnabled();
1682	}
1683
1684	function cr_validate_review_form( submitBtn ) {
1685		let validationResult = true;
1686
1687		submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-cont.cr-review-form-rating-req" ).each( function( index ) {
1688			if( 1 > jQuery( this ).find( ".cr-review-form-rating-actv" ).length ) {
1689				jQuery( this ).closest( ".cr-review-form-rating" ).addClass( "cr-review-form-error" );
1690				validationResult = false;
1691			}
1692		} );
1693		if( 1 > submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment-txt" ).val().trim().length ) {
1694			submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment" ).addClass( "cr-review-form-error" );
1695			validationResult = false;
1696		}
1697		if( 1 > submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim().length ) {
1698			submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name" ).addClass( "cr-review-form-error" );
1699			validationResult = false;
1700		}
1701		if( ! crValidateEmail( submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim() ) ) {
1702			submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email" ).addClass( "cr-review-form-error" );
1703			validationResult = false;
1704		}
1705		// validate custom questions
1706		submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-question.cr-review-form-que-req" ).each( function( index ) {
1707			if ( 0 < jQuery( this ).find( "input[type=text]" ).length ) {
1708				if( 1 > jQuery( this ).find( "input[type=text]" ).val().trim().length ) {
1709					jQuery( this ).closest( ".cr-onsite-question" ).addClass( "cr-review-form-error" );
1710					validationResult = false;
1711				} else {
1712					jQuery( this ).closest( ".cr-onsite-question" ).removeClass( "cr-review-form-error" );
1713				}
1714			}
1715			if ( 0 < jQuery( this ).find( "input[type=number]" ).length ) {
1716				if( 1 > jQuery( this ).find( "input[type=number]" ).val().trim().length ) {
1717					jQuery( this ).closest( ".cr-onsite-question" ).addClass( "cr-review-form-error" );
1718					validationResult = false;
1719				} else {
1720					jQuery( this ).closest( ".cr-onsite-question" ).removeClass( "cr-review-form-error" );
1721				}
1722			}
1723		} );
1724		// validate terms and conditions if available
1725		if ( 0 < submitBtn.closest( ".cr-review-form-wrap" ).find( '.cr-review-form-terms' ).length ) {
1726			if ( ! submitBtn.closest( ".cr-review-form-wrap" ).find( '.cr-review-form-terms .cr-review-form-checkbox' ).is(':checked') ) {
1727				submitBtn.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-terms" ).addClass( "cr-review-form-error" );
1728				validationResult = false;
1729			}
1730		}
1731		if ( crCaptchaEnabled() && ! crCaptcha.isInvisible() ) {
1732			const captchaForm = submitBtn.closest( ".cr-review-form-wrap" );
1733			if ( 0 < captchaForm.find( '.cr-review-form-captcha .cr-captcha-widget' ).length ) {
1734				if ( "" === crCaptcha.getResponse( captchaForm ) ) {
1735					captchaForm.find( ".cr-review-form-captcha" ).addClass( "cr-review-form-error" );
1736					validationResult = false;
1737				}
1738			}
1739		}
1740
1741		return validationResult;
1742	}
1743
1744	function cr_validate_qna( submitBtn ) {
1745		let validationResult = true;
1746		if( 1 > submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment-txt" ).val().trim().length ) {
1747			submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment" ).addClass( "cr-review-form-error" );
1748			validationResult = false;
1749		}
1750		if( 1 > submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim().length ) {
1751			submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-name" ).addClass( "cr-review-form-error" );
1752			validationResult = false;
1753		}
1754		if( ! crValidateEmail( submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim() ) ) {
1755			submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-email" ).addClass( "cr-review-form-error" );
1756			validationResult = false;
1757		}
1758		if ( 0 < submitBtn.closest( ".cr-qna-new-q-form" ).find( '.cr-review-form-terms' ).length ) {
1759			if ( ! submitBtn.closest( ".cr-qna-new-q-form" ).find( '.cr-review-form-terms .cr-review-form-checkbox' ).is(':checked') ) {
1760				submitBtn.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-terms" ).addClass( "cr-review-form-error" );
1761				validationResult = false;
1762			}
1763		}
1764		return validationResult;
1765	}
1766
1767	function cr_validate_ans( submitBtn ) {
1768		let validationResult = true;
1769		if( 1 > submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment-txt" ).val().trim().length ) {
1770			submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment" ).addClass( "cr-review-form-error" );
1771			validationResult = false;
1772		}
1773		if( 1 > submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-name .cr-review-form-txt" ).val().trim().length ) {
1774			submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-name" ).addClass( "cr-review-form-error" );
1775			validationResult = false;
1776		}
1777		if( ! crValidateEmail( submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-email .cr-review-form-txt" ).val().trim() ) ) {
1778			submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-email" ).addClass( "cr-review-form-error" );
1779			validationResult = false;
1780		}
1781		if ( 0 < submitBtn.closest( ".cr-qna-list-inl-answ" ).find( '.cr-review-form-terms' ).length ) {
1782			if ( ! submitBtn.closest( ".cr-qna-list-inl-answ" ).find( '.cr-review-form-terms .cr-review-form-checkbox' ).is(':checked') ) {
1783				submitBtn.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-terms" ).addClass( "cr-review-form-error" );
1784				validationResult = false;
1785			}
1786		}
1787		return validationResult;
1788	}
1789
1790	function cr_reset_review_form( refElement ) {
1791		// reset the rating bar
1792		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-cont .cr-review-form-rating-inner" ).removeClass( "cr-review-form-rating-actv" );
1793		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-cont .cr-review-form-rating-inner .cr-rating-act" ).hide();
1794		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-cont .cr-review-form-rating-inner .cr-rating-deact" ).show();
1795		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating-cont .cr-review-form-rating-nbr" ).text( "0/5" );
1796		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-rating" ).removeClass( "cr-review-form-error" );
1797
1798		// reset the comment field
1799		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment-txt" ).val('');
1800		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1801
1802		// reset the name field
1803		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name .cr-review-form-txt" ).val('');
1804		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-name" ).removeClass( "cr-review-form-error" );
1805
1806		// reset the email field
1807		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email .cr-review-form-txt" ).val('');
1808		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-email" ).removeClass( "cr-review-form-error" );
1809
1810		// reset the custom questions
1811		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-questions .cr-onsite-question" ).removeClass( "cr-review-form-error" );
1812		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-questions .cr-onsite-question input[type = 'text']" ).val('');
1813		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-questions .cr-onsite-question input[type = 'number']" ).val('');
1814
1815		// reset the key custom questions
1816		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-key-question" ).removeClass( "cr-review-form-error" );
1817		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-key-question input[type = 'text']" ).val('');
1818		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-onsite-key-question input[type = 'number']" ).val('');
1819
1820		// reset the media files
1821		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media .cr-upload-images-containers" ).remove();
1822		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media .cr-form-item-media-preview" ).removeClass( "cr-form-visible" );
1823		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-form-item-media .cr-form-item-media-preview" ).parents( ".cr-form-item-subcontainer" ).removeClass( "cr-form-visible" );
1824
1825		// reset the terms and conditions checkbox
1826		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-terms .cr-review-form-checkbox" ).prop( 'checked', false );
1827		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1828
1829		// reset captcha
1830		refElement.closest( ".cr-review-form-wrap" ).find( ".cr-review-form-captcha" ).removeClass( "cr-review-form-error" );
1831		if ( crCaptchaEnabled() ) {
1832			crCaptcha.reset( refElement.closest( ".cr-review-form-wrap" ) );
1833		}
1834	}
1835
1836	function cr_reset_qna_form( refElement ) {
1837		// reset the comment field
1838		refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment-txt" ).val('');
1839		refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1840
1841		// reset the name field
1842		const nameField = refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-name" );
1843		nameField.find( ".cr-review-form-txt" ).val(nameField.find( ".cr-review-form-txt" ).data('defval'));
1844		nameField.removeClass( "cr-review-form-error" );
1845
1846		// reset the email field
1847		const emailField = refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-email" );
1848		emailField.find( ".cr-review-form-txt" ).val(emailField.find( ".cr-review-form-txt" ).data('defval'));
1849		emailField.removeClass( "cr-review-form-error" );
1850
1851		// reset the terms and conditions checkbox
1852		refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-terms .cr-review-form-checkbox" ).prop( 'checked', false );
1853		refElement.closest( ".cr-qna-new-q-form" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1854	}
1855
1856	function cr_reset_ans_form( refElement ) {
1857		// reset the comment field
1858		refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment-txt" ).val("");
1859		refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-comment" ).removeClass( "cr-review-form-error" );
1860
1861		// reset the name field
1862		const nameField = refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-name" );
1863		nameField.find( ".cr-review-form-txt" ).val("");
1864		nameField.removeClass( "cr-review-form-error" );
1865
1866		// reset the email field
1867		const emailField = refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-email" );
1868		emailField.find( ".cr-review-form-txt" ).val("");
1869		emailField.removeClass( "cr-review-form-error" );
1870
1871		// reset the terms and conditions checkbox
1872		refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-terms .cr-review-form-checkbox" ).prop( 'checked', false );
1873		refElement.closest( ".cr-qna-list-inl-answ" ).find( ".cr-review-form-terms" ).removeClass( "cr-review-form-error" );
1874	}
1875
1876	function crDebounce(callback, wait) {
1877		let timeout;
1878		return (...args) => {
1879			clearTimeout(timeout);
1880			if ( 0 < args.length && 13 === args[0].keyCode ) {
1881				wait = 0;
1882			} else {
1883				wait = 1000;
1884			}
1885			timeout = setTimeout(function () { callback.apply(this, args); }, wait);
1886		};
1887	}
1888
1889	function crShowMoreReviewsPrd( refElement ) {
1890		let cr_product_id = refElement.parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").attr("data-product");
1891		let cr_nonce = refElement.parents(".cr-reviews-ajax-comments").attr("data-nonce");
1892		let cr_page = refElement.parents(".cr-reviews-ajax-comments").attr("data-page");
1893		let cr_sort = refElement.parents(".cr-reviews-ajax-comments").find(".cr-ajax-reviews-sort").children("option:selected").val();
1894		let cr_rating = refElement.parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax .ivole-histogramRow.ivole-histogramRow-s a.cr-histogram-a").attr("data-rating");
1895		let cr_search = refElement.parents(".cr-reviews-ajax-comments").find(".cr-ajax-search input").val();
1896		let cr_tags = [];
1897		refElement.parents(".cr-reviews-ajax-comments").find(".cr-review-tags-filter .cr-tags-filter.cr-tag-selected").each(
1898			function() {
1899				cr_tags.push( jQuery(this).attr("data-crtagid") );
1900			}
1901		);
1902		if ( ! cr_rating ){
1903			cr_rating = 0;
1904		}
1905		let cr_data = {
1906			"action": "cr_show_more_reviews",
1907			"productID": cr_product_id,
1908			"page": cr_page,
1909			"sort": cr_sort,
1910			"rating": cr_rating,
1911			"search": cr_search,
1912			"tags": cr_tags,
1913			"security": cr_nonce
1914		};
1915		refElement.parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax").addClass("cr-summaryBar-updating");
1916		refElement.parents(".cr-reviews-ajax-comments").find(".cr-ajax-reviews-sort").addClass("cr-sort-updating");
1917		refElement.parents(".cr-reviews-ajax-comments").find(".cr-review-tags-filter").addClass("cr-review-tags-filter-disabled");
1918		refElement.parents(".cr-reviews-ajax-comments").find(".cr-search-no-reviews").hide();
1919		refElement.parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").hide();
1920		refElement.parents(".cr-reviews-ajax-comments").find(".cr-show-more-review-spinner").show();
1921		jQuery.post( {
1922			url: cr_ajax_object.ajax_url,
1923			data: cr_data,
1924			context: refElement,
1925			success: function(response) {
1926				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-review-spinner").hide();
1927				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-summaryBox-ajax").removeClass("cr-summaryBar-updating");
1928				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-ajax-reviews-sort").removeClass("cr-sort-updating");
1929				jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-review-tags-filter").removeClass("cr-review-tags-filter-disabled");
1930				if( response.page > 0 ) {
1931					jQuery(this).parents(".cr-reviews-ajax-comments").find(".commentlist.cr-ajax-reviews-list").append( response.html );
1932					jQuery(this).parents(".cr-reviews-ajax-comments").attr("data-page",response.page);
1933					if ( response.show_more_label ) {
1934						jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").text( response.show_more_label );
1935					}
1936					if ( response.count_row ) {
1937						jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-count-row .cr-count-row-count").html( response.count_row );
1938					}
1939					if ( ! response.last_page ) {
1940						jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-show-more-reviews-prd").show();
1941					}
1942					cr_maybe_download_media_frontend();
1943				}
1944				if ( response.html == null && response.page === 1 ) {
1945					jQuery(this).parents(".cr-reviews-ajax-comments").find(".cr-search-no-reviews").show();
1946				}
1947			},
1948			dataType: "json"
1949		} );
1950	}
1951
1952})();
1953
1954function crResizeAllGridItemsUtil(grids) {
1955	jQuery(grids).each( function() {
1956		if(800 > jQuery(this).width()) {
1957			jQuery(this).find(".cr-reviews-grid-col3").addClass("cr-reviews-grid-col-none");
1958		}
1959		if(550 > jQuery(this).width()) {
1960			jQuery(this).find(".cr-reviews-grid-col2").addClass("cr-reviews-grid-col-none");
1961		}
1962		jQuery(this).colcade( {
1963			columns: ".cr-reviews-grid-col",
1964			items: ".cr-review-card"
1965		} );
1966	} );
1967}
1968
1969function crResizeAllGridItems() {
1970	if (
1971		typeof Colcade !== "undefined" &&
1972		typeof Colcade.makeJQueryPlugin !== "undefined" &&
1973		typeof Colcade.makeJQueryPlugin === "function"
1974	) {
1975		if (
1976			! typeof jQuery.fn.colcade === "function" ||
1977			typeof jQuery.fn.colcade === "undefined"
1978		) {
1979			Colcade.makeJQueryPlugin();
1980		}
1981	}
1982	crResizeAllGridItemsUtil( jQuery(".cr-reviews-grid-inner") );
1983}
1984
1985function crResizeTrustBadges() {
1986	jQuery(".cr-trustbadgef").each(function() {
1987		let badge = jQuery(this).find(".cr-badge").eq(0);
1988		let scale = jQuery(this).width() / badge.outerWidth();
1989		if( 1 > scale ) {
1990			badge.css("transform", "scale(" + scale + ")");
1991		}
1992		badge.css("visibility", "visible");
1993	});
1994}

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.