From f5d15532f58dbed18798e1d8cd53334a954758ed Mon Sep 17 00:00:00 2001
From: PranavAwasthi <pranavawasthi01@gmail.com>
Date: Tue, 23 Jan 2024 11:23:20 +0530
Subject: [PATCH 1/4] Fixed advance question type compatibility with inline
 result

---
 js/qsm-quiz.js | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/js/qsm-quiz.js b/js/qsm-quiz.js
index 2efce226c..670663697 100644
--- a/js/qsm-quiz.js
+++ b/js/qsm-quiz.js
@@ -1867,6 +1867,13 @@ function qsm_question_quick_result_js(question_id, answer, answer_type = '', sho
 			got_ans = true;
 		}
 
-		return { "correct_index": correct_index, "success": correct_answer ? 'correct' : 'incorrect', "message": show_correct_info && got_ans ? correct_info_text : "" };
+		let returnObject = { 
+			"correct_index": correct_index, 
+			"success": correct_answer ? 'correct' : 'incorrect', 
+			"message": show_correct_info && got_ans ? correct_info_text : "" 
+		};
+
+		jQuery(document).trigger('qsm_question_quick_result_js_after', [returnObject, correct_answer, answer, answer_array, answer_type, settings, decrypt, question_id]);
+		return returnObject;
 	}
 }

From 326b74deb34d650e68ea8acabbc1e03701486b5b Mon Sep 17 00:00:00 2001
From: Mohammad Zubair Ali <zubair@expresstech.io>
Date: Tue, 23 Jan 2024 12:38:11 +0530
Subject: [PATCH 2/4] merged with dev2

---
 js/qsm-quiz.js                            | 9 ++++-----
 mlw_quizmaster2.php                       | 4 ++--
 php/question-types/qsm-question-title.php | 2 +-
 readme.txt                                | 9 ++++++++-
 4 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/js/qsm-quiz.js b/js/qsm-quiz.js
index 670663697..254ba7e74 100644
--- a/js/qsm-quiz.js
+++ b/js/qsm-quiz.js
@@ -1330,7 +1330,6 @@ function qmnInitPagination(quiz_id) {
 
 	jQuery(document).trigger('qsm_init_pagination_after', [quiz_id, qmn_quiz_data]);
 }
-
 jQuery(document).on('qsm_next_button_click_after qsm_previous_button_click_after', function(event, quiz_id) {
 	let video_sections = jQuery('.qsm-quiz-container-' + quiz_id + '.qmn_quiz_container').find('video');
 	let iframeVideos = jQuery('.qsm-quiz-container-' + quiz_id + '.qmn_quiz_container .qsm-page, .qsm-quiz-container-' + quiz_id + '.qmn_quiz_container .qsm-auto-page-row').find('iframe');
@@ -1867,10 +1866,10 @@ function qsm_question_quick_result_js(question_id, answer, answer_type = '', sho
 			got_ans = true;
 		}
 
-		let returnObject = { 
-			"correct_index": correct_index, 
-			"success": correct_answer ? 'correct' : 'incorrect', 
-			"message": show_correct_info && got_ans ? correct_info_text : "" 
+		let returnObject = {
+			"correct_index": correct_index,
+			"success": correct_answer ? 'correct' : 'incorrect',
+			"message": show_correct_info && got_ans ? correct_info_text : ""
 		};
 
 		jQuery(document).trigger('qsm_question_quick_result_js_after', [returnObject, correct_answer, answer, answer_array, answer_type, settings, decrypt, question_id]);
diff --git a/mlw_quizmaster2.php b/mlw_quizmaster2.php
index b4130e1b5..628392474 100644
--- a/mlw_quizmaster2.php
+++ b/mlw_quizmaster2.php
@@ -2,7 +2,7 @@
 /**
  * Plugin Name: Quiz And Survey Master
  * Description: Easily and quickly add quizzes and surveys to your website.
- * Version: 8.2.1
+ * Version: 8.2.2
  * Author: ExpressTech
  * Author URI: https://quizandsurveymaster.com/
  * Plugin URI: https://expresstech.io/
@@ -43,7 +43,7 @@ class MLWQuizMasterNext {
 	 * @var string
 	 * @since 4.0.0
 	 */
-	public $version = '8.2.1';
+	public $version = '8.2.2';
 
 	/**
 	 * QSM Alert Manager Object
diff --git a/php/question-types/qsm-question-title.php b/php/question-types/qsm-question-title.php
index 6471cee38..bc730e070 100644
--- a/php/question-types/qsm-question-title.php
+++ b/php/question-types/qsm-question-title.php
@@ -22,7 +22,7 @@ function qsm_question_title_func( $question, $question_type = '', $new_question_
 		$deselect_answer_text = ! empty( $qmn_quiz_options->deselect_answer_text ) ? $qmn_quiz_options->deselect_answer_text : $default_texts['deselect_answer_text'];
 		$deselect_answer = '<a href="javascript:void(0)" class="qsm-deselect-answer">'. $mlwQuizMasterNext->pluginHelper->qsm_language_support( $deselect_answer_text, "deselect_answer_text-{$qmn_quiz_options->quiz_id}" ) .'</a>';
 	}
-	do_action('qsm_question_title_func_before',$question, $question_type, $new_question_title, $question_id );
+	do_action('qsm_question_title_function_before',$question, $question_type, $new_question_title, $question_id );
 	if ( '' !== $new_question_title ) {
 		$new_question_title = $mlwQuizMasterNext->pluginHelper->qsm_language_support( htmlspecialchars_decode( $new_question_title, ENT_QUOTES ), "Question-{$question_id}", "QSM Questions");
 		$new_question_title = apply_filters( 'qsm_question_title_before', $new_question_title, $question_type, $question_id );
diff --git a/readme.txt b/readme.txt
index fe5a6eae8..8500c2b12 100644
--- a/readme.txt
+++ b/readme.txt
@@ -4,7 +4,7 @@ Tags: quiz, survey, lead, test, score, exam, questionnaire, question,wordpress q
 Requires at least: 4.9
 Tested up to: 6.4
 Requires PHP: 5.4
-Stable tag: 8.2.1
+Stable tag: 8.2.2
 License: GPLv2
 License URI: http://www.gnu.org/licenses/gpl-2.0.html
 
@@ -163,6 +163,13 @@ This is usually a theme conflict. You can [checkout out our common conflict solu
 18. Database
 
 == Changelog ==
+= 8.2.2 (January 18, 2024) =
+* Feature: Added an option to mark texts as code snippets in the question description
+* Bug: Fixed the issue of skipping question validation after the quiz timer ends
+* Bug: Fixed issue when using apostrophe in fill-in-the-blanks questions
+* Bug: Fixed the quiz navigation problem with reCAPTCHA
+* Enhancement: Improved auto-pause logic for embedded audio when shifting pages.
+
 = 8.2.1 (January 05, 2024) =
 * Feature: Added option to delete bulk questions
 * Bug: Resolved JavaScript conflicts

From 5ddd4386c03df2f7f15d1e44180bdf1c7782c0b4 Mon Sep 17 00:00:00 2001
From: PranavAwasthi <pranavawasthi01@gmail.com>
Date: Wed, 24 Jan 2024 12:04:31 +0530
Subject: [PATCH 3/4] Changed function positions to access from addon

---
 js/qsm-quiz.js | 184 +++++++++++++++++++++++++------------------------
 1 file changed, 93 insertions(+), 91 deletions(-)

diff --git a/js/qsm-quiz.js b/js/qsm-quiz.js
index 670663697..752c8bdce 100644
--- a/js/qsm-quiz.js
+++ b/js/qsm-quiz.js
@@ -1483,98 +1483,8 @@ jQuery(function () {
 		}, 2000);
 	});
 
-	const videoAttributePatterns = [
-		/\ssrc="([^"]+)"/,
-		/\smp4="([^"]+)"/,
-		/\sm4v="([^"]+)"/,
-		/\swebm="([^"]+)"/,
-		/\sogv="([^"]+)"/,
-		/\swmv="([^"]+)"/,
-		/\sflv="([^"]+)"/,
-		/\swidth="(\d+)"/,
-		/\sheight="(\d+)"/
-	];
-
-	function parseAttributes(match, src, width, height) {
-		let videoAttrs = { src: '', width: '', height: '' };
-
-		videoAttributePatterns.forEach(pattern => {
-			const attrMatch = match.match(pattern);
-			if (attrMatch) {
-				const value = attrMatch[1] || '';
-				if (pattern.toString().includes('width')) {
-					videoAttrs.width = value;
-				} else if (pattern.toString().includes('height')) {
-					videoAttrs.height = value;
-				} else {
-					videoAttrs.src = value;
-				}
-			}
-		});
-
-		return videoAttrs;
-	}
-
-	function generateVideoTag(src, width, height, content) {
-		return `<video src="${src}" width="${width}" height="${height}" controls>${content}</video>`;
-	}
-
-	function qsm_check_shortcode(message = null) {
-		const videoContentRegex = /\[video(?:\s(?:src|mp4|m4v|webm|ogv|wmv|flv|width|height)="[^"]*")*\](.*?)\[\/video\]/g;
-		let videoMatch = message.match(videoContentRegex);
-
-		if (videoMatch) {
-			let videoHTML = message.replace(videoContentRegex, function(match, content) {
-				const { src, width, height } = parseAttributes(match);
-				const videoTag = generateVideoTag(src, width, height, content);
-				return `<div class="video-content">${videoTag}</div>`;
-			});
-			return videoHTML;
-		}
-
-		// Check if message contains an image shortcode
-		let imageRegex = /\[img(?:(?:\ssrc="([^"]+)")|(?:\salt="([^"]+)")|(?:\swidth="(\d+)")|(?:\sheight="(\d+)")){0,4}\s*\]/g;
-		let imageMatch = message.match(imageRegex);
-
-		if (imageMatch) {
-			let imageHTML = message.replace(imageRegex, function(match, src, alt, width, height) {
-				return '<img src="' + (src || '') + '" alt="' + (alt || '') + '" width="' + (width || '') + '" height="' + (height || '') + '">';
-			});
-			return '<div class="image-content">' + imageHTML + '</div>';
-		}
-
-		return message;
-	}
-
 	//inline result status function
-	function qsm_show_inline_result(quizID, question_id, value, $this, answer_type, $i_this, index = null) {
-		jQuery('.qsm-spinner-loader').remove();
-		addSpinnerLoader($this,$i_this);
-		let data = qsm_question_quick_result_js(question_id, value, answer_type, qmn_quiz_data[quizID].enable_quick_correct_answer_info,quizID);
-		$this.find('.quick-question-res-p, .qsm-inline-correct-info').remove();
-		$this.find('.qmn_radio_answers').children().removeClass('data-correct-answer');
-		if ( 0 < value.length && data.success == 'correct') {
-			$this.append('<div style="color: green" class="quick-question-res-p qsm-correct-answer-info">' + qmn_quiz_data[quizID].quick_result_correct_answer_text + '</div>')
-			$this.append('<div class="qsm-inline-correct-info">' + qsm_check_shortcode(data.message) + '</div>');
-		} else if ( 0 < value.length && data.success == 'incorrect') {
-			$this.find('.qmn_radio_answers').children().eq(parseInt(data.correct_index)).addClass('data-correct-answer');
-			$this.append('<div style="color: red" class="quick-question-res-p qsm-incorrect-answer-info">' + qmn_quiz_data[quizID].quick_result_wrong_answer_text + '</div>')
-			$this.append('<div class="qsm-inline-correct-info">' + qsm_check_shortcode(data.message) + '</div>');
-		}
-		if (1 != qmn_quiz_data[quizID].disable_mathjax) {
-			MathJax.typesetPromise();
-		}
-		jQuery('.qsm-spinner-loader').remove();
-	}
-	function addSpinnerLoader($this,$i_this) {
-		if ($this.find('.mlw_answer_open_text').length) {
-			$this.find('.mlw_answer_open_text').after('<div class="qsm-spinner-loader" style="font-size: 2.5px;margin-left:10px;"></div>');
-		  } else if ($this.find('.mlw_answer_number').length) {
-			$this.find('.mlw_answer_number').after('<div class="qsm-spinner-loader" style="font-size: 2.5px;margin-left:10px;"></div>');
-		  } else {
-			$i_this.next('.qsm-input-label').after('<div class="qsm-spinner-loader" style="font-size: 2.5px;"></div>');
-		  }
-	  }
+	
 	// Autocomplete off
 	jQuery('.qsm-quiz-container').find('.qmn_quiz_id').each(function () {
 		var quizID = jQuery(this).val();
@@ -1732,6 +1642,98 @@ jQuery(function () {
 	});
 });
 
+const videoAttributePatterns = [
+	/\ssrc="([^"]+)"/,
+	/\smp4="([^"]+)"/,
+	/\sm4v="([^"]+)"/,
+	/\swebm="([^"]+)"/,
+	/\sogv="([^"]+)"/,
+	/\swmv="([^"]+)"/,
+	/\sflv="([^"]+)"/,
+	/\swidth="(\d+)"/,
+	/\sheight="(\d+)"/
+];
+
+function parseAttributes(match, src, width, height) {
+	let videoAttrs = { src: '', width: '', height: '' };
+
+	videoAttributePatterns.forEach(pattern => {
+		const attrMatch = match.match(pattern);
+		if (attrMatch) {
+			const value = attrMatch[1] || '';
+			if (pattern.toString().includes('width')) {
+				videoAttrs.width = value;
+			} else if (pattern.toString().includes('height')) {
+				videoAttrs.height = value;
+			} else {
+				videoAttrs.src = value;
+			}
+		}
+	});
+
+	return videoAttrs;
+}
+
+function generateVideoTag(src, width, height, content) {
+	return `<video src="${src}" width="${width}" height="${height}" controls>${content}</video>`;
+}
+
+function qsm_check_shortcode(message = null) {
+	const videoContentRegex = /\[video(?:\s(?:src|mp4|m4v|webm|ogv|wmv|flv|width|height)="[^"]*")*\](.*?)\[\/video\]/g;
+	let videoMatch = message.match(videoContentRegex);
+
+	if (videoMatch) {
+		let videoHTML = message.replace(videoContentRegex, function(match, content) {
+			const { src, width, height } = parseAttributes(match);
+			const videoTag = generateVideoTag(src, width, height, content);
+			return `<div class="video-content">${videoTag}</div>`;
+		});
+		return videoHTML;
+	}
+
+	// Check if message contains an image shortcode
+	let imageRegex = /\[img(?:(?:\ssrc="([^"]+)")|(?:\salt="([^"]+)")|(?:\swidth="(\d+)")|(?:\sheight="(\d+)")){0,4}\s*\]/g;
+	let imageMatch = message.match(imageRegex);
+
+	if (imageMatch) {
+		let imageHTML = message.replace(imageRegex, function(match, src, alt, width, height) {
+			return '<img src="' + (src || '') + '" alt="' + (alt || '') + '" width="' + (width || '') + '" height="' + (height || '') + '">';
+		});
+		return '<div class="image-content">' + imageHTML + '</div>';
+	}
+
+	return message;
+}
+
+function qsm_show_inline_result(quizID, question_id, value, $this, answer_type, $i_this, index = null) {
+	jQuery('.qsm-spinner-loader').remove();
+	addSpinnerLoader($this,$i_this);
+	let data = qsm_question_quick_result_js(question_id, value, answer_type, qmn_quiz_data[quizID].enable_quick_correct_answer_info,quizID);
+	$this.find('.quick-question-res-p, .qsm-inline-correct-info').remove();
+	$this.find('.qmn_radio_answers').children().removeClass('data-correct-answer');
+	if ( 0 < value.length && data.success == 'correct') {
+		$this.append('<div style="color: green" class="quick-question-res-p qsm-correct-answer-info">' + qmn_quiz_data[quizID].quick_result_correct_answer_text + '</div>')
+		$this.append('<div class="qsm-inline-correct-info">' + qsm_check_shortcode(data.message) + '</div>');
+	} else if ( 0 < value.length && data.success == 'incorrect') {
+		$this.find('.qmn_radio_answers').children().eq(parseInt(data.correct_index)).addClass('data-correct-answer');
+		$this.append('<div style="color: red" class="quick-question-res-p qsm-incorrect-answer-info">' + qmn_quiz_data[quizID].quick_result_wrong_answer_text + '</div>')
+		$this.append('<div class="qsm-inline-correct-info">' + qsm_check_shortcode(data.message) + '</div>');
+	}
+	if (1 != qmn_quiz_data[quizID].disable_mathjax) {
+		MathJax.typesetPromise();
+	}
+	jQuery('.qsm-spinner-loader').remove();
+}
+function addSpinnerLoader($this,$i_this) {
+	if ($this.find('.mlw_answer_open_text').length) {
+		$this.find('.mlw_answer_open_text').after('<div class="qsm-spinner-loader" style="font-size: 2.5px;margin-left:10px;"></div>');
+	  } else if ($this.find('.mlw_answer_number').length) {
+		$this.find('.mlw_answer_number').after('<div class="qsm-spinner-loader" style="font-size: 2.5px;margin-left:10px;"></div>');
+	  } else {
+		$i_this.next('.qsm-input-label').after('<div class="qsm-spinner-loader" style="font-size: 2.5px;"></div>');
+	  }
+  }
+
 // captcha question type
 var mlw_code;
 jQuery(document).ready(function () {

From 4f6f4e9ec5384f8b1408ed6580e937efcf8bb107 Mon Sep 17 00:00:00 2001
From: PranavAwasthi <pranavawasthi01@gmail.com>
Date: Wed, 24 Jan 2024 14:59:10 +0530
Subject: [PATCH 4/4] Fixed contact form pop up issue

---
 php/classes/class-qmn-quiz-manager.php | 1 +
 1 file changed, 1 insertion(+)

diff --git a/php/classes/class-qmn-quiz-manager.php b/php/classes/class-qmn-quiz-manager.php
index ab4153d26..a3a70a293 100644
--- a/php/classes/class-qmn-quiz-manager.php
+++ b/php/classes/class-qmn-quiz-manager.php
@@ -894,6 +894,7 @@ public function display_quiz( $options, $quiz_data, $question_amount, $shortcode
 		wp_enqueue_script( 'jquery-ui-core' );
 		wp_enqueue_script( 'jquery-ui-tooltip' );
 		wp_enqueue_style( 'jquery-redmond-theme', QSM_PLUGIN_CSS_URL . '/jquery-ui.css', array(), $mlwQuizMasterNext->version );
+		wp_enqueue_style( 'qsm_quiz_common_style', $this->common_css, array(), $mlwQuizMasterNext->version );
 
 		global $qmn_json_data;
 		$qmn_json_data['error_messages'] = array(