function sunSetRise(type_of_coordinates){
    if(type_of_coordinates == 'poi_coordinates'){
        X = poi_x
        Y = poi_y
        Z = poi_z
    }
    else if(type_of_coordinates == 'verseguide_coordinates'){
        X = R * Math.cos(lat_radians) * Math.cos(long_radians)
        Y = R * Math.cos(lat_radians) * Math.sin(long_radians)
        Z = R * Math.sin(lat_radians)
    }
    else if(type_of_coordinates == 'classic_coordinates'){
        X = R * Math.cos(lat_radians) * Math.cos(long_radians)
        Y = R * Math.cos(lat_radians) * Math.sin(long_radians)
        Z = R * Math.sin(lat_radians)
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Étape 1. Déterminez les coordonnées ECEF de Stanton par rapport à la planète ou à la lune actuelle.  //
    ////////////////////////////////////////////////////////////////////////////////////////////////////////

    // HCHF - heliocentric / helio fixed
    // ECEF - earth centered / earth fixed

    // Informations requises :
    // (1) Coordonnées HCHF de Stanton (Stanton XYZ) (sx, sy, sz)           extraites des fichiers du jeu
    // (2) Coordonnées HCHF de la planète/lune (Stanton XYZ) (bx, by, bz)   extraites des fichiers du jeu
    // (3) rotation quaternaire de la planète/lune (qw, qx, qy, qz)         extraite des fichiers du jeu

    // Formule pour convertir les coordonnées HCHF de Stanton en coordonnées ECEF, où le centre de la planète/lune est (0,0,0).
    // Il s'agit en fait d'une transformation qui recentre l'ensemble du système Stanton et place l'origine du système de coordonnées au centre de la planète.

    // Stanton ECEF X = bsx
    bsx = ((1 - (2 * Math.pow(qy,2)) - (2 * Math.pow(qz,2))) * (sx-bx))    +    (((2*qx*qy) - (2*qz*qw)) * (sy-by))    +    (((2*qx*qz) + (2*qy*qw)) * (sz-bz))
    // Stanton ECEF Y = bsy
    bsy = ((1 - (2 * Math.pow(qx,2)) - (2 * Math.pow(qz,2))) * (sy-by))    +    (((2*qx*qy) + (2*qz*qw)) * (sx-bx))    +    (((2*qy*qz) - (2*qx*qw)) * (sz-bz))
    // Stanton ECEF Z = bsz
    bsz = ((1 - (2 * Math.pow(qx,2)) - (2 * Math.pow(qy,2))) * (sz-bz))    +    (((2*qx*qz) - (2*qy*qw)) * (sx-bx))    +    (((2*qy*qz) + (2*qx*qw)) * (sy-by))

        // console.log("bsx = " + bsx)
        // console.log("bsy = " + bsy)
        // console.log("bsz = " + bsz)

    //////////////////////////////////////////////
    // Étape 2. Déclinaison solaire de Stanton  //
    //////////////////////////////////////////////

        stantonSolarDeclination = Math.acos((   (Math.pow(Math.sqrt(Math.pow(bsx,2) + Math.pow(bsy,2) + Math.pow(bsz,2)),2)) +    
        
                                            (Math.pow(Math.sqrt(Math.pow(bsx,2) + Math.pow(bsy,2)),2)) -
    
                                            (Math.pow(bsz,2))
                                        
                                        ) / (
                                            
                                            2*(Math.sqrt(Math.pow(bsx,2)+Math.pow(bsy,2)+Math.pow(bsz,2))) *
                                            
                                            (Math.sqrt(Math.pow(bsx,2)+Math.pow(bsy,2)))
                                        
                                            )
                                        )
                                            * 180 / Math.PI
    
    if(bsz<0){
        stantonSolarDeclination = -1 * stantonSolarDeclination
    }

        // console.log("Declination = " + stantonSolarDeclination)

    ///////////////////////////////////////////////////////
    // Étape 3. Déterminez le rayon apparent de l'étoile // 
    ///////////////////////////////////////////////////////
    apparentRadius = (Math.asin(starRadius/(Math.sqrt(Math.pow(bsx,2)+Math.pow(bsy,2)+Math.pow(bsz,2))))) * 180 / Math.PI
    //Le rayon de l'étoile est le rayon de Stanton ; sa valeur est dataminée et depuis la version 3.15.0, elle est de 696000 km.
        // console.log("apparentRadius = " + apparentRadius)



    /////////////////////////////////////////////////////////////////
    // Ensuite, nous déterminons la longitude solaire de Stanton.  //
    /////////////////////////////////////////////////////////////////

    // Informations requises :
    // (1) Taux de rotation de la planète
    // (2) Cycle actuel de la planète
    // (3) Correction de la rotation


    // Étape 1: conversion du taux de rotation des planètes en durée du jour
    // Le taux de rotation des planètes est extrait des fichiers du jeu et est exprimé en heures pour un cycle jour/nuit.
    // La durée d'un jour est le taux de rotation de la planète exprimé en fraction d'un jour de 24 heures.
    dayLength = 3600 * rotationRate / 86400  // jour_de_la_planète/jour_IRL_24_h
        console.log("Lenght of Day = " + dayLength)

    // Étape 2: calculer current Julian Date.

    // Julian Date est simplement le nombre de jours et la fraction de jour depuis un événement spécifique.

    // Dans le cadre de Star Citizen, l'événement spécifique est le 1er janvier 2020 à 0:00 UTC.  C'est le début de la période julienne et cela n'a aucun rapport avec les périodes juliennes ou les calendriers du monde réel.
    // julianDate = NOW() - 43831   // dans un tableur        43831 correspond à 01/01/2020 <=> 43831 jours écoulés depuis le 01/01/1900
   
    myTime().then((julianDate) => {
        console.log("julianDate: " + julianDate)
        // julianDate = (data / 86400) - 43831

        // Étape 3: déterminer le cycle jour/nuit actuel de la planète.

            currentCycle = julianDate / dayLength
            
            console.log("Current Cycle = " + currentCycle)

        
        // Le cycle actuel est exprimé par le nombre de cycles jour/nuit et la fraction du cycle qui se sont produits sur cette planète depuis le 1er janvier 2020, compte tenu de la longueur du jour. Seule la partie fractionnelle nous intéresse vraiment dans la suite.    Exemple: si 18451.2145 rotations, on ne s'intéresse qu'à 0.2145

        // Étape 4: calcul de la rotation actuelle de la planète

        // Nous utilisons la partie fractionnaire du cycle pour déterminer la distance de rotation de la planète au cours du cycle jour/nuit actuel, exprimée en nombre de degrés restants avant que la planète ne termine un autre cycle jour/nuit.

        // La correction de rotation est une valeur qui tient compte de la rotation de la planète le 1er janvier 2020, car nous ne savons pas exactement quand la rotation de la planète a commencé.  Cette valeur est mesurée et corrigée lors d'un alignement de rotation qui est effectué périodiquement dans le jeu et est récupérée dans la base de données de navigation.
        // current rotation position = Position de rotation actuelle = Hour Angle = CycleHourAngle
        
        // Création (pas par moi) d'une fonction qui permet d'avoir un modulo négatif (car % ne le permet pas)
        /*Number.prototype.mod = function(n) {
            return (( this % n ) + n ) % n;
        };*/
        
        cycleHourAngle = (360 - (currentCycle % 1) * 360 - rotationCorrection).mod(360)
                        
            console.log("Cycle Hour Angle = " + cycleHourAngle)
            
        
        // Étape 5:  déterminez où se trouverait l'étoile si la planète ne tournait pas.

        // Entre la planète et Stanton, il existe un plan qui contient le pôle nord et le pôle sud de la planète, et le centre de Stanton. Les endroits de la surface de la planète situés sur ce plan connaissent le phénomène que nous appelons midi. 
        
        
        sMeridian = parseFloat(Math.atan2(bsy,bsx)-(Math.PI/2)).mod(Math.PI * 2) * 180 / Math.PI
                        
            // console.log("Meridian = " + sMeridian)

        // Étape 6: longitude solaire de Stanton.

        // Comme la planète tourne, l'emplacement de midi se déplace constamment. Cette équation calcule la longitude actuelle de l'emplacement de midi sur la planète.
        
            if ((cycleHourAngle - ((0-sMeridian).mod(360))) > 180){
            
                sLongitude = cycleHourAngle - ((0 - sMeridian).mod(360)) - 360
        
        }
        else if ((cycleHourAngle - ((0-sMeridian).mod(360))) < -180){
            
                sLongitude = cycleHourAngle - ((0 - sMeridian).mod(360)) + 360
        }
        else { 

                sLongitude = cycleHourAngle - ((0 - sMeridian).mod(360))

        }

            // console.log("sLongitude = " + sLongitude)
        // Maintenant nous savons où se trouve l'étoile: nous connaissons sa déclinaison solaire et sa longitude solaire.


        
        /////////////////////////////////////////////////////////
        // Déterminer l'heure du lever et du coucher du soleil //
        /////////////////////////////////////////////////////////

        // Le deuxième ensemble d'équations est utilisé pour déterminer la position de l'étoile par rapport à l'endroit où nous voulons calculer les heures de lever et de coucher du soleil.

        // Pour déterminer l'heure du lever et du coucher du soleil, nous devons connaître le lieu pour lequel nous voulons calculer ces heures.

        // La position de l'étoile par rapport au lieu est connue sous le nom d'angle horaire.

        // À l'angle horaire 0, il est midi et à l'angle horaire +180/-180, il est minuit.  Les valeurs positives de l'angle horaire indiquent le matin (entre minuit et midi). Les valeurs négatives de l'angle horaire indiquent l'après-midi (entre midi et minuit). À partir de minuit, l'angle horaire est décompté de 180 à 0, et continue jusqu'à -180 pour compléter le cycle. Le lever du soleil se produit entre 180 et 0, le coucher du soleil entre 0 et -180. 

        // Lorsque nous calculons le lever et le coucher du soleil, nous devons calculer l'angle horaire auquel se produisent le lever et le coucher.

        // Les cinq facteurs qui influencent l'angle horaire de lever/coucher sont les suivants :
        // (1) la latitude du lieu
        // (2) Hauteur du lieu
        // (3) Rayon apparent de l'étoile
        // (4) Déclinaison solaire de l'étoile
        // (5) Obstructions obscurcissant l'horizon sur l'azimut de l'étoile pendant le lever ou le coucher du soleil.

        
        // Étape 1. En fonction des coordonnées ECEF XYZ d'un lieu, obtenues à partir des fichiers du jeu ou calculées par multilatération, déterminez la latitude, la longitude et la hauteur du lieu.

        // Informations requises - toutes les valeurs sont exprimées en kilomètres
        // (1) Coordonnées ECEF X de l'emplacement - données extraites des fichiers du jeu ou calculées par multilatération.
        // (2) Coordonnées ECEF Y de l'emplacement - données extraites des fichiers du jeu ou multilatérées
        // (3) Coordonnées ECEF Z de l'emplacement - données extraites des fichiers du jeu ou multidimensionnelles.
        // (4) Rayon du corps - calculé à partir des fichiers du jeu.
        
        locationLatitude = (Math.atan2(Z,(Math.sqrt(Math.pow(X,2) + Math.pow(Y,2))))) * 180 / Math.PI
            console.log("Location Latitude = " + locationLatitude)
        

            if (Math.abs(locationLatitude) == 90){

                locationLongitude = 0
        }
        else if (((((Math.atan2(Y,X)-(Math.PI/2)) % 2*Math.PI)) * 180 / Math.PI) > 180){

                locationLongitude = -1 * ( 360 - (((Math.atan2(X,Y) - (Math.PI / 2)) % (2 * Math.PI)) * 180 / Math.PI))
        }            
        else {
                locationLongitude = -1 * (((Math.atan2(X,Y) - (Math.PI / 2)) % (2 * Math.PI)) * 180 / Math.PI)
        }
            console.log("Location Longitude = " + locationLongitude)

        
        
            if (Math.abs(locationLatitude) == 90 ){

                locationLongitude360 = 0
                
        }
        else if (locationLongitude < 0){

                locationLongitude360 = 360 - ((Math.atan2(X,Y) - (Math.PI / 2)) % (2 * Math.PI)) * 180 / Math.PI
        }
        else {
            
            locationLongitude360 = locationLongitude
        }

            console.log("Location Longitude360 = " + locationLongitude360)


        locationHeight = (Math.sqrt(Math.pow(X,2) + Math.pow(Y,2) + Math.pow(Z,2)) - R)//*1000
            console.log("Location Height = " + locationHeight)

        // La différence entre la longitude et la longitude360 est que pour la longitude, les valeurs positives indiquent des emplacements dans l'hémisphère oriental, les valeurs négatives indiquent des emplacements dans l'hémisphère occidental.
        // Pour la longitude360, les lieux de longitude 0-180 se trouvent dans l'hémisphère oriental, les lieux de longitude 180-359 se trouvent dans l'hémisphère occidental.


        // Étape 2: déterminez la correction pour l'altitude de l'emplacement
        if(locationHeight < 0){
            elevationCorrection = (Math.acos(R / R)) * 180 / Math.PI
        }
        else{
            elevationCorrection = (Math.acos(R / (parseFloat(R) + parseFloat(locationHeight)))) * 180 / Math.PI
        }
            console.log("elevationCorrection = " + elevationCorrection)
            console.log("R = " + (parseFloat(R) + parseFloat(locationHeight)))
        // Étape 3: détermination de l'angle de l'heure de lever/de coucher
        // La déclinaison solaire et le rayon apparent proviennent du premier jeu d'équations lorsque nous avons déterminé l'emplacement de l'étoile.
        riseSetHourAngle = (Math.acos(-1 * Math.tan(locationLatitude * Math.PI/180) * Math.tan(stantonSolarDeclination * Math.PI/180))) * (180 / Math.PI) + apparentRadius + elevationCorrection
        
        // L'étoile se lève à + (valeur positive) de l'angle de lever/de coucher et se couche à - (valeur négative) de l'angle de lever/de coucher.
            console.log("riseSetHourAngle = " + riseSetHourAngle)

        // Étape 4: déterminer l'angle horaire actuel de l'étoile

        if(astre == 'Clio'){
            hourAngle = /*currentRotation*/cycleHourAngle - ((locationLongitude360 - sMeridian)/*.mod(360)*/)//.mod(360) + 360
        }
        else if((/*currentRotation*/cycleHourAngle - ((locationLongitude360 - sMeridian).mod(360)).mod(360)) > 180){
            hourAngle = (/*currentRotation*/cycleHourAngle - ((locationLongitude360 - sMeridian).mod(360)).mod(360)) - 360
        }
        else{
            hourAngle = /*currentRotation*/cycleHourAngle - ((locationLongitude360 - sMeridian).mod(360)).mod(360)
        }
        /*if(((/cycleHourAngle - ((locationLongitude360 - sMeridian).mod(360)).mod(360)) > 180){
            hourAngle = (cycleHourAngle - ((locationLongitude360 - sMeridian).mod(360).mod(360)) - 360
        }
        else{
            hourAngle = (cycleHourAngle - ((locationLongitude360 - sMeridian).mod(360)).mod(360))
        }*/
            console.log("Hour Angle = " + hourAngle)
        // Les hourAngle compris entre (+)riseSetHourAngle et +180 sont avant le lever du soleil.
        // Les hourAngle compris entre 0 et (+)riseSetHourAngle sont après le lever du soleil & avant midi.
        // Les hourAngle compris entre 0 et (-)riseSetHourAngle sont après le lever du soleil & après midi.
        // Les hourAngle compris entre (-)riseSetHourAngle et -180 sont après le coucher du soleil.
        // Une fois l'angle horaire actuel déterminé, nous connaissons maintenant l'angle réel (en degrés) entre la position de l'étoile et l'angle horaire +rise et l'angle horaire -set.


        // Étape 5: déterminez le taux de rotation angulaire de la planète.

        // Le taux de rotation angulaire est simplement le taux de rotation de la planète converti des heures en degrés par minute.   Le taux de rotation de la planète est calculé à partir des fichiers du jeu.
        
        angularRotationRate = 6 / rotationRate // Le résultat est en ° / min

            console.log("angularRotationRate = " + angularRotationRate)
    
    
    
        // Étape 6: calculer le temps (en minutes) jusqu'au lever du soleil et l'heure du lever du soleil.
        // Le temps jusqu'au lever du soleil est la différence entre l'angle horaire et (+l'angle de l'heure du lever moins la correction du terrain du lever du soleil) qui est en degrés multiplié par le taux de rotation angulaire.
        // Tout effet du terrain, par exemple les montagnes, fait que le lever du soleil se produit plus tard.
        // Ajoutez ou soustrayez ensuite l'heure actuelle pour calculer l'heure prévue du lever du soleil.
        timeToRise = (hourAngle - riseSetHourAngle) * angularRotationRate
        // Étape 7: calculer le temps (en minutes) jusqu'au coucher du soleil et de l'heure du coucher du soleil.
        // Le temps jusqu'au coucher du soleil est la différence entre l'angle horaire et (-Set Hour Angle minus Sunset Terrain correction) multipliée par la vitesse de rotation angulaire.
        // Le terrain fait que le coucher du soleil a lieu plus tôt.
        // Ajoutez ou soustrayez l'heure actuelle pour calculer l'heure prévue du coucher du soleil.
        timeToSet = (hourAngle - (-1 * riseSetHourAngle)) * angularRotationRate
        console.log("timeToRise = " + timeToRise)
        console.log("timeToSet = " + timeToSet)

        timeLocal = parseFloat(julianDate) + 43831
        // NOON 
        if(hourAngle > 0 ){
            noon = hourAngle / angularRotationRate / 1440 + (parseFloat(julianDate) + 43831)
        }
        else{
            noon = (360 + hourAngle) / angularRotationRate / 1440 + (parseFloat(julianDate) + 43831)
        }
        console.log("noon = " + noon)
        
        console.log("Noon : " + timeFormat(noon))


        // RISE
        if (hourAngle > riseSetHourAngle){
            rise = noon - (riseSetHourAngle / angularRotationRate / 1440 )
        }
        else if (hourAngle > 0){
            rise = noon - (riseSetHourAngle / angularRotationRate / 1440 ) + dayLength
        }
        else (rise = noon - (riseSetHourAngle / angularRotationRate / 1440 ))

        console.log("Rise : " + timeFormat(rise))


        // SET
        if (hourAngle > -1 * riseSetHourAngle){
            if(hourAngle > 0){
                set = noon + (riseSetHourAngle / angularRotationRate / 1440 )
            }
            else{
                set = noon + (riseSetHourAngle / angularRotationRate / 1440 ) - dayLength
            }
        }    
        else{
            set = noon + (riseSetHourAngle / angularRotationRate / 1440 )
        }
        
        console.log("Set : " + timeFormat(set))

        // STANTON MAX ALTITUDE
        
        stantonMaxAltitude = (180 / Math.PI) * (Math.acos((Math.sqrt(Math.pow(Math.pow(X,2)+Math.pow(Y,2)+Math.pow(Z,2),2))+(Math.pow(Math.sqrt(Math.sqrt(Math.pow(Math.pow(X,2)+Math.pow(Y,2)+Math.pow(Z,2),2))+Math.sqrt(Math.pow(Math.pow(bsx,2)+Math.pow(bsy,2)+Math.pow(bsz,2),2))-(2*Math.sqrt(Math.pow(X,2)+Math.pow(Y,2)+Math.pow(Z,2))*Math.sqrt(Math.pow(bsx,2)+Math.pow(bsy,2)+Math.pow(bsz,2))*Math.cos((Math.PI/180)*(Math.abs(stantonSolarDeclination-locationLatitude))))),2))-Math.sqrt(Math.pow(Math.pow(bsx,2)+Math.pow(bsy,2)+Math.pow(bsz,2),2)))/(2*Math.sqrt(Math.pow(X,2)+Math.pow(Y,2)+Math.pow(Z,2))*(Math.sqrt(Math.sqrt(Math.pow(Math.pow(X,2)+Math.pow(Y,2)+Math.pow(Z,2),2))+Math.sqrt(Math.pow(Math.pow(bsx,2)+Math.pow(bsy,2)+Math.pow(bsz,2),2))-(2*Math.sqrt(Math.pow(X,2)+Math.pow(Y,2)+Math.pow(Z,2))*Math.sqrt(Math.pow(bsx,2)+Math.pow(bsy,2)+Math.pow(bsz,2))*Math.cos((Math.PI/180)*(Math.abs(stantonSolarDeclination-locationLatitude)))))))))-90
        let light
        console.log("stantonMaxAltitude = " + stantonMaxAltitude)
        // TIME TO RISE or TIME TO SET
        if(Math.abs(locationLatitude) > Math.abs(90 - Math.abs(stantonSolarDeclination))){

            if (stantonMaxAltitude < 0){
                light = 'night'
            }
            else{
                light = 'daylight'
            }

        }
        else if (hourAngle == 0 ){
                light = '☀️ Noon ☀️'
        }
        else if (hourAngle == -1 * riseSetHourAngle){
                light = 'Sunset'
        }
        else if (hourAngle == riseSetHourAngle){
                light = 'Sunrise'
        }
        else if (hourAngle == 180){
                light = '🌙 Midnight 🌙'
        }
        else if ((hourAngle > -1 * riseSetHourAngle) && (hourAngle < 0)){
                light = '☀️ Afternoon ☀️'
                
                timeToSolarEvent = 'Sets in ↘ ' + Math.trunc(parseFloat((set - timeLocal)*1440)) + ' minutes'
                
        }
        else if ((hourAngle > 0) && (hourAngle < riseSetHourAngle)){
                light = '​​☕​ Morning ​☕​'
                
                timeToSolarEvent = 'Sets in ↘ ' + Math.trunc(parseFloat((set - timeLocal)*1440)) + ' minutes'
                
        }
        else if ((hourAngle > riseSetHourAngle) && (hourAngle < riseSetHourAngle + 18)){
                light = '🐓 Morning Twilight 🐓'
                
                timeToSolarEvent = 'Rises in ↗ ' + Math.trunc(parseFloat((rise - timeLocal)*1440)) + ' minutes'
                
        }
        else if ((hourAngle > -1 * (riseSetHourAngle + 18)) && (hourAngle < -1 * riseSetHourAngle)){
                light = '😴 Evening Twilight 😴'
                
                timeToSolarEvent = 'Rises in ↗ ' + Math.trunc(parseFloat((rise - timeLocal)*1440)) + ' minutes'
                
        }
        else if ((hourAngle > -180) && (hourAngle < -1 * (riseSetHourAngle + 18))){
                light = '🌙 Night 🌙'
                
                timeToSolarEvent = 'Rises in ↗ ' + Math.trunc(parseFloat((rise - timeLocal)*1440)) + ' minutes'
                
        }
        else{
                light = '🌙 After midnight 🌙'
                
                timeToSolarEvent = 'Rises in ↗ ' + Math.trunc(parseFloat((rise - timeLocal)*1440)) + ' minutes'
                
        }
        console.log('hourAngle = ' + hourAngle)
        console.log('riseSetHourAngle = ' + riseSetHourAngle)
        console.log('Light : ' + light)
        
            console.log(timeToSolarEvent)
            $('.daylight').text(light + '     ' + timeToSolarEvent)
        
        
        
    })
}


function timeFormat(value){
    fraction = value.mod(1)

    hours_dec = fraction * 24
    hours = Math.trunc(hours_dec)

    minutes_dec = (hours_dec % 1) * 60
    minutes = Math.trunc(minutes_dec)

    hours_display = hours
    if (hours < 10){hours_display = '0' +hours}
    minutes_display = minutes
    if (minutes < 10){minutes_display = '0' + minutes}
    
    return hours_display + ':' + minutes_display
}