{"version":3,"sources":["llms-quiz.js"],"names":["$","quiz","$buttons","$container","$ui","attempt_key","current_question","total_questions","questions","validators","status","bind","self","this","on","e","preventDefault","start_quiz","each","LLMS","Donut","val","window","location","href","l10n","translate","complete_quiz","document","post_append_question","register_validator","validate","validate_choice","add_error","msg","find","remove","$err","fadeOut","setTimeout","append","answer_question","$btn","valid","$question","type","attr","answer","Ajax","call","data","action","question_id","question_type","beforeSend","hasClass","toggle_loader","update_progress_bar","success","r","html","load_question","redirect","message","console","log","get_question_index","qid","Object","keys","indexOf","url","previous_question","ids","curr","prev_id","func","load_ui_elements","lesson_id","quiz_id","stop","animate","scrollTop","error","s","t","time_limit","start_quiz_timer","total","is_touch_device","addClass","removeClass","total_minutes","$el","days","hours","minutes","seconds","target_date","Date","getTime","countdown","getElementById","getCountdown","setInterval","trigger","event","$html","update_progress","$header","$footer","after","length","wp","mediaelement","initialize","display","empty","Spinner","start","removeAttr","index","text","show","hide","dir","progress","css","seconds_left","pad","parseInt","innerHTML","n","ret","llms","quizzes","checked","push","jQuery"],"mappings":"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","file":"../../js/llms-quiz.min.js","sourcesContent":[";/* global LLMS, $ */\n/* jshint strict: true */\n\n/**\n * Front End Quiz Class\n *\n * @type     {Object}\n * @since    1.0.0\n * @version  3.24.3\n */( function( $ ) {\n\n\tvar quiz = {\n\n\t\t/**\n\t\t * Selector of all the available button elements\n\t\t *\n\t\t * @type  obj\n\t\t */\n\t\t$buttons: null,\n\n\t\t/**\n\t\t * Main Question Container Element\n\t\t *\n\t\t * @type  obj\n\t\t */\n\t\t$container: null,\n\n\t\t/**\n\t\t * Main Quiz container UI element\n\t\t *\n\t\t * @type  obj\n\t\t */\n\t\t$ui: null,\n\n\t\t/**\n\t\t * Attempt key for the current quiz\n\t\t *\n\t\t * @type  {[type]}\n\t\t */\n\t\tattempt_key: null,\n\n\t\t/**\n\t\t * Question ID of the current question\n\t\t *\n\t\t * @type  {Number}\n\t\t */\n\t\tcurrent_question: 0,\n\n\t\t/**\n\t\t * Total number of questions in the current quiz\n\t\t *\n\t\t * @type  {Number}\n\t\t */\n\t\ttotal_questions: 0,\n\n\t\t/**\n\t\t * Object of quiz question HTML\n\t\t *\n\t\t * @type  {Object}\n\t\t */\n\t\tquestions: {},\n\n\t\t/**\n\t\t * Validator functions for question types\n\t\t * Third party custom question types can register validators for use when answering questions\n\t\t *\n\t\t * @type  {Object}\n\t\t */\n\t\tvalidators: {},\n\n\t\t/**\n\t\t * Records current status of a quiz session\n\t\t * If a user attempts to navigate away from a quiz\n\t\t * while taking the quiz they'll be warned that their progress\n\t\t * will not be saved if this status is not null\n\t\t *\n\t\t * @type  boolean\n\t\t */\n\t\tstatus: null,\n\n\t\t/**\n\t\t * Bind DOM events\n\t\t *\n\t\t * @return void\n\t\t * @since    1.0.0\n\t\t * @version  3.16.6\n\t\t */\n\t\tbind: function() {\n\n\t\t\tvar self = this;\n\n\t\t\t// start quiz\n\t\t\t$( '#llms_start_quiz' ).on( 'click', function( e ) {\n\t\t\t\te.preventDefault();\n\t\t\t\tself.start_quiz();\n\t\t\t} );\n\n\t\t\t// draw quiz grade circular chart\n\t\t\t$( '.llms-donut' ).each( function() {\n\t\t\t\tLLMS.Donut( $( this ) );\n\t\t\t} );\n\n\t\t\t// redirect to attempt on attempt selection change\n\t\t\t$( '#llms-quiz-attempt-select' ).on( 'change', function() {\n\t\t\t\tvar val = $( this ).val();\n\t\t\t\tif ( val ) {\n\t\t\t\t\twindow.location.href = val;\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// warn when quiz is running and user tries to leave the page\n\t\t\t$( window ).on( 'beforeunload', function() {\n\t\t\t\tif ( self.status ) {\n\t\t\t\t\treturn LLMS.l10n.translate( 'Are you sure you wish to quit this quiz attempt?' );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t// complete the quiz attempt when user leaves if the quiz is running\n\t\t\t$( window ).on( 'unload', function() {\n\t\t\t\tif ( self.status ) {\n\t\t\t\t\tself.complete_quiz();\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\t$( document ).on( 'llms-post-append-question', self.post_append_question );\n\n\t\t\t// register validators\n\t\t\tthis.register_validator( 'content', this.validate );\n\t\t\tthis.register_validator( 'choice', this.validate_choice );\n\t\t\tthis.register_validator( 'picture_choice', this.validate_choice );\n\t\t\tthis.register_validator( 'true_false', this.validate_choice );\n\n\t\t},\n\n\t\t/**\n\t\t * Add an error message to the UI\n\t\t *\n\t\t * @param    string   msg  error message string\n\t\t * @return   void\n\t\t * @since    3.16.0\n\t\t * @version  3.16.0\n\t\t */\n\t\tadd_error: function( msg ) {\n\n\t\t\tvar self = this;\n\n\t\t\tself.$container.find( '.llms-error' ).remove();\n\t\t\tvar $err = $( '<p class=\"llms-error\">' + msg + '<a href=\"#\"><i class=\"fa fa-times-circle\" aria-hidden=\"true\"></i></a></p>' );\n\t\t\t$err.on( 'click', 'a', function( e ) {\n\t\t\t\te.preventDefault();\n\t\t\t\t$err.fadeOut( '200' );\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\t$err.remove();\n\t\t\t\t}, 210 );\n\t\t\t} );\n\t\t\tself.$container.append( $err );\n\n\t\t},\n\n\t\t/**\n\t\t * Answer a Question\n\t\t *\n\t\t * @param    obj   $btn   jQuery object for the \"Next Lesson\" button\n\t\t * @return   void\n\t\t * @since    1.0.0\n\t\t * @version  3.16.6\n\t\t */\n\t\tanswer_question: function( $btn ) {\n\n\t\t\tvar self      = this,\n\t\t\t\t$question = this.$container.find( '.llms-question-wrapper' ),\n\t\t\t\ttype      = $question.attr( 'data-type' ),\n\t\t\t\tvalid;\n\n\t\t\tif ( ! this.validators[ type ] ) {\n\n\t\t\t\tconsole.log( 'No validator registered for question type ' + type );\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\tvalid = this.validators[ type ]( $question );\n\t\t\tif ( ! valid || true !== valid.valid || ! valid.answer ) {\n\t\t\t\treturn self.add_error( valid.valid );\n\t\t\t}\n\n\t\t\tLLMS.Ajax.call( {\n\t\t\t\tdata: {\n\t\t\t\t\taction: 'quiz_answer_question',\n\t\t\t\t\tanswer: valid.answer,\n\t\t\t\t\tattempt_key: self.attempt_key,\n\t\t\t\t\tquestion_id: $question.attr( 'data-id' ),\n\t\t\t\t\tquestion_type: $question.attr( 'data-type' ),\n\t\t\t\t},\n\t\t\t\tbeforeSend: function() {\n\n\t\t\t\t\tvar msg = $btn.hasClass( 'llms-button-quiz-complete' ) ? LLMS.l10n.translate( 'Grading Quiz...' ) : LLMS.l10n.translate( 'Loading Question...' );\n\t\t\t\t\tself.toggle_loader( 'show', msg );\n\n\t\t\t\t\tself.update_progress_bar( 'increment' );\n\n\t\t\t\t},\n\t\t\t\tsuccess: function( r ) {\n\n\t\t\t\t\tself.toggle_loader( 'hide' );\n\n\t\t\t\t\tif ( r.data && r.data.html ) {\n\n\t\t\t\t\t\t// load html from the cached questions if it exists already\n\t\t\t\t\t\tif ( r.data.question_id && self.questions[ 'q-' + r.data.question_id ] ) {\n\n\t\t\t\t\t\t\tself.load_question( self.questions[ 'q-' + r.data.question_id ] );\n\n\t\t\t\t\t\t\t// load html from server if the question's never been seen before\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tself.load_question( r.data.html );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if ( r.data && r.data.redirect ) {\n\n\t\t\t\t\t\tself.redirect( r.data.redirect );\n\n\t\t\t\t\t} else if ( r.message ) {\n\n\t\t\t\t\t\tself.$container.append( '<p>' + r.message + '</p>' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar msg = LLMS.l10n.translate( 'An unknown error occurred. Please try again.' );\n\t\t\t\t\t\tself.$container.append( '<p>' + msg + '</p>' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t},\n\n\t\t/**\n\t\t * Complete the quiz\n\t\t * Called when timed quizzes reach time limit\n\t\t * & during unload events to record the attempt as abandoned\n\t\t *\n\t\t * @return   void\n\t\t * @since    1.0.0\n\t\t * @version  3.9.0\n\t\t */\n\t\tcomplete_quiz: function() {\n\n\t\t\tvar self = this;\n\n\t\t\tLLMS.Ajax.call( {\n\t\t\t\tdata: {\n\t\t\t\t\taction: 'quiz_end',\n\t\t\t\t\tattempt_key: self.attempt_key,\n\t\t\t\t},\n\t\t\t\tbeforeSend: function() {\n\n\t\t\t\t\tself.toggle_loader( 'show', 'Grading Quiz...' );\n\n\t\t\t\t},\n\t\t\t\tsuccess: function( r ) {\n\n\t\t\t\t\tself.toggle_loader( 'hide' );\n\n\t\t\t\t\tif ( r.data && r.data.redirect ) {\n\n\t\t\t\t\t\tself.redirect( r.data.redirect );\n\n\t\t\t\t\t} else if ( r.message ) {\n\n\t\t\t\t\t\tself.$container.append( '<p>' + r.message + '</p>' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar msg = LLMS.l10n.translate( 'An unknown error occurred. Please try again.' );\n\t\t\t\t\t\tself.$container.append( '<p>' + msg + '</p>' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t},\n\n\t\t/**\n\t\t * Retrieve the index of a question by question id\n\t\t *\n\t\t * @param    int   qid  WP Post ID of the question\n\t\t * @return   int\n\t\t * @since    3.16.0\n\t\t * @version  3.16.0\n\t\t */\n\t\tget_question_index: function( qid ) {\n\n\t\t\treturn Object.keys( this.questions ).indexOf( 'q-' + qid );\n\n\t\t},\n\n\t\t/**\n\t\t * Redirect on quiz completion / timeout\n\t\t *\n\t\t * @param    string   url  redirect url\n\t\t * @return   void\n\t\t * @since    3.9.0\n\t\t * @version  3.16.0\n\t\t */\n\t\tredirect: function( url ) {\n\n\t\t\tthis.toggle_loader( 'show', 'Grading Quiz...' );\n\t\t\tthis.status          = null;\n\t\t\twindow.location.href = url;\n\n\t\t},\n\n\t\t/**\n\t\t * Return to the previous question\n\t\t *\n\t\t * @return   void\n\t\t * @since    1.0.0\n\t\t * @version  3.16.6\n\t\t */\n\t\tprevious_question: function() {\n\n\t\t\tvar self = this;\n\n\t\t\tself.toggle_loader( 'show', LLMS.l10n.translate( 'Loading Question...' ) );\n\t\t\tself.update_progress_bar( 'decrement' );\n\n\t\t\tvar ids     = Object.keys( self.questions ),\n\t\t\t\tcurr    = ids.indexOf( 'q-' + self.current_question ),\n\t\t\t\tprev_id = ids[0];\n\n\t\t\tif ( curr >= 1 ) {\n\t\t\t\tprev_id = ids[ curr - 1 ];\n\t\t\t}\n\n\t\t\tsetTimeout( function() {\n\t\t\t\tself.toggle_loader( 'hide' );\n\t\t\t\tself.load_question( self.questions[ prev_id ] );\n\t\t\t}, 100 );\n\n\t\t},\n\n\t\t/**\n\t\t * Register question type validator functions\n\t\t *\n\t\t * @param    string     type  question type id\n\t\t * @param    function   func  callback function to validate the question with\n\t\t * @return   void\n\t\t * @since    3.16.0\n\t\t * @version  3.16.0\n\t\t */\n\t\tregister_validator: function( type, func ) {\n\n\t\t\tthis.validators[ type ] = func;\n\n\t\t},\n\n\t\t/**\n\t\t * Start a Quiz via AJAX call\n\t\t *\n\t\t * @return   void\n\t\t * @since    1.0.0\n\t\t * @version  3.24.3\n\t\t */\n\t\tstart_quiz: function () {\n\n\t\t\tvar self = this;\n\n\t\t\tthis.load_ui_elements();\n\t\t\tthis.$ui        = $( '#llms-quiz-ui' );\n\t\t\tthis.$buttons   = $( '#llms-quiz-nav button' );\n\t\t\tthis.$container = $( '#llms-quiz-question-wrapper' );\n\n\t\t\t// bind submission event for answering questions\n\t\t\t$( '#llms-next-question, #llms-complete-quiz' ).on( 'click', function( e ) {\n\t\t\t\te.preventDefault();\n\t\t\t\tself.answer_question( $( this ) );\n\t\t\t} );\n\n\t\t\t// bind submission event for navigating backwards\n\t\t\t$( '#llms-prev-question' ).on( 'click', function( e ) {\n\t\t\t\te.preventDefault();\n\t\t\t\tself.previous_question();\n\t\t\t} );\n\n\t\t\tLLMS.Ajax.call( {\n\t\t\t\tdata: {\n\t\t\t\t\taction: 'quiz_start',\n\t\t\t\t\tattempt_key: $( '#llms-attempt-key' ).val(),\n\t\t\t\t\tlesson_id : $( '#llms-lesson-id' ).val(),\n\t\t\t\t\tquiz_id : $( '#llms-quiz-id' ).val(),\n\t\t\t\t},\n\t\t\t\tbeforeSend: function() {\n\n\t\t\t\t\tself.status = true;\n\t\t\t\t\t$( '#llms-quiz-wrapper, #quiz-start-button' ).remove();\n\t\t\t\t\t$( 'html, body' ).stop().animate( {scrollTop: 0 }, 500 );\n\t\t\t\t\tself.toggle_loader( 'show', LLMS.l10n.translate( 'Loading Quiz...' ) );\n\n\t\t\t\t},\n\t\t\t\terror: function( r, s, t ) {\n\t\t\t\t\tconsole.log( r, s, t );\n\t\t\t\t},\n\t\t\t\tsuccess: function( r ) {\n\n\t\t\t\t\tself.toggle_loader( 'hide' );\n\n\t\t\t\t\tif ( r.data && r.data.html ) {\n\n\t\t\t\t\t\t// start the quiz timer when a time limit is set\n\t\t\t\t\t\tif ( r.data.time_limit ) {\n\t\t\t\t\t\t\tself.start_quiz_timer( r.data.time_limit );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tself.attempt_key     = r.data.attempt_key;\n\t\t\t\t\t\tself.total_questions = r.data.total;\n\n\t\t\t\t\t\tself.load_question( r.data.html );\n\n\t\t\t\t\t} else if ( r.message ) {\n\n\t\t\t\t\t\tself.$container.append( '<p>' + r.message + '</p>' );\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\tvar msg = LLMS.l10n.translate( 'An unknown error occurred. Please try again.' );\n\t\t\t\t\t\tself.$container.append( '<p>' + msg + '</p>' );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\t/**\n\t\t\t * Use JS mouse events instead of CSS :hover because iOS is really smart\n\t\t\t *\n\t\t\t * @see: https://css-tricks.com/annoying-mobile-double-tap-link-issue/\n\t\t\t */\n\t\t\tif ( ! LLMS.is_touch_device() ) {\n\n\t\t\t\tthis.$ui.on( 'mouseenter', 'li.llms-choice label', function() {\n\t\t\t\t\t$( this ).addClass( 'hovered' );\n\t\t\t\t} );\n\t\t\t\tthis.$ui.on( 'mouseleave', 'li.llms-choice label', function() {\n\t\t\t\t\t$( this ).removeClass( 'hovered' );\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t},\n\n\t\t/**\n\t\t * Start Quiz Timer\n\t\t * Gets minutes from hidden field\n\t\t * Not used as actual quiz timer. Quiz is timed on the server from the quiz class\n\t\t * Calculates minutes to milliseconds and then converts to hours / minutes\n\t\t * When time limit reaches 0 calls complete_quiz() to complete quiz.\n\t\t *\n\t\t * @return Calls get_count_down at a set interval of 1 second\n\t\t * @since    1.0.0\n\t\t * @version  3.16.0\n\t\t */\n\t\tstart_quiz_timer: function( total_minutes ) {\n\n\t\t\t// create and append the UI for the countdown clock\n\t\t\tvar $el = $( '<div class=\"llms-quiz-timer\" id=\"llms-quiz-timer\" />' ),\n\t\t\t\tmsg = LLMS.l10n.translate( 'Time Remaining' );\n\n\t\t\t$el.append( '<i class=\"fa fa-clock-o\" aria-hidden=\"true\"></i><span class=\"screen-reader-text\">' + msg + '</span>' );\n\t\t\t$el.append( '<div id=\"llms-tiles\" class=\"llms-tiles\"></div>' );\n\n\t\t\t$( '#llms-quiz-header' ).append( $el );\n\n\t\t\t// start the timer\n\t\t\tvar self        = this,\n\t\t\t\ttarget_date = new Date().getTime() + ( ( total_minutes * 60 ) * 1000 ), // set the countdown date\n\t\t\t\ttime_limit  = ( ( total_minutes * 60 ) * 1000 ),\n\t\t\t\tcountdown   = document.getElementById( 'llms-tiles' ), // get tag element\n\t\t\t\tdays, hours, minutes, seconds; // variables for time units\n\n\t\t\t// set actual timer\n\t\t\tsetTimeout( function() {\n\t\t\t\tself.complete_quiz();\n\t\t\t}, time_limit + 1000 );\n\n\t\t\tthis.getCountdown(\n\t\t\t\ttotal_minutes,\n\t\t\t\ttarget_date,\n\t\t\t\ttime_limit,\n\t\t\t\tdays,\n\t\t\t\thours,\n\t\t\t\tminutes,\n\t\t\t\tseconds,\n\t\t\t\tcountdown\n\t\t\t);\n\n\t\t\t// call get_count_down every 1 second\n\t\t\tsetInterval( function () {\n\t\t\t\tself.getCountdown(\n\t\t\t\t\ttotal_minutes,\n\t\t\t\t\ttarget_date,\n\t\t\t\t\ttime_limit,\n\t\t\t\t\tdays,\n\t\t\t\t\thours,\n\t\t\t\t\tminutes,\n\t\t\t\t\tseconds,\n\t\t\t\t\tcountdown\n\t\t\t\t);\n\t\t\t}, 1000 );\n\t\t},\n\n\t\t/**\n\t\t * Trigger events\n\t\t *\n\t\t * @param    string   event  event to trigger\n\t\t * @return   void\n\t\t * @since    3.16.0\n\t\t * @version  3.16.0\n\t\t */\n\t\ttrigger: function( event ) {\n\n\t\t\tvar self = this;\n\n\t\t\t// trigger question submission for the current question\n\t\t\tif ( 'answer_question' === event ) {\n\n\t\t\t\tif ( this.get_question_index( self.current_question ) === self.total_questions ) {\n\n\t\t\t\t\t$( '#llms-complete-quiz' ).trigger( 'click' );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t$( '#llms-next-question' ).trigger( 'click' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t},\n\n\t\t/**\n\t\t * Load the HTML of a question into the DOM and the question cache\n\t\t *\n\t\t * @param    string   html  string of html\n\t\t * @return   void\n\t\t * @since    3.9.0\n\t\t * @version  3.16.6\n\t\t */\n\t\tload_question: function( html ) {\n\n\t\t\tvar $html = $( html ),\n\t\t\t\tqid   = $html.attr( 'data-id' );\n\n\t\t\t// cache the question HTML for faster rewinds\n\t\t\tif ( ! this.questions[ 'q-' + qid ] ) {\n\t\t\t\tthis.questions[ 'q-' + qid ] = $html;\n\t\t\t}\n\n\t\t\tthis.update_progress( qid );\n\n\t\t\tthis.current_question = qid;\n\n\t\t\t$( document ).trigger( 'llms-pre-append-question', $html );\n\n\t\t\tthis.$container.append( $html );\n\n\t\t\t$( document ).trigger( 'llms-post-append-question', $html );\n\n\t\t},\n\n\t\t/**\n\t\t * Constructs the quiz UI & adds the elements into the DOM\n\t\t *\n\t\t * @return   void\n\t\t * @since    3.16.0\n\t\t * @version  3.16.9\n\t\t */\n\t\tload_ui_elements: function() {\n\n\t\t\tvar $html   = $( '<div class=\"llms-quiz-ui\" id=\"llms-quiz-ui\" />' ),\n\t\t\t\t$header = $( '<header class=\"llms-quiz-header\" id=\"llms-quiz-header\" />' )\n\t\t\t\t$footer = $( '<footer class=\"llms-quiz-nav\" id=\"llms-quiz-nav\" />' );\n\n\t\t\t$footer.append( '<button class=\"button large llms-button-action\" id=\"llms-next-question\" name=\"llms_next_question\" type=\"submit\">' + LLMS.l10n.translate( 'Next Question' ) + '</button>' );\n\t\t\t$footer.append( '<button class=\"button large llms-button-action llms-button-quiz-complete\" id=\"llms-complete-quiz\" name=\"llms_complete_quiz\" type=\"submit\" style=\"display:none;\">' + LLMS.l10n.translate( 'Complete Quiz' ) + '</button>' );\n\t\t\t$footer.append( '<button class=\"button llms-button-secondary\" id=\"llms-prev-question\" name=\"llms_prev_question\" type=\"submit\" style=\"display:none;\">' + LLMS.l10n.translate( 'Previous Question' ) + '</button>' );\n\n\t\t\t$header.append( '<div class=\"llms-progress\"><div class=\"progress-bar-complete\"></div></div>' );\n\t\t\t$footer.append( '<div class=\"llms-quiz-counter\" id=\"llms-quiz-counter\"><span class=\"llms-current\"></span><span class=\"llms-sep\">/</span><span class=\"llms-total\"></span></div>' )\n\n\t\t\t$html.append( $header )\n\t\t\t\t .append( '<div class=\"llms-quiz-question-wrapper\" id=\"llms-quiz-question-wrapper\" />' )\n\t\t\t\t .append( $footer );\n\n\t\t\t$( '#llms-quiz-wrapper' ).after( $html );\n\n\t\t},\n\n\t\t/**\n\t\t * Perform actions on question HTML after it's been appended to the DOM\n\t\t *\n\t\t * @param    obj      event  js event object\n\t\t * @param    obj      html   js HTML object\n\t\t * @return   void\n\t\t * @since    3.16.6\n\t\t * @version  3.16.6\n\t\t */\n\t\tpost_append_question: function( event, html ) {\n\n\t\t\tvar $html = $( html );\n\n\t\t\tif ( $html.find( 'audio' ).length ) {\n\t\t\t\twp.mediaelement.initialize();\n\t\t\t}\n\n\t\t},\n\n\t\t/**\n\t\t * Show or hide the \"loading\" spinner with an option message\n\t\t *\n\t\t * @param    string   display  show|hide\n\t\t * @param    string   msg      text to display when showing\n\t\t * @return   void\n\t\t * @since    3.9.0\n\t\t * @version  3.16.6\n\t\t */\n\t\ttoggle_loader: function( display, msg ) {\n\n\t\t\tif ( 'show' === display ) {\n\n\t\t\t\tmsg = msg || LLMS.l10n.translate( 'Loading...' );\n\n\t\t\t\tthis.$buttons.attr( 'disabled', 'disabled' );\n\n\t\t\t\tthis.$container.empty();\n\t\t\t\tLLMS.Spinner.start( this.$container );\n\t\t\t\tthis.$container.append( '<div class=\"llms-quiz-loading\">' + LLMS.l10n.translate( msg ) + '</div>' );\n\n\t\t\t} else {\n\n\t\t\t\tLLMS.Spinner.stop( this.$container );\n\t\t\t\tthis.$buttons.removeAttr( 'disabled' );\n\t\t\t\tthis.$container.find( '.llms-quiz-loading' ).remove();\n\n\t\t\t}\n\n\t\t},\n\n\t\t/**\n\t\t * Update the progress bar and toggle button availability based on question the question being shown\n\t\t *\n\t\t * @param    {[type]}   qid  [description]\n\t\t * @return   {[type]}\n\t\t * @since    3.16.0\n\t\t * @version  3.16.0\n\t\t */\n\t\tupdate_progress: function( qid ) {\n\n\t\t\tvar index = this.get_question_index( qid ),\n\t\t\t\tprogress;\n\n\t\t\tif ( -1 === index ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tindex++;\n\n\t\t\t$( '#llms-quiz-counter .llms-current' ).text( index );\n\t\t\tif ( index === 1 ) {\n\t\t\t\t$( '#llms-quiz-counter .llms-total' ).text( this.total_questions );\n\t\t\t\t$( '#llms-quiz-counter' ).show();\n\t\t\t}\n\n\t\t\t// handle prev question\n\t\t\tif ( index >= 2 ) {\n\t\t\t\t$( '#llms-prev-question' ).show();\n\t\t\t} else {\n\t\t\t\t$( '#llms-prev-question' ).hide();\n\t\t\t}\n\n\t\t\tif ( index === this.total_questions ) {\n\t\t\t\t$( '#llms-next-question' ).hide();\n\t\t\t\t$( '#llms-complete-quiz' ).show();\n\t\t\t} else {\n\t\t\t\t$( '#llms-next-question' ).show();\n\t\t\t\t$( '#llms-complete-quiz' ).hide();\n\t\t\t}\n\n\t\t},\n\n\t\t/**\n\t\t * Increase progress bar ui element\n\t\t *\n\t\t * @param    string   dir  update direction [increment|decrement]\n\t\t * @return   void\n\t\t * @since    3.16.0\n\t\t * @version  3.16.0\n\t\t */\n\t\tupdate_progress_bar: function( dir ) {\n\n\t\t\tvar index = this.get_question_index( this.current_question );\n\t\t\tif ( 'increment' === dir ) {\n\t\t\t\tindex++;\n\t\t\t} else {\n\t\t\t\tindex--;\n\t\t\t}\n\n\t\t\tprogress = ( index / this.total_questions ) * 100;\n\t\t\tthis.$ui.find( '.progress-bar-complete' ).css( 'width', progress + '%' );\n\n\t\t},\n\n\t\t/**\n\t\t * Get Count Down\n\t\t * Called every second to update the on screen countdown timer\n\t\t * Changes color to yellow at 1/2 of total time\n\t\t * Changes color to red at 1/4 of total time\n\t\t *\n\t\t * @param  {[int]} minutes     [description]\n\t\t * @param  {[date]} target_date [description]\n\t\t * @param  {[int]} time_limit  [description]\n\t\t * @param  {[int]} days        [description]\n\t\t * @param  {[int]} hours       [description]\n\t\t * @param  {[int]} minutes     [description]\n\t\t * @param  {[int]} seconds     [description]\n\t\t * @param  {[int]} countdown   [description]\n\t\t * @return Displays updates hours, minutes on quiz timer\n\t\t * @since    1.0.0\n\t\t * @version  1.0.0\n\t\t */\n\t\tgetCountdown: function( total_minutes, target_date, time_limit, days, hours, minutes, seconds, countdown ){\n\n\t\t\t// find the amount of \"seconds\" between now and target\n\t\t\tvar current_date = new Date().getTime(),\n\t\t\t\tseconds_left = ( target_date - current_date ) / 1000;\n\n\t\t\tif ( seconds_left >= 0 ) {\n\n\t\t\t\tif ( ( seconds_left * 1000 ) < ( time_limit / 2 ) ) {\n\n\t\t\t\t\t$( '#llms-quiz-timer' ).addClass( 'color-half' );\n\n\t\t\t\t}\n\n\t\t\t\tif ( ( seconds_left * 1000 ) < ( time_limit / 4 ) ) {\n\n\t\t\t\t\t$( '#llms-quiz-timer' ).removeClass( 'color-half' );\n\t\t\t\t\t$( '#llms-quiz-timer' ).addClass( 'color-empty' );\n\n\t\t\t\t}\n\n\t\t\t\tdays         = this.pad( parseInt( seconds_left / 86400 ) );\n\t\t\t\tseconds_left = seconds_left % 86400;\n\t\t\t\thours        = this.pad( parseInt( seconds_left / 3600 ) );\n\t\t\t\tseconds_left = seconds_left % 3600;\n\t\t\t\tminutes      = this.pad( parseInt( seconds_left / 60 ) );\n\t\t\t\tseconds      = this.pad( parseInt( seconds_left % 60 ) );\n\n\t\t\t\t// format countdown string + set tag value\n\t\t\t\tcountdown.innerHTML = '<span class=\"hours\">' + hours + '</span>:<span class=\"minutes\">' + minutes + '</span>:<span class=\"seconds\">' + seconds + '</span>';\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Pad Number\n\t\t * pads number with 0 if single digit.\n\t\t *\n\t\t * @param  {[int]} n [number]\n\t\t * @return {[string]} [padded number]\n\t\t * @since    1.0.0\n\t\t * @version  1.0.0\n\t\t */\n\t\tpad: function(n) {\n\t\t\treturn (n < 10 ? '0' : '') + n;\n\t\t},\n\n\t\t/**\n\t\t * Basic validation method which performs no validation and returns a validation object\n\t\t * in the format required by the application\n\t\t *\n\t\t * @param    obj   $question  jQuery selector of the question\n\t\t * @return   obj\n\t\t * @since    3.16.0\n\t\t * @version  3.16.0\n\t\t */\n\t\tvalidate: function( $question ) {\n\t\t\treturn {\n\t\t\t\tanswer: [],\n\t\t\t\tvalid: true,\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Validates a choice question to ensure there's at least one checked input\n\t\t *\n\t\t * @param    obj   $question  jQuery selector of the question\n\t\t * @return   obj\n\t\t * @since    3.16.0\n\t\t * @version  3.16.0\n\t\t */\n\t\tvalidate_choice: function( $question ) {\n\n\t\t\tvar ret     = window.llms.quizzes.validate( $question ),\n\t\t\t\tchecked = $question.find( 'input:checked' );\n\n\t\t\tif ( ! checked.length ) {\n\t\t\t\tret.valid = LLMS.l10n.translate( 'You must select an answer to continue.' );\n\t\t\t} else {\n\t\t\t\tchecked.each( function() {\n\t\t\t\t\tret.answer.push( $( this ).val() );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn ret;\n\n\t\t},\n\n\t};\n\n\tquiz.bind();\n\n\twindow.llms         = window.llms || {};\n\twindow.llms.quizzes = quiz;\n\n} )( jQuery );\n"],"sourceRoot":"../../js"}