From 8cdb6595887a39df93f7bc143a3b6167fe275bab Mon Sep 17 00:00:00 2001
From: Sebastien Curt <sebastien.curt@tetras-libre.fr>
Date: Mon, 2 May 2022 17:24:51 +0200
Subject: [PATCH] Fix bug on image thumbnail

---
 capsule-prototype/js/online-rekall/Project.js | 889 ++++++++----------
 capsule-prototype/js/online-rekall/Rekall.js  | 327 ++++---
 capsule-prototype/js/online-rekall/Tags.js    |  38 +-
 capsule-prototype/js/rekall/Sorting.js        |   4 +-
 4 files changed, 647 insertions(+), 611 deletions(-)

diff --git a/capsule-prototype/js/online-rekall/Project.js b/capsule-prototype/js/online-rekall/Project.js
index c741f51..8f655f6 100644
--- a/capsule-prototype/js/online-rekall/Project.js
+++ b/capsule-prototype/js/online-rekall/Project.js
@@ -22,503 +22,414 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-function Project(url) {
-	this.sources = new Object();
-	this.url = url;
-	this.firstAnalysis = true;
-	this.metadata = {      
-		"Title":    "",
-		"Author":   "",
-		"Email":    "",
-		"Date": 	"",
-		"Comments": "",
-	};
-	var urlItems = rekall.baseUrl.split("/");
-	urlItems = $.grep(urlItems,function(n){ return(n) });
-	this.metadata["Title"] = urlItems[urlItems.length-1];
-
+function Project(url, rekall) {
+    this.sources = {};
+    this.url = url;
+    this.firstAnalysis = true;
+    this.metadata = {
+        "Title": "",
+        "Author": "",
+        "Email": "",
+        "Date": "",
+        "Comments": "",
+    };
+    var urlItems = rekall.baseUrl.split("/");
+    urlItems = $.grep(urlItems, function (n) {
+        return (n)
+    });
+    this.metadata["Title"] = urlItems[urlItems.length - 1];
+    this.rekall = rekall;
 }
 
-Project.prototype.addDocument = function(key, document) {
-	if(this.sources[key] == undefined)
-		this.sources[key] = new Source();
-	this.sources[key].addDocument(document);
+Project.prototype.addDocument = function (key, document) {
+    if (this.sources[key] == undefined)
+        this.sources[key] = new Source();
+    this.sources[key].addDocument(document);
 }
-Project.prototype.getDocument = function(path) {
-	var retour = undefined;
-	for (var key in this.sources) {
-		if(retour == undefined)
-			retour = this.sources[key].getDocument(path);
-	}
-	return retour;
+
+Project.prototype.getDocument = function (path) {
+    var retour = undefined;
+    for (var key in this.sources) {
+        if (retour == undefined)
+            retour = this.sources[key].getDocument(path);
+    }
+    return retour;
 }
 
-Project.prototype.loadXML = function(xml) {
-	this.sources["Files"] = new Source();
-
-	var thiss = this;
-	var counts = {documents: 0, tags: 0, metadatas: 0};
-	xml.find('document').each(function() {
-		if(($(this).attr("remove") != undefined) && ($(this).attr("key") != undefined) && ($(this).attr("remove") == "true")) {
-			var rekallDoc = thiss.sources["Files"].documents[$(this).attr("key")];
-			if(rekallDoc != undefined) {
-				for (var tagIndex in rekallDoc.tags)
-					rekallDoc.tags[tagIndex].visuel.rect.remove();
-				delete rekall.project.sources["Files"].documents[rekallDoc.key];
-			}
-		}
-		else {
-			var rekallDoc = new Document();
-			counts.documents++;
-			counts.tags++;
-			$(this).find('meta').each(function() {
-				var rekallDocMeta = new Metadata();
-				rekallDocMeta.content 	  = $(this).attr('cnt');
-				rekallDocMeta.metadataKey = $(this).attr('ctg');
-				rekallDoc.setMetadata(rekallDocMeta);
-				counts.metadatas++;
-			});
-			if($(this).attr("key") != undefined)
-				rekallDoc.key = $(this).attr("key");
-			thiss.addDocument("Files", rekallDoc);
-		}
-	});
-	xml.find('edition').each(function() {
-		var key = $(this).attr('key');
-		if(thiss.sources["Files"].documents[key] != undefined) {
-			var version       = $(this).attr('version');
-			var metadataKey   = $(this).attr('metadataKey');
-			var metadataValue = $(this).attr('metadataValue');
-			thiss.sources["Files"].documents[key].setMetadata(metadataKey, metadataValue, version);
-		}
-	});
-	xml.find('tag').each(function() {
-		var key = $(this).attr('key');
-		if(thiss.sources["Files"].documents[key] != undefined) {
-			var version   = $(this).attr('version');
-			var timeStart = parseFloat($(this).attr('timeStart')) + 0.;
-			var timeEnd   = parseFloat($(this).attr('timeEnd'))   + 0.;
-			for (var index in thiss.sources["Files"].documents[key].tags) {
-				thiss.sources["Files"].documents[key].tags[index].setTimeStart(timeStart);
-				thiss.sources["Files"].documents[key].tags[index].setTimeEnd(timeEnd);
-			}
-		}
-	});
-	xml.find('projectMeta').each(function() {
-		thiss.metadata[$(this).attr('ctg')] = $(this).attr('cnt');
-	});
-	var videoUrl = undefined, videoTech = undefined;
-	xml.find('video').each(function() {
-		videoUrl  = $(this).attr('url');
-		videoTech = $(this).attr('tech');
-	});
-	
-	if((videoUrl != "") && (videoUrl != undefined)) {
-		var techOrder = ["vimeo", "youtube", "html5"];
-		if(videoUrl.indexOf("youtube") >= 0)		videoTech = "youtube";
-		if(videoUrl.indexOf("youtu.be") >= 0)		videoTech = "youtube";
-		if(videoUrl.indexOf("vimeo") >= 0)			videoTech = "vimeo";
-		if(videoUrl.indexOf("dailymotion") >= 0)	videoTech = "dailymotion";
-		if(videoUrl.indexOf("dai.ly") >= 0)			videoTech = "dailymotion";
-		if((videoTech != "") && (videoTech != undefined))
-			techOrder = [videoTech, "html5"];
-
-		//Video
-		if(rekall.videoPlayer == undefined) {
-			videojs("video", {
-				"techOrder": techOrder,
-				"controls": true,
-				"autoplay": false,
-				"loop": 	"false",
-				"preload": 	"auto",
-				"sources": [
-					{
-						"type": "video/" + videoTech,
-						"src": videoUrl
-					}
-				]
-			}, function() {
-				rekall.videoPlayer = this;
-				$(".vjs-fullscreen-control").hide();
-				
-				rekall.videoPlayer.on("durationchange", function(e) {
-					rekall.videoPlayer.markers.removeAll == undefined;
-
-					if(counts.documents>0){
-						rekall.project.analyse();
-						rekall.videoPlayer.markers.initialize();
-					}
-				});
-				rekall.videoPlayer.on("ended", function(e) {
-				});
-				rekall.videoPlayer.on("error", function(e) {
-				});
-				rekall.videoPlayer.on("firstplay", function(e) {
-				});
-				rekall.videoPlayer.on("fullscreenchange", function(e) {
-				});
-				rekall.videoPlayer.on("loadedalldata", function(e) {
-				});
-				rekall.videoPlayer.on("loadeddata", function(e) {
-				});
-				rekall.videoPlayer.on("loadedmetadata", function(e) {
-					console.log(counts.documents + " documents analysés, " + counts.metadatas + " métadonnées extraites et " + counts.tags + " tags affichés !");
-					if(counts.documents>0){ 
-						rekall.project.analyse();
-					}
-				});
-				rekall.videoPlayer.on("loadstart", function(e) {
-				});
-				rekall.videoPlayer.on("pause", function(e) {
-				});
-				rekall.videoPlayer.on("play", function(e) {
-				});
-				rekall.videoPlayer.on("progress", function(e) {
-				});
-				rekall.videoPlayer.on("seeked", function(e) {
-				});
-				rekall.videoPlayer.on("seeking", function(e) {
-				});
-				rekall.videoPlayer.on("timeupdate", function(e) {
-					rekall.timeline.update(rekall.videoPlayer.currentTime());
-				});
-				rekall.videoPlayer.on("volumechange", function(e) {
-				});
-				rekall.videoPlayer.on("waiting", function(e) {
-				});
-				rekall.videoPlayer.on("resize", function(e) {
-				});
-				$(window).trigger("resize");
-	
-			});
-		}
-		else {
-			console.log(counts.documents + " documents analysés, " + counts.metadatas + " métadonnées extraites et " + counts.tags + " tags affichés !");
-			rekall.project.analyse();
-		}
-	}
+Project.prototype.loadXML = function (xml) {
+    this.sources["Files"] = new Source();
+
+    let thiss = this;
+    let counts = {documents: 0, tags: 0, metadatas: 0};
+    xml.find('document').each(function () {
+        if (($(this).attr("remove") != undefined) && ($(this).attr("key") != undefined) && ($(this).attr("remove") == "true")) {
+            var rekallDoc = thiss.sources["Files"].documents[$(this).attr("key")];
+            if (rekallDoc != undefined) {
+                for (var tagIndex in rekallDoc.tags)
+                    rekallDoc.tags[tagIndex].visuel.rect.remove();
+                delete this.rekall.project.sources["Files"].documents[rekallDoc.key];
+            }
+        } else {
+            let rekallDoc = new Document();
+            counts.documents++;
+            counts.tags++;
+            $(this).find('meta').each(function () {
+                let rekallDocMeta = new Metadata();
+                rekallDocMeta.content = $(this).attr('cnt');
+                rekallDocMeta.metadataKey = $(this).attr('ctg');
+                rekallDoc.setMetadata(rekallDocMeta);
+                counts.metadatas++;
+            });
+            if ($(this).attr("key") != undefined)
+                rekallDoc.key = $(this).attr("key");
+            thiss.addDocument("Files", rekallDoc);
+        }
+    });
+    xml.find('edition').each(function () {
+        let key = $(this).attr('key');
+        if (thiss.sources["Files"].documents[key] != undefined) {
+            var version = $(this).attr('version');
+            var metadataKey = $(this).attr('metadataKey');
+            var metadataValue = $(this).attr('metadataValue');
+            thiss.sources["Files"].documents[key].setMetadata(metadataKey, metadataValue, version);
+        }
+    });
+    xml.find('tag').each(function () {
+        let key = $(this).attr('key');
+        if (thiss.sources["Files"].documents[key] != undefined) {
+            let version = $(this).attr('version');
+            let timeStart = parseFloat($(this).attr('timeStart')) + 0.;
+            let timeEnd = parseFloat($(this).attr('timeEnd')) + 0.;
+            for (var index in thiss.sources["Files"].documents[key].tags) {
+                thiss.sources["Files"].documents[key].tags[index].setTimeStart(timeStart);
+                thiss.sources["Files"].documents[key].tags[index].setTimeEnd(timeEnd);
+            }
+        }
+    });
+    xml.find('projectMeta').each(function () {
+        thiss.metadata[$(this).attr('ctg')] = $(this).attr('cnt');
+    });
+    let videoUrl = undefined, videoTech = undefined;
+    xml.find('video').each(function () {
+        videoUrl = $(this).attr('url');
+        videoTech = $(this).attr('tech');
+    });
+
+    if (this.rekall.ensureVideoPlayerCreated(videoUrl, videoTech)) {
+        $(window).trigger("resize");
+    }
+
+    this.analyse();
 }
 
-Project.prototype.timelineUpdate = function() {
-	
+Project.prototype.timelineUpdate = function () {
+
 }
 
-Project.prototype.analyse = function() {
-	$('#flattentimeline').html("<div id='flattentimeline_highlight'></div>");
-
-  var parsed_labels = $('input.annotation_labels').toArray().map(i => i.value);
-
-	//Analyse
-	Tags.flattenTimelineTags = [];
-	var filtredTags = new Array();
-	rekall.sortings["horizontal"].analyseStart();
-	rekall.sortings["colors"]    .analyseStart();
-	for (var keySource in this.sources) {      
-		for (var keyDocument in this.sources[keySource].documents) {
-			for (var key in this.sources[keySource].documents[keyDocument].tags) {
-				var tag = this.sources[keySource].documents[keyDocument].tags[key];
-				rekall.sortings["horizontal"].analyseAdd(tag);
-				rekall.sortings["colors"]    .analyseAdd(tag);
-				Tags.flattenTimelineTags.push(tag);
-        var labels = tag.getMetadata('Rekall->Labels');
-        if (labels && labels != '') {
-          var input_template = $('input.annotation_labels_template').first();
-          var html_label_template = $('label.annotation_labels_template').first();
-          var _labels = labels.split(';');
-          for (var i in _labels) {
-            var label = _labels[i];
-            if (label == '') continue;
-            if (parsed_labels.indexOf(label) != -1)
-              continue;
-            parsed_labels.push(label);
-            var inp = input_template.clone();
-            var id = 'annotation_label_' + parsed_labels.indexOf(label);
-            inp.attr('id', id);
-            inp.attr('value', label);
-
-            var html_label = html_label_template.clone();
-            html_label.attr('for', id);
-            html_label.html(label);
-
-            html_label.show();
-            html_label.addClass('annotation_labels').removeClass('annotation_labels_template');
-            inp.addClass('annotation_labels').removeClass('annotation_labels_template');
-
-            $('#popupLabelsInput').append(inp);
-            $('#popupLabelsInput').append(html_label);
-          }
+Project.prototype.analyse = function () {
+    $('#flattentimeline').html("<div id='flattentimeline_highlight'></div>");
+
+    let parsed_labels = $('input.annotation_labels').toArray().map(i => i.value);
+
+    //Analyse
+    Tags.reset();
+    this.rekall.sortings["horizontal"].analyseStart();
+    this.rekall.sortings["colors"].analyseStart();
+    for (let keySource in this.sources) {
+        for (let keyDocument in this.sources[keySource].documents) {
+            for (let key in this.sources[keySource].documents[keyDocument].tags) {
+                let tag = this.sources[keySource].documents[keyDocument].tags[key];
+                this.rekall.sortings["horizontal"].analyseAdd(tag);
+                this.rekall.sortings["colors"].analyseAdd(tag);
+                Tags.push(tag);
+                let labels = tag.getMetadata('Rekall->Labels');
+                if (labels && labels != '') {
+                    let input_template = $('input.annotation_labels_template').first();
+                    let html_label_template = $('label.annotation_labels_template').first();
+                    let _labels = labels.split(';');
+                    for (let i in _labels) {
+                        let label = _labels[i];
+                        if (label == '') continue;
+                        if (parsed_labels.indexOf(label) != -1)
+                            continue;
+                        parsed_labels.push(label);
+                        let inp = input_template.clone();
+                        let id = 'annotation_label_' + parsed_labels.indexOf(label);
+                        inp.attr('id', id);
+                        inp.attr('value', label);
+
+                        let html_label = html_label_template.clone();
+                        html_label.attr('for', id);
+                        html_label.html(label);
+
+                        html_label.show();
+                        html_label.addClass('annotation_labels').removeClass('annotation_labels_template');
+                        inp.addClass('annotation_labels').removeClass('annotation_labels_template');
+
+                        $('#popupLabelsInput').append(inp);
+                        $('#popupLabelsInput').append(html_label);
+                    }
+                }
+            }
+        }
+    }
+    this.rekall.sortings["horizontal"].analyseEnd();
+    this.rekall.sortings["colors"].analyseEnd();
+    Tags.sort();
+
+    //Affichage
+    let categories = rekall.sortings["horizontal"].categories;
+    if (this.rekall.sortings["horizontal"].metadataKey == "Time")
+        categories = {time: {tags: Tags.getFlattenTimeLineTags()}};
+
+    //Affectation des couleurs
+    for (let key in this.rekall.sortings["colors"].categories) {
+        let colorSortingCategory = this.rekall.sortings["colors"].categories[key];
+        for (let tagKey in colorSortingCategory.tags) {
+            let tag = colorSortingCategory.tags[tagKey];
+            tag.update(colorSortingCategory.color);
+            tag.isSelectable = colorSortingCategory.checked;
         }
-			}
-		}
-	}
-	rekall.sortings["horizontal"].analyseEnd();
-	rekall.sortings["colors"]    .analyseEnd();
-	Tags.flattenTimelineTags.sort(function(a, b) {
-		if(a.timeStart < b.timeStart) return -1;
-		if(a.timeStart > b.timeStart) return 1;
-		return 0;
-	});
-
-	//Affichage
-	var categories = rekall.sortings["horizontal"].categories;
-	if(rekall.sortings["horizontal"].metadataKey == "Time")
-		categories = {time: {tags: Tags.flattenTimelineTags}};
-	
-	//Affectation des couleurs
-	for (var key in rekall.sortings["colors"].categories) {
-		var colorSortingCategory = rekall.sortings["colors"].categories[key];
-		for (var key in colorSortingCategory.tags) {
-			var tag = colorSortingCategory.tags[key];
-			tag.update(colorSortingCategory.color);
-			tag.isSelectable = colorSortingCategory.checked;
-		}
-	}
-	
-
-	//Tags / catégories
-	var markers = [], captions = [];
-	for (var key in categories) {
-		$.each(categories[key].tags, function(index, tag) {
-			//Elements sur la timeline
-			markers.push({
-				time: 		 tag.getTimeStart()+0.1,
-				text: 		 tag.getMetadata("Rekall->Name"),
-				overlayText: tag.getMetadata("Rekall->Comments"), 
-				css: {
-					"background-color": tag.color,
-					"width": 			"2px",
-				},
-				markerTipCss: {
-					"font-familly": 	"OpenSans",
-					"color": 			tag.color,
-				},
-				onMarkerClick: function() {
-					tag.openPopupEdit();
-				}
-			});
-			
-			//Captions en popup
-			if(tag.isMarker()) {
-				captions.push({
-					startTime: 	tag.getTimeStart() * 1000,
-					endTime: 	(tag.timeStart + max(2, tag.timeEnd - tag.timeStart)) * 1000,
-					position:  	"HB",
-					data: 	 	tag.getMetadata("Rekall->Name"),
-					alignment: 	"C",
-					css: {
-						"background-color": "black",
-						"font-familly": 	"OpenSans",
-						"color": 			tag.color,
-					},
-					onCaptionChange: function() {
-						tag.openPopupEdit();
-					}
-				});
-			}
-			
-			//Analyse de vignettes
-			if(true) {
-				var thumbUrl = Utils.getPreviewPath(tag);
-				tag.thumbnail = {url: thumbUrl, tag: tag};
-			}
-			
-			
-			if((tag.getMetadata("Rekall->Highlight") != undefined) && (tag.getMetadata("Rekall->Highlight") != "")) {   
-			
-				//Dom
-				$('#flattentimeline').append(function() {
-					var styleColor = "background-color: " + tag.color + ";";
-					var textColor = "color: " + tag.color + ";";       
-					var textColor2 = "color: rgba(255,255,255,1)";     
-					var textColor3 = "color: rgba(255,255,255,.75)";
-					
-					var colorTransp = "";
-
-					var styleColor2 = styleColor;
-					var styleImage = "";
-					if(tag.thumbnail.url != undefined) {  
-
-						styleImage = "background-image: -webkit-linear-gradient(right bottom,  rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + "); background-image: -moz-linear-gradient(right bottom,  rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + "); background-image: -o-linear-gradient(right bottom,  rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + ");";
-					} else styleImage = "background-color: " + tag.color + "; background-image: -webkit-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -moz-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -o-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%);" ;
-
-					var icnType = "";
-					var tmpType = tag.getMetadata("Rekall->Type");
-					if(tmpType.indexOf("application/msword") >=0 ) 		icnType = "background-image:url(css/images/icn-word.png);";
-					else if(tmpType.indexOf("application/pdf") >=0 ) 	icnType = "background-image:url(css/images/icn-pdf.png);";
-					else if(tmpType.indexOf("application/") >=0 ) 		icnType = "background-image:url(css/images/icn-document.png);";
-					else if(tmpType.indexOf("audio/") >=0 ) 			icnType = "background-image:url(css/images/icn-music.png);";
-					else if(tmpType.indexOf("image/") >=0 ) 			icnType = "background-image:url(css/images/icn-image.png);";
-					else if(tmpType.indexOf("text/x-vcard") >=0 ) 		icnType = "background-image:url(css/images/icn-user.png);";
-					else if(tmpType.indexOf("text/") >=0 ) 				icnType = "background-image:url(css/images/icn-document.png);";
-					else if(tmpType.indexOf("video/") >=0 ) 			icnType = "background-image:url(css/images/icn-video.png);";  
-					
-					var typeTxt = tmpType.split("/")[1].replace(/marker/g, "note");  
-					
-					var htmlHighlight = ""; 
-					htmlHighlight	+=	"<div draggable=true class='flattentimeline_item flattentimeline_highlightitem' style='"+colorTransp+" "+styleImage+"'>";
-					htmlHighlight 	+=	"<div class='flattentimeline_title' 		style='" + textColor + "' title='" + tag.getMetadata("Rekall->Name") + "'>" + tag.getMetadata("Rekall->Name") + "</div>"; 
-					
-					
-					if(tag.getMetadata("Rekall->Comments")!="") {
-						
-						var tmpComments = tag.getMetadata("Rekall->Comments");
-						if(tmpComments.length>150){
-							tmpComments = tmpComments.substring(0, 150) + "...";
-						}
-						
-						var tmpcount = 0;
-						var tmpIndex = tmpComments.indexOf("<br/>");
-						while((tmpcount<3)&&(tmpIndex!=-1)) {
-							tmpcount++;
-							tmpIndex = tmpComments.indexOf("<br/>",tmpIndex+1);
-						}
-						if(tmpIndex!=-1) {
-							tmpComments = tmpComments.substring(0, tmpIndex) + "...";
-						}
-						htmlHighlight 	+=	"<div class='flattentimeline_description'>" + tmpComments + "</div>"; 
-					}
-						
-					if(tag.getMetadata("Rekall->Author")!="")	htmlHighlight 	+=	"<div class='flattentimeline_author'>" + tag.getMetadata("Rekall->Author") + "</div>";
-				
-						
-					htmlHighlight 	+=	"<div class='flattentimeline_typeTxt'		>" + typeTxt + "</div>";      
-					htmlHighlight 	+= "<div class='flattentimeline_opacifiant' style='" + styleColor2 + "'></div>";  
-					htmlHighlight    += "</div>";
-                   
-					tag.flattenTimelineDom = $(htmlHighlight); 
-					tag.flattenTimelineDom.click(function(event) { 
-						tag.openPopupEdit();                
-					});
-					tag.flattenTimelineDom.on({
-						dragstart: function(event) {
-							event.dataTransfer.setData("key", 	  tag.document.key);
-							event.dataTransfer.setData("version", tag.version);
-						}
-					});  
-				
-					return tag.flattenTimelineDom;   
-				
-				});     
-			
-			} else {    
-			
-				//Dom
-				$('#flattentimeline').append(function() {
-					var styleColor = "background-color: " + tag.color + ";";
-					var textColor = "color: " + tag.color + ";";
-					var textColor2 = "color: rgba(255,255,255,.8)";     
-					var textColor3 = "color: rgba(0,0,0,.75);";    
-					
-					var colorTransp = styleColor.replace(/rgb/g, "rgba").replace(/\)/g, ",.75)");
-
-					var styleColor2 = styleColor;
-					var styleImage = "";
-					if(tag.thumbnail.url != undefined) {
-						styleImage = "background-image: url(" + tag.thumbnail.url + ");";
-					} else styleImage = "background-color: rgba(255,255,255,.25)";
-
-					var icnType = "";
-					var tmpType = tag.getMetadata("Rekall->Type");
-					if(tmpType.indexOf("application/msword") >=0 ) 		icnType = "background-image:url(css/images/icn-word.png);";
-					else if(tmpType.indexOf("application/pdf") >=0 ) 	icnType = "background-image:url(css/images/icn-pdf.png);";
-					else if(tmpType.indexOf("application/") >=0 ) 		icnType = "background-image:url(css/images/icn-document.png);";
-					else if(tmpType.indexOf("audio/") >=0 ) 			icnType = "background-image:url(css/images/icn-music.png);";
-					else if(tmpType.indexOf("image/") >=0 ) 			icnType = "background-image:url(css/images/icn-image.png);";
-					else if(tmpType.indexOf("text/x-vcard") >=0 ) 		icnType = "background-image:url(css/images/icn-user.png);";
-					else if(tmpType.indexOf("text/") >=0 ) 				icnType = "background-image:url(css/images/icn-document.png);";
-					else if(tmpType.indexOf("video/") >=0 ) 			icnType = "background-image:url(css/images/icn-video.png);";
-                                    
-
-					var html = ""; 
-					html	+= "<div draggable=true class='flattentimeline_item' title='" + tag.getMetadata("Rekall->Comments") + "' >";  
-					html 	+= "<div class='flattentimeline_image'      style='" + styleImage + "'></div>";   
-					html 	+= "<div class='flattentimeline_opacifiant' style='" + styleColor2 + "'></div>";                     
-					html 	+= "<div class='flattentimeline_type'		style='" + icnType +"' title='" + tmpType + "'></div>";                                                           
-					html 	+= "<div class='flattentimeline_title' 		style='" + textColor2 + "' title='" + tag.getMetadata("Rekall->Name") + "'>" + tag.getMetadata("Rekall->Name") + "</div>";     
-					html    += "</div>";           
-
-					tag.flattenTimelineDom = $(html);
-					tag.flattenTimelineDom.click(function(event) {                
-						tag.openPopupEdit(); 
-					});
-					tag.flattenTimelineDom.on({
-						dragstart: function(event) {
-							event.dataTransfer.setData("key", 	  tag.document.key);
-							event.dataTransfer.setData("version", tag.version);
-						}
-					});        
-				
-					return tag.flattenTimelineDom;    
-				
-				});  
-			}
-			
-			//Ouverture du popup
-			if((Tag.keyToOpenAfterLoading != undefined) && (tag.document.key == Tag.keyToOpenAfterLoading)) {
-				tag.openPopupEdit();
-				Tag.keyToOpenAfterLoading = undefined;
-			}
-		});
-	}
-	rekall.timeline.updateFlattenTimeline();
-
-	//Initialisation des captions
-	if(rekall.videoPlayer.caption.updateCaption == undefined) {
-		rekall.videoPlayer.caption({
-			data: captions, 
-			setting: {
-				captionSize:  3,
-				captionStyle: {
-					'background-color': 'rgba(255,0,0,0.8)',
-					'color':  			'white',
-					'padding': 			'3px',
-					'font-family': 		'OpenSans',
-				},
-				onCaptionChange: function(num_c) {
-				}
-			}
-		});
-	}
-	else if((captions) && (captions.length > 0)) {
-		rekall.videoPlayer.caption.loadNewCaption({data: captions});
-	}
-	
-	//Ajout des marqueurs sur la timeline
-	if(rekall.videoPlayer.markers.removeAll == undefined) {
-		rekall.videoPlayer.markers({
-			markerStyle: {
-				'width':            '7px',
-				'border-radius':    '30%',
-				'background-color': 'yellow'
-			},
-			markerTip:{
-				display: true,
-				text: function(marker) {
-					return marker.text;
-				},
-				time: function(marker) {
-					return marker.time;
-				}
-			},
-			breakOverlay:{
-				display:     false,
-				displayTime: 3,
-				style: {
-					'width':            '100%',
-					'height':           '20%',
-					'background-color': 'rgba(0,0,0,0.7)',
-					'color':            'white',
-					'font-size':        '17px'
-				},
-				text: function(marker) {
-					return "Break overlay: " + marker.overlayText;
-				}
-			},
-			onMarkerClick: 	 function(marker) {},
-			onMarkerReached: function(marker) {},
-			markers: markers
-		});
-	}
-	else
-		rekall.videoPlayer.markers.reset(markers);
+    }
+
+
+    //Tags / catégories
+    let markers = [], captions = [];
+    for (let key in categories) {
+        $.each(categories[key].tags, function (index, tag) {
+            //Elements sur la timeline
+            markers.push({
+                time: tag.getTimeStart() + 0.1,
+                text: tag.getMetadata("Rekall->Name"),
+                overlayText: tag.getMetadata("Rekall->Comments"),
+                css: {
+                    "background-color": tag.color,
+                    "width": "2px",
+                },
+                markerTipCss: {
+                    "font-familly": "OpenSans",
+                    "color": tag.color,
+                },
+                onMarkerClick: function () {
+                    tag.openPopupEdit();
+                }
+            });
+
+            //Captions en popup
+            if (tag.isMarker()) {
+                captions.push({
+                    startTime: tag.getTimeStart() * 1000,
+                    endTime: (tag.timeStart + max(2, tag.timeEnd - tag.timeStart)) * 1000,
+                    position: "HB",
+                    data: tag.getMetadata("Rekall->Name"),
+                    alignment: "C",
+                    css: {
+                        "background-color": "black",
+                        "font-familly": "OpenSans",
+                        "color": tag.color,
+                    },
+                    onCaptionChange: function () {
+                        tag.openPopupEdit();
+                    }
+                });
+            }
+
+            //Analyse de vignettes
+            let thumbUrl = Utils.getPreviewPath(tag);
+            tag.thumbnail = {url: thumbUrl, tag: tag};
+
+
+            if ((tag.getMetadata("Rekall->Highlight") != undefined) && (tag.getMetadata("Rekall->Highlight") != "")) {
+
+                //Dom
+                $('#flattentimeline').append(function () {
+                    let styleColor = "background-color: " + tag.color + ";";
+                    let textColor = "color: " + tag.color + ";";
+
+                    let colorTransp = "";
+
+                    let styleColor2 = styleColor;
+                    let styleImage = "";
+                    if (tag.thumbnail.url != undefined) {
+
+                        styleImage = "background-image: -webkit-linear-gradient(right bottom,  rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + "); background-image: -moz-linear-gradient(right bottom,  rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + "); background-image: -o-linear-gradient(right bottom,  rgba(20,46,51,.60) 0%,rgba(20,46,51,.90) 100%), url(" + tag.thumbnail.url + ");";
+                    } else styleImage = "background-color: " + tag.color + "; background-image: -webkit-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -moz-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%); background-image: -o-linear-gradient(right bottom, rgba(20,46,51,.5) 0%,rgba(20,46,51,.8) 100%);";//styleColor.replace(/rgb/g, "rgba").replace(/\)/g, ",.85)");//"background-color: rgba(255,255,255,.25)";
+
+                    let icnType = "";
+                    let tmpType = tag.getMetadata("Rekall->Type");
+                    if (tmpType.indexOf("application/msword") >= 0) icnType = "background-image:url(css/images/icn-word.png);";
+                    else if (tmpType.indexOf("application/pdf") >= 0) icnType = "background-image:url(css/images/icn-pdf.png);";
+                    else if (tmpType.indexOf("application/") >= 0) icnType = "background-image:url(css/images/icn-document.png);";
+                    else if (tmpType.indexOf("audio/") >= 0) icnType = "background-image:url(css/images/icn-music.png);";
+                    else if (tmpType.indexOf("image/") >= 0) icnType = "background-image:url(css/images/icn-image.png);";
+                    else if (tmpType.indexOf("text/x-vcard") >= 0) icnType = "background-image:url(css/images/icn-user.png);";
+                    else if (tmpType.indexOf("text/") >= 0) icnType = "background-image:url(css/images/icn-document.png);";
+                    else if (tmpType.indexOf("video/") >= 0) icnType = "background-image:url(css/images/icn-video.png);";
+
+                    let typeTxt = tmpType.split("/")[1].replace(/marker/g, "note");
+
+                    let htmlHighlight = "";
+                    htmlHighlight += "<div draggable=true class='flattentimeline_item flattentimeline_highlightitem' style='" + colorTransp + " " + styleImage + "'>";
+                    htmlHighlight += "<div class='flattentimeline_title' 		style='" + textColor + "' title='" + tag.getMetadata("Rekall->Name") + "'>" + tag.getMetadata("Rekall->Name") + "</div>";
+
+
+                    if (tag.getMetadata("Rekall->Comments") != "") {
+
+                        let tmpComments = tag.getMetadata("Rekall->Comments");
+                        if (tmpComments.length > 150) {
+                            tmpComments = tmpComments.substring(0, 150) + "...";
+                        }
+
+                        let tmpcount = 0;
+                        let tmpIndex = tmpComments.indexOf("<br/>");
+                        while ((tmpcount < 3) && (tmpIndex != -1)) {
+                            tmpcount++;
+                            tmpIndex = tmpComments.indexOf("<br/>", tmpIndex + 1);
+                        }
+                        if (tmpIndex != -1) {
+                            tmpComments = tmpComments.substring(0, tmpIndex) + "...";
+                        }
+                        htmlHighlight += "<div class='flattentimeline_description'>" + tmpComments + "</div>";
+                    }
+
+                    if (tag.getMetadata("Rekall->Author") != "") htmlHighlight += "<div class='flattentimeline_author'>" + tag.getMetadata("Rekall->Author") + "</div>";
+
+
+                    htmlHighlight += "<div class='flattentimeline_typeTxt'		>" + typeTxt + "</div>";
+                    htmlHighlight += "<div class='flattentimeline_opacifiant' style='" + styleColor2 + "'></div>";
+                    htmlHighlight += "</div>";
+
+                    tag.flattenTimelineDom = $(htmlHighlight);
+                    tag.flattenTimelineDom.click(function (event) {
+                        tag.openPopupEdit();
+                    });
+                    tag.flattenTimelineDom.on({
+                        dragstart: function (event) {
+                            event.dataTransfer.setData("key", tag.document.key);
+                            event.dataTransfer.setData("version", tag.version);
+                        }
+                    });
+
+                    return tag.flattenTimelineDom;
+
+                });
+
+            } else {
+
+                //Dom
+                $('#flattentimeline').append(function () {
+                    let styleColor = "background-color: " + tag.color + ";";
+                    let textColor2 = "color: rgba(255,255,255,.8)";
+
+                    let styleColor2 = styleColor;
+                    let styleImage = "";
+                    if (tag.thumbnail.url != undefined) {
+                        styleImage = "background-image: url(" + encodeURI(tag.thumbnail.url) + ");";//" opacity: 0.5;";
+                    } else styleImage = "background-color: rgba(255,255,255,.25)";
+
+                    let icnType = "";
+                    let tmpType = tag.getMetadata("Rekall->Type");
+                    if (tmpType.indexOf("application/msword") >= 0) icnType = "background-image:url(css/images/icn-word.png);";
+                    else if (tmpType.indexOf("application/pdf") >= 0) icnType = "background-image:url(css/images/icn-pdf.png);";
+                    else if (tmpType.indexOf("application/") >= 0) icnType = "background-image:url(css/images/icn-document.png);";
+                    else if (tmpType.indexOf("audio/") >= 0) icnType = "background-image:url(css/images/icn-music.png);";
+                    else if (tmpType.indexOf("image/") >= 0) icnType = "background-image:url(css/images/icn-image.png);";
+                    else if (tmpType.indexOf("text/x-vcard") >= 0) icnType = "background-image:url(css/images/icn-user.png);";
+                    else if (tmpType.indexOf("text/") >= 0) icnType = "background-image:url(css/images/icn-document.png);";
+                    else if (tmpType.indexOf("video/") >= 0) icnType = "background-image:url(css/images/icn-video.png);";
+
+
+                    let html = "";
+                    html += "<div draggable=true class='flattentimeline_item' title='" + tag.getMetadata("Rekall->Comments") + "' >";
+                    html += "<div class='flattentimeline_image'      style='" + styleImage + "'></div>";
+                    html += "<div class='flattentimeline_opacifiant' style='" + styleColor2 + "'></div>";
+                    html += "<div class='flattentimeline_type'		style='" + icnType + "' title='" + tmpType + "'></div>";
+                    html += "<div class='flattentimeline_title' 		style='" + textColor2 + "' title='" + tag.getMetadata("Rekall->Name") + "'>" + tag.getMetadata("Rekall->Name") + "</div>";
+                    html += "</div>";
+
+                    tag.flattenTimelineDom = $(html);
+                    tag.flattenTimelineDom.click(function (event) {
+                        tag.openPopupEdit();
+                    });
+                    tag.flattenTimelineDom.on({
+                        dragstart: function (event) {
+                            event.dataTransfer.setData("key", tag.document.key);
+                            event.dataTransfer.setData("version", tag.version);
+                        }
+                    });
+
+                    return tag.flattenTimelineDom;
+
+                });
+            }
+
+            //Ouverture du popup
+            if ((Tag.keyToOpenAfterLoading != undefined) && (tag.document.key == Tag.keyToOpenAfterLoading)) {
+                tag.openPopupEdit();
+                Tag.keyToOpenAfterLoading = undefined;
+            }
+        });
+    }
+    this.rekall.timeline.updateFlattenTimeline();
+
+    //Initialisation des captions
+    if (this.rekall.videoPlayer.caption.updateCaption == undefined) {
+        this.rekall.videoPlayer.caption({
+            data: captions,
+            setting: {
+                captionSize: 3,
+                captionStyle: {
+                    'background-color': 'rgba(255,0,0,0.8)',
+                    'color': 'white',
+                    'padding': '3px',
+                    'font-family': 'OpenSans',
+                },
+                onCaptionChange: function (num_c) {
+                }
+            }
+        });
+    } else if ((captions) && (captions.length > 0)) {
+        this.rekall.videoPlayer.caption.loadNewCaption({data: captions});
+    }
+
+    //Ajout des marqueurs sur la timeline
+    if (this.rekall.videoPlayer.markers.removeAll == undefined) {
+        this.rekall.videoPlayer.markers({
+            markerStyle: {
+                'width': '7px',
+                'border-radius': '30%',
+                'background-color': 'yellow'
+            },
+            markerTip: {
+                display: true,
+                text: function (marker) {
+                    return marker.text;
+                },
+                time: function (marker) {
+                    return marker.time;
+                }
+            },
+            breakOverlay: {
+                display: false,
+                displayTime: 3,
+                style: {
+                    'width': '100%',
+                    'height': '20%',
+                    'background-color': 'rgba(0,0,0,0.7)',
+                    'color': 'white',
+                    'font-size': '17px'
+                },
+                text: function (marker) {
+                    return "Break overlay: " + marker.overlayText;
+                }
+            },
+            onMarkerClick: function (marker) {
+            },
+            onMarkerReached: function (marker) {
+            },
+            markers: markers
+        });
+    } else {
+        this.rekall.videoPlayer.markers.reset(markers);
+    }
 }
diff --git a/capsule-prototype/js/online-rekall/Rekall.js b/capsule-prototype/js/online-rekall/Rekall.js
index 0f14490..2a83503 100644
--- a/capsule-prototype/js/online-rekall/Rekall.js
+++ b/capsule-prototype/js/online-rekall/Rekall.js
@@ -23,125 +23,218 @@
 */
 
 function Rekall(options) {
-	this.sortings = new Object();
-	this.sortings["horizontal"] = new Sorting("Time");
-	this.sortings["colors"]     = new Sorting("Rekall->Type", false, "");
-	this.timeline = new Timeline();
-	this.videoPlayer = undefined;
-
-	function getDefaultBaseUrl() {
-		var oldURL = window.document.location + "";
-		var url = oldURL;
-		var index = 0;
-		url = url.replace("pro-index.html", "");
-		url = url.replace("online-index.html", "");
-		url = url.replace("index.html", "");
-		index = oldURL.indexOf('?');
-		if(index == -1)
-			index = oldURL.indexOf('#');
-		if(index != -1)
-			url = oldURL.substring(0, index);
-		if(!url.endsWith("/"))
-			url = url + "/";
-
-		return url;
-	}
-
-	var defaultSettings = {
-		_allowProjectDeletion: false,
-		baseUrl: getDefaultBaseUrl()
-	}
-
-	this.Settings = $.extend({}, defaultSettings, options);
+    this.sortings = new Object();
+    this.sortings["horizontal"] = new Sorting("Time");
+    this.sortings["colors"] = new Sorting("Rekall->Type", false, "");
+    this.timeline = new Timeline();
+    this.videoPlayer = undefined;
+
+    function getDefaultBaseUrl() {
+        var oldURL = window.document.location + "";
+        var url = oldURL;
+        var index = 0;
+        url = url.replace("pro-index.html", "");
+        url = url.replace("online-index.html", "");
+        url = url.replace("index.html", "");
+        index = oldURL.indexOf('?');
+        if (index == -1)
+            index = oldURL.indexOf('#');
+        if (index != -1)
+            url = oldURL.substring(0, index);
+        if (!url.endsWith("/"))
+            url = url + "/";
+
+        return url;
+    }
+
+    let defaultSettings = {
+        _allowProjectDeletion: false,
+        baseUrl: getDefaultBaseUrl()
+    }
+
+    this.Settings = $.extend({}, defaultSettings, options);
+}
+
+Rekall.prototype.allowProjectDeletion = function () {
+    if (arguments.length <= 0 && 'boolean' !== typeof arguments[0]) {
+        return this.Settings._allowProjectDeletion;
+    }
+
+    if (arguments[0]) {
+        this.Settings._allowProjectDeletion = true;
+        $('#popupSettingsBtnDelete').attr('display', null);
+    } else {
+        this.Settings._allowProjectDeletion = false;
+        $('#popupSettingsBtnDelete').hide();
+    }
+    this.Settings._allowProjectDeletion = arguments[0];
 }
 
-Rekall.prototype.allowProjectDeletion = function(){
-	if (arguments.length <= 0 && 'boolean' !== typeof arguments[0]){
-		return this.Settings._allowProjectDeletion;
-	}
-
-	if (arguments[0]) {
-		this.Settings._allowProjectDeletion = true;
-		$('#popupSettingsBtnDelete').attr('display', null);
-	}
-	else {
-		this.Settings._allowProjectDeletion = false;
-		$('#popupSettingsBtnDelete').hide();
-	}
-	this.Settings._allowProjectDeletion = arguments[0];
+Rekall.prototype.loadXMLFile = function () {
+    var oldURL = window.document.location + "";
+    var index = 0;
+    var url = oldURL;
+    url = url.replace("pro-index.html", "");
+    url = url.replace("online-index.html", "");
+    url = url.replace("index.html", "");
+    index = oldURL.indexOf('?');
+    if (index == -1)
+        index = oldURL.indexOf('#');
+    if (index != -1)
+        url = oldURL.substring(0, index);
+    if (!url.endsWith("/"))
+        url = url + "/";
+
+    if (!this.Settings._allowProjectDeletion) {
+        $('#popupSettingsBtnDelete').hide();
+    }
+    ;
+
+    this.baseUrl = url;
+
+    let that = this;
+    rouletteStart();
+    $.ajax("php/file.php?r=project.xml", {
+        type: "GET",
+        cache: false,
+        data: {"rand": random()},
+        dataType: "xml",
+        success: function (xml) {
+            if ((xml == null) || (xml == undefined))
+                openAlert("Your project is unreachable. Did you move the folder to an other location?", 60);
+            else {
+                $(xml).find('project').each(function () {
+                    //if($(this).find('document').length == 0) {
+                    //	openAlert("Start by adding files to your project.", 60);
+                    //} else {
+                    if (rekall.project == undefined)
+                        rekall.project = new Project(url, that);
+                    rekall.project.loadXML($(this));
+                    //}
+                });
+            }
+            rouletteEnd();
+        },
+        error: function () {
+            $.ajax("file/project.xml", {
+                type: "GET",
+                cache: false,
+                data: {"rand": random()},
+                dataType: "xml",
+                success: function (xml) {
+                    if ((xml == null) || (xml == undefined))
+                        openAlert("Your project is unreachable. Did you move the folder to an other location?", 60);
+                    else {
+                        $(xml).find('project').each(function () {
+                            if ($(this).find('document').length == 0) {
+                                openAlert("Start by adding files to your project.", 60);
+                            } else {
+                                if (rekall.project == undefined)
+                                    rekall.project = new Project(url, that);
+                                rekall.project.loadXML($(this));
+                            }
+                        });
+                    }
+                    rouletteEnd();
+                },
+                error: function () {
+                    rouletteEnd();
+                }
+            });
+            rouletteEnd();
+        }
+    });
 }
 
-Rekall.prototype.loadXMLFile = function() {
-	var oldURL = window.document.location + "";
-	var index = 0;
-	var url = oldURL;
-	url = url.replace("pro-index.html", "");
-	url = url.replace("online-index.html", "");
-	url = url.replace("index.html", "");
-	index = oldURL.indexOf('?');
-	if(index == -1)
-		index = oldURL.indexOf('#');
-	if(index != -1)
-		url = oldURL.substring(0, index);
-	if(!url.endsWith("/"))
-		url = url + "/";
-
-	if(!this.Settings._allowProjectDeletion){
-		$('#popupSettingsBtnDelete').hide();
-	};
-
-	this.baseUrl = url;
-	
-	var thiss = this;
-	rouletteStart();
-	$.ajax("php/file.php?r=project.xml", {
-		type: 	"GET",
-		cache: 	false,
-		data: 	{"rand": random()},
-		dataType: "xml",
-		success: function(xml) {
-			if((xml == null) || (xml == undefined))
-				openAlert("Your project is unreachable. Did you move the folder to an other location?", 60);
-			else {
-				$(xml).find('project').each(function() {
-					//if($(this).find('document').length == 0) {
-					//	openAlert("Start by adding files to your project.", 60);
-					//} else {
-						if(rekall.project == undefined)
-							rekall.project = new Project(url);
-						rekall.project.loadXML($(this));
-						//}
-				});
-			}
-			rouletteEnd();
-		},
-		error: function() {
-			$.ajax("file/project.xml", {
-				type: 	"GET",
-				cache: 	false,
-				data: 	{"rand": random()},
-				dataType: "xml",
-				success: function(xml) {
-					if((xml == null) || (xml == undefined))
-						openAlert("Your project is unreachable. Did you move the folder to an other location?", 60);
-					else {
-						$(xml).find('project').each(function() {
-							if($(this).find('document').length == 0) {
-								openAlert("Start by adding files to your project.", 60);
-							} else {
-								if(rekall.project == undefined)
-									rekall.project = new Project(url);
-								rekall.project.loadXML($(this));
-							}
-						});
-					}
-					rouletteEnd();
-				},
-				error: function() {
-					rouletteEnd();
-				}
-			});
-			rouletteEnd();
-		}
-	});
+Rekall.prototype.ensureVideoPlayerCreated = function (url, tech) {
+    if (undefined !== this.videoPlayer)
+        return false;
+
+    let that = this;
+    let techOrder = ["vimeo", "youtube", "html5"];
+    if (url.indexOf("youtube") >= 0) tech = "youtube";
+    if (url.indexOf("youtu.be") >= 0) tech = "youtube";
+    if (url.indexOf("vimeo") >= 0) tech = "vimeo";
+    if (url.indexOf("dailymotion") >= 0) tech = "dailymotion";
+    if (url.indexOf("dai.ly") >= 0) tech = "dailymotion";
+    if ((tech !== "") && (tech !== undefined))
+        techOrder = [tech, "html5"];
+
+    //Video
+    this.videoPlayer = videojs("video", {
+        "techOrder": techOrder,
+        "controls": true,
+        "autoplay": false,
+        "loop": "false",
+        "preload": "auto",
+        "sources": [
+            {
+                "type": "video/" + tech,
+                "src": url
+            }
+        ]
+    }, function () {
+        $(".vjs-fullscreen-control").hide();
+
+        that.videoPlayer.on("durationchange", function () {
+            console.log("durationchange");
+            that.project.analyse();
+            that.videoPlayer.markers.initialize();
+        });
+        that.videoPlayer.on("ended", function () {
+            console.log("ended");
+        });
+        that.videoPlayer.on("error", function () {
+            console.log("error");
+        });
+        that.videoPlayer.on("firstplay", function () {
+            console.log("firstplay");
+        });
+        that.videoPlayer.on("fullscreenchange", function () {
+            console.log("fullscreenchange");
+        });
+        that.videoPlayer.on("loadedalldata", function () {
+            console.log("loadedalldata");
+        });
+        that.videoPlayer.on("loadeddata", function () {
+            console.log("loadeddata");
+        });
+        that.videoPlayer.on("loadedmetadata", function () {
+            console.log("loadedmetadata");
+            that.project.analyse();
+        });
+        that.videoPlayer.on("loadstart", function () {
+            console.log("loadstart");
+        });
+        that.videoPlayer.on("pause", function () {
+            console.log("pause");
+        });
+        that.videoPlayer.on("play", function () {
+            console.log("play");
+        });
+        that.videoPlayer.on("progress", function () {
+            console.log("progress");
+        });
+        that.videoPlayer.on("seeked", function () {
+            console.log("seeked");
+        });
+        that.videoPlayer.on("seeking", function () {
+            console.log("seeking");
+        });
+        that.videoPlayer.on("timeupdate", function () {
+            console.log("timeupdate");
+            that.timeline.update(that.videoPlayer.currentTime());
+        });
+        that.videoPlayer.on("volumechange", function () {
+            console.log("volumechange");
+        });
+        that.videoPlayer.on("waiting", function () {
+            console.log("waiting");
+        });
+        that.videoPlayer.on("resize", function () {
+            console.log("resize");
+        });
+    });
+
+    return true;
 }
\ No newline at end of file
diff --git a/capsule-prototype/js/online-rekall/Tags.js b/capsule-prototype/js/online-rekall/Tags.js
index 6234ec7..9a057be 100644
--- a/capsule-prototype/js/online-rekall/Tags.js
+++ b/capsule-prototype/js/online-rekall/Tags.js
@@ -21,7 +21,39 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-function Tags() {
-}
+const Tags = (function() {
+    let flattenTimelineTags;
 
-Tags.flattenTimelineTags = new Array();
+    function getFlattenTimeLineTags() {
+        if(!flattenTimelineTags){
+            flattenTimelineTags = [];
+        }
+
+        return flattenTimelineTags;
+    }
+
+    function empty(){
+        flattenTimelineTags = [];
+    }
+
+    let sort = function() {
+        let localFlattenTimeline = getFlattenTimeLineTags();
+        localFlattenTimeline.sort(function (a, b) {
+            if (a.timeStart < b.timeStart) return -1;
+            if (a.timeStart > b.timeStart) return 1;
+            return 0;
+        });
+    }
+
+    let push = function(value) {
+        let localFlattenTimeline = getFlattenTimeLineTags();
+        localFlattenTimeline.push(value);
+    }
+
+    return {
+        getFlattenTimeLineTags: getFlattenTimeLineTags,
+        reset: empty,
+        sort: sort,
+        push: push
+    }
+})();
diff --git a/capsule-prototype/js/rekall/Sorting.js b/capsule-prototype/js/rekall/Sorting.js
index 614f7e0..0829e4c 100644
--- a/capsule-prototype/js/rekall/Sorting.js
+++ b/capsule-prototype/js/rekall/Sorting.js
@@ -108,9 +108,9 @@ Sorting.prototype.analyseStart = function(tags) {
 		this.valMin = 0;     
 	else {
 		this.categoriesIndex = 0;
-		for (var key in this.categories) {
+		for (let key in this.categories) {
 			this.categories[key].shoudBeRemoved = true;
-			this.categories[key].tags = new Array();
+			this.categories[key].tags = [];
 		}
 	}
 }
-- 
GitLab