PageSourceSearch

https://pauljohncaffeine.in/wp-content/plugins/customer-reviews-woocommerce/js/frontend.js?ver=5.93.0

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

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.