	
	var E_PAYEMENT_DELETE		= parseInt ( '0x0000', 16 );
	var E_PAYEMENT_PARTIAL		= parseInt ( '0x0001', 16 );
	var E_PAYEMENT_DONE			= parseInt ( '0x0010', 16 );
	
	var EV_VISIT_PAID			= parseInt ( '0x0014', 16 );

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/get_staff_list.php";
			
		xhra.open ('GET', url, true );
		xhra.send ();
	}

	function FillDepartmentsList ( idSelect, ins_id )
	{
		if ( ins_id == undefined )
			ins_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 departments	 	= reponse.getElementsByTagName ( 'department' );
				
				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 = eoDACS.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 = eoDACS.ServerFolder+"/eoQUAL/SubFW/database/common/get_devices.php?dep_id=" + dep_id;
		xhra.open ('GET', url, false );
		xhra.send ();
	}

	function FillStatusList ( idSelect, type )
	{
		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 status		 	= reponse.getElementsByTagName ( 'status' );
				
				for ( let i=0; i<status.length; i++ )
				{
					let id			= status.item (i).getAttribute ( "id" 	);
					let name		= status.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 = eoDACS.ServerFolder + "/eoQUAL/SubFW/database/common/get_status.php?type=" + type;
		xhra.open ('GET', url, false );
		xhra.send ();
	}

	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 = eoDACS.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 )
	{
		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 ( 'role' );

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

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

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

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

	function FillLoginRoleList ( 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 ( 'role' );

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

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

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

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

	function FillValueList ( idSelect, scope )
	{
		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 ( 'value' );
				
				for ( let i=0; i<list.length; i++ )
				{
					let value		= list.item (i).getAttribute ( "value" 	);
					let name		= list.item (i).getAttribute ( "name" );

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

		let url = "SubFW/database/common/get_enumlistvalue.php?scope=" + scope;
		xhra.open ('GET', url, false );
		xhra.send ();
	}
	
	
	
	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";
		
	}
		
	function DICOMDate2StdDate ( date )
	{
		if ( 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 == null )
			return "";
		
		if ( 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 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;
		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 )
	{
		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", eoDACS.ServerFolder+"/SubFW/database/common/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 = eoDACS.ServerFolder+"/SubFW/database/common/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 FillRISUserList ( idSelect )
	{
		var request = $.ajax ({
        	url: 		eoDACS.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: 		eoDACS.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 )
	{
		function parseFilesList ( text, withExtension ) 
		{
			let files;

			if ( withExtension == true )
    			files = text
                 .match(/href="([\w.]+)/g) 
                 .map((x) => x.replace('href="', ''));
        	else
        		files = text
                 .match(/href="([\w]+)/g)
                 .map((x) => x.replace('href="', ''));

   			return files;
		}

		let filesList;

		$.ajax (
		{
			url : folder,
			type : 'get',
			async : false,
			success :  function (data) 
				{
					filesList = parseFilesList ( data, withExtension );
				}
			});

		return filesList;
	}




	function InitStudiesCBList ( cbElem )
	{
		function ok ( data )
		{
			for ( let i=0; i< data.length; i++ )
			{
				cbElem.AddTextSeparator ( data [i].label );

				for ( let j=0; j<data[i].children.length; j++ )
				{
					cbElem.AddItem ( i, data[i].children [j].value, data[i].children [j].label );
				}
			}
		}

		function error ()
		{
			console.log ( "InitStudiesCBList - error..." );	
		}

		var request = $.ajax ({
        		url: 		eoDACS.ServerFolder+"/SubFW/database/stats/get_studymaster.php",
        		type: 		"get",
        		dataType: 	"json"
    			}
    	)
		.done ( ok )
    	.fail ( error );
    }

    function InitSeriesCBList ( cbElem )
	{
		function ok ( data )
		{
			for ( let i=0; i< data.length; i++ )
			{
				cbElem.AddTextSeparator ( data [i].label );

				for ( let j=0; j<data[i].children.length; j++ )
				{
					cbElem.AddItem ( i, data[i].children [j].value, data[i].children [j].label );
				}
			}
		}

		function error ()
		{
			console.log ( "InitSeriesCBList - error..." );	
		}

		var request = $.ajax ({
        		url: 		eoDACS.ServerFolder+"/SubFW/database/stats/get_seriemaster.php",
        		type: 		"get",
        		dataType: 	"json"
    			}
    	)
		.done ( ok )
    	.fail ( error );
    }



    function InitModalitiesCBList ( cbElem, modality )
	{
		modality = ( modality == undefined )? "*" : modality;
		function ok ( data )
		{
			for ( let i=0; i< data.length; i++ )
			{
				cbElem.AddTextSeparator ( data [i].label );

				for ( let j=0; j<data[i].children.length; j++ )
				{
					cbElem.AddItem ( i, data[i].children [j].value, data[i].children [j].label, data[i].label );
				}
			}
		}

		function error ()
		{
			console.log ( "InitModalitiesCBList - error..." );	
		}

		var request = $.ajax ({
        		url: 		eoDACS.ServerFolder+"/SubFW/database/common/get_modality.php?modality="+modality,
        		type: 		"get",
        		dataType: 	"json"
    			}
    	)
		.done ( ok )
    	.fail ( error );
    }

    function InitIMCCBList ( cbElem )
	{
		function ok ( data )
		{
			for ( let i=0; i< data.length; i++ )
				cbElem.AddItem ( 0, data[i].value, data[i].label );
		}

		function error ()
		{
			console.log ( "InitIMCCBList - error..." );	
		}

		var request = $.ajax ({
        		url: 		eoDACS.ServerFolder+"/SubFW/database/stats/get_imc.php",
        		type: 		"get",
        		dataType: 	"json"
    			}
    	)
		.done ( ok )
    	.fail ( error );
    }

    function InitAgeCBList ( cbElem )
	{
		function ok ( data )
		{
			for ( let i=0; i< data.length; i++ )
				cbElem.AddItem ( 0, data[i].value, data[i].label );
		}

		function error ()
		{
			console.log ( "InitAgeCBList - error..." );	
		}

		var request = $.ajax ({
        		url: 		eoDACS.ServerFolder+"/SubFW/database/stats/get_age.php",
        		type: 		"get",
        		dataType: 	"json"
    			}
    	)
		.done ( ok )
    	.fail ( error );
    }


    function formatParams( params )
    {
  		return "?" + Object
        .keys(params)
        .map(function(key){
          return key+"="+encodeURIComponent(params[key])
        })
        .join("&")
	}

	function get_nodevalue(xmlDoc, node)
	{
  		var x = xmlDoc.getElementsByTagName(node)[0];

  		if(!x.hasChildNodes())
		    return "Undefined";
  		return x.childNodes[0].nodeValue;
	}


	


	function FillGroupFilterList ( idSelect )
	{
		$.post (
				"SubFW/database/common/get_filtergroup.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 FillAlertFilterList ( idSelect )
	{
		$.post (
				"SubFW/database/common/get_alertfiltergroup.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 isValidDate ( a )
	{
  		var c=a.match(/^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/);

  		return true;
  		return c !== null;
	}