
	var CurrentLanguage = 'fr';	
	var G_USE_ID 		= -1;
	var G_UserFullName 	= '';
	var	G_UserAccess	= null;

	var Time3 = 0;
	var AllowColumnsOrderSaving = false;

	Date.prototype.yyyymmdd = function() {
		var mm = this.getMonth() + 1; // getMonth() is zero-based
		var dd = this.getDate();

		return [this.getFullYear(),
          (mm>9 ? '' : '0') + mm,
          (dd>9 ? '' : '0') + dd
         ].join('');
	};


	Date.prototype.hhmmss = function(){
		var mm = this.getMinutes();
		var ss = this.getSeconds();
		var hh = this.getHours();

		return [(hh>9 ? '':'0')+hh,(mm>9 ? '':'0')+mm,(ss>9 ? '':'0')+ss ].join('');
	};
	
		
	class C_Splitter 
	{
		constructor ( id )
		{
			this.ID 		= id;
			this.Splitter	= null;
			this.Orient 	= "";
			this.Collapsed 	= -1;		// -1 : no collapse, 0 : collapse pan_1, 1 : collapse pan_2
			this.Timer		= null;
			
			this.Initialize ();
		}
		
		Initialize ()
		{
			this.Splitter = document.getElementById ( this.ID );
				
			if ( this.Splitter.className.includes ( "splitter-v" ) )
				this.Orient = "V";
			else
				if ( this.Splitter.className.includes ( "splitter-h" ) )
					this.Orient = "H";
			
			if ( this.Orient.length == 0 )
			{
				console.log ( "Error : bad splitter class : " + this.Splitter.className );
				return;
			}	
			
			let childs = this.Splitter.children;
		
			if ( childs.length != 3 )
			{
				console.log ( "Error : bad childs number : " + childs.length );
				return;
			}
			
		
			if ( this.Orient == "V" )
			{
				if ( childs [0].className.includes ( "pan-left" ) == true )
				{
					if ( childs [1].className.includes ( "separator_v" ) == true )
					{
						if ( childs [2].className.includes ( "pan-right" ) == true )
						{
						}
						else
						{
							console.log ( "Error : bad third child class : " + childs [2].className + " wanted : pan-right" );
							return;
						}
					}
					else
					{
						console.log ( "Error : bad second child class : " + childs [1].className + " wanted : separator_v"  );
						return;
					}
				}
				else
				{
					console.log ( "Error : bad first child class : " + childs [0].className + " wanted : pan-left" );
					return;
				}
			}
			else
			{
				if ( childs [0].className.includes ( "pan-top" ) == true )
				{
					if ( childs [1].className.includes ( "separator_h" ) == true )
					{
						if ( childs [2].className.includes ( "pan-bottom" ) == true )
						{
						}
						else
						{
							console.log ( "Error : bad third child class : " + childs [2].className + " wanted : pan-bottom" );
							return;
						}
					}
					else
					{
						console.log ( "Error : bad second child class : " + childs [1].className + " wanted : separator_h"  );
						return;
					}
				}
				else
				{
					console.log ( "Error : bad first child class : " + childs [0].className + " wanted : pan-top" );
					return;
				}
			}
		
			this.Pan_1 	= childs [0];
			this.Sep	= childs [1];
			this.Pan_2 	= childs [2];
				
			this.NewRatio = parseFloat ( this.Splitter.dataset.ratio );
		
			var delta = {x: 0, y: 0};
			
			this.SplitterUpdateSize ( delta );
			var that = this;
			new ResizeObserver ( function (ev) { that.OnSplitterSize ( ev ); } ).observe ( this.Splitter );
			
			this.Sep.onmousedown = function (ev) { that.onSepMouseDown (ev); };
		}

		onSepMouseDown ( e )
		{
			if ( this.Collapsed >= 0 )
				return;
			
			this.md = 	{	e,
						offsetLeft:		this.Sep.offsetLeft,
						offsetTop:		this.Sep.offsetTop,
						firstWidth:		this.Pan_1.offsetWidth,
						secondWidth:	this.Pan_2.offsetWidth,
						firstHeight:	this.Pan_1.offsetHeight,
						secondHeight:	this.Pan_2.offsetHeight
					};
						
			var that = this;
			document.onmousemove	= function (ev) { that.onSepMouseMove(ev); },
			document.onmouseup		= () =>
			{
				document.onmousemove = document.onmouseup = null;
				this.Splitter.dataset.ratio = this.NewRatio;
			}
		}
			
		onSepMouseMove ( e )
		{
				let parentHeight 	= this.Pan_1.parentNode.clientHeight;
				let parentWidth 	= this.Pan_1.parentNode.clientWidth;
						
				var delta = {x: e.clientX - this.md.e.clientX, y: e.clientY - this.md.e.clientY};
			
				if ( this.Orient == "V" )
				{
					delta.x = Math.min(Math.max(delta.x, -this.md.firstWidth), this.md.secondWidth );
				}
				else
				{
					delta.y = Math.min(Math.max(delta.y, -this.md.firstHeight), this.md.secondHeight );
				}
			
				this.SplitterUpdateSize ( delta );
			}
			
		SplitterUpdateSize ( delta )
		{
			let ratio 	= parseFloat ( this.Splitter.dataset.ratio 	);
			
			if ( this.Orient == "V" )
			{
				let parentWidth		= this.Splitter.clientWidth;
				let parentLeft 		= parseInt 	 ( this.Splitter.offsetLeft	);
				let sepWidth 		= parseInt 	 ( this.Sep.offsetWidth 		);
			
				let newElemLeft = ( this.Collapsed >= 0 )? this.Sep.offsetLeft : ratio * parentWidth + parentLeft - sepWidth/2 + delta.x ;
			
				if ( (newElemLeft - parentLeft) > 0 && (newElemLeft - parentLeft) < (parentWidth-0) )
				{
					this.Sep.style.left	= newElemLeft + "px";
					
					this.NewRatio = ( newElemLeft - parentLeft  + sepWidth/2 ) / parentWidth;
					
					let newW1 = this.NewRatio * parentWidth - sepWidth / 2;
					let newW2 = parentWidth - newW1 - sepWidth;
									
					this.Pan_1.style.width		= newW1 + "px";
					this.Pan_2.style.width		= newW2 + "px";
					this.Pan_1.style.maxWidth 	= newW1 + "px";
					this.Pan_2.style.maxWidth 	= newW2 + "px";
				}
			}
			else
			{
				let collapsedHeight1 	= parseInt( this.Pan_1.dataset.collapsedheight );
				let collapsedHeight2 	= parseInt( this.Pan_2.dataset.collapsedheight );
				
				let parentHeight	= this.Splitter.clientHeight;
				let parentTop 		= parseInt 	 ( this.Splitter.offsetTop 		);
				let sepHeight 		= parseInt 	 ( this.Sep.offsetHeight 		);
			
				let newSepPos = ratio * parentHeight + parentTop - sepHeight/2 + delta.y;
				
				if ( this.Collapsed == 0 )	// Pan_1
				{
					newSepPos = parentTop + collapsedHeight1;
				}
				if ( this.Collapsed == 1 )	// Pan_2
				{
					newSepPos = parentTop + parentHeight - collapsedHeight1;
				}
				
				let newElemTop = newSepPos;
			
				if ( (newElemTop - parentTop) > 0 && (newElemTop - parentTop) < (parentHeight-0) )
				{
					this.Sep.style.top	= newElemTop + "px";
					
					this.NewRatio = ( newElemTop - parentTop + sepHeight/2 ) / parentHeight;
						
					let newH1 = this.NewRatio * parentHeight - sepHeight / 2;
					let newH2 = parentHeight - newH1 - sepHeight;
					
					this.Pan_1.style.height		= newH1 + "px";
					this.Pan_2.style.height		= newH2 + "px";
					this.Pan_1.style.maxHeight 	= newH1 + "px";
					this.Pan_2.style.maxHeight 	= newH2 + "px";
				}
			}
			if ( this.Timer != null )
				clearTimeout ( this.Timer );
			
			this.Timer = setTimeout ( this.Timeout.bind(this), 2000 );
		}

		Timeout ()
		{
			this.SaveUserCfg ( G_USE_ID );
		}

		GetJSON ()
		{
			let json = '';
			
			json += '{"'+this.ID+'":{"Ident": "'+this.ID+'", "Properties": {"Ratio": '+this.NewRatio+'}}}';
						
			return json;
		}

		LoadUserCfg ( userID )
		{
			let variable = 'SplitterConfiguration&sub_param_name='+this.ID;
			let elDTCfgJSON = LoadUserCfg ( userID, variable );

			let elDTCfg = "";
			let jsonOK = true;
			try { elDTCfg = JSON.parse ( elDTCfgJSON )
			} catch (e) { jsonOK = false; console.log ( e ); }

			if ( jsonOK )
			{
				if ( elDTCfg.Ident != undefined )
				{
					let delta = {x: 0, y: 0};
					this.Splitter.dataset.ratio = parseFloat ( elDTCfg.Properties.Ratio 	);
					this.SplitterUpdateSize ( delta );
				}
			}
			else
			{
				console.log ("Error : Bad JSON !!!" );
			}
		}

		SaveUserCfg ( userID )
		{
			let json = this.GetJSON ();

			SaveUserCfg ( userID, 'SplitterConfiguration', json );
		}
		
		OnSplitterSize ( entries )
		{
			var delta = {x: 0, y: 0};
			
			this.SplitterUpdateSize ( delta );
		}
		
		Collapse ( pan )
		{
			if ( this.Orient == "V" && ( pan != "L" && pan != "R" ) )
				return;
			
			if ( this.Orient == "H" && ( pan != "T" && pan != "B" ) )
				return;
		
			let panToProcess 	= null;
			let panSecondary 	= null;
			let toCollapse 		= -1;
			if ( pan == "L" || pan == "T" )
			{
				panToProcess 	= this.Pan_1;
				panSecondary	= this.Pan_2;
				toCollapse 		= 0;
			}
			else
			{
				panToProcess 	= this.Pan_2;
				panSecondary	= this.Pan_1;
				toCollapse 		= 1;
			}
			
			if ( panToProcess == null )
			{
				console.log ( "Error. panToProcess == null !!!" );
				return;
			}
		
					
			let expandedDiv = null;
			const expandedDivList = panToProcess.querySelectorAll("div.expanded");

			if ( expandedDivList.length > 0 )
				expandedDiv = expandedDivList [0];
			
			let collapsedDiv = null;
			const collapsedDivList = panToProcess.querySelectorAll("div.collapsed");
			if ( collapsedDivList.length > 0 )
				collapsedDiv = collapsedDivList [0];
		
			
			let collapseImage = panToProcess.getElementsByTagName('img')[0];
					
			let panchilds = panToProcess.children;
		
			if ( this.Orient == "V" )
			{
				let collapsedWidth 	= parseInt( panToProcess.dataset.collapsedwidth );
				let lastWidth 		= parseInt( panToProcess.dataset.lastwidth );
			
				let w1 = panToProcess.offsetWidth;
				let w2 = panSecondary.offsetWidth;
	
				let expandedDiv 	= null;
				let collapsedDiv 	= null;
				for ( let i=0; i<panchilds.length; i++ )
				{
					if ( panchilds [i].className.includes ( "expanded" ) == true )
						expandedDiv = panchilds [i];
					if ( panchilds [i].className.includes ( "collapsed" ) == true )
						collapsedDiv = panchilds [i];
				}
				
			
				if ( this.Collapsed >= 0 )
				{	
					let w = lastWidth;
		
					panToProcess.dataset.lastwidth = -1;
		
					collapsedDiv.setAttribute ( "style", "display: none !important;" );
					expandedDiv.setAttribute ( "style", "display: '';" );
			
					let newW1 = w;
					let newW2 = w2 - w + collapsedWidth;
		
					panToProcess.style.width	= newW1 + "px";
					panToProcess.style.maxWidth	= newW1 + "px";
					panSecondary.style.width	= newW2 + "px";
					panSecondary.style.maxWidth	= newW2 + "px";
					
					this.Collapsed = -1;
				}
				else
				{
					collapsedDiv.setAttribute ( "style", "display: '';" );
					expandedDiv.setAttribute ( "style", "display: none !important;" );
					
	
					panToProcess.dataset.lastwidth = w1;
					let newW1 = collapsedWidth;
					let newW2 = w2 + w1 - newW1;

					panToProcess.style.width	= newW1 + "px";
					panToProcess.style.maxWidth	= newW1 + "px";
					panSecondary.style.width	= newW2 + "px";
					panSecondary.style.maxWidth	= newW2 + "px";
		
					this.Collapsed = toCollapse;
				}
			}
			else	// Orient H
			{
				let collapsedHeight 	= parseInt( panToProcess.dataset.collapsedheight );
				let lastHeight	 		= parseInt( panToProcess.dataset.lastheight );
			
				let h1 = panToProcess.offsetHeight;
				let h2 = panSecondary.offsetHeight;
				
				let newH1 = h1;
				let newH2 = h2;
				
				if ( this.Collapsed >= 0 )
				{
					panToProcess.dataset.lastheight = -1;
					
					newH1 = lastHeight;
					newH2 = h2 - newH1 + h1; 
					
					this.Collapsed = -1;
					if ( collapseImage != null )
						collapseImage.style.transform = "";
					
					if ( expandedDiv != null )
					{
						expandedDiv.style.display = expandedDiv.dataset.lastdisplay;
					}
				}
				else
				{
					panToProcess.dataset.lastheight = h1;
					
					newH1 = collapsedHeight;
					newH2 = h2 + h1 - newH1; 
					this.Collapsed = toCollapse;
					
					if ( collapseImage != null )
						collapseImage.style.transform = "rotate(180deg)";
					if ( expandedDiv != null )
					{
						expandedDiv.dataset.lastdisplay = expandedDiv.style.display;
						expandedDiv.style.display = "none";
					}
				}
				
				panToProcess.style.height		= newH1 + "px";
				panToProcess.style.maxHeight	= newH1 + "px";
				panSecondary.style.height		= newH2 + "px";
				panSecondary.style.maxHeight	= newH2 + "px";
			}				
		}
	}
	
	
	function go(c)
	{
		if ( !c.data.replace(/\s/g,'') )
		{
			c.parentNode.removeChild(c);
		}
	}
		
	function clean(d)
	{
		var bal=d.getElementsByTagName('*');

		for(i=0;i<bal.length;i++)
		{
			a = bal[i].previousSibling;
			
			if ( a && a.nodeType==3 )
				go(a);
			
			b = bal[i].nextSibling;
			if ( b && b.nodeType==3 )
				go(b);
		}
		return d;
	}
		
	function getxhr()
	{
		var xhr = null;

		if(window.XMLHttpRequest) // Firefox et autres
		{
			xhr = new XMLHttpRequest();
		}
		else 
			if(window.ActiveXObject)
			{ // Internet Explorer
				try {
					xhr = new ActiveXObject("Msxml2.XMLHTTP");
				} catch (e) 
					{
						xhr = new ActiveXObject("Microsoft.XMLHTTP");
					}
			}
			else 
			{ // XMLHttpRequest non supportÃ¯Â¿Â½ par le navigateur
				alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
				xhr = false;
			}
		
		return xhr;
	}
		
	function loadXMLDoc(theURL)
    {
        if (window.XMLHttpRequest)
        {// code for IE7+, Firefox, Chrome, Opera, Safari, SeaMonkey
            xmlhttp=new XMLHttpRequest();
        }
        else
        {// code for IE6, IE5
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange=function()
        {
            if (xmlhttp.readyState==4 && xmlhttp.status==200)
            {
                alert(xmlhttp.responseText);
            }
        }
        xmlhttp.open("GET", theURL, false);
        xmlhttp.send();
    }

		
	function GetSyncData ( url )
	{
		let xhra = getxhr();
		
		xhra.open ('GET', url, false );
		xhra.send ();
		
		if ( xhra.status == 200 )  
			return ( clean(xhra.responseXML.documentElement) );
		else
			return null;
	}
	
	function PostSyncData ( url, param, contentType )
	{
		let xhra = getxhr();
		
		xhra.open ( "POST", url, false ); 				// Synchrone
		xhra.setRequestHeader('Content-Type', contentType );
		
		xhra.send ( param );
		
		if ( xhra.status == 200 ) 
		{
			let retval = xhra.responseText;
			return retval;
		}
		else
			return null;
	}

	function PostASyncData ( url, param, contentType, okFunction, errorFunction )
	{
		let xhra = getxhr();

		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 ) 
			{		
				let retval = xhra.responseText;
				okFunction ( retval );
			}
			else
			{
				errorFunction ();
			}
		}
		
		xhra.open ( "POST", url, true ); 				// Asynchrone
		xhra.withCredentials = true;
		if ( contentType != null  )
			xhra.setRequestHeader('Content-Type', contentType );
		
		xhra.send ( param );
	}


		


	
	
	var myLayout = null;
		
	function RenderPage ( url, container_id )
	{
		var http;

		if ( window.XMLHttpRequest )
		{	
			try { http = new XMLHttpRequest(); }
			catch(e) {}
		}
			else
			{
				if (window.ActiveXObject)
				{
					try { http = new ActiveXObject("Msxml2.XMLHTTP"); }
					catch(e)
					{
						try { http = new ActiveXObject("Microsoft.XMLHTTP");  }
    			        catch(e) {}
					}	
				}
			}

			if ( !http )
			{
				alert('\n\nSorry, unable to open a connection to the server.');

				return false;
			}

			var target = document.querySelector( '#'+container_id );

			// create an observer instance
			var observer = new MutationObserver
			( function ( mutations )
				{
					mutations.forEach
					(
						function ( mutation )
						{
							// later, you can stop observing
							// observer.disconnect();
							// var newElement = document.getElementById("page_content");
							// myLayout = null;
							// var scripts = newElement.getElementsByTagName("script");
							//   for (var i = 0; i < scripts.length; ++i) {
							//     var script = scripts[i];
							//     eval(script.innerHTML);
							//   }
						}
					);
				}
			);

			// configuration of the observer:
			//  var config = {childList: true };

			// pass in the target node, as well as the observer options
			//    observer.observe(target, config);

			http.onreadystatechange = function(){
				if (http.readyState == 4) 
				{
					if(http.status == 200) 
					{
						if(http.responseText)
						{
							if(myLayout != null)
							{
								myLayout.unload();
							}
							myLayout = null;
							window.myLayout = null;
							var node = document.getElementById ( container_id );
							if ( node == null )
							{
								console.log ( "node is null !!!" );
							}
							var last;
							while (last = node.lastChild) 
								node.removeChild(last);
							node.innerHTML = http.responseText;
							var scripts = node.getElementsByTagName("script");
							for (var i = 0; i < scripts.length; ++i) 
							{
								var script = scripts[i];
								eval ( script.innerHTML );
							}
							var links = node.getElementsByTagName("link");
							for(var i = 0; i < links.length; ++i) 
							{
								var link = links[i];
								if(link.type=='text/css')
								{
									var style = document.createElement('style');
									style.type = 'text/css';
									document.getElementsByTagName('head')[0].appendChild(style);
									var xmlhttp=false;
									if(xmlhttp==false){  }
									else {  }
								}

								//eval(link);
							}
							dispatchEvent(new Event('load'));
							myLayout = window.myLayout;
							dispatchEvent(new Event('resize'));
						}
					}
				}
			};
			
			http.open('GET',url, true);
			http.send(null);
	}
		
	

	function FillStaffList ( elementToFill )
	{
		var xhra= getxhr();
			
		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 )  
			{
				let idcSelect 		= document.getElementById ( elementToFill );
				let reponse			= clean(xhra.responseXML.documentElement);
				let users		 	= reponse.getElementsByTagName ( 'user' );
				for ( var i=0; i<users.length; i++ )
				{
					let option_elem = document.createElement('option');
  
					option_elem.value 		= users.item (i).getAttribute ( "id" 	);
					option_elem.textContent = users.item (i).getAttribute ( "name" 	)
					
					idcSelect.appendChild ( option_elem );
  				}	
			}
		};

		let url = "SubFW/database/staff/get_staff_list.php";
			
		xhra.open ('GET', url, true );
		xhra.send ();
	}

	function FillDepartmentsList ( idSelect, ins_id, add_all )
	{
		if ( add_all == undefined )
			add_all = false;
		
		let lastSeparator = "";

		$('#' + idSelect ).empty();
		
		var xhra= getxhr();
			
		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 )  
			{
				let idcSelect 		= document.getElementById ( idSelect );
				let reponse			= clean(xhra.responseXML.documentElement);
				let departments	 	= reponse.getElementsByTagName ( 'department' );
				if ( add_all = true )
				{
					let option_elem = document.createElement('option');
					option_elem.value 		= -1;
					option_elem.textContent = Translate ('All');
  
					idcSelect.appendChild ( option_elem );				
				}
				
				for ( let i=0; i<departments.length; i++ )
				{
					let inst_id			= departments.item (i).getAttribute ( "inst_id" 	);
					let institution		= departments.item (i).getAttribute ( "institution" );
					let id	 			= departments.item (i).getAttribute ( "id" 	);
					let department		= departments.item (i).getAttribute ( "department" 	);
					let removed			= departments.item (i).getAttribute ( "removed" 	);
					
					if ( inst_id != -1 && id != -1 )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= id;
						option_elem.textContent = (ins_id==-1)? institution + " - " + department : department;
  
						idcSelect.appendChild ( option_elem );				
					}
				}
			}
		};

		let url = G_ServerFolder+"/eoQUAL/SubFW/database/common/get_departments.php?ins_id=" + ins_id;
		xhra.open ('GET', url, false );
		xhra.send ();
	}

	function FillDevicesList ( idSelect, dep_id )
	{
		if ( dep_id == undefined )
			dep_id = -1;
		
		let lastSeparator = "";

		$('#' + idSelect ).empty();
		
		var xhra= getxhr();
			
		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 )  
			{
				let idcSelect 		= document.getElementById ( idSelect );
				let reponse			= clean(xhra.responseXML.documentElement);
				let devices		 	= reponse.getElementsByTagName ( 'device' );
				
				for ( let i=0; i<devices.length; i++ )
				{
					let id		= devices.item (i).getAttribute ( "id" 	);
					let device	= devices.item (i).getAttribute ( "device" );
										
					if ( id != -1 )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= id;
						option_elem.textContent = device;
  
						idcSelect.appendChild ( option_elem );				
					}
				}
			}
		};

		let url = G_ServerFolder+"/eoQUAL/SubFW/database/common/get_devices.php?dep_id=" + dep_id;
		xhra.open ('GET', url, false );
		xhra.send ();
	}

	function FillStatusList ( idSelect, type )
	{
		console.log ("FillStatusList...");
		$.post (
				G_ServerFolder+"/eoQUAL/SubFW/database/common/get_status.php",
				{
					type: type
				},
				function (data)
				{
					let idcSelect 		= document.getElementById ( idSelect );
					for ( let i=0; i<data.results.length; i++ )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= data.results[i].id;
						option_elem.textContent = Translate(data.results [i].name);
  
						idcSelect.appendChild ( option_elem );	
					}
				}
			);
	}

	function FillDocumentTypeList ( idSelect )
	{
		$.post (
				"SubFW/database/document/get_document_type1.php",
				{
				},
				function (data)
				{
					let idcSelect 		= document.getElementById ( idSelect );
					for ( let i=0; i<data.results.length; i++ )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= data.results[i].type;
						option_elem.textContent = Translate(data.results [i].name);
  
						idcSelect.appendChild ( option_elem );	
					}
				}
			);
	}

	function FillDeviceTypeList ( idSelect )
	{
		$.post (
				G_ServerFolder+"/eoQUAL/SubFW/database/common/get_device_type.php",
				{
					// type: type
				},
				function (data)
				{
					let idcSelect 		= document.getElementById ( idSelect );
					for ( let i=0; i<data.results.length; i++ )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= data.results[i].id;
						option_elem.textContent = Translate(data.results [i].name);
  
						idcSelect.appendChild ( option_elem );	
					}
				}
			);
	}

	function FillDocumentType ( idSelect, defaultValue )
	{
		$.post (
				G_ServerFolder+"/eoQUAL/SubFW/database/common/get_document_type.php",
				{
				},
				function (data)
				{
					let idcSelect 		= document.getElementById ( idSelect );
					for ( let i=0; i<data.results.length; i++ )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= data.results[i].id;
						option_elem.textContent = data.results [i].name;

						if ( defaultValue != undefined )
							option_elem.selected = true;
  
						idcSelect.appendChild ( option_elem );	
					}
				}
			);
	}

	function FillInstitutionsList ( idSelect )
	{
		var xhra= getxhr();
			
		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 )  
			{
				let idcSelect 		= document.getElementById ( idSelect );
				let reponse			= clean(xhra.responseXML.documentElement);
				let institutions	= reponse.getElementsByTagName ( 'institution' );
				
				for ( let i=0; i<institutions.length; i++ )
				{
					let id			= institutions.item (i).getAttribute ( "id" 	);
					let name		= institutions.item (i).getAttribute ( "name" );

					if ( id != -1 )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= id;
						option_elem.textContent = name;
  
						idcSelect.appendChild ( option_elem );				
					}
				}
			}
		};

		let url = G_ServerFolder + "/eoQUAL/SubFW/database/common/get_institutions.php";
		xhra.open ('GET', url, false );
		xhra.send ();
	}

	function FillSexList ( idSelect )
	{
		var xhra= getxhr();
			
		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 )  
			{
				let idcSelect 		= document.getElementById ( idSelect );
				let reponse			= clean(xhra.responseXML.documentElement);
				let list			= reponse.getElementsByTagName ( 'sex' );
				
				for ( let i=0; i<list.length; i++ )
				{
					let id			= list.item (i).getAttribute ( "id" 	);
					let label		= list.item (i).getAttribute ( "label" );

					if ( id != -1 )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= id;
						option_elem.textContent = Translate ( label );
  
						idcSelect.appendChild ( option_elem );				
					}
				}
			}
		};

		let url = "SubFW/database/common/get_sexlist.php";
		xhra.open ('GET', url, false );
		xhra.send ();
	}

	function FillAgeList ( idSelect )
	{
		var xhra= getxhr();
			
		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 )  
			{
				let idcSelect 		= document.getElementById ( idSelect );
				let reponse			= clean(xhra.responseXML.documentElement);
				let list		= reponse.getElementsByTagName ( 'age' );

				for ( let i=0; i<list.length; i++ )
				{
					let id			= list.item (i).getAttribute ( "id" 	);
					let label		= list.item (i).getAttribute ( "label" );

					if ( id != -1 )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= id;
						option_elem.textContent = Translate ( label );
  
						idcSelect.appendChild ( option_elem );				
					}
				}
			}
		};

		let url = "SubFW/database/common/get_agelist.php";

		xhra.open ('GET', url, false );
		xhra.send ();
	}

	function FillStaffRoleList ( idSelect )
	{
		$.post (
				"SubFW/database/common/get_staffrolelist.php",
				{
				},
				function (data)
				{
					let idcSelect 		= document.getElementById ( idSelect );
					for ( let i=0; i<data.results.length; i++ )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= data.results[i].id;
						option_elem.textContent = data.results [i].name;
  
						idcSelect.appendChild ( option_elem );	
					}
				}
			);
	}

	function FillCivilityList ( idSelect )
	{
		$.post (
				"SubFW/database/common/get_civilitylist.php",
				{
				},
				function (data)
				{
					let idcSelect 		= document.getElementById ( idSelect );
					for ( let i=0; i<data.results.length; i++ )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= data.results[i].id;
						option_elem.textContent = Translate(data.results [i].name);
  
						idcSelect.appendChild ( option_elem );	
					}
				}
			);
	}


	function FillLoginRoleList ( idSelect )
	{
		$.post (
				"SubFW/database/common/get_loginrolelist.php",
				{
				},
				function (data)
				{
					let idcSelect 		= document.getElementById ( idSelect );
					for ( let i=0; i<data.results.length; i++ )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= data.results[i].id;
						option_elem.textContent = data.results [i].name;
  
						idcSelect.appendChild ( option_elem );	
					}
				}
			);
	}

	function FillValueList ( idSelect, scope )
	{
		$.post (
				"SubFW/database/common/get_enumlistvalue.php",
				{
					scope: scope
				},
				function (data)
				{
					let idcSelect 		= document.getElementById ( idSelect );
					for ( let i=0; i<data.results.length; i++ )
					{
						let option_elem = document.createElement('option');
  
						option_elem.value 		= data.results[i].value;
						option_elem.textContent = Translate (data.results [i].name);
  
						idcSelect.appendChild ( option_elem );	
					}
				}
			);
	}
	
	
	
	function RightClick ( e, idcMenu )
	{
		let index = e.currentTarget.dataset.index;
		
		e.preventDefault();
		
		HideRightMenus ();
		
		var menu = document.getElementById ( idcMenu );
			
		menu.dataset.index 	= index;
		
		let posX = e.pageX + "px";
		let posY = e.pageY + "px";
		
		$('#'+idcMenu).css ( { left: posX, top: posY } );
		$('#'+idcMenu).show ();
	}
	
	function DoubleQuote ( str )
	{
		if ( str != null )
			return str.replaceAll ( "'", "''" );
		else
			return "";
	}
	
	function DICOMDate2FmtDate ( date )
	{
		if ( date != null && date.length>0 )
		{
			var year 	= date.substring ( 0, 4 );
			var month	= date.substring ( 4, 6 );
			var day 	= date.substring ( 6, 8 );
			
			return day + "/" + month + "/" + year;
		}

		// return "01/01/1900";
		return "";
		
	}
		
	function DICOMDate2StdDate ( date )
	{
		if ( date != undefined && date.length == 8 )
		{
			var year 	= date.substring ( 0, 4 );
			var month	= date.substring ( 4, 6 );
			var day 	= date.substring ( 6, 8 );

			return year + "-" + month + "-" + day;
		}
		else
			return "";
	}
	
	function DICOMDate2StdDateFR ( date )
	{

		if ( date != undefined && date.length == 8 )
		{
			var year 	= date.substring ( 0, 4 );
			var month	= date.substring ( 4, 6 );
			var day 	= date.substring ( 6, 8 );

			return day + "/" + month + "/" + year;
		}
		else
			return "";
	}

	function DBDate2StdDateFR ( date )
	{
		if ( date != undefined && date.length >= 10 )
		{
			var year 	= date.substring ( 0, 4 );
			var month	= date.substring ( 5, 7 );
			var day 	= date.substring ( 8, 10 );

			return day + "/" + month + "/" + year;
		}
		else
			return "";
	}
	
	function DICOMDate2JSDate ( date )
	{
		let year 	= parseInt ( date.substring ( 0, 4 ) );
		let month	= parseInt ( date.substring ( 4, 6 ) ) - 1;
		let day 	= parseInt ( date.substring ( 6, 8 ) );

		return new Date ( year, month, day );
	}
	
	function StdDate2DICOMDate ( date )
	{
		let year 	= date.substring ( 0, 4 );
		let month	= date.substring ( 5, 7 );
		let day 	= date.substring ( 8, 10 );

		return year + month + day;
	}
	
	function StdDateFR2DICOMDate ( date )
	{
		let day 	= date.substring ( 0, 2 );
		let month	= date.substring ( 3, 5 );
		let year 	= date.substring ( 6, 10 );

		return year + month + day;
	}
		
	
					
	function DICOMTime2FmtTime ( time )
	{
		let hour 	= time.substring ( 0, 2 );
		let min		= time.substring ( 2, 4 );
		let sec 	= time.substring ( 4, 6 );

		// return hour + ":" + min + ":" + sec;
		return hour + ":" + min;
	}
	
	function FmtTime2DICOMTime ( time )
	{
		let hour 	= time.substring ( 0, 2 );
		let min		= time.substring ( 3, 5 );
		let sec 	= ( time.length == 8 )? time.substring ( 6, 8 ) : "00";

		return hour + min + sec;
	}
	
	function GetCurrentDICOMDate ()
	{
		let today = new Date ();
		
		return today.yyyymmdd ();
	}
	
	function GetCurrentDICOMDateTime ()
	{
		let today = new Date ();
		
		return today.yyyymmdd () + today.hhmmss ();
	}
	
	function GetCurrentDate ( format )
	{
		if ( format=='fr')
			return DICOMDate2StdDateFR ( GetCurrentDICOMDate () );
		else
			return DICOMDate2StdDate ( GetCurrentDICOMDate () );
	}
	

	
	function SaveUserCfg ( use_id, param_name, value )
	{
		// console.log ( "SaveUserCfg..." );

		var xhra= getxhr();
			
		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 )  
			{
				var  response = xhra.responseText;
				if ( response == -1 )
					alert ( "Error during update 1 !!!" );
				else
				{
				}
			}
		}
		
		let param = "use_id=" + use_id + "&param_name=" + param_name + "&value=" + value;
		xhra.open ( "POST", G_ServerFolder+"/eoQUAL/SubFW/database/SaveUserCfg.php", true ); 				// Asynchrone
		xhra.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		xhra.send(encodeURI(param));
	}
	
	function LoadUserCfg ( use_id, param_name,  )
	{
		let value = -1;
		
		var xhra= getxhr();
			
		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 )  
			{
				var  response = xhra.responseText;
								
				reponse = clean(xhra.responseXML.documentElement);
				
				var cfgs 	= reponse.getElementsByTagName('cfg') ;
				if ( cfgs.length != 1 )
				{
					alert ( "Error during loading ( nb elem : "+cfgs.length+", param_name : "+param_name+") !!!" );
				}
				else
				{
					value = cfgs.item(0).getAttributeNode("data").value;
				}
			}
		}
		
		let url = G_ServerFolder+"/eoQUAL/SubFW/database/LoadUserCfg.php?use_id=" + use_id + "&param_name=" + param_name;
			
		xhra.open ('POST', url, false );
		xhra.send ();
		
		return value;
	}
	
	
	function DatePickerHandler (e) 
	{
		if ( e.inputType == 'insertText' )
		{
			let vv = e.target.value;
			vv = vv.slice ( 0, -1 );
				
			if ( e.data != '/' && vv.length < 10 )
			{
				let val = '';
					
				if ( parseInt (vv.length) == 1 || parseInt (vv.length) == 4 )
					val = vv + e.data + '/';
				else
				{
					if ( parseInt (vv.length) == 2 || parseInt (vv.length) == 5 )
						val = vv + '/' + e.data;
					else
						val = vv + e.data;
				}
					
				if ( val.length == 3 )
				{
					let valNum = parseInt ( val.substring (0,2) );
					if ( valNum <= 0 )	val = '01/';
					if ( valNum > 31 )	val = '31/';
				}
					
				if ( val.length == 6 )
				{
					let tmp = val.substring (0,3);
					let valNum = parseInt ( val.substring (3,5) );
					if ( valNum <= 0 )	val = tmp + '01/';
					if ( valNum > 12 )	val = tmp + '12/';
				}
					
				e.target.value = val;
			}
			else
				e.target.value = vv;
		}
	}
	
	
	
	function IntegerToRGB (  val ) 
	{
		let tmp = val;
		
		let r = 0xFF & tmp;
		
		tmp >>= 8;
		let g = 0xFF & tmp;
		
		tmp >>= 8;
		let b = 0xFF & tmp;
		
		let rh = (r<16)? '0'+r.toString(16) : r.toString(16);
		let gh = (g<16)? '0'+g.toString(16) : g.toString(16);
		let bh = (b<16)? '0'+b.toString(16) : b.toString(16);
		
		let ret = '#'+rh+gh+bh;
		
		return ret;
	}

	
	

	function InitTagInstDepCBList ( cbElem )
	{
		let lastSeparator = "";
		
		var xhra= getxhr();
			
		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 )  
			{
				let reponse			= clean(xhra.responseXML.documentElement);
				let departments	 	= reponse.getElementsByTagName ( 'department' );
				
				cbElem.AddTextSeparator ( "Institution" );

				
				for ( let i=0; i<departments.length; i++ )
				{
					let inst_id			= departments.item (i).getAttribute ( "inst_id" 	);
					let institution		= departments.item (i).getAttribute ( "institution" );
					let tag_id			= departments.item (i).getAttribute ( "tag_id" 	);
					let department		= departments.item (i).getAttribute ( "department" 	);
										
					if ( inst_id != '-1' && lastSeparator != inst_id && department=='' )
					{
						cbElem.AddItem ( -1, tag_id, institution );
						lastSeparator = inst_id;
					}
				}

				lastSeparator = "";

				for ( let i=0; i<departments.length; i++ )
				{
					let inst_id			= departments.item (i).getAttribute ( "inst_id" 	);
					let institution		= departments.item (i).getAttribute ( "institution" );
					let tag_id 			= departments.item (i).getAttribute ( "tag_id" 	);
					let department		= departments.item (i).getAttribute ( "department" 	);
						
					if ( inst_id !='-1' && department != '' )				
					{
						if ( lastSeparator != inst_id )
						{
							cbElem.AddTextSeparator ( institution );
							lastSeparator = inst_id;
						}
					
						cbElem.AddItem ( inst_id, tag_id, department, institution );
					}
				}
			}
		};

		let url = G_ServerFolder + "/eoQUAL/SubFW/database/common/get_taginstdep.php?ins_id=-1";
		xhra.open ('GET', url, false );
		xhra.send ();
	}

	function InitJobUserCBList ( cbElem )
	{
		/*
		let lastSeparator = "";
		
		var xhra= getxhr();
			
		xhra.onloadend = function f()
		{
			if ( xhra.readyState == 4 && xhra.status == 200 )  
			{
				let reponse			= clean(xhra.responseXML.documentElement);
				let departments	 	= reponse.getElementsByTagName ( 'department' );
				
				cbElem.AddTextSeparator ( "Institution" );

				
				for ( let i=0; i<departments.length; i++ )
				{
					let inst_id			= departments.item (i).getAttribute ( "inst_id" 	);
					let institution		= departments.item (i).getAttribute ( "institution" );
					let tag_id			= departments.item (i).getAttribute ( "tag_id" 	);
					let department		= departments.item (i).getAttribute ( "department" 	);
										
					if ( inst_id != '-1' && lastSeparator != inst_id && department=='' )
					{
						cbElem.AddItem ( -1, tag_id, institution );
						lastSeparator = inst_id;
					}
				}

				lastSeparator = "";

				for ( let i=0; i<departments.length; i++ )
				{
					let inst_id			= departments.item (i).getAttribute ( "inst_id" 	);
					let institution		= departments.item (i).getAttribute ( "institution" );
					let tag_id 			= departments.item (i).getAttribute ( "tag_id" 	);
					let department		= departments.item (i).getAttribute ( "department" 	);
						
					if ( inst_id !='-1' && department != '' )				
					{
						if ( lastSeparator != inst_id )
						{
							cbElem.AddTextSeparator ( institution );
							lastSeparator = inst_id;
						}
					
						cbElem.AddItem ( inst_id, tag_id, department, institution );
					}
				}
			}
		};

		let url = G_ServerFolder + "/eoQUAL/SubFW/database/common/get_jobuserlist.php?ins_id=-1";
		xhra.open ('GET', url, false );
		xhra.send ();
		*/

		$.post (
				"SubFW/database/common/get_jobuserlist.php",
				{
					// dep_id: dep_id
				},
				function (data)
				{
					let lastSeparator = "";

					cbElem.AddTextSeparator ( "Fonctions" );

					for ( let i=0; i<data.results.length; i++ )
					{
						let staff_id 		= data.results[i].staff_id;
						let staff_role_id 	= data.results[i].staff_role_id;
						let role_name 		= data.results[i].role_name;

						if ( staff_role_id != null && lastSeparator != staff_role_id )
						{
							cbElem.AddItem ( -1, staff_role_id, role_name );
							lastSeparator = staff_role_id;
						}
					}

					lastSeparator = "";

					for ( let i=0; i<data.results.length; i++ )
					{
						let staff_id 		= data.results[i].staff_id;
						let staff_role_id 	= data.results[i].staff_role_id;
						let fullname  		= data.results[i].lastname.toUpperCase() + ' ' + data.results[i].firstname;
						let role_name 		= data.results[i].role_name;

						if ( staff_id != null )
						{
							if ( lastSeparator != staff_role_id )
							{
								cbElem.AddTextSeparator ( role_name );
								lastSeparator = staff_role_id;
							}

							cbElem.AddItem ( staff_role_id, staff_id, fullname, role_name );
						}
					}
				}
			);
	}


	function FillRISUserList ( idSelect )
	{
		var request = $.ajax ({
        	url: 		G_ServerFolder + "/eoQUAL/SubFW/database/common/statistic/get_ris_user.php",
        	type: 		"post",
        	dataType: 	"json"
    		}
    	)
		.done ( function ( data ) 
				{
					let idcSelect 		= document.getElementById ( idSelect );
					for( let i=0; i<data.users.length; i++ )
					{
						let use_id 	= data.users [i].use_id;
						let name 	= data.users [i].name;
						if ( use_id != -1 )
						{
							let option_elem = document.createElement('option');
  
							option_elem.value 		= use_id;
							option_elem.textContent = name;
  
							idcSelect.appendChild ( option_elem );				
						}
					}
				} )
    	.fail ( function () {console.log ("Error : Unable to get RIS users list !!!");} );
    }
	


	function FillRISModalityList ( idSelect )
	{
		var request = $.ajax ({
        	url: 		G_ServerFolder + "/eoQUAL/SubFW/database/common/statistic/get_ris_modality.php",
        	type: 		"post",
        	dataType: 	"json"
    		}
    	)
		.done ( function ( data ) 
				{
					let idcSelect 		= document.getElementById ( idSelect );
					for( let i=0; i<data.users.length; i++ )
					{
						let mod_id 	= data.users [i].mod_id;
						let name 	= data.users [i].name;
						if ( mod_id != -1 )
						{
							let option_elem = document.createElement('option');
  
							option_elem.value 		= mod_id;
							option_elem.textContent = name;
  
							idcSelect.appendChild ( option_elem );				
						}
					}
				} )
    	.fail ( function () {console.log ("Error : Unable to get RIS modalities list !!!");} );
    }






    

	function GetFilesInServerFolder ( folder, withExtension )
	{
		let filesList = new Array ();
		
		$.ajax (
		{
			url : "./SubFW/database/common/get_files_in_folder.php",
			data : {
				folder: '/eoQUALBootstrap/eoQUAL/i18n'
			},
			type : 'post',
			async : false,
			dataType: 'json',
			success :  function (data) 
				{
					for ( let i=0; i<data.fileslist.length; i++ )
					{
						let fileName = data.fileslist[i];
						
						if ( withExtension == false )
							fileName = fileName.replace(/\.[^/.]+$/, "");

						if ( data.fileslist [i] != '.' && data.fileslist [i] != '..' )
							filesList.push ( fileName );
					}
				}
			});

		return filesList;
	}


	function AddLanguages ()
	{
		let navLang = navigator.language.substr(0,2);
		let filesList = GetFilesInServerFolder ( '/eoQUALBootstrap/eoQUAL/i18n/', false );

		let tmp = '';
		for ( let i=0; i<filesList.length; i++ )
		{
			if ( navLang == filesList [i] )
				CurrentLanguage = navLang;

			tmp += '<div class="col-auto">';
			tmp +=		'<img id="IdcLanguageImg_'+filesList [i]+'" src="SubFW/bmp/lang-'+filesList [i]+'.png" class="language imgclickable d-inline m-0 p-0 ps-1 pe-1" height="26" data-lang="fr" onclick="switchLanguage ( \''+filesList [i]+'\' );"/>';
			tmp +=	'</div>';
		}

		document.getElementById ('IdcLanguageDiv').innerHTML = tmp;
	}



	function Logout ()
	{
		sessionStorage.setItem ( 'MainPageInitialized', 		false  );
			
		IdcUserDiv.style.display				= "none";
		IdcMainDiv.style.display				= "block";
			
		G_USE_ID 		= -1;
		G_UserAccess 	= null;

		PostASyncData ( "SubFW/database/Logout.php", "", 'application/x-www-form-urlencoded' );
	}
		
	function OnUserLogout ()
	{
		MsgYesNo ( Translate ( "Do you want to close your session ?" ), Logout );
	}
		
	function OnUserLogin ()
	{
		$('#IdcUserAccess').modal('show');
	}
		
		
	function OnAuthorizedAccess ()
	{
		$('#IdcAuthorizedAccess').modal ('show');
		InitAuthorizedAccessDlg ();
	}

	function OnHelpHTML ()
	{
	}

		function OnHelpPDF ()
		{
			console.log ( "lang : " + navigator.language );
			window.open ( "Doc/"+CurrentLanguage+"/PDF/eoQUAL.pdf",  "_blank" );
		}

		function OnLeftTabWidth ()
		{
			LeftTabs.SwitchMode ();

			switchLanguage ( CurrentLanguage );
		}
		
			
		
		
		// ======================================================================================
		// User access
		
		function AllowedUserAccess ( use_id, userFullName )
		{
			G_USE_ID 		= use_id;
			G_UserFullName	= userFullName;

			localStorage.setItem("UseID", use_id);
			
			InitMainPage ();
			
			IdcMainDiv.style.display				= "none";
			IdcUserDiv.style.display				= "block";
			
			document.getElementById ( "IdcUserName"			).innerHTML = userFullName;
			
			$('#IdcUserAccess').modal('hide');
		}
		
		function DeniedUserAccess ()
		{
			IdcUserErrorLogin.style.display ="block";
			IdcUserIdent.value = '';
			IdcUserPassword.value = ''
		}
		
		function OnCheckAccess ( data )
 		{
			let error 	= JSON.parse ( data ) ['error'];
			if ( error != undefined )
			{
				DeniedUserAccess ();
			}
			else
			{
				let id 			= JSON.parse ( data ) ['id'];		
				let lastname 	= JSON.parse ( data ) ['lastname'];	
				let firstname 	= JSON.parse ( data ) ['firstname'];
				G_UserAccess	= JSON.parse ( data ) ['access'];

				AllowedUserAccess ( id, lastname + ' ' + firstname );
			}
		}

		function OnCheckAccessError ()
 		{
 			DeniedUserAccess ();
		}
			
		function CheckUserAccess ()
		{
			console.log ( "CheckUserAccess..." );
			
			let userIdent 		= IdcUserIdent.value;
			let userPassword 	= IdcUserPassword.value;
			// let userIdent 		= 'ximeo';
			// let userPassword 	= 'ximeo';

			IdcUserIdent.value		= '';
			IdcUserPassword.value 	= '';
			IdcUserErrorLogin.style.display ="none";

			PostASyncData ( "SubFW/database/CheckUserAccess.php", "username="+userIdent+"&password="+userPassword, 'application/x-www-form-urlencoded', OnCheckAccess, OnCheckAccessError );
		}

		function CloseLoginDlg ()
		{
			IdcUserIdent.value		= '';
			IdcUserPassword.value 	= '';
			IdcUserErrorLogin.style.display ="none";

			$('#IdcUserAccess').modal('hide');
		}

		async function CreateDOCX () 
		{
    		const { Document, Packer, Paragraph, TextRun } = docx;

    		const doc = new Document({
      			sections: [
        			{
          				children: [
            				new Paragraph({
              					children: [
                					// new TextRun("Ceci est un document Word généré dynamiquement."),
              					],
            				}),
          				],
        			},
      			],
    		});

    		const blob = await Packer.toBlob(doc);

    		const file = new File([blob], "document.docx", {
      			type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
    		});

    		return file;
  		}


  		function CreateXLSX() 
  		{
    		return new Promise((resolve) => {
    			/*
      			const data = [
        			["Name", "Age", "Email"],
        			["Name 1", 30, "n1@example.com"],
        			["Name 2", 25, "n2@example.com"]
      			];
      			*/

      			const data = []

      			const ws = XLSX.utils.aoa_to_sheet(data);

      			const wb = XLSX.utils.book_new();
      			XLSX.utils.book_append_sheet(wb, ws, "Feuille1");

      			const wbout = XLSX.write(wb, { bookType: 'xlsx', type: 'array' });

      			const blob = new Blob([wbout], {
        			type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
      			});

      			const file = new File([blob], "tableau.xlsx", {
        			type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
      			});

      			resolve(file);
    		});
  		}


  		function SendDocumentReminder ( doc_id, staff_id, field_to_update )
		{
			console.log ( "SendDocumentReminder ("+doc_id+", "+staff_id+")...");

			$.post (
				"SubFW/database/document/send_reminder.php",
				{
					doc_id: 			doc_id,
					staff_member_id: 	staff_id
				},
				function (data)
				{
					console.log ( "Status : " + data.status );
					console.log ( "Last reminder : " + data.results[0].last_reminder );

					$('#'+field_to_update).html ( Translate("Reminder today.") ) ;
				}
			);
		}

		function SendTaskReminder ( task_id, staff_id, field_to_update, reminder_staff_id )
		{
			console.log ( "SendTaskReminder ("+task_id+", "+staff_id+")...");

			$.post (
				"SubFW/database/task/send_reminder.php",
				{
					task_id: 			task_id,
					staff_member_id: 	staff_id,
					reminder_staff_id: 	reminder_staff_id
				},
				function (data)
				{
					console.log ( "Status : " + data.status );
					console.log ( "Last reminder : " + data.results[0].last_reminder );

					$('#'+field_to_update).html ( Translate("Reminder today.") ) ;
				}
			);
		}




		function retrieve_selectedtagid ( sol1, sol2 )
    	{
    		let ret = {};
      		let idlist1 = ''; //nothing selected
      		let idlist2 = '';
      		let valueList = sol1.GetSelection2();

      		if(valueList.length)
        		idlist1 = valueList[0];

      		for ( var j = 1; j < valueList.length; j++ )
      		{
       	 		idlist1 += ','+valueList[j];
      		}

      		if ( sol2 != undefined )
      			valueList = sol2.GetSelection2();
      		else
      			valueList = '';
      		if(valueList.length)
        		idlist2 = valueList[0];
      		for(var j = 1; j < valueList.length; j++)
      		{
        		idlist2 += ','+valueList[j];
      		}

      		var taglistor = '';
      		if(idlist1 != '')
        		taglistor = '&idtaglistor=' + idlist1;
        	ret ['or'] = idlist1;

      		if(idlist1 != '')
      		{	
        		if(idlist2 != '')
          			idlist1 += ',';
      		}

      		var taglistand = '';
      		if(idlist2 != '')
         		taglistand = '&idtaglistand=' + idlist2;
        	ret ['and'] = idlist2;

      		idlist1 += idlist2;

      		ret ['ids'] = idlist1;

      		return ret;
    	}

    	function GetDaysFromToday ( dte )	// YYYYMMDD
    	{
    		const year 	= parseInt ( dte.substring(0, 4), 10 );
    		const month 	= parseInt ( dte.substring(4, 6), 10 ) - 1;
    		const day 	= parseInt ( dte.substring(6, 8), 10 );

    		const jsDte = new Date ( year, month, day );
    		const today = new Date ();

    		jsDte.setHours ( 0, 0, 0, 0 );
    		today.setHours ( 0, 0, 0, 0 );

    		const diffTime = jsDte - today;

    		const diffDays = Math.round( diffTime / (1000*60*60*24))

    		return diffDays;
    	}


    	function selectpointXX(x,y)
    	{

    	}