(function () {
    var settingsElement = document.querySelector('head > script[type="application/json"][data-drupal-selector="drupal-settings-json"], body > script[type="application/json"][data-drupal-selector="drupal-settings-json"]');
  
    window.drupalSettings = {};
    let jsonP_exp = {
      "sot_questions": {
        "part": [
          {
            "questions": [
              {
                "text_question": "<p> Where are you from? </p>",
                "suggestion_text": "",
                "question_video": null,
                "question_recording": null,
                "id": "1",
                "time_to_think_qs": 25
              }
            ],
            "time": {
              "time_question_to_think": 5,
              "total_answer_time": "300",
              "time_to_think": 15,
              "time_to_think_each_qs": 45
            },
            "instructions": "In this first part, the examiner will ask you about basic information"
          }
        ]
      }
    };
  
    if (document.querySelector('[data-drupal-selector="drupal-json-settings"]')) {
      let jsonP = document.querySelector('[data-drupal-selector="drupal-json-settings"]').innerText;
      window.drupalSettings = JSON.parse(jsonP);
    }
  })();
  
  /**
   * DO NOT EDIT THIS FILE.
   * See the following change record for more information,
   * https://www.drupal.org/node/2815083
   * @preserve
   **/
  
  window.Drupal = {
    behaviors: {},
    locale: {}
  };
  
  (function (Drupal, drupalSettings, drupalTranslations, console, Proxy, Reflect) {
    Drupal.throwError = function (error) {
      setTimeout(function () {
        throw error;
      }, 0);
    };
  
    Drupal.attachBehaviors = function (context, settings) {
      context = context || document;
      settings = settings || drupalSettings;
      var behaviors = Drupal.behaviors;
  
      Object.keys(behaviors || {}).forEach(function (i) {
        if (typeof behaviors[i].attach === 'function') {
          try {
            behaviors[i].attach(context, settings);
          } catch (e) {
            Drupal.throwError(e);
          }
        }
      });
    };
  
    Drupal.detachBehaviors = function (context, settings, trigger) {
      context = context || document;
      settings = settings || drupalSettings;
      trigger = trigger || 'unload';
      var behaviors = Drupal.behaviors;
  
      Object.keys(behaviors || {}).forEach(function (i) {
        if (typeof behaviors[i].detach === 'function') {
          try {
            behaviors[i].detach(context, settings, trigger);
          } catch (e) {
            Drupal.throwError(e);
          }
        }
      });
    };
  
    Drupal.checkPlain = function (str) {
      str = str.toString().replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#39;');
      return str;
    };
  
    Drupal.formatString = function (str, args) {
      var processedArgs = {};
  
      Object.keys(args || {}).forEach(function (key) {
        switch (key.charAt(0)) {
          case '@':
            processedArgs[key] = Drupal.checkPlain(args[key]);
            break;
  
          case '!':
            processedArgs[key] = args[key];
            break;
  
          default:
            processedArgs[key] = Drupal.theme('placeholder', args[key]);
            break;
        }
      });
  
      return Drupal.stringReplace(str, processedArgs, null);
    };
  
    Drupal.stringReplace = function (str, args, keys) {
      if (str.length === 0) {
        return str;
      }
  
      if (!Array.isArray(keys)) {
        keys = Object.keys(args || {});
  
        keys.sort(function (a, b) {
          return a.length - b.length;
        });
      }
  
      if (keys.length === 0) {
        return str;
      }
  
      var key = keys.pop();
      var fragments = str.split(key);
  
      if (keys.length) {
        for (var i = 0; i < fragments.length; i++) {
          fragments[i] = Drupal.stringReplace(fragments[i], args, keys.slice(0));
        }
      }
  
      return fragments.join(args[key]);
    };
  
    Drupal.t = function (str, args, options) {
      options = options || {};
      options.context = options.context || '';
  
      if (typeof drupalTranslations !== 'undefined' && drupalTranslations.strings && drupalTranslations.strings[options.context] && drupalTranslations.strings[options.context][str]) {
        str = drupalTranslations.strings[options.context][str];
      }
  
      if (args) {
        str = Drupal.formatString(str, args);
      }
      return str;
    };
  
    Drupal.url = function (path) {
      return drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix + path;
    };
  
    Drupal.url.toAbsolute = function (url) {
      var urlParsingNode = document.createElement('a');
  
      try {
        url = decodeURIComponent(url);
      } catch (e) {}
  
      urlParsingNode.setAttribute('href', url);
  
      return urlParsingNode.cloneNode(false).href;
    };
  
    Drupal.url.isLocal = function (url) {
      var absoluteUrl = Drupal.url.toAbsolute(url);
      var protocol = window.location.protocol;
  
      if (protocol === 'http:' && absoluteUrl.indexOf('https:') === 0) {
        protocol = 'https:';
      }
      var baseUrl = protocol + '//' + window.location.host + drupalSettings.path.baseUrl.slice(0, -1);
  
      try {
        absoluteUrl = decodeURIComponent(absoluteUrl);
      } catch (e) {}
      try {
        baseUrl = decodeURIComponent(baseUrl);
      } catch (e) {}
  
      return absoluteUrl === baseUrl || absoluteUrl.indexOf(baseUrl + '/') === 0;
    };
  
    Drupal.formatPlural = function (count, singular, plural, args, options) {
      args = args || {};
      args['@count'] = count;
  
      var pluralDelimiter = drupalSettings.pluralDelimiter;
      var translations = Drupal.t(singular + pluralDelimiter + plural, args, options).split(pluralDelimiter);
      var index = 0;
  
      if (typeof drupalTranslations !== 'undefined' && drupalTranslations.pluralFormula) {
        index = count in drupalTranslations.pluralFormula ? drupalTranslations.pluralFormula[count] : drupalTranslations.pluralFormula.default;
      } else if (args['@count'] !== 1) {
        index = 1;
      }
  
      return translations[index];
    };
  
    Drupal.encodePath = function (item) {
      return window.encodeURIComponent(item).replace(/%2F/g, '/');
    };
  
    Drupal.deprecationError = function (_ref) {
      var message = _ref.message;
  
      if (drupalSettings.suppressDeprecationErrors === false && typeof console !== 'undefined' && console.warn) {
        console.warn('[Deprecation] ' + message);
      }
    };
  
    Drupal.deprecatedProperty = function (_ref2) {
      var target = _ref2.target,
        deprecatedProperty = _ref2.deprecatedProperty,
        message = _ref2.message;
  
      if (!Proxy || !Reflect) {
        return target;
      }
  
      return new Proxy(target, {
        get: function get(target, key) {
          for (var _len = arguments.length, rest = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
            rest[_key - 2] = arguments[_key];
          }
  
          if (key === deprecatedProperty) {
            Drupal.deprecationError({
              message: message
            });
          }
          return Reflect.get.apply(Reflect, [target, key].concat(rest));
        }
      });
    };
  
    Drupal.theme = function (func) {
      if (func in Drupal.theme) {
        var _Drupal$theme;
  
        for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
          args[_key2 - 1] = arguments[_key2];
        }
  
        return (_Drupal$theme = Drupal.theme)[func].apply(_Drupal$theme, args);
      }
    };
  
    Drupal.theme.placeholder = function (str) {
      return '<em class="placeholder">' + Drupal.checkPlain(str) + '</em>';
    };
    
  })(Drupal, window.drupalSettings, window.console);
  
  
  
  if (window.jQuery) {
    jQuery.noConflict();
  }
  
  
  (function (Drupal, drupalSettings) {
    var domReady = function domReady(callback) {
      if (document.readyState !== 'loading') {
        callback();
      } else {
        var listener = function listener() {
          callback();
          document.removeEventListener('DOMContentLoaded', listener);
        };
        document.addEventListener('DOMContentLoaded', listener);
      }
    };
  
    domReady(function () {
      Drupal.attachBehaviors(document, drupalSettings);
    });
  })(Drupal, window.drupalSettings);;
  
  
  
  
  /**
   * DO NOT EDIT THIS FILE.
   * See the following change record for more information,
   * https://www.drupal.org/node/2815083
   * @preserve
   **/
  
  /**
   * @file
   * Extends methods from core/misc/progress.js.
   */
  
  /**
   * DO NOT EDIT THIS FILE.
   * See the following change record for more information,
   * https://www.drupal.org/node/2815083
   * @preserve
   **/
  
  
  
  
  /**
   * Swiper 8.2.4
   * Most modern mobile touch slider and framework with hardware accelerated transitions
   * https://swiperjs.com
   *
   * Copyright 2014-2022 Vladimir Kharlampidi
   *
   * Released under the MIT License
   *
   * Released on: June 13, 2022
   */
  
  
  /**
   * Owl Carousel v2.3.4
   * Copyright 2013-2018 David Deutsch
   * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
   */
  /**
   * Owl carousel
   * @version 2.3.4
   * @author Bartosz Wojciechowski
   * @author David Deutsch
   * @license The MIT License (MIT)
   * @todo Lazy Load Icon
   * @todo prevent animationend bubling
   * @todo itemsScaleUp
   * @todo Test Zepto
   * @todo stagePadding calculate wrong active classes
   */
  
  
  /**
   * AutoRefresh Plugin
   * @version 2.3.4
   * @author Artus Kolanowski
   * @author David Deutsch
   * @license The MIT License (MIT)
   */
  
  /**
   * Lazy Plugin
   * @version 2.3.4
   * @author Bartosz Wojciechowski
   * @author David Deutsch
   * @license The MIT License (MIT)
   */
  
  
  
  /* Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
   * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
   * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
   * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
   * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
   *
   * Version: 3.0.2
   * 
   * Requires: 1.2.2+
   */
  
  
  /*!
   * element-resize-detector 1.1.15
   * Copyright (c) 2016 Lucas Wiener
   * https://github.com/wnr/element-resize-detector
   * Licensed under MIT
   */
  
  
  /*!
   * Pusher JavaScript Library v4.3.0
   * https://pusher.com/
   *
   * Copyright 2017, Pusher
   * Released under the MIT licence.
   */
  
  
  /**
   * DO NOT EDIT THIS FILE.
   * See the following change record for more information,
   * https://www.drupal.org/node/2815083
   * @preserve
   **/
  
  
  /**
   * @file
   * Global vars.
   */
  
  var sot_state = {
    screens: ['#step-general-instructions', '#step-test-mic', '#step-test-form'],
    active: 0
  };
  
  (function ($, Drupal) {
    Drupal.behaviors.SOTHelper = {
      attach: function (context, settings) {
        // Active first screen.
        var cur_screen = sot_state.active;
        if ($(sot_state.screens[cur_screen]).length) {
          $(sot_state.screens[cur_screen]).addClass('in active').removeClass('hide');
          window.location.hash = sot_state.screens[cur_screen];
        }
        // Change screen.
        $('body').on('click', '[data-drupal-selector="change-screen"]', function (e) {
          // Checking user browser.
          // Detect user browser.
          if($(this).hasClass('js-check-ios2')) {
            var browserName = (function (agent) {
              switch (true) {
                case agent.indexOf("edge") > -1: return true;
                case agent.indexOf("edg/") > -1: return true;
                case agent.indexOf("opr") > -1 && !!window.opr: return true;
                case agent.indexOf("chrome") > -1 && !!window.chrome: return true;
                case agent.indexOf("trident") > -1: return false;
                case agent.indexOf("firefox") > -1: return true;
                case agent.indexOf("safari") > -1: return true;
                default: return false;
              }
            })(window.navigator.userAgent.toLowerCase());
            if(!browserName) {
              $('#modal-no-support').modal({
                backdrop: 'static'
              });
              return;
            }
          }
  
          var cur_screen = sot_state.active;
          if ($(sot_state.screens[cur_screen]).length) {
            $(sot_state.screens[cur_screen]).removeClass('in active').addClass('hide');
          }
  
          if ($(sot_state.screens[cur_screen + 1]).length) {
            $(sot_state.screens[cur_screen + 1]).addClass('in active').removeClass('hide');
            sot_state.active = cur_screen + 1;
            window.location.hash = sot_state.screens[cur_screen + 1];
            if (sot_state.screens[cur_screen + 1] === '#step-test-mic') {
              $('.speaking-test').addClass('test-mic');
            } else {
              $('.speaking-test').removeClass('test-mic');
            }
          }
        });
      }
    };
  }(jQuery, Drupal));
  
  /**
   * @file
   */
  
  var csrfToken = '';
  var takeTestForm = document.getElementById('take-test-form');
  var curPart = 0;
  var curQuestion = 0;
  var startTest = false;
  var interval;
  var finish_countdown = null;
  var startTime = 0;
  var submited = false;
  var blobFiles = [];
  var timeToThink, intervalTimeToThink;
  var timeTest, intervalTimeTest;
  var intervalModalCount;
  var isShowPartPreview = false;
  var startTestMic = false;
  var isAnswering = true;
  var wavesurferElm;
  var lap = 0;
  var player;
  var audioState = false;
  var currentTimeRecording = 0;
  var questionBoundaries = [];
  
  (function ($, Drupal, drupalSettings) {
    // Global element.
    var qsSelector = $('[data-drupal-selector="question"]');
    var qsNumber = $('#question-number');
    var qsDescSelector = $('[data-drupal-selector="question-desc"]');
    var btnRecord = $('#js-record');
    var jsTimeDuration = $('#js-time-duration');
    var jsTimeNote = $('#js-time-note');
    var timeToThinkNote = $('#time-to-think-note');
    var recordingIndicator = $('#recording-indicator');
    var jsSpeakerRadial = $('#js-speaker-radial');
    var modalTimeUp = $("#modal-time-up");
    var modalFinish = $("#modal-finish");
    var btnReset = $("#js-reset-exam");
    var jsNextPart = $("#js-next-part");
    var resultPart = $(".mic-box__result-part");
    var recordPart = $(".mic-box__record-part");
    var partCaption = $(".part-caption");
    var jsPlayer = document.getElementById("js-player");
    var set = false;
    var nextQuestionCooldown = false;
  
    // Init.
    jsSpeakerRadial.knob({
      width: "100%",
      height: "100%",
      displayInput: false,
      fgColor: "#c86478",
      bgColor: "#fff",
      displayPrevious: false,
      thickness: 0.1,
      lineCap: "round",
      step: 0.01,
      min: 0
    });
  
  
    btnRecord.on('click', function () {
      if (audioState === false) {
        showRecordingError();
        return;
      }
      if ($(this).hasClass('time-to-think')) {
        $(this).removeClass('time-to-think');
        startTest = true;
      } else {
        if (nextQuestionCooldown) {
          return;
        }
        nextQuestionCooldown = true;
        setTimeout(function () {
          nextQuestionCooldown = false;
        }, 1000);
        nextQuestion()
      }
    });
  
  
    // Click reset part.w
    btnReset.on('click', function () {
      if (!$('#step-test-mic').length) {
        $('#modal-reset-record').modal('show');
        $('#modal-reset-record').on('click', '.modal__button.-yes', function () {
          resetPart();
        });
      }
    });
  
  
    // Click next part.
    jsNextPart.on('click', function () {
      nextPart();
    });
  
  
    modalTimeUp.on('click', '#js-finish-part', function () {
      clearInterval(intervalModalCount);
      // modalTimeUp.modal('hide')
    });
  
  
    modalTimeUp.on('show.bs.modal', function (e) {
      var time = 5;
      var f1 = new Date().getTime();
      intervalModalCount = setInterval(function () {
        var now = new Date().getTime();
        if ((now - f1) / 1000 >= 1) {
          f1 = now;
          time--;
        }
        if (time < 0 || isShowPartPreview) {
          clearInterval(intervalModalCount);
          modalTimeUp.find('#js-finish-part').trigger('click');
          // showPartPreview();
        } else {
          $('#js-countdown-number').html(time);
        }
      }, 10)
      getAnswer();
    });
  
    modalTimeUp.on('hide.bs.modal', function (e) {
      clearInterval(intervalModalCount);
      showPartPreview();
    });
  
    modalFinish.on('click', '#js-finish-test', function () {
      clearInterval(intervalModalCount);
      // modalFinish.modal('hide');
    });
  
  
  
    modalFinish.on('show.bs.modal', function (e) {
      clearInterval(intervalTimeTest);
      var time = 5;
      var f1 = new Date().getTime();
      intervalModalCount = setInterval(function () {
        var now = new Date().getTime();
        if ((now - f1) / 1000 >= 1) {
          f1 = now;
          time--;
        }
        if (time < 0 || isShowPartPreview) {
          clearInterval(intervalModalCount);
          modalFinish.find('#js-finish-test').trigger('click');
          // showPartPreview();
        } else {
          $('#js-countdown-finished').html(time);
        }
      }, 10)
    });
  
    modalFinish.on('hide.bs.modal', function (e) {
      clearInterval(intervalModalCount);
      showPartPreview();
    });
  
    function runSpeakingRadial(newTime) {
      jsSpeakerRadial.attr('data-max', newTime).val(0).trigger('configure', {
        max: newTime
      });
    }
  
    // URL shim.
    window.URL = window.URL || window.webkitURL;
    // Audio context + .createScriptProcessor shim.
    var AudioContext =
      window.AudioContext || // Default.
      window.webkitAudioContext || // Safari and old versions of Chrome.
      false;
    var audioContext = null;
    var audioRecorder = null;
    var microphoneLevel = null;
    var microphone = undefined;
    if (AudioContext) {
      // Declare audioContext variable.
      try {
        audioContext = new AudioContext({ sampleRate: 16000 });
      } catch (err) {
        audioContext = new AudioContext();
      }
      audioContext.suspend();
      audioContext.onstatechange = function () {
        console.log('audioContext.state', audioContext.state, startTest)
        if (audioContext.state === 'running') {
          startTest = true;
          countDownTimeTest();
        }
      }
    } else {
      // Web Audio API is not supported.
      alert(
        "Sorry, but the Web Audio API is not supported by your browser. Please, consider upgrading to the latest version or downloading Google Chrome or Mozilla Firefox"
      );
    }
  
  
    if (audioContext.createScriptProcessor == null) {
      audioContext.createScriptProcessor = audioContext.createJavaScriptNode;
    }
  
  
    // Elements (jQuery objects)
    var $recordingList = $("#recording-list"),
      $modalLoading = $("#modal-loading"),
      $modalProgress = $("#modal-progress"),
      $modalError = $("#modal-error");
      $partTitle = $('#js-part-title');
  
    var microphone = undefined, // Obtained by user click.
      microphoneLevel = audioContext.createGain(),
      mixer = audioContext.createGain();
      microphoneLevel.gain.value = 1;
      microphoneLevel.connect(mixer);
  
  
    // Audio recorder object.
    var audioRecorder = new WebAudioRecorder(mixer, {
      workerDir: window.site_url + "/wp-content/plugins/spacetree/libs/proqyz/includes/templates/public/quiz/dist/speaking/advance/recorder/",
      encoding: "wav",
      numChannels: 1,
      onEncoderLoading: function (recorder, encoding) {
        $modalLoading
          .find(".modal-title")
          .html("Loading " + encoding.toUpperCase() + " encoder ...");
        $modalLoading.modal("show");
      },
      onEncoderLoaded: function () {
        $modalLoading.modal("hide");
      }
    });
  
    // Encoding selector + encoding options.
    var OGG_QUALITY = [-0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
      OGG_KBPS = [45, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 500],
      MP3_BIT_RATE = [64, 80, 96, 112, 128, 160, 192, 224, 256, 320],
      WAV_BIT_RATE = [8000, 11025, 16000, 22050, 32000, 44100, 48000],
      optionValue = {
        ogg: 6,
        mp3: MP3_BIT_RATE.indexOf(128),
        wav: WAV_BIT_RATE.indexOf(16000)
      };
  
  
    // Encoding progress report modal.
    var progressComplete = false;
  
    /** ---------------
     * Event Audio API handlers.
     * ------------------- */
    audioRecorder.onTimeout = function (recorder) {
      stopRecording(true);
    };
  
    audioRecorder.onEncodingProgress = function (recorder, progress) {};
  
    audioRecorder.onComplete = function (recorder, blob) {
      url = URL.createObjectURL(blob);
      console.log("WE ARE HERE", url);
      if (jsPlayer.plyr === undefined) {
        player = new Plyr(jsPlayer, {
          settings: []
        });
        player.source = {
          type: "audio",
          sources: [{
            src: url,
            type: "audio/wav" // wav is required for OpenAI Whisper transcription
          }]
        }
      } else {
        player.source = {
          type: "audio",
          sources: [{
            src: url,
            type: "audio/wav" // wav is required for OpenAI Whisper transcription
          }]
        };
      }
  
      try {
        recordingIndicator.hide();
        player.currentTime = 0;
        var part = curPart + 1
        if ($('textarea[name="field_part_' + part + '_questions"]').length) {
          $('.part-caption > .part-caption__note').html(Drupal.t('You can review your part @part recording by clicking the Play button below', {
            '@part': part
          }));
          var currentPartData = JSON.parse($('textarea[name="field_part_' + part + '_questions"]').val())
          var playerWrapper = $('#js-player__audio-question');
          var playerWrapperSuggetion = $('#js-player__audio-question__suggestion');
          playerWrapper.find('.question-number').empty();
          playerWrapper.find('.question-content').empty();
          playerWrapperSuggetion.empty();
          player.on('timeupdate', function (event) {
            let currentTime = player.currentTime
            if (currentPartData.length) {
              for (var i in currentPartData) {
                if (currentPartData[i].time.start <= currentTime && currentPartData[i].time.end > currentTime) {
                  playerWrapper.find('.question-number').html(Drupal.t('Question @number', {
                    '@number': (parseInt(i) + 1)
                  }))
                  playerWrapper.find('.question-content').html(currentPartData[i].question_txt);
                  if (currentPartData[i].suggestion_text !== undefined) {
                    playerWrapperSuggetion.html(currentPartData[i].suggestion_text)
                  }
                }
              }
            }
          });
        }
      } catch (err) {
        console.warn('error: ', err);
      }
      if (recorder.options.encodeAfterRecord) {
        $modalProgress.modal('hide');
      }
      blobFiles[curPart] = blob;
    }
  
    audioRecorder.onError = function (recorder, message) {
      $modalError.find('.alert').html(message);
      $modalError.modal('show');
    }
  
    /* ----------------------------------------------------------- */
  
    // Encoding selector + encoding options.
    var OGG_QUALITY = [-0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
      OGG_KBPS = [45, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 500],
      MP3_BIT_RATE = [64, 80, 96, 112, 128, 160, 192, 224, 256, 320],
      WAV_BIT_RATE = [8000, 11025, 16000, 22050, 32000, 44100, 48000],
      optionValue = {
        ogg: 6,
        mp3: MP3_BIT_RATE.indexOf(128),
        wav: WAV_BIT_RATE.indexOf(16000)
      };
  
    // Encoding progress report modal.
    var progressComplete = false;
  
    /**
     * -------------------------
     * General function
     * ------------------------
     */
    // Check microphone driver.
    function showRecordingError() {
      var msg = Drupal.t('We cannot detect your microphone, please check your microphone again or try a different one');
      $('#modal-upload-error').find('[data-drupal-selector="message"]').html(msg);
      $('#modal-upload-error').modal({
        keyboard: false,
        show: true,
        backdrop: 'static'
      });
    }
  
    // Start Recording.
    function startRecording(duration) {
      document.body.classList.add('part-recording');
      audioContext.resume();
      disableControlsOnRecord(true);
      audioRecorder.setOptions({
        timeLimit: duration,
        bufferSize: undefined,
        encodeAfterRecord: false,
        ogg: {
          quality: OGG_QUALITY[optionValue.ogg]
        },
        mp3: {
          bitRate: MP3_BIT_RATE[optionValue.mp3]
        },
        wav: {
          bitRate: WAV_BIT_RATE[optionValue.wav]
        }
      })
      audioRecorder.startRecording();
    }
  
    // Record | stop | cancel buttons.
    function disableControlsOnRecord(disabled) {}
  
    // Stop Recording.
    function stopRecording(finish) {
      console.log(4);
      recordingIndicator.hide();
      disableControlsOnRecord(false);
      if (finish) {
        var finalBoundary = parseFloat(jsSpeakerRadial.val());
        if (!isNaN(finalBoundary)) {
          var lastBoundary = questionBoundaries.length ? questionBoundaries[questionBoundaries.length - 1] : null;
          if (lastBoundary === null || Math.abs(lastBoundary - finalBoundary) > 0.001) {
            questionBoundaries.push(finalBoundary);
          }
        }
        audioContext.suspend();
        currentTimeRecording = audioContext.currentTime;
        audioRecorder.finishRecording();
        if (audioRecorder.options.encodeAfterRecord) {
          $modalProgress
            .find('.modal-title')
            .html('Encoding ' + audioRecorder.encoding.toUpperCase());
          $modalProgress.modal('show');
        }
      } else {
        audioRecorder.cancelRecording();
      }
    }
  
    /**
     * Convert setting time from minute to string.
     *
     * @param {int} time
     *   The time to convert in second.
     */
    function convertTimeToString(time) {
      var s = time % 60 | 0;
      var m = time / 60 | 0;
      var output = ('0' + m).slice(-2);
      output += ':' + ('0' + s).slice(-2);
      return output;
    }

    $('.audio__slider').roundSlider({
      radius: 13,
      value: 0,
      startAngle: 90,
      width: 2,
      handleSize: '+6',
      handleShape: 'round',
      sliderType: 'min-range' 
    });

    function playQuestionRecord () {
      

      try{
        
        var partData = drupalSettings.sot_questions.part[curPart];
        var questionData = partData.questions[curQuestion];
        $('.speaker--container').addClass('hidden');
        if(questionData['question_recording']){

          let url = questionData['recording_url'];
          $('.slide__audio-player')[0].src = url;
          $('.slide__audio-player')[0].currentTime = 0;
          console.log(questionData);

          if(!set){
            $('.js-audio').each(function (index, el) {
              initAudioPlayer($(this), index);
            });
            set = true;
          }


          $('.speaker--container').removeClass('hidden');
          $('.play-pause').click();
        }
      }catch(err){
        console.log(err);
        $('.speaker--container').html('');
      }
    }
  
    /**
     * Start recording the test.
     */
    function startTestRecord(duration) {
      timeToThinkNote.hide();
      btnRecord.removeClass('time-to-think count-down').html(Drupal.t('Next Question') + '<i class="fa fa-step-forward"></i>');
      jsTimeNote.hide();
      recordingIndicator.show();
      startRecording(duration);
    }
  
    /**
     * Get audio context status.
     */
    function getAudioContextStatus(callback) {
      try {
        if (microphone === (null || undefined)) {
          if (!navigator.getUserMedia) {
            navigator.getUserMedia =
              navigator.webkitGetUserMedia ||
              navigator.mozGetUserMedia ||
              navigator.msGetUserMedia;
          }
          if (!navigator.cancelAnimationFrame) {
            navigator.cancelAnimationFrame =
              navigator.webkitCancelAnimationFrame ||
              navigator.mozCancelAnimationFrame;
          }
          if (!navigator.requestAnimationFrame) {
            navigator.requestAnimationFrame =
              navigator.webkitRequestAnimationFrame ||
              navigator.mozRequestAnimationFrame;
          }
          if (navigator.mediaDevices) {
            // If navigator.mediaDevices exists, use it.
            navigator.mediaDevices
              .getUserMedia({
                audio: true
              })
              .then(gotStream, function (e) {
                console.warn('navigator error: ', e);
                $('#js-skip-test-mic').removeAttr('data-toggle').on('click', function (e) {
                  e.preventDefault();
                  showRecordingError();
                })
                var msg = generateErrorMsg(e);
                notifyErrorMicrophone(msg);
              });
          } else {
            navigator.getUserMedia({
                audio: {
                  mandatory: {
                    googEchoCancellation: "false",
                    googAutoGainControl: "false",
                    googNoiseSuppression: "false",
                    googHighpassFilter: "false"
                  },
                  optional: []
                }
              },
              gotStream,
              function (e) {
                console.warn('navigator error: ', e);
                $('#js-skip-test-mic').removeAttr('data-toggle').on('click', function (e) {
                  e.preventDefault();
                  showRecordingError();
                })
                var msg = generateErrorMsg(e);
                notifyErrorMicrophone(msg);
              }
            );
          }
        } else {
          toggleStartTest();
        }
      } catch (e) {
        var msg = Drupal.t('You must switch to https to continue testing!')
        notifyErrorMicrophone(msg);
        $('#js-start-part').on('click', function () {
          $('#modal-upload-error').modal({
            keyboard: false,
            show: true,
            backdrop: 'static'
          })
        });
      }
    }
  
    function notifyErrorMicrophone(msg) {
      $('#modal-upload-error').find('.modal-title').html(Drupal.t('Cannot access your microphone'))
      $('#modal-upload-error').find('[data-drupal-selector="message"]').html(msg)
      $('#modal-upload-error').modal({
        keyboard: false,
        show: true,
        backdrop: 'static'
      });
    }
  
    function gotStream(stream) {
      audioState = true;
      microphone = audioContext.createMediaStreamSource(stream);
      microphone.connect(microphoneLevel);
      toggleStartTest();
      runWaveSurfer();
    }
  
    function generateErrorMsg(err) {
      var errMsg = err.toString();
      // NotAllowedError
      if (errMsg.search('NotAllowedError') > -1 || errMsg.search('denied') > -1) {
        return Drupal.t('Please allow the website to use your microphone to continue the practice test. Read the instruction on how to re-enable the microphone <a href="@url" target="_blank"><strong>here</strong>.</a>', {
          '@url': getInstructionUrl()
        });
      }
  
      return Drupal.t('We cannot detect your microphone, please check your microphone again or try a different one');
    }
  
    function getInstructionUrl() {
      try {
        if (drupalSettings.sot_questions.instructions) {
          var elm = document.createElement('div');
          elm.innerHTML = drupalSettings.sot_questions.instructions.value;
          var $elm = $(elm);
          if ($elm.find('a').length) {
            return $elm.find('a').attr('href');
          }
        }
      } catch (e) {
        console.warn(e);
      }
  
      return '';
    }
  
    function toggleStartTest() {
      $('#js-start-part').on('click', function () {
        $('#js-start-part').addClass('hide');
        $('#part-instruction-content').addClass('hide');
        $('.mic-box__btn-group-action.hide').removeClass('hide');
        $('#part-question-content.hide').removeClass('hide');
        playQuestionRecord();
        countDownTimeToThink();
  
      })
    }
  
    /**
     * -------------------------
     * END General function
     * ------------------------
     */
  
    /**
     *  Drupal handle.
     */
    
  
    function iOS() {
      return [
          'iPad Simulator',
          'iPhone Simulator',
          'iPod Simulator',
          'iPad',
          'iPhone',
          'iPod'
        ].includes(navigator.platform)
        // iPad on iOS 13 detection
        ||
        (navigator.userAgent.includes("Mac") && "ontouchend" in document)
    }
    /**
     * ------------------------------
     * 1. Test mic func.
     * ------------------------------
     */
  
    function handlerTestMicrophone() {
      $('#js-skip-test-mic').show();
      $('#waveform').addClass('thinking');
      // Step 1: Change Screen.
      $('[data-drupal-selector="change-screen"]').on('click', function () {
        if ($(this).hasClass('js-check-ios')) {
          //   var iOS = !!navigator.platform && (/iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1));
          //   if (iOS) {
          //     return;
          //   }
          // Checking user browser.
          // Detect user browser
          var browserName = (function (agent) {
            switch (true) {
              case agent.indexOf("edge") > -1:
                return true;
              case agent.indexOf("edg/") > -1:
                return true;
              case agent.indexOf("opr") > -1 && !!window.opr:
                return true;
              case agent.indexOf("chrome") > -1 && !!window.chrome:
                return true;
              case agent.indexOf("trident") > -1:
                return false;
              case agent.indexOf("firefox") > -1:
                return true;
              case agent.indexOf("safari") > -1:
                return true;
              default:
                return false;
            }
          })(window.navigator.userAgent.toLowerCase());
          if (!browserName) {
            $('#modal-no-support').modal({
              backdrop: 'static'
            });
            return;
          }
        }
        timeTest = 20;
        runSpeakingRadial(timeTest);
        jsTimeDuration.text(convertTimeToString(timeTest));
        getAudioContextStatus();
        runWaveSurfer();
      })
      btnRecord.on('click', function () {
        testMicrophone();
      })
  
      btnReset.on('click', function () {
        jsSpeakerRadial.val(0).trigger('change');
        startTestMic = false;
        $('.test-caption').show();
        runSpeakingRadial(timeTest);
        jsTimeDuration.text('');
        recordPart.show();
        btnRecord.show();
        btnReset.hide();
        resultPart.hide();
        $('.iot-bt.-next-part').css({
          display: 'none'
        })
        testMicrophone();
      })
    }
  
    function showTestMicPreview() {
      // Stop recording.
      if (audioRecorder.isRecording()) {
        stopRecording(true);
      }
      $('#js-skip-test-mic').hide()
      recordPart.hide();
      btnRecord.hide();
      btnReset.css({
        display: 'inline-flex'
      })
      resultPart.show();
      jsNextPart.css({
        display: 'inline-flex'
      });
      $('.test-caption').hide();
    }
  
    function testMicrophone() {
      if (!audioState) {
        showRecordingError();
        return;
      }
  
      if (jsPlayer.plyr !== undefined) {
        jsPlayer.plyr.pause()
        jsPlayer.plyr.media.src = ''
      }
  
      $('#js-skip-test-mic').show();
      startTestMic = !startTestMic;
      if (startTestMic) {
        timeTest = 20;
        btnRecord.addClass('recording');
        btnRecord.html('Stop');
        startRecording(timeTest);
        var start = Date.now();
        $('#waveform').removeClass('thinking');
        intervalTimeTest = setInterval(function () {
          var now = Date.now();
          var diff = lap + (now - start) / 1000 | 0;
  
          jsTimeDuration.text(convertTimeToString(timeTest - diff));
          jsSpeakerRadial.val(diff).trigger('change');
          if (timeTest <= diff || !startTestMic) {
            clearInterval(intervalTimeTest);
            showTestMicPreview();
          }
        }, 10)
      } else {
        $('#waveform').addClass('thinking');
        showTestMicPreview();
        clearInterval(intervalTimeTest);
  
      }
    }
  
    /**
     * ------------------------------
     *  End Test Microphone
     * -----------------------------
     */
  
    /**
     * ------------------------------
     *  STEP 2. Take Test.
     * -----------------------------
     */
  
    /**
     * Pausing the current test for time to think for next question.
     */
    function pauseRecording() {
      var diffTime = currentTimeRecording > 0 ? audioRecorder.context.currentTime - currentTimeRecording : audioRecorder.context.currentTime;
      questionBoundaries.push(diffTime);
      recordingIndicator.hide();
      btnRecord.addClass('time-to-think count-down');
      timeToThink = 5;
      try {
        timeToThink = drupalSettings.sot_questions.part[curPart].questions[curQuestion].time_to_think_qs;
        console.log("time to think", drupalSettings.sot_questions.part[curPart].questions[curQuestion].time_to_think_qs);
      } catch (e) {
        console.warn(e);
      }
      startTest = false;
      clearInterval(intervalTimeTest);
      audioContext.suspend();
      countDownTimeToThink();
    }
  
    /**
     * Counting down "time to think".
     */
    function countDownTimeToThink() {
      if ($('#step-test-mic').length || !audioState) {
        return;
      }
      timeToThinkNote.show();
      var start = Date.now();
      if (intervalTimeToThink) {
        clearInterval(intervalTimeToThink);
      }
      intervalTimeToThink = setInterval(function () {
        var now = Date.now();
        var diff = (now - start) / 1000 | 0;
        if (timeToThink <= diff || startTest) {
          clearInterval(intervalTimeToThink);
          startTestRecord(timeTest);
          if (curQuestion === 0) {
            qsSelector.addClass('titleFlash');
            $('.recording-mess').addClass('zoomInSpeak');
            setTimeout(function () {
              qsSelector.removeClass('titleFlash');
              $('.recording-mess').removeClass('zoomInSpeak');
            }, 1000);
          }
          $('#waveform').removeClass('thinking');
        } else {
          var timeToThinkString = convertTimeToString(timeToThink - diff);
          btnRecord.text(Drupal.t('Time to Think @time', {
            '@time': timeToThinkString
          }))
        }
      }, 10);
      lap = parseFloat(jsSpeakerRadial.val());
    }
  
    /**
     * Counting down "time to test".
     */
    function countDownTimeTest() {
      if ($('#step-test-mic').length || !audioState) {
        return;
      }
      timeToThink = 0;
      var start = Date.now();
      if (intervalTimeTest) {
        clearInterval(intervalTimeTest);
      }
      intervalTimeTest = setInterval(function () {
        var now = Date.now();
        var diff = lap + (now - start) / 1000 | 0;
  
        var diffTime = currentTimeRecording > 0 ? audioRecorder.context.currentTime - currentTimeRecording : audioRecorder.context.currentTime;
        jsTimeDuration.text(convertTimeToString(timeTest - diffTime));
        jsSpeakerRadial.val(diffTime).trigger('change')
        if (timeTest <= diffTime || !startTest) {
          clearInterval(intervalTimeTest);
          if (timeTest <= diffTime) {
            showModalTimeUp();
          }
        }
      }, 10);
    }
  
    /**
     * Showing the test result of current part.
     */
    function showPartPreview() {
      // modalFinish.modal('hide');
      // modalTimeUp.modal('hide');
      recordPart.hide();
      btnRecord.hide();
      btnReset.css({
        display: 'inline-flex'
      })
      resultPart.show();
      partCaption.show();
      jsNextPart.css({
        display: 'inline-flex'
      })
      jsSpeakerRadial.val(0).trigger('change');
    }
  
    /**
     * Showing the modal when the testing is time up.
     */
    function showModalTimeUp() {
      // Stop recording.
      stopRecording(true);
      modalTimeUp.modal({
        keyboard: false,
        show: true,
        backdrop: 'static'
      });
    }
  
    /**
     * Showing the modal when the last question click.
     */
    function showModalFinish() {
      // Stop recording.
      stopRecording(true);
      modalFinish.modal({
        keyboard: false,
        show: true,
        backdrop: 'static'
      });
      console.info(questionBoundaries);
    }
  
    function runWaveSurfer(status) {
      var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
      var context, processor;
      $("#waveform").css({
        visibility: 'visible',
        opacity: 1
      });
      var iOSCheck = iOS();
      if (wavesurferElm === undefined) {
        // if (isSafari) {
        //   // Safari 11 or newer automatically suspends new AudioContext's that
        //   // aren't created in response to a user-gesture, like a click or tap, so
        //   // create one here (inc. the script processor)
        //   context = context || new AudioContext();
        //   processor = context.createScriptProcessor(1024, 1, 1);
        // }
        if (iOSCheck) {
          //disable wave surfer on the IOS platform
          return true;
        }
        // Init wavesurfer.
        wavesurferElm = wavesurferElm || WaveSurfer.create({
          container: "#waveform",
          waveColor: "#d28393",
          progressColor: "#4353ff",
          cursorColor: "#4353ff",
          barWidth: 0,
          barHeight: 1,
          barRadius: 0,
          cursorWidth: 1,
          height: 100,
          barGap: null,
          interact: false,
          cursorWidth: 0,
          audioContext: context || null,
          audioScriptProcessor: processor || null,
          plugins: [
            WaveSurfer.microphone.create({
              bufferSize: 4096,
              numberOfInputChannels: 1,
              numberOfOutputChannels: 1,
              constraints: {
                video: false,
                audio: true
              }
            })
          ]
        });
  
        wavesurferElm.microphone.on("deviceReady", function () {
          console.info("Device ready!");
        });
        wavesurferElm.microphone.on("deviceError", function (code) {
          console.warn("Device error: " + code);
        });
        wavesurferElm.on("error", function (e) {
          console.warn(e);
        });
        wavesurferElm.microphone.start();
      } else {
        // start/stop mic on button click
        if (wavesurferElm.microphone.active) {
          wavesurferElm.microphone.stop();
        } else {
          wavesurferElm.microphone.start();
        }
      }
    }
  
    /**
     * Rendering current part for test.
     */
    function renderPart() {
      try {
        $('#waveform').addClass('thinking');
        var partData = drupalSettings.sot_questions.part[curPart];
        var questionData = partData.questions[curQuestion];
        var part = curPart + 1;
        if (player !== undefined) {
          player.stop();
          player.currentTime = 0;
        }
        recordingIndicator.hide();
        $('#part-instruction-content .mic-box__instruction-desc').html(partData.instructions);
        $('#js-start-part').removeClass('hide');
        $('#part-instruction-content').removeClass('hide');
        $('.test-mic-actions').addClass('hide');
        $('#part-question-content').addClass('hide');
  
        $('#js-part-title').find('.mic-box__part-num').html(Drupal.t("Part @part:", {
          '@part': part
        }));
        $('[data-drupal-selector="part-title"]').html(partData.title);
        $('[data-drupal-selector="end-part-title"]').html(Drupal.t("It’s the end of Part @part", {
          '@part': part
        }));
        if (curPart < drupalSettings.sot_questions.part.length - 1) {
          $('[data-drupal-selector="end-part-desc"]').html(Drupal.t("You can click <strong>Next Part</strong> to continue Part @next <br>Or <strong>Reset this part</strong> to record again", {
            '@next': curPart + 2
          }));
        } else {
          $('[data-drupal-selector="end-part-desc"]').html(Drupal.t('You can click <strong>submit</strong> to finish the test <br>Or <strong>Reset this part</strong> to record again'));
          jsNextPart.text(Drupal.t('Submit Test')).attr('data-drupal-selector', 'submit-test');
        }
        $('[name="field_part_' + part + '_questions"]').val('');
        if (partData.questions.length === 1) {
          // Render question data.
          qsNumber.html(Drupal.t('Question @number', {
            '@number': ''
          }))
        } else {
          // Render question data.
          qsNumber.html(Drupal.t('Question @number', {
            '@number': (curQuestion + 1)
          }))
        }
  
        qsSelector.html(questionData.text_question);
        qsDescSelector.html(questionData.suggestion_text);
        
        
  
        // Init time.
        timeTest = partData.time.total_answer_time;
        var timeTestString = convertTimeToString(timeTest);
        timeToThink = partData.questions[curQuestion].time_to_think_qs;
  
        var timeToThinkString = convertTimeToString(timeToThink);
        btnRecord.addClass('time-to-think');
        btnRecord.text(Drupal.t("Time to Think @time", {
          "@time": timeToThinkString
        }));
        jsTimeDuration.html(timeTestString);
        var timeTestInM = timeTest / 60;
        var note = Drupal.t("You have @time minutes to speak…", {
          "@time": timeTestInM < 1 ? timeTestInM.toFixed(1) : timeTestInM
        });
        jsTimeNote.show().text(note);
        runSpeakingRadial(timeTest);
        startTest = false;
        btnRecord.addClass('time-to-think count-down');
        startTime = 0;
        questionBoundaries = [0];
        setTimeout(function () {
          getAudioContextStatus();
        }, 500)
      } catch (e) {
        console.warn(e);
      }
    }
  
    /**
     * Geting the answer of current question.
     */
    function getAnswer() {
      var part = curPart + 1;
      // Init data.
      var data = drupalSettings.sot_questions.part[curPart];
      var question = data.questions[curQuestion];
      var field_questions = $('[name="field_part_' + part + '_questions"]');
      var init_answer = [];
      if (field_questions.val() != '') {
        var init_answer = JSON.parse(field_questions.val());
      }
      var answer = {
        time: {
          start: startTime,
          end: parseFloat(jsSpeakerRadial.val())
        },
        question_txt: question.text_question,
        id: question.id,
        suggestion_text: question.suggestion_text !== undefined ? question.suggestion_text : ''
      }
      startTime = parseFloat(jsSpeakerRadial.val());
  
      init_answer.push(answer);
  
      field_questions.val(JSON.stringify(init_answer));
    }
  
    /**
     * Geting the answer of current question.
     */
    function getAnswerNotTest(question_id) {
      var part = curPart + 1
      // Init data.
      var data = drupalSettings.sot_questions.part[curPart];
      var question = data.questions[question_id];
      var field_questions = $('[name="field_part_' + part + '_questions"]');
      var init_answer = [];
      if (field_questions.val() != '') {
        var init_answer = JSON.parse(field_questions.val());
      }
      var answer = {
        time: {
          start: startTime,
          end: parseFloat(jsSpeakerRadial.val())
        },
        question_txt: question.text_question,
        id: question.id,
        suggestion_text: question.suggestion_text !== undefined ? question.suggestion_text : ''
      };
      startTime = parseFloat(jsSpeakerRadial.val());
  
      init_answer.push(answer);
  
      field_questions.val(JSON.stringify(init_answer));
    }
  
    /**
     * Geting next question
     */
    function nextQuestion() {
      var part = curPart + 1;
      if (!qsSelector.length && !$('[name="field_part_' + part + '_questions"]').length) {
        return false;
      }
  
      if (drupalSettings.sot_questions.part[curPart] !== undefined || null) {
        // Init data.
        var data = drupalSettings.sot_questions.part[curPart];
        // Init question data.
        if (data.questions[curQuestion] !== undefined || null) {
          getAnswer();
          curQuestion++;
          if (curQuestion == data.questions.length) {
            showModalFinish();
            return;
          }
  
          pauseRecording();
          if (data.questions[curQuestion] !== undefined || null) {
            qsSelector.html(data.questions[curQuestion].text_question).addClass('titleFlash');
            setTimeout(function () {
              qsSelector.removeClass('titleFlash');
            }, 1000);
            qsNumber.html(Drupal.t('Question @number', {
              '@number': (curQuestion + 1)
            }))
            if (data.questions[curQuestion].suggestion_text !== undefined) {
              qsDescSelector.html(data.questions[curQuestion].suggestion_text);
            } else {
              qsDescSelector.html('');
            }

            playQuestionRecord();



          } else {
            return false;
          }
        }
      }
  
      return true;
    }
  
    /**
     * Geting next part.
     */
    function nextPart() {
      var blobFile = blobFiles[curPart];
      if (jsNextPart.hasClass('clicked')) { return; }
      jsNextPart.addClass('clicked');
      var part = curPart + 1;
      var field_name = 'field_part_' + part + '_recording';
      var now = new Date();
      var suffix = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate();
      blobFile.name = drupalSettings.sot_questions.file_name_suffix + '_result_part_' + part + '_' + suffix + '.wav';
      
      // Generate question.
      var data = drupalSettings.sot_questions.part[curPart]
      let questionIds = [];
      data.questions.forEach(q => {
        questionIds.push(q.id);
      });

      let session    = JSON.parse(jQuery('#session-details[type="application/json"]').text()); 
      let quiz      = JSON.parse(jQuery('#quiz-json[type="application/json"]').text());
      
      // Sent file to the server.
      $("body").addClass("uploading");
      let formdata = new FormData();
      formdata.append('file2upload', blobFile);
      formdata.append('name', field_name);
      formdata.append('action', 'proqyz-save-speaking-progress');
      formdata.append('intervals', questionBoundaries.join(','));
      formdata.append("passage_id", data.id);
      formdata.append('passage_key', curPart);
      formdata.append("total_parts", drupalSettings.sot_questions.part.length);
      formdata.append("question_ids", questionIds);
      formdata.append("json", JSON.stringify(session));
      formdata.append("quiz", JSON.stringify(quiz));
  
      
      if(1 == 1){
  
        $.ajax({
          xhr: function () {
            var xhr = new window.XMLHttpRequest();
            // Handle progress
            // Upload progress.
            xhr.upload.addEventListener(
              "progress",
              function (evt) {
                if (evt.lengthComputable) {
                  var percentComplete = Math.ceil((evt.loaded / evt.total));
                  // Do something with upload progress.
                  $("#progress-upload").text(percentComplete + "%");
                }
              },
              false
            );
            return xhr;
          },
          url           : window.site_url + '/wp-admin/admin-ajax.php',
          type          : "POST",
          data          : formdata,
          processData   : false,
          contentType   : false,
          success       : function (res) {
            if(res.status){
              jsNextPart.removeClass('clicked');
              curPart++;
              curQuestion = 0;
              
              if (curPart <= drupalSettings.sot_questions.part.length - 1) {
                resetPart();
                $('body').removeClass('uploading');
              } else {
                if (res.result == 1) {
                  if (res.redirect) {
                    window.location.href = res.url;
                  }
                    
                }
                /* $(takeTestForm).trigger('submit'); */
              }
            } else {
              jsNextPart.removeClass('clicked');
              showModalError(res.res_type, Drupal.t(res.res), res.url);
              $("body").removeClass("uploading");                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
            }
          },
          error         : function (err) {
            jsNextPart.removeClass('clicked');
            showModalError('error', Drupal.t('An error occurred, please save the test to your device!'), URL.createObjectURL(blobFile));
            $("body").removeClass("uploading");  
          }
        });
  
      } else {
        jsNextPart.removeClass('clicked');
        curPart++;
        curQuestion = 0;
        if (curPart <= drupalSettings.sot_questions.part.length - 1) {
          resetPart();
          $('body').removeClass('uploading');
        } else {
          window.alert("Preview finished");
          window.location.reload();
  
        }
      }
  
  
  
    }
  
    /**
     * Showing modal error and download link.
     */
    function showModalError($type = "warning", $msg, $url) {
      $('#modal-upload-error').find('[data-drupal-selector="message"]').html(`<div class="alert alert-${$type}">${$msg}</div>`);
      $('#modal-upload-error').find('[data-drupal-selector="download"]').html('<a class="btn iot-bt" href="' + $url + '" target="_blank">' +
        Drupal.t('Download') +
        '</a>');
      $('#modal-upload-error').modal('show');
    }
  
    /**
     * Reset current part.
     */
    function resetPart() {
      clearInterval(intervalModalCount);
      clearInterval(intervalTimeToThink);
      clearInterval(intervalTimeTest);
      curQuestion = 0;
      startTest = false;
      recordPart.show();
      btnRecord.show();
      btnReset.hide();
      resultPart.hide();
      partCaption.hide();
      jsNextPart.hide();
      $('#js-start-part').addClass('hide');
      $('.mic-box__btn-group-action').addClass('hide');
      renderPart();
    }
  
    /**
     * ------------------------------
     *  End Take Test.
     * -----------------------------
     */
    Drupal.behaviors.SOTTakeTest = {
      attach: function (context, settings) {
        if ($('#step-test-mic').length) {
          handlerTestMicrophone()
        } else {
          if ($('textarea[name="notes"]').length) {
            var navigator_device = [];
            navigator_device.push({
              'userAgent': navigator.userAgent,
              'platform': navigator.platform
            });
            $('textarea[name="notes"]').val(JSON.stringify(navigator_device));
          }
          setTimeout(function () {
            renderPart();
          }, 500);
        }
        // Get csrfToken.
        if (csrfToken === '') {
          
        }
      }
    }


    $('.audio__slider').on('drag, change', function (e) {
      let $this = $(this);
      let $elem = $this.closest('.js-audio');
      updateAudio(e, $elem);
      $this.addClass('active');
    });
    
    function updateAudio(e, $elem) {
      console.log(e.handle.value);
      let value = e.handle.value;
      // var thisPlayer = el.find('.js-audio'),
      var play = $elem.find('.play-pause'),
      circle = $elem.find('#seekbar'),
    
      getCircle = circle.get(0),
      totalLength = getCircle.getTotalLength(),
      //currentTime = $elem.find('audio')[0].currentTime,
      maxduration = $elem.find('audio')[0].duration;
      var y = value * maxduration / 100;
      $elem.find('audio')[0].currentTime = y;
    
    }
    
    function initAudioPlayer(player) {
      let audio = player.find('audio'),
      play = player.find('.play-pause'),
      circle = player.find('#seekbar'),
      getCircle = circle.get(0),
      totalLength = getCircle.getTotalLength();

      circle.attr({
        'stroke-dasharray': totalLength,
        'stroke-dashoffset': totalLength });
    
    
      play.on('click', () => {
        if (audio[0].paused) {
          $('audio').each((index, el) => {
            $('audio')[index].pause();
          });
          $('.js-audio').removeClass('playing');
          audio[0].play();
          player.removeClass('paused');
          player.addClass('playing');
        } else {
          audio[0].pause();
          player.removeClass('playing');
          player.addClass('paused');
        }
      });
    
      audio.on('timeupdate', () => {
        let currentTime = audio[0].currentTime,
        maxduration = audio[0].duration,
        calc = totalLength - currentTime / maxduration * totalLength;
    
        circle.attr('stroke-dashoffset', calc);
    
        let value = Math.floor(currentTime / maxduration * 100);
    
        var slider = audio.closest('.js-audio').find('.audio__slider');
        $(slider).roundSlider('setValue', value);
      });
    
      audio.on('ended', () => {
        player.removeClass('playing');
        circle.attr('stroke-dashoffset', totalLength);
    
      });

      //audio.play();
      // play.click();
    }






  }(jQuery, Drupal, drupalSettings));