<commit_before>

function Vrt(type, list, streamUrl, streamName, apiDomain, apiUser, apiPassword,  options) {


    //User settings
    this.videoList = null;
    this.videoFullscreen = false;
    this.videoType = null; //youtube or customserver
    this.canSkip = false;
    this.debug = false;
    this.debugEvt = false;
    this.debugTime = false;
    this.debugChrono = false;
    this.debugVImportant = false;
    this.options = {};

    //Producer
    this.playerVersion = null;
    this.producer = null;
    this.producerID = null;
    this.producerID = null;
    this.producerWidth = null;
    this.producerHeight = null;
    this.swfobject = false;
    this.vrt = false;
    this.vrtID = false;
    this.producerStreamUrl = null;
    this.producerStreamName = null;
    this.producerStreamWidth = 640;
    this.producerStreamHeight = 480;
    this.stream_code = null;
    this.recAutoHide =true;
    this.recorderCenter =true;
    this.randomOrder = false;

    //Various
    this.flash_allowed = false;
    this.ww = 0;            //windows width
    this.wh = 0;            //windows height
    this.media_id = null;   //media played
    this.media_length = 0;  //media played
    this.media_path = null; //media played
    this.exitcode = null;
    this.mainStyle =  '';

    //steps && user actions
    this.click_start = false;
    this.isRecording = false;
    this.isPlaying = false;
    this.currentMedia = -1;
    this.mediaCount = 0;
    this.streamName = '';
    this.stop_handle;
    this.stop_handle_rec;

    //player values
    this.vjs = false;
    this.player = null;
    this.is_player_ready = false;
    this.player_starts_recorder = false;
    this.avgPreLoadTime = 0;

    //api client values
    this.ceclient;
    this.apiUsername, this.apiPassword, this.apiDomain;
    this.eventList = {};


    this.initialized = function(type, list, streamUrl, streamName, apiDomain, apiUser, apiPassword,  options){

        if(options == undefined || options == null) options = {player : {}};

        if(options && options.fullscreen) {this.videoFullscreen = options.fullscreen && this.checkSafariMinVer(false,6)} else {  this.videoFullscreen = false };
        (options && options.skip !=undefined)? this.canSkip = options.skip : this.canSkip = false;
        (options && options.vrtID)? this.vrtID = options.vrtID : this.vrtID = 'vrt';
        (options && options.producerID)? this.producerID = options.producerID : this.producerID = 'producer';
        (options && options.producerWidth)? this.producerWidth = options.producerWidth : this.producerWidth = 320;
        (options && options.producerHeight)? this.producerHeight = options.producerHeight : this.producerHeight = 240;
        (options && options.debug !=undefined)? this.debug = options.debug : this.debug = false;
        (options && options.debugEvt !=undefined)? this.debugEvt = options.debugEvt : this.debugEvt = false;
        (options && options.debugTime !=undefined)? this.debugTime = options.debugTime : this.debugTime = false;
        (options && options.debugChrono !=undefined)? this.debugChrono = options.debugChrono : this.debugChrono = false;
        (options && options.debugImportant !=undefined)? this.debugImportant = options.debugImportant : this.debugImportant = false;
        (options && options.debugVImportant !=undefined)? this.debugVImportant = options.debugVImportant : this.debugVImportant = false;
        (options && options.producerStreamWidth)? this.producerStreamWidth = options.producerStreamWidth : this.producerStreamWidth = 640;
        (options && options.producerStreamHeight)? this.producerStreamHeight = options.producerStreamHeight : this.producerStreamHeight = 480;
        (options && options.avgPreLoadTime)? this.avgPreLoadTime = options.avgPreLoadTime : this.avgPreLoadTime = 0;
        (options && options.recorderCenter!=undefined)? this.recorderCenter = options.recAutoHide : this.recorderCenter = true;
        (options && options.randomOrder!=undefined)? this.randomOrder = options.randomOrder : this.randomOrder = false;

        this.options = options;
        if(options.player == undefined || options.player == null) options.player = {};

        (options && options.playerCentered!=undefined)? this.options.player.centered = options.playerCentered : this.options.player.centered = true;
        (options && options.playerWidth!=undefined)? this.options.player.width = options.playerWidth : this.options.player.Width = 640;
        (options && options.playerHeight!=undefined)? this.options.player.height = options.playerHeight : this.options.player.height = 400;



        this.mediaCount = list.length;
        this.videoType  = type;
        this.videoList  = list;
        this.producerStreamUrl = streamUrl;
        this.producerStreamName = this.clearname(streamName);
        this.calculateListData();
        this.randomizeOrderList();
        this.log(type,'type');
        this.log(list,'list');
        this.apiDomain = apiDomain;
        this.apiUsername = apiUser;
        this.apiPassword = <PASSWORD>;
    }


    this.init = function (type, list, streamUrl, streamName, apiDomain, apiUser, apiPassword,  options) {
        this.log('>>STEP: vrt init');
        this.log(arguments);

        window.vrt = this;

        this.log(this.mediaCount,'mediaCount');
        this.log(this.currentMedia,'currentMedia');
        this.log(this.producerStreamUrl,'producerStreamUrl');
        this.log(this.producerStreamName,'producerStreamName');

        this.injectLayout();
        this.initVar();
        this.vrtOn();


        //todo insert resizingWindovs

        this.playerVersion = swfobject.getFlashPlayerVersion();

        this.log("playerVersion");
        this.log(this.playerVersion.major);
        this.log(this.playerVersion.minor);

        this.log('EVT flash'+this.playerVersion.major);
        // TODO move Flash version check on the first page
        if (this.playerVersion.major == 0) {
            $(window.vrt).trigger('vrt_event_flash_no');
            this.log('EVT no flash');
        }

        if (swfobject.getFlashPlayerVersion("11.1.0")) {
            this.loadProducer();
        } else {
            $(window.vrt).trigger('vrt_event_flash_old');
            this.log('Flash is old=' + this.playerVersion.major + '.' + this.playerVersion.minor);
        }


        this.ceclient =  new CEClient();


        this.apiClientSetup(
            function(){
                $(window.vrt).trigger('api_init_ok');
                if(console.log)console.log('apiClientSetup api login success')
            },
            function(){
                $(window.vrt).trigger('vrt_event_api_login_fail');
                if(console.log)console.log('apiClientSetup api login error')
            }
        );

        $(this).trigger('vrt_init_ok');
    };

    this.initVar = function(){
    };

    this.injectLayout = function(){
        var pre = this.vrtID;
        var certerstyle ="";//   "    position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);";
        (this.options && this.options.mainStyle)? '' : this.options.mainStyle = certerstyle;
        (this.options && this.options.recStyle)? '' : this.options.recStyle = certerstyle;
        (this.options && this.options.videoStyle)? '' : this.options.videoStyle = certerstyle;


        var html=" <div id='vrtWrapper' class='vrtWrap' style='"+this.options.mainStyle+"'> " +
                ((this.options.htmlRecorderPre)? this.options.htmlRecorderPre : '') +
                "       <div id='vrtProducer' class='vrtWrap "+this.options.htmlRecorderClass+"' style='"+this.options.recStyle+"'>                      "+
                "           <div id='producer'></div>                                                                   "+
                "           <div class='clearfix'></div>                                                                "+
                "       </div>                                                                                          "+
                ((this.options.htmlRecorderPost)? this.options.htmlRecorderPost : '') +
                ((this.options.htmlVideoPre)? this.options.htmlVideoPre : '') +
                "<div id='vrtVideoWrapper' class='vrtWrap' style='"+this.options.videoStyle+"'>                                                      "+
                "      <div id='vrtvideo' class='"+this.options.htmlVideoClass+"'></div>                                "+
                "      <div id='videoDiv' class='"+this.options.htmlVideoClass+"'></div>                                "+
                "      <div id='ytPlayer' class='"+this.options.htmlVideoClass+"'></div>                                "+
                "      <div class='clearfix'></div>                                                                     "+
                "</div>                                                                                               "+
                ((this.options.htmlVideoPost)? this.options.htmlVideoPost : '') +
                "<div id='vrtLogWrapper' class='vrtWrap'>                                                      "+
                "      <div id='vrtalert'></div>                                                                        "+
                "      <div id='vrt_timer_player'></div>                                                                       " +
                "      <div id='vrt_timer_recorder'></div>                                                                       " +
                "      <div class='clearfix'></div>                                                                     "+
                "</div>                                                                                               "+
                "</div>";

        var debugHtml="<div id='vrtValues' class='vrtWrap'>                                                             "+
                "          <h4>Info</h4>                                                                                "+
                "          <div id='vrtVal_type'>Type: <span></span></div>                                              "+
                "          <div id='vrtVal_mediaCount'>media count: <span></span></div>                                 "+
                "          <div id='vrtVal_currentMedia'>current media: <span></span></div>                             "+
                "          <div id='vrtVal_list'>List: <span></span></div>                                              "+
                "          <div id='vrtVal_producerStreamUrl'>Producer stream URL: <span></span></div>                  "+
                "          <div id='vrtVal_producerStreamName'>Producer stream name: <span></span></div>                "+
                "          <div id='vrtVal_producerConnStatus'>Producer conn status: <span>Not connected</span></div>   "+
                "          <div id='vrtVal_apiStatus'>API status: <span>Not connected</span></div>                      "+
                "          <div id='vrtVal_fileUpload'>Files: <span>Not connected</span></div>                          "+
                "      </div>                                                                                           "+
                "      <div id='vrtLog'></div>                                                                          "

        $("#"+pre).html(html);

    };

    /**
     * The function set recorder to visibility hidden, if not a altFunction is specified.
     * In some browser, if you use display: none, the swf object will be destroyed
     * @param altFunction
     * @param callback
     */
    this.recorderHide = function(altFunction,callback){
        if(!altFunction){
            $('#vrtProducer').css('visibility','hidden');
            $('#producer').css('visibility','hidden');
            $('#vrtProducer').css('z-index',-1000);
            $('#producer').css('z-index',-1000);
            $('#vrtProducer').css('height','1px');
            $('#producer').css('width','1px');
        }else{
            altFunction();
        }
        if(callback)callback();
    };

    this.recorderShow = function(altFunction,callback ){
        if(!altFunction){
            $('#vrtProducer').css('visibility','visible');
            $('#producer').css('visibility','visible');
            $('#vrtProducer').css('z-index',1000);
            $('#producer').css('z-index',1000);
            $('#vrtProducer').css('height','320px');
            $('#producer').css('width','240px');
        }else{
            altFunction();
        }
        if(callback)callback();
    };

    this.trigger = function( type, data){
        $(vrt).trigger( type, data);
    };

    this.vrtOnStartSequence = 0;
    this.vrtOn = function(){

        //internal event: start
        $(window.vrt).on('vrt_init_ok', function() {
            window.vrt.vrtTrigLoadend('vrt_init_ok');
        });
        $(window.vrt).on('producer_init_ok', function() {
            vrt.producerSetupConnection( vrt.producerConnection );
            window.vrt.vrtTrigLoadend('producer_init_ok');
        });
        $(window.vrt).on('api_init_ok', function() {
            window.vrt.vrtTrigLoadend('api_init_ok');
        });


        $(window.vrt).on('vrtstep_loaded', function() {
            vrt.log('EVT vrtstep_loaded');
            vrt.log('>>EVT vrtstep_loaded');
            vrt.player.video_play(vrt.showVisibility('#videoDiv'));
            //TODO open_video_window();  // HACK else the Flash player is not instantiated
        });
        $(window.vrt).on('vrtstep_playerStateChange', function(e, data) {
            vrt.log('EVT vrtstep_playerStateChange '+data.state+' time '+data.time[4]+' '+data.time[5]+' '+data.time[6]);
        });

        $(window.vrt).on('vrtstep_loadplay', function() {
            vrt.log('EVT vrtstep_loadplay');

        });
        $(window.vrt).on('vrtstep_play', function(e, data) {
            vrt.log('EVT vrtstep_play caller '+data.caller);
            if(vrt.isPlaying==false){
                streamName = this.videoList[this.currentMedia].streamCode;

                vrt.producer.publish(streamName);
                vrt.isPlaying=true;
                vrt.logChrono(1, true, 'player');
                vrt.setup_stop_playing();
            }

        });

        $(window.vrt).on('vrtstep_connect', function() {
            vrt.log('EVT vrtstep_connect ' + vrt.logTime());

        });

        $(window.vrt).on('vrt_event_publish', function() {
            vrt.log('EVT vrt_event_publish  ' + vrt.logTime());
        });

        $(window.vrt).on('vrtstep_disconnect', function() {
                vrt.log('EVT vrtstep_disconnect');
        });

        //external event
        $(window.vrt).on('vrt_event_start_video_session', function() {
            if(window.vrt.recAutoHide==false){
                window.vrt.setupPlayer()
            }else{
                window.vrt.recorderHide(null,window.vrt.setupPlayer());
            }
        });

        $(window.vrt).on('vrt_event_user_next_video', function() {
            window.vrt.nextStep()
        });

        $(window.vrt).on('vrt_event_user_session_complete', function() {
            window.vrt.closeSession();
        });

        $(window.vrt).on('vrt_event_frame_open', function(e, data) {
            vrt.log('EVT vrt_event_frame_open');
            vrt.createFrame(data);
        });

        $('#vrtWrapper').on('click','#vrtFrameClose', function(){
           vrt.closeFrame();
        });

    };

    this.openFrame = function(src, options){

        $(vrt).trigger('vrt_event_frame_open', [{src : src, html: options.html, width: options.width, height: options.height, showBtnClose: options.showBtnClose,
                                        btnCssClass: options.btnCssClass, btnStyle: options.btnStyle, btnText:options.btnText, btnPosition: options.btnPosition}]);
    };

    this.closeFrame = function(){
        $('#vrtFrame').hide();
        $(window.vrt).trigger('vrt_event_frame_close');
    };

    this.vrtTrigLoadend = function(evtname){
        window.vrt.vrtOnStartSequence++;
        vrt.log('EVT vrtOnStartSequence '+evtname+' '+ window.vrt.vrtOnStartSequence);
        if(window.vrt.vrtOnStartSequence>=3){
            $(window.vrt).trigger('vrt_event_preview_loaded');
        }
    };

    this.playerConnectionLatency = function(){
        return 0;
        if(vrt.videoType=='youtube'){
            return 0;
        }else{
            return 0;
        }
    }

    this.createHashCode = function (s){
        var hash = 0;
        s = s.toString();
        if (s.length == 0) return s;
        for (i = 0; i < s.length; i++) {
            var char = s.charCodeAt(i);
            hash = ((hash<<5)-hash)+char;
            hash = hash & hash; // Convert to 32bit integer
        }
        return hash;
    };

    this.calculateListData = function (){

        for(var i = 0; i<this.mediaCount; i++){
            var d = new Date();
            var n = d.getTime();
            var pre = '';
            if(this.producerStreamName){
                var l = 4;
                if(this.producerStreamName.length<4) l = this.producerStreamName.length;
                pre = this.producerStreamName.substring(0,l);
            }
            this.videoList[i].streamCode = pre +'_'+ i +'_' + this.clearname(this.createHashCode(n));
            this.videoList[i].order = i;
        }
    };

    this.randomizeOrderList = function(){
        if(this.randomOrder===true && this.mediaCount>1){
            this.videoList =  this.shuffle(this.videoList);
        }
    }

    this.shuffle = function(o){ //v1.0
        for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
        return o;
    };

    //mediaInfo, instance of this.videoList
    this.buildVideoSources = function(mediaInfo) {
        if(this.videoType == 'customserver') {

            this.sources = [
                { type: "video/mp4", src: mediaInfo.path }
            ];

        } else {
            this.sources = [
                { type: "video/youtube", src: mediaInfo.path_original }
            ];
        }
    };

    this.startButton = function(){
        $("#vrtGuidingButton").click( this, function (vrtObj) {

            vrt.click_start = true;
            vrt.hideAllAndStartPlayer();
            vrt.trigger('vrt_start_ok');

        });
    };

    this.canStartButton = function(){
        this.log('canStartButton');
        $('body').on('click','#vrtCanStartButton',  this.setupCanStartButton);
    };

    this.setupCanStartButton = function () {
        vrt.log('canStartButton click');
        vrt.click_start = true;
        $('#vrtGuidingButton').show();
        vrt.popOverCe('pop_start');
    };


    this.hideAllAndStartPlayer = function(){
        this.hideVisibility('#vrtProducer');
        this.hideVisibility('#vrtCanStartButtonWrapper');
        this.hideVisibility('#vrtGuidingButton');

        this.producer.height=1;
        this.producer.width=1;
    };

    this.hideVisibility = function(el){
        $(el).css('visibility','hidden');
        $(el).css('z-index',-1000);
    };
    this.showVisibility = function(el){
        $(el).css('visibility','visible');
        $(el).css('z-index',0);
    };

    //TODO skipVideo
    this.skipVideo = function(){

    };

    this.facevideoUpload = function(url,cb){
        this.log(url,'fileUpload','a');
        this.log('!! '+url);
        this.apiClientUploadLink(url, cb);
    };

    //TODO hideVideoBox
    this.hideVideoBox= function(cb){
        if(cb)cb();
    };

    //TODO postPartecipate
    this.postPartecipate= function(cb){

        if(cb)cb();
    };

    this.Webprod_videoSaved_video = function(){
        this.facevideoUpload(this.afterfacevideoUpload);
    };

    this.afterfacevideoUpload = function(res){
        this.log('upload face video');
        this.log(res);
        $(window.vrt).trigger('vrt_event_facevideo_upload',res.responseId);
    };

    this.setupPlayer = function(){
        this.log('setupPlayer / guideButtonVideo');

        if(this.videoType=='youtube'){
            this.player = window.ytInterface;
        }else{
            //videojs.options.flash.swf = "videovideo-js.swf";
            videojs.options.techOrder = ["flash","html5"];
            this.player = window.vjsInterface;
        }

        var preloadfunc = this.player.preloadPlayer();

        this.dopreload(preloadfunc);
    }

    this.afterpreload = function (success) {

        // TODO preload managed properly

        //if (success) {
            if(this.currentMedia == -1)
                this.nextStep();
        //}
    };

    this.dopreload = function (preloadfunc) {
        if (preloadfunc) {
            preloadfunc(this.afterpreload);
        } else {
            this.afterpreload(true);
        }
    };

    this.stepComplete = function(res){
        //vrt.logChrono(3, false, 'API UPLOD FILES');
        $(window.vrt).trigger('vrt_event_video_step_completed',[{responseId: res.responseId}]);
    };


    this.nextStep = function(){
        this.log('nextStep');
        this.log('>>STEP nextStep ' + this.currentMedia);
        if (this.currentMedia++ < this.mediaCount-1) {
            this.logChronoReset();
            this.log(this.currentMedia,'currentMedia');
            this.log('nextStep=' + this.currentMedia);

            if (this.currentMedia >= 0) {
                // TODO trigger event: media info
            }

            this.media_id = this.clearname(this.videoList[this.currentMedia].name); //was media_info[current_media].id
            this.media_length = this.videoList[this.currentMedia].length;
            if(this.videoType=='youtube'){
                this.media_path = this.youtubeParser(this.videoList[this.currentMedia].path);
            }else{
                this.media_path = this.videoList[this.currentMedia].path;
            }
            this.log('>>STEP  YT path ' + this.media_path);

            this.proceedToShow();
            //$(vrt).trigger('vrt_event_video_session_complete');
        } else {
            $(window.vrt).trigger('vrt_event_video_session_complete');
        }
    };

    this.clearname = function(s){
        if(s)
            return s.toString().replace(/[^a-z0-9]/gi, '_').toLowerCase();
        else return s;
    };

    this.closeSession = function() {
        if (this.fullscreen_needed) this.videoEndFullscreen();
        this.playerDispose();

        this.log('close_session');

        // TODO finish session alert
    };

    // TODO videoEndFullscreen
    this.videoEndFullscreen = function(){

    };

    this.playerDispose = function(){
        if(this.player){
            this.player.player_dispose();
        }
    };

    this.proceedToShow = function () {
        this.log('proceedToShow');
        this.player.loadPlayer(this.options.player);
    };

    this.player_is_ready = function(){

        // TODO fullscreen

        /*
         if (fullscreen_needed && !_player_is_fullscreen) {

         openDialog(__t.p_show_22, function () {
         video_go_fullscreen();
         player_is_ready_after();
         }, $.browser.msie || !checkSafariMinVer('Win', 6) ? 'bottom' : false);

         } else { */
        this.player_is_ready_after();
        //}
    };

    this.player_is_ready_after = function(){

        this.log('>>STEP player is ready aft');
        this.log('player_is_ready_after');

        // set inside the method onytplayerStateChange
        //OLD
        //this.is_player_ready = true;
        //this.startRecording();
        this.player.video_play();

    };

    this.startRecording = function() {
        this.log('startRecording');
        //if (!this.isRecording) {
            this.log('Producer recording starting');
            this.producerConnection();
            this.isRecording = true;
        //}
    };

    this.producerSetupConnection = function(cb) {

        this.log(streamUrl);
        this.log('!! filename ' + this.producerStreamName);
        var url = 'rtmp://' + this.producerStreamUrl + ':1935/live'; // "live/" is the RTMP application name, always the same.
        this.log('!! url ' + url);

        this.producer.setUrl(url);
        this.producer.setStreamWidth(this.producerStreamWidth);
        this.producer.setStreamHeight(this.producerStreamHeight);

        $(vrt).trigger('vrt_event_connection_setup');

        if(cb)cb();
    };

    this.producerConnection = function() {
        vrt.log('>>STEP producer connection')
        vrt.producer.connect();
        $(vrt).trigger('vrt_event_connect_start');
    };

    this.hideVideobox = function(cb){
        this.log('hideVideoBox');
        var id = 'videoDiv'; //id || 'videoDiv';
        $('#'+id).css('z-index','-1000');
        $('.ui-dialog').css('z-index','-1000');
        $('#vjsPlayer').hide();
        if(cb)cb();
    };

    this.loadProducer = function(){
        this.log('loadProducer');
        this.log('>>STEP producer init')

        //$('#'+this.producerID).css('display', 'inline-block');
        //$('#'+this.producerID).addClass('rotating-loader');

        this.webProducerInit();
    };

    // TODO popOverCe
    this.popOverCe = function(type){};

    // LOG FUNCTIONS
    this.log = function (msg , display ,mode) {

        if(!this.debug) return'';
        var str = msg.toString().substring(0,2);

        if(!this.debugEvt && str=='EV') return'';
        if(!this.debugTime && str=='TM') return'';
        if(!this.debugImportant && str=='>>') return'';
        if(!this.debugVImportant && str=='!!') return'';

        if(str=='>>' || str=='EV' || str=='TM' || str=='!!') {
            if(str == 'TM') this.logTime(msg);
            if (console && console.log) console.log(msg);
            if (display != undefined && this.debug == true) {
                if (msg instanceof Object) {
                    $('#vrtVal_' + display + ' span').html(JSON.stringify(msg));
                } else {
                    if (mode && mode == 'a')
                        $('#vrtVal_' + display + ' span').append('<br/>' + JSON.stringify(msg));
                    else
                        $('#vrtVal_' + display + ' span').html(msg.toString());
                }
            }
        }
    };

    this.logTime = function(msg){

        if(!msg) msg='';
        var date = new Date();
        var datevalues = [
            date.getFullYear()
            ,date.getMonth()+1
            ,date.getDate()
            ,date.getHours()
            ,date.getMinutes()
            ,date.getSeconds()
            ,date.getMilliseconds()
            ,date.getTime()
        ];
        if(!this.debugTime){}
        else {
            if (console && console.log && msg!='') console.log('TIME '+ msg +': '+datevalues[4]+' '+datevalues[5]+' '+datevalues[6]);
        }
        return datevalues;
    };

    this.chronoStart = [];
    this.chronoEnd = [];
    this.chronoMessagge = [];
    this.chronoALertStart = false;
    this.chronoALertEnd = false;
    this.chronoType = ['recording','playing','producer_saving','api_upload','','publish'];

    this.logChronoReset = function(){
        this.chronoStart = [];
        this.chronoEnd = [];
        this.chronoMessagge = [];
        this.chronoALertStart = false;
        this.chronoALertEnd = false;
    };

    this.logChrono = function (pos, start, msg){

        if(msg == undefined) msg = vrt.chronoType[pos];

        var echo = false;
        (this.debugChrono==undefined)? '': echo = this.debugChrono  ;

        var startm='end';
        (start==true)? startm = 'start':'';
        var timeCheck = vrt.logTime();

        if(start){
            vrt.chronoMessagge[pos] = msg;
            vrt.chronoStart[pos] = timeCheck;
            if (echo && console && console.log) console.log('CHRONO '+pos+': ' +startm+ ' ' + msg +': '+vrt.chronoStart[pos][4]+' '+vrt.chronoStart[pos][5]+' '+vrt.chronoStart[pos][6]);
        }else{
            vrt.chronoEnd[pos] = timeCheck;
            if (echo && console && console.log) console.log('CHRONO '+pos+': '+startm+ ' ' + msg +': '+vrt.chronoEnd[pos][4]+' '+vrt.chronoEnd[pos][5]+' '+vrt.chronoEnd[pos][6]);
            if (echo && console && console.log) console.log('CHRONO '+pos+': '+ msg +' RESULTS: '
                + vrt.get_time_diff(vrt.chronoStart[pos][7], vrt.chronoEnd[pos][7])
            );
        };

        $(vrt).trigger('vrt_eventList', [{event: this.chronoType[pos], position:startm, time: timeCheck[7], timeFull: timeCheck}]);


        if(vrt.chronoStart[0] && vrt.chronoStart[1] && vrt.chronoALertStart==false){
            vrt.chronoALertStart=true;
            var after = vrt.chronoStart[0], before = vrt.chronoStart[1];
            var start_first = 'player';
            if(after[7]<before[7]){
                before = vrt.chronoStart[0];
                after = vrt.chronoStart[1];
                start_first = 'recorder';
            }
            var difft = after[7]-before[7];
            if (echo && console && console.log) console.log('CHRONO DIFF START '+ start_first +' start first by '+ (difft));
            this.eventList.startFirst = start_first;
            this.eventList.startFirstDiff = difft;
            $(vrt).trigger('vrt_eventList_startFirst', [{startFirst: start_first, timeDiff: difft}]);
        }

        if(vrt.chronoEnd[0] && vrt.chronoEnd[1] && vrt.chronoALertEnd==false && vrt.chronoEnd[0][7] && vrt.chronoEnd[1][7]){
            vrt.chronoALertEnd=true;
            var after = vrt.chronoEnd[0], before = vrt.chronoEnd[1];
            var end_first = 'player';
            if(after[7]<before[7]){
                before = vrt.chronoEnd[0];
                after = vrt.chronoEnd[1];
                end_first = 'recorder';
            }
            var difft = after[7]-before[7];
            if (echo && console && console.log) console.log('CHRONO DIFF END '+ end_first +' end first by '+ (difft));<commit_msg>Webcam recording synchronises with video playback #78828342<commit_after>

function Vrt(type, list, streamUrl, streamName, apiDomain, apiUser, apiPassword,  options) {


    //User settings
    this.videoList = null;
    this.videoFullscreen = false;
    this.videoType = null; //youtube or customserver
    this.canSkip = false;
    this.debug = false;
    this.debugEvt = false;
    this.debugTime = false;
    this.debugChrono = false;
    this.debugVImportant = false;
    this.options = {};

    //Producer
    this.playerVersion = null;
    this.producer = null;
    this.producerID = null;
    this.producerID = null;
    this.producerWidth = null;
    this.producerHeight = null;
    this.swfobject = false;
    this.vrt = false;
    this.vrtID = false;
    this.producerStreamUrl = null;
    this.producerStreamName = null;
    this.producerStreamWidth = 640;
    this.producerStreamHeight = 480;
    this.stream_code = null;
    this.recAutoHide =true;
    this.recorderCenter =true;
    this.randomOrder = false;

    //Various
    this.flash_allowed = false;
    this.ww = 0;            //windows width
    this.wh = 0;            //windows height
    this.media_id = null;   //media played
    this.media_length = 0;  //media played
    this.media_path = null; //media played
    this.exitcode = null;
    this.mainStyle =  '';

    //steps && user actions
    this.click_start = false;
    this.isRecording = false;
    this.isPlaying = false;
    this.currentMedia = -1;
    this.mediaCount = 0;
    this.streamName = '';
    this.stop_handle;
    this.stop_handle_rec;

    //player values
    this.vjs = false;
    this.player = null;
    this.is_player_ready = false;
    this.player_starts_recorder = false;
    this.avgPreLoadTime = 0;

    //api client values
    this.ceclient;
    this.apiUsername, this.apiPassword, this.apiDomain;
    this.eventList = {};


    this.initialized = function(type, list, streamUrl, streamName, apiDomain, apiUser, apiPassword,  options){

        if(options == undefined || options == null) options = {player : {}};

        if(options && options.fullscreen) {this.videoFullscreen = options.fullscreen && this.checkSafariMinVer(false,6)} else {  this.videoFullscreen = false };
        (options && options.skip !=undefined)? this.canSkip = options.skip : this.canSkip = false;
        (options && options.vrtID)? this.vrtID = options.vrtID : this.vrtID = 'vrt';
        (options && options.producerID)? this.producerID = options.producerID : this.producerID = 'producer';
        (options && options.producerWidth)? this.producerWidth = options.producerWidth : this.producerWidth = 320;
        (options && options.producerHeight)? this.producerHeight = options.producerHeight : this.producerHeight = 240;
        (options && options.debug !=undefined)? this.debug = options.debug : this.debug = false;
        (options && options.debugEvt !=undefined)? this.debugEvt = options.debugEvt : this.debugEvt = false;
        (options && options.debugTime !=undefined)? this.debugTime = options.debugTime : this.debugTime = false;
        (options && options.debugChrono !=undefined)? this.debugChrono = options.debugChrono : this.debugChrono = false;
        (options && options.debugChronoHtml !=undefined)? this.debugChronoHtml = options.debugChronoHtml : this.debugChrono = false;
        (options && options.debugImportant !=undefined)? this.debugImportant = options.debugImportant : this.debugImportant = false;
        (options && options.debugVImportant !=undefined)? this.debugVImportant = options.debugVImportant : this.debugVImportant = false;
        (options && options.producerStreamWidth)? this.producerStreamWidth = options.producerStreamWidth : this.producerStreamWidth = 640;
        (options && options.producerStreamHeight)? this.producerStreamHeight = options.producerStreamHeight : this.producerStreamHeight = 480;
        (options && options.avgPreLoadTime)? this.avgPreLoadTime = options.avgPreLoadTime : this.avgPreLoadTime = 0;
        (options && options.recorderCenter!=undefined)? this.recorderCenter = options.recAutoHide : this.recorderCenter = true;
        (options && options.randomOrder!=undefined)? this.randomOrder = options.randomOrder : this.randomOrder = false;

        this.options = options;
        if(options.player == undefined || options.player == null) options.player = {};

        (options && options.playerCentered!=undefined)? this.options.player.centered = options.playerCentered : this.options.player.centered = true;
        (options && options.playerWidth!=undefined)? this.options.player.width = options.playerWidth : this.options.player.Width = 640;
        (options && options.playerHeight!=undefined)? this.options.player.height = options.playerHeight : this.options.player.height = 400;



        this.mediaCount = list.length;
        this.videoType  = type;
        this.videoList  = list;
        this.producerStreamUrl = streamUrl;
        this.producerStreamName = this.clearname(streamName);
        this.calculateListData();
        this.randomizeOrderList();
        this.log(type,'type');
        this.log(list,'list');
        this.apiDomain = apiDomain;
        this.apiUsername = apiUser;
        this.apiPassword = <PASSWORD>;
    }


    this.init = function (type, list, streamUrl, streamName, apiDomain, apiUser, apiPassword,  options) {
        this.log('>>STEP: vrt init');
        this.log(arguments);

        window.vrt = this;

        this.log(this.mediaCount,'mediaCount');
        this.log(this.currentMedia,'currentMedia');
        this.log(this.producerStreamUrl,'producerStreamUrl');
        this.log(this.producerStreamName,'producerStreamName');

        this.injectLayout();
        this.initVar();
        this.vrtOn();


        //todo insert resizingWindovs

        this.playerVersion = swfobject.getFlashPlayerVersion();

        this.log("playerVersion");
        this.log(this.playerVersion.major);
        this.log(this.playerVersion.minor);

        this.log('EVT flash'+this.playerVersion.major);
        // TODO move Flash version check on the first page
        if (this.playerVersion.major == 0) {
            $(window.vrt).trigger('vrt_event_flash_no');
            this.log('EVT no flash');
        }

        if (swfobject.getFlashPlayerVersion("11.1.0")) {
            this.loadProducer();
        } else {
            $(window.vrt).trigger('vrt_event_flash_old');
            this.log('Flash is old=' + this.playerVersion.major + '.' + this.playerVersion.minor);
        }


        this.ceclient =  new CEClient();


        this.apiClientSetup(
            function(){
                $(window.vrt).trigger('api_init_ok');
                if(console.log)console.log('apiClientSetup api login success')
            },
            function(){
                $(window.vrt).trigger('vrt_event_api_login_fail');
                if(console.log)console.log('apiClientSetup api login error')
            }
        );

        $(this).trigger('vrt_init_ok');
    };

    this.initVar = function(){
    };

    this.injectLayout = function(){
        var pre = this.vrtID;
        var certerstyle ="";//   "    position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);";
        (this.options && this.options.mainStyle)? '' : this.options.mainStyle = certerstyle;
        (this.options && this.options.recStyle)? '' : this.options.recStyle = certerstyle;
        (this.options && this.options.videoStyle)? '' : this.options.videoStyle = certerstyle;


        var html=" <div id='vrtWrapper' class='vrtWrap' style='"+this.options.mainStyle+"'> " +
                ((this.options.htmlRecorderPre)? this.options.htmlRecorderPre : '') +
                "       <div id='vrtProducer' class='vrtWrap "+this.options.htmlRecorderClass+"' style='"+this.options.recStyle+"'>                      "+
                "           <div id='producer'></div>                                                                   "+
                "           <div class='clearfix'></div>                                                                "+
                "       </div>                                                                                          "+
                ((this.options.htmlRecorderPost)? this.options.htmlRecorderPost : '') +
                ((this.options.htmlVideoPre)? this.options.htmlVideoPre : '') +
                "<div id='vrtVideoWrapper' class='vrtWrap' style='"+this.options.videoStyle+"'>                                                      "+
                "      <div id='vrtvideo' class='"+this.options.htmlVideoClass+"'></div>                                "+
                "      <div id='videoDiv' class='"+this.options.htmlVideoClass+"'></div>                                "+
                "      <div id='ytPlayer' class='"+this.options.htmlVideoClass+"'></div>                                "+
                "      <div class='clearfix'></div>                                                                     "+
                "</div>                                                                                               "+
                ((this.options.htmlVideoPost)? this.options.htmlVideoPost : '') +
                "<div id='vrtLogWrapper' class='vrtWrap'>                                                      "+
                "      <div id='vrtalert'></div>                                                                        "+
                "      <div id='vrt_timer_player'></div>                                                                       " +
                "      <div id='vrt_timer_recorder'></div>                                                                       " +
                "      <div class='clearfix'></div>                                                                     "+
                "</div>                                                                                               "+
                "</div>";

        var debugHtml="<div id='vrtValues' class='vrtWrap'>                                                             "+
                "          <h4>Info</h4>                                                                                "+
                "          <div id='vrtVal_type'>Type: <span></span></div>                                              "+
                "          <div id='vrtVal_mediaCount'>media count: <span></span></div>                                 "+
                "          <div id='vrtVal_currentMedia'>current media: <span></span></div>                             "+
                "          <div id='vrtVal_list'>List: <span></span></div>                                              "+
                "          <div id='vrtVal_producerStreamUrl'>Producer stream URL: <span></span></div>                  "+
                "          <div id='vrtVal_producerStreamName'>Producer stream name: <span></span></div>                "+
                "          <div id='vrtVal_producerConnStatus'>Producer conn status: <span>Not connected</span></div>   "+
                "          <div id='vrtVal_apiStatus'>API status: <span>Not connected</span></div>                      "+
                "          <div id='vrtVal_fileUpload'>Files: <span>Not connected</span></div>                          "+
                "      </div>                                                                                           "+
                "      <div id='vrtLog'></div>                                                                          "

        $("#"+pre).html(html);

    };

    /**
     * The function set recorder to visibility hidden, if not a altFunction is specified.
     * In some browser, if you use display: none, the swf object will be destroyed
     * @param altFunction
     * @param callback
     */
    this.recorderHide = function(altFunction,callback){
        if(!altFunction){
            $('#vrtProducer').css('visibility','hidden');
            $('#producer').css('visibility','hidden');
            $('#vrtProducer').css('z-index',-1000);
            $('#producer').css('z-index',-1000);
            $('#vrtProducer').css('height','1px');
            $('#producer').css('width','1px');
        }else{
            altFunction();
        }
        if(callback)callback();
    };

    this.recorderShow = function(altFunction,callback ){
        if(!altFunction){
            $('#vrtProducer').css('visibility','visible');
            $('#producer').css('visibility','visible');
            $('#vrtProducer').css('z-index',1000);
            $('#producer').css('z-index',1000);
            $('#vrtProducer').css('height','320px');
            $('#producer').css('width','240px');
        }else{
            altFunction();
        }
        if(callback)callback();
    };

    this.trigger = function( type, data){
        $(vrt).trigger( type, data);
    };

    this.vrtOnStartSequence = 0;
    this.vrtOn = function(){

        //internal event: start
        $(window.vrt).on('vrt_init_ok', function() {
            window.vrt.vrtTrigLoadend('vrt_init_ok');
        });
        $(window.vrt).on('producer_init_ok', function() {
            vrt.producerSetupConnection( vrt.producerConnection );
            window.vrt.vrtTrigLoadend('producer_init_ok');
        });
        $(window.vrt).on('api_init_ok', function() {
            window.vrt.vrtTrigLoadend('api_init_ok');
        });


        $(window.vrt).on('vrtstep_loaded', function() {
            vrt.log('EVT vrtstep_loaded');
            vrt.log('>>EVT vrtstep_loaded');
            vrt.player.video_play(vrt.showVisibility('#videoDiv'));
            //TODO open_video_window();  // HACK else the Flash player is not instantiated
        });
        $(window.vrt).on('vrtstep_playerStateChange', function(e, data) {
            vrt.log('EVT vrtstep_playerStateChange '+data.state+' time '+data.time[4]+' '+data.time[5]+' '+data.time[6]);
        });

        $(window.vrt).on('vrtstep_loadplay', function() {
            vrt.log('EVT vrtstep_loadplay');

        });
        $(window.vrt).on('vrtstep_play', function(e, data) {
            vrt.log('EVT vrtstep_play caller '+data.caller);
            if(vrt.isPlaying==false){
                streamName = this.videoList[this.currentMedia].streamCode;

                vrt.producer.publish(streamName);
                vrt.isPlaying=true;
                vrt.logChrono(1, true, 'player');
                vrt.setup_stop_playing();
            }

        });

        $(window.vrt).on('vrtstep_connect', function() {
            vrt.log('EVT vrtstep_connect ' + vrt.logTime());

        });

        $(window.vrt).on('vrt_event_publish', function() {
            vrt.log('EVT vrt_event_publish  ' + vrt.logTime());
        });

        $(window.vrt).on('vrtstep_disconnect', function() {
                vrt.log('EVT vrtstep_disconnect');
        });

        //external event
        $(window.vrt).on('vrt_event_start_video_session', function() {
            if(window.vrt.recAutoHide==false){
                window.vrt.setupPlayer()
            }else{
                window.vrt.recorderHide(null,window.vrt.setupPlayer());
            }
        });

        $(window.vrt).on('vrt_event_user_next_video', function() {
            window.vrt.nextStep()
        });

        $(window.vrt).on('vrt_event_user_session_complete', function() {
            window.vrt.closeSession();
        });

        $(window.vrt).on('vrt_event_frame_open', function(e, data) {
            vrt.log('EVT vrt_event_frame_open');
            vrt.createFrame(data);
        });

        $('#vrtWrapper').on('click','#vrtFrameClose', function(){
           vrt.closeFrame();
        });

    };

    this.openFrame = function(src, options){

        $(vrt).trigger('vrt_event_frame_open', [{src : src, html: options.html, width: options.width, height: options.height, showBtnClose: options.showBtnClose,
                                        btnCssClass: options.btnCssClass, btnStyle: options.btnStyle, btnText:options.btnText, btnPosition: options.btnPosition}]);
    };

    this.closeFrame = function(){
        $('#vrtFrame').hide();
        $(window.vrt).trigger('vrt_event_frame_close');
    };

    this.vrtTrigLoadend = function(evtname){
        window.vrt.vrtOnStartSequence++;
        vrt.log('EVT vrtOnStartSequence '+evtname+' '+ window.vrt.vrtOnStartSequence);
        if(window.vrt.vrtOnStartSequence>=3){
            $(window.vrt).trigger('vrt_event_preview_loaded');
        }
    };

    this.playerConnectionLatency = function(){
        return 0;
        if(vrt.videoType=='youtube'){
            return 0;
        }else{
            return 0;
        }
    }

    this.createHashCode = function (s){
        var hash = 0;
        s = s.toString();
        if (s.length == 0) return s;
        for (i = 0; i < s.length; i++) {
            var char = s.charCodeAt(i);
            hash = ((hash<<5)-hash)+char;
            hash = hash & hash; // Convert to 32bit integer
        }
        return hash;
    };

    this.calculateListData = function (){

        for(var i = 0; i<this.mediaCount; i++){
            var d = new Date();
            var n = d.getTime();
            var pre = '';
            if(this.producerStreamName){
                var l = 4;
                if(this.producerStreamName.length<4) l = this.producerStreamName.length;
                pre = this.producerStreamName.substring(0,l);
            }
            this.videoList[i].streamCode = pre +'_'+ i +'_' + this.clearname(this.createHashCode(n));
            this.videoList[i].order = i;
        }
    };

    this.randomizeOrderList = function(){
        if(this.randomOrder===true && this.mediaCount>1){
            this.videoList =  this.shuffle(this.videoList);
        }
    }

    this.shuffle = function(o){ //v1.0
        for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
        return o;
    };

    //mediaInfo, instance of this.videoList
    this.buildVideoSources = function(mediaInfo) {
        if(this.videoType == 'customserver') {

            this.sources = [
                { type: "video/mp4", src: mediaInfo.path }
            ];

        } else {
            this.sources = [
                { type: "video/youtube", src: mediaInfo.path_original }
            ];
        }
    };

    this.startButton = function(){
        $("#vrtGuidingButton").click( this, function (vrtObj) {

            vrt.click_start = true;
            vrt.hideAllAndStartPlayer();
            vrt.trigger('vrt_start_ok');

        });
    };

    this.canStartButton = function(){
        this.log('canStartButton');
        $('body').on('click','#vrtCanStartButton',  this.setupCanStartButton);
    };

    this.setupCanStartButton = function () {
        vrt.log('canStartButton click');
        vrt.click_start = true;
        $('#vrtGuidingButton').show();
        vrt.popOverCe('pop_start');
    };


    this.hideAllAndStartPlayer = function(){
        this.hideVisibility('#vrtProducer');
        this.hideVisibility('#vrtCanStartButtonWrapper');
        this.hideVisibility('#vrtGuidingButton');

        this.producer.height=1;
        this.producer.width=1;
    };

    this.hideVisibility = function(el){
        $(el).css('visibility','hidden');
        $(el).css('z-index',-1000);
    };
    this.showVisibility = function(el){
        $(el).css('visibility','visible');
        $(el).css('z-index',0);
    };

    //TODO skipVideo
    this.skipVideo = function(){

    };

    this.facevideoUpload = function(url,cb){
        this.log(url,'fileUpload','a');
        this.log('!! '+url);
        this.apiClientUploadLink(url, cb);
    };

    //TODO hideVideoBox
    this.hideVideoBox= function(cb){
        if(cb)cb();
    };

    //TODO postPartecipate
    this.postPartecipate= function(cb){

        if(cb)cb();
    };

    this.Webprod_videoSaved_video = function(){
        this.facevideoUpload(this.afterfacevideoUpload);
    };

    this.afterfacevideoUpload = function(res){
        this.log('upload face video');
        this.log(res);
        $(window.vrt).trigger('vrt_event_facevideo_upload',res.responseId);
    };

    this.setupPlayer = function(){
        this.log('setupPlayer / guideButtonVideo');

        if(this.videoType=='youtube'){
            this.player = window.ytInterface;
        }else{
            //videojs.options.flash.swf = "videovideo-js.swf";
            videojs.options.techOrder = ["flash","html5"];
            this.player = window.vjsInterface;
        }

        var preloadfunc = this.player.preloadPlayer();

        this.dopreload(preloadfunc);
    }

    this.afterpreload = function (success) {

        // TODO preload managed properly

        //if (success) {
            if(this.currentMedia == -1)
                this.nextStep();
        //}
    };

    this.dopreload = function (preloadfunc) {
        if (preloadfunc) {
            preloadfunc(this.afterpreload);
        } else {
            this.afterpreload(true);
        }
    };

    this.stepComplete = function(res){
        //vrt.logChrono(3, false, 'API UPLOD FILES');
        $(window.vrt).trigger('vrt_event_video_step_completed',[{responseId: res.responseId}]);
    };


    this.nextStep = function(){
        this.log('nextStep');
        this.log('>>STEP nextStep ' + this.currentMedia);
        if (this.currentMedia++ < this.mediaCount-1) {
            this.logChronoReset();
            this.log(this.currentMedia,'currentMedia');
            this.log('nextStep=' + this.currentMedia);

            if (this.currentMedia >= 0) {
                // TODO trigger event: media info
            }

            this.media_id = this.clearname(this.videoList[this.currentMedia].name); //was media_info[current_media].id
            this.media_length = this.videoList[this.currentMedia].length;
            if(this.videoType=='youtube'){
                this.media_path = this.youtubeParser(this.videoList[this.currentMedia].path);
            }else{
                this.media_path = this.videoList[this.currentMedia].path;
            }
            this.log('>>STEP  YT path ' + this.media_path);

            this.proceedToShow();
            //$(vrt).trigger('vrt_event_video_session_complete');
        } else {
            $(window.vrt).trigger('vrt_event_video_session_complete');
        }
    };

    this.clearname = function(s){
        if(s)
            return s.toString().replace(/[^a-z0-9]/gi, '_').toLowerCase();
        else return s;
    };

    this.closeSession = function() {
        if (this.fullscreen_needed) this.videoEndFullscreen();
        this.playerDispose();

        this.log('close_session');

        // TODO finish session alert
    };

    // TODO videoEndFullscreen
    this.videoEndFullscreen = function(){

    };

    this.playerDispose = function(){
        if(this.player){
            this.player.player_dispose();
        }
    };

    this.proceedToShow = function () {
        this.log('proceedToShow');
        this.player.loadPlayer(this.options.player);
    };

    this.player_is_ready = function(){

        // TODO fullscreen

        /*
         if (fullscreen_needed && !_player_is_fullscreen) {

         openDialog(__t.p_show_22, function () {
         video_go_fullscreen();
         player_is_ready_after();
         }, $.browser.msie || !checkSafariMinVer('Win', 6) ? 'bottom' : false);

         } else { */
        this.player_is_ready_after();
        //}
    };

    this.player_is_ready_after = function(){

        this.log('>>STEP player is ready aft');
        this.log('player_is_ready_after');

        // set inside the method onytplayerStateChange
        //OLD
        //this.is_player_ready = true;
        //this.startRecording();
        this.player.video_play();

    };

    this.startRecording = function() {
        this.log('startRecording');
        //if (!this.isRecording) {
            this.log('Producer recording starting');
            this.producerConnection();
            this.isRecording = true;
        //}
    };

    this.producerSetupConnection = function(cb) {

        this.log(streamUrl);
        this.log('!! filename ' + this.producerStreamName);
        var url = 'rtmp://' + this.producerStreamUrl + ':1935/live'; // "live/" is the RTMP application name, always the same.
        this.log('!! url ' + url);

        this.producer.setUrl(url);
        this.producer.setStreamWidth(this.producerStreamWidth);
        this.producer.setStreamHeight(this.producerStreamHeight);

        $(vrt).trigger('vrt_event_connection_setup');

        if(cb)cb();
    };

    this.producerConnection = function() {
        vrt.log('>>STEP producer connection')
        vrt.producer.connect();
        $(vrt).trigger('vrt_event_connect_start');
    };

    this.hideVideobox = function(cb){
        this.log('hideVideoBox');
        var id = 'videoDiv'; //id || 'videoDiv';
        $('#'+id).css('z-index','-1000');
        $('.ui-dialog').css('z-index','-1000');
        $('#vjsPlayer').hide();
        if(cb)cb();
    };

    this.loadProducer = function(){
        this.log('loadProducer');
        this.log('>>STEP producer init')

        //$('#'+this.producerID).css('display', 'inline-block');
        //$('#'+this.producerID).addClass('rotating-loader');

        this.webProducerInit();
    };

    // TODO popOverCe
    this.popOverCe = function(type){};

    // LOG FUNCTIONS
    this.log = function (msg , display ,mode) {

        if(!this.debug) return'';
        var str = msg.toString().substring(0,2);

        if(!this.debugEvt && str=='EV') return'';
        if(!this.debugTime && str=='TM') return'';
        if(!this.debugImportant && str=='>>') return'';
        if(!this.debugVImportant && str=='!!') return'';

        if(str=='>>' || str=='EV' || str=='TM' || str=='!!') {
            if(str == 'TM') this.logTime(msg);
            if (console && console.log) console.log(msg);
            if (display != undefined && this.debug == true) {
                if (msg instanceof Object) {
                    $('#vrtVal_' + display + ' span').html(JSON.stringify(msg));
                } else {
                    if (mode && mode == 'a')
                        $('#vrtVal_' + display + ' span').append('<br/>' + JSON.stringify(msg));
                    else
                        $('#vrtVal_' + display + ' span').html(msg.toString());
                }
            }
        }
    };

    this.logTime = function(msg){

        if(!msg) msg='';
        var date = new Date();
        var datevalues = [
            date.getFullYear()
            ,date.getMonth()+1
            ,date.getDate()
            ,date.getHours()
            ,date.getMinutes()
            ,date.getSeconds()
            ,date.getMilliseconds()
            ,date.getTime()
        ];
        if(!this.debugTime){}
        else {
            if (console && console.log && msg!='') console.log('TIME '+ msg +': '+datevalues[4]+' '+datevalues[5]+' '+datevalues[6]);
        }
        return datevalues;
    };

    this.chronoStart = [];
    this.chronoEnd = [];
    this.chronoMessagge = [];
    this.chronoALertStart = false;
    this.chronoALertEnd = false;
    this.chronoType = ['recording','playing','producer_saving','api_upload','','publish'];

    this.logChronoReset = function(){
        this.chronoStart = [];
        this.chronoEnd = [];
        this.chronoMessagge = [];
        this.chronoALertStart = false;
        this.chronoALertEnd = false;
    };

    this.logChrono = function (pos, start, msg){

        if(msg == undefined) msg = vrt.chronoType[pos];


        var echo = false ; var echoHtml = false; var str = ''; var strend = '';
        (this.debugChrono==undefined)? '': echo = this.debugChrono  ;
        (this.debugChronoHtml==undefined)? '': echoHtml = this.debugChronoHtml  ;

        var startm='end';
        (start==true)? startm = 'start':'';
        var timeCheck = vrt.logTime();

        if(start){
            vrt.chronoMessagge[pos] = msg;
            vrt.chronoStart[pos] = timeCheck;
            str = 'CHRONO '+pos+': ' +startm+ ' ' + msg +': '+vrt.chronoStart[pos][4]+' '+vrt.chronoStart[pos][5]+' '+vrt.chronoStart[pos][6];
            if (echo && console && console.log) str;

        }else{
            vrt.chronoEnd[pos] = timeCheck;
            str = 'CHRONO '+pos+': '+startm+ ' ' + msg +': '+vrt.chronoEnd[pos][4]+' '+vrt.chronoEnd[pos][5]+' '+vrt.chronoEnd[pos][6];
            strend += 'CHRONO '+pos+': '+ msg +' RESULTS: ' + vrt.get_time_diff(vrt.chronoStart[pos][7], vrt.chronoEnd[pos][7])
            if (echo && console && console.log) console.log(str);
            if (echo && console && console.log) console.log(strend);
        };

        if(echoHtml && pos==1) $('#vrt_timer_player').append('<br/>'+str +'<br/>'+ strend);
        if(echoHtml && pos==0) $('#vrt_timer_recorder').append('<br/>'+str +'<br/>'+ strend);
        str = ''; strend = '';

        $(vrt).trigger('vrt_eventList', [{event: this.chronoType[pos], position:startm, time: timeCheck[7], timeFull: timeCheck}]);


        if(vrt.chronoStart[0] && vrt.chronoStart[1] && vrt.chronoALertStart==false){
            vrt.chronoALertStart=true;
            var after = vrt.chronoStart[0], before = vrt.chronoStart[1];
            var start_first = 'player';
            if(after[7]<before[7]){
                before = vrt.chronoStart[0];
                after = vrt.chronoStart[1];
                start_first = 'recorder';
            }
            var difft = after[7]-before[7];
            if (echo && console && console.log) console.log('CHRONO DIFF START '+ start_first +' start first by '+ (difft));

            this.eventList.startFirst = start_first;
            this.eventList.startFirstDiff = difft;
            $(vrt).trigger('vrt_eventList_startFirst', [{startFirst: start_first, timeDiff: difft}]);
        }

        if(vrt.chronoEnd[0] && vrt.chronoEnd[1] && vrt.chronoALertEnd==false && vrt.chronoEnd[0][7] && vrt.chronoEnd[1][7]){
            vrt.chronoALertEnd=true;
            var after = vrt.chronoEnd[0], before = vrt.chronoEnd[1];
            var end_first = 'player';
            if(after[7]<before[7]){
                before = vrt.chronoEnd[0];
                after = vrt.chronoEnd[1];
                end_first = 'recorder';
            }
            var difft = after[7]-before[7];
            if (echo && console && console.log) console.log('CHRONO DIFF END '+ end_first +' end first by '+ (difft));
{'fraction_non_alphanumeric': 0.1487116928504311, 'fraction_numerical': 0.0055060088030200625, 'mean_word_length': 1.898189288614973, 'pattern_counts': {'":': 0, '<': 167, '<?xml version=': 0, '>': 193, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 100, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6435165', 'n_tokens_mistral': 18061, 'n_tokens_neox': 17336, 'n_words': 2804}