persister l'affichage des itinéraires

This commit is contained in:
Tykayn 2025-05-04 23:48:53 +02:00 committed by tykayn
parent da7292e746
commit dd6fbeb0a1
5 changed files with 109 additions and 103 deletions

View file

@ -76,6 +76,7 @@
<!-- </fieldset>-->
</form>
<div id="current_station_infos"></div>
<div class="routing_infos"></div>
<div id="round_power_legend">
<br>
<span class="marker-demo">
@ -178,6 +179,21 @@
<input type="number" id="charge_to_level" min="0" max="100" value="80" step="1"
style="width: 4em;">
</p>
<p>
<label for="max_charge_power">
Puissance de charge maximale (kW) :
</label>
<input type="number" id="max_charge_power" min="1" max="350" value="50" step="1"
style="width: 4em;">
</p>
</div>
<div class="filter-display" id="filterDisplay">
<h3>Options d'affichage</h3>
<label>
<input type="checkbox" id="display_charges">
<span class="checkbox-custom"></span>
<span>Afficher les tarifs des stations</span>
</label>
</div>
<div class="filter-sockets" id="filterSockets">

View file

@ -305,6 +305,8 @@ function updateURLWithMapCoordinatesAndZoom() {
history.replaceState(null, null, url);
updateExternalEditorsLinks();
}
@ -611,9 +613,10 @@ function displayPointsFromApi(points, convert_to_osm_json) {
},
onEachFeature: eachFeature,
});
// Mettre à jour le compteur de stations filtrées
updateFilteredStationsCount();
calculerEtAfficherItineraire(endItinerary);
}
function displaySocketsList(feature) {
@ -655,6 +658,12 @@ function makePopupOfFeature(feature) {
}
})
popupContent += '</div>'
// Ajouter l'affichage des tarifs si l'option est activée
if ($('#display_charges').is(':checked') && feature.properties.tags.charge) {
popupContent += '<div class="charge-info"><strong>Tarifs :</strong> ' + feature.properties.tags.charge + '</div>'
}
return popupContent;
}
@ -1691,6 +1700,7 @@ async function calculerEtAfficherItineraire(destination, mode = 'car') {
const consumptionPerKm = parseFloat($('#consumption_per_km').val()) || 160;
const minBatteryLevel = parseFloat($('#min_battery_level').val()) || 15;
const chargeToLevel = parseFloat($('#charge_to_level').val()) || 80;
const maxChargePower = parseFloat($('#max_charge_power').val()) || 50;
// Construire l'URL OSRM
const url = `https://router.project-osrm.org/route/v1/${mode}/${startLon},${startLat};${endLon},${endLat}?overview=full&geometries=geojson&alternatives=false&steps=false`;
@ -1786,111 +1796,64 @@ async function calculerEtAfficherItineraire(destination, mode = 'car') {
const pauseDurationMinutes = 10;
const totalPauseTimeMinutes = numberOfPauses * pauseDurationMinutes;
// Ajouter les marqueurs de pause
window.pauseMarkers = [];
// Calculer les temps de recharge nécessaires
let totalRechargeTimeMinutes = 0;
if (numberOfPauses > 0) {
const totalDistance = route.distance;
const pauseInterval = totalDistance / (numberOfPauses + 1);
for (let i = 1; i <= numberOfPauses; i++) {
const pauseDistance = pauseInterval * i;
let accumulatedDistance = 0;
let pauseCoords;
// Trouver les coordonnées pour cette pause
for (let j = 0; j < coords.length - 1; j++) {
const segmentDistance = L.latLng(coords[j]).distanceTo(coords[j + 1]);
if (accumulatedDistance + segmentDistance >= pauseDistance) {
const ratio = (pauseDistance - accumulatedDistance) / segmentDistance;
pauseCoords = [
coords[j][0] + (coords[j + 1][0] - coords[j][0]) * ratio,
coords[j][1] + (coords[j + 1][1] - coords[j][1]) * ratio
];
break;
}
accumulatedDistance += segmentDistance;
}
if (pauseCoords) {
// Calculer la distance restante jusqu'à la prochaine pause ou la fin
const nextPauseDistance = (i < numberOfPauses) ? pauseInterval : (totalDistance - pauseDistance);
const consumptionToNextPause = (nextPauseDistance / 1000) * consumptionPerKm / 1000; // en kWh
const batteryLevelNeeded = (consumptionToNextPause / batteryCapacity) * 100 + minBatteryLevel;
// Calculer le niveau de batterie actuel à ce point
const currentBatteryLevel = ((batteryStartKwh - (pauseDistance / 1000 * consumptionPerKm / 1000)) / batteryCapacity) * 100;
// Rechercher les stations de recharge autour du point de pause
const chargingStations = await searchChargingStationsAroundPoint(pauseCoords[0], pauseCoords[1]);
// Créer le contenu du popup avec les stations trouvées
let popupContent = `<div class="pause-info">
<h3>Pause recommandée n°${i}</h3>
<p>Durée : 10 minutes</p>
<p>Niveau de batterie actuel : ${currentBatteryLevel.toFixed(1)}%</p>
<p>Niveau de batterie nécessaire : ${batteryLevelNeeded.toFixed(1)}%</p>
<p>Distance jusqu'à la prochaine pause : ${(nextPauseDistance / 1000).toFixed(1)} km</p>`;
if (chargingStations.length > 0) {
popupContent += `<div class="charging-stations">
<h4>Stations de recharge à proximité (${chargingStations.length}) :</h4>
<ul>`;
chargingStations.forEach(station => {
const name = station.tags?.name || 'Sans nom';
const operator = station.tags?.operator || 'Opérateur inconnu';
const distance = L.latLng(pauseCoords).distanceTo([station.lat, station.lon]).toFixed(0);
popupContent += `<li>
<strong>${name}</strong><br>
Opérateur : ${operator}<br>
Distance : ${distance} m
</li>`;
});
popupContent += `</ul></div>`;
} else {
popupContent += `<p>Aucune station de recharge trouvée dans un rayon de 1.5 km</p>`;
}
popupContent += `</div>`;
const pauseMarker = L.marker(pauseCoords, {
icon: L.divIcon({
className: 'pause-marker',
html: '⏸️',
iconSize: [30, 30]
})
}).addTo(map);
pauseMarker.bindPopup(popupContent);
window.pauseMarkers.push(pauseMarker);
}
const nextPauseDistance = (i < numberOfPauses) ? pauseInterval : (totalDistance - pauseDistance);
// Calculer la consommation jusqu'à la prochaine pause
const consumptionToNextPause = (nextPauseDistance / 1000) * consumptionPerKm / 1000; // en kWh
const batteryLevelNeeded = (consumptionToNextPause / batteryCapacity) * 100 + minBatteryLevel;
// Calculer le niveau de batterie actuel
const currentBatteryLevel = ((batteryStartKwh - (pauseDistance / 1000 * consumptionPerKm / 1000)) / batteryCapacity) * 100;
// Calculer la quantité d'énergie à recharger
const energyToRecharge = (batteryLevelNeeded - currentBatteryLevel) * batteryCapacity / 100;
// Calculer le temps de recharge nécessaire
const rechargeTimeHours = energyToRecharge / maxChargePower;
const rechargeTimeMinutes = Math.ceil(rechargeTimeHours * 60);
// Ajouter le temps de recharge au total (minimum 10 minutes)
totalRechargeTimeMinutes += Math.max(rechargeTimeMinutes, pauseDurationMinutes);
}
}
// Afficher distance, durée, et boutons de mode de transport
const distanceKm = (route.distance / 1000).toFixed(1);
const durationMin = Math.round(route.duration / 60);
const totalDurationMin = durationMin + totalPauseTimeMinutes;
// Convertir les différentes durées en format lisible
const formatDuration = (minutes) => {
if (minutes >= 60) {
const hours = Math.floor(minutes / 60);
const mins = minutes % 60;
return `${hours}h${mins > 0 ? ` ${mins}min` : ''}`;
}
return `${minutes} min`;
};
// Convertir la durée totale en heures et minutes si nécessaire
let durationDisplay = '';
if (totalDurationMin >= 60) {
const hours = Math.floor(totalDurationMin / 60);
const minutes = totalDurationMin % 60;
durationDisplay = `${hours}h${minutes > 0 ? ` ${minutes}min` : ''}`;
} else {
durationDisplay = `${totalDurationMin} min`;
}
const durationNoPause = formatDuration(durationMin);
const durationWithPauses = formatDuration(durationMin + totalPauseTimeMinutes);
const durationWithRecharge = formatDuration(durationMin + totalRechargeTimeMinutes);
$('#current_station_infos').html(`
$('#routing_infos').html(`
<section class="routing">
<h2>Itinéraire</h2>
<div>Distance: <strong>${distanceKm} km</strong></div>
<div>Durée estimée: <strong>${durationDisplay}</strong> (dont ${totalPauseTimeMinutes} min de pause)</div>
<div class="battery-info">
<h3>Niveaux de batterie :</h3>
<div>Départ : <strong>${batteryStartLevel}%</strong></div>
<div>Arrivée : <strong>${batteryEndLevel.toFixed(1)}%</strong></div>
</div>
<div class="duration-info">
<h3>Durées estimées :</h3>
<div>Sans pause : <strong>${durationNoPause}</strong></div>
<div>Avec pauses (10 min) : <strong>${durationWithPauses}</strong></div>
<div>Avec recharges : <strong>${durationWithRecharge}</strong></div>
</div>
<div>Nombre de pauses recommandées: <strong>${numberOfPauses}</strong> (10 min toutes les 2h)</div>
<div>Niveau de batterie final estimé: <strong>${batteryEndLevel.toFixed(1)}%</strong></div>
<div>Consommation totale estimée: <strong>${totalConsumptionKwh.toFixed(1)} kWh</strong></div>
<div>
<button onclick="calculerEtAfficherItineraire(window.lastRouteDestination, 'car')">🚗 Voiture</button>
@ -1909,7 +1872,14 @@ async function calculerEtAfficherItineraire(destination, mode = 'car') {
function setStartMarker(latlng) {
if (startMarker) map.removeLayer(startMarker);
startMarker = L.marker(latlng, { draggable: true, icon: L.divIcon({className: 'start-marker', html: '🟢', iconSize: [30, 30]}) }).addTo(map);
startMarker = L.marker(latlng, {
draggable: true,
icon: L.divIcon({
className: 'start-marker',
html: '🟢<br>départ',
iconSize: [30, 30]
})
}).addTo(map);
startCoords = [latlng.lat, latlng.lng];
startMarker.on('dragend', function(e) {
startCoords = [e.target.getLatLng().lat, e.target.getLatLng().lng];
@ -1919,7 +1889,14 @@ function setStartMarker(latlng) {
function setEndMarker(latlng) {
if (endMarker) map.removeLayer(endMarker);
endMarker = L.marker(latlng, { draggable: true, icon: L.divIcon({className: 'end-marker', html: '🔴', iconSize: [30, 30]}) }).addTo(map);
endMarker = L.marker(latlng, {
draggable: true,
icon: L.divIcon({
className: 'end-marker',
html: '🔴<br>arrivée',
iconSize: [30, 30]
})
}).addTo(map);
endCoords = [latlng.lat, latlng.lng];
endMarker.on('dragend', function(e) {
endCoords = [e.target.getLatLng().lat, e.target.getLatLng().lng];

View file

@ -1,11 +1,7 @@
/**
overrides leaflet
*/
// .leaflet-interactive {
// border: solid 3px white;
// }
.leaflet-control-layers {
&.leaflet-control-layers-toggle {
@ -106,4 +102,12 @@ overrides leaflet
padding: 5px;
border-radius: 4px;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.4);
}
}
.battery-marker {
background: white;
border-radius: 1rem;
padding: 30px;
width: 5rem;
height: 5rem;
border: solid 1px #ccc;}

View file

@ -1099,6 +1099,15 @@ overrides leaflet
height: 30px !important;
}
.battery-marker {
background: white;
border-radius: 1rem;
padding: 30px;
width: 5rem;
height: 5rem;
border: solid 1px #ccc;
}
@keyframes rainbow-border {
0% {
border-left-color: #ff0000;

View file

@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["main.scss","_osmose.scss","_recherche.scss","_filters.scss","_mobile.scss","_overrides.scss","_animations.scss","_stats.scss"],"names":[],"mappings":";AAIA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAKA;EACE;;AAGE;EACE;EACA;;AAKJ;EACE;;;AAMN;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;EAIE;EACA;EACA;EACA;EACA;;;AAKA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;AAGA;EACE;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EAOE;;AANA;EACE;EACA;EACA;;;AAMJ;EACE;;;AAGF;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;AAAA;AAAA;AAIA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAIF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAIA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAOF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAIA;EACE;EACA;;;AAKN;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIA;EACE;;;AAIJ;EACE;;AAUE;EACE;EACA;EACA;;AAcJ;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;;;AAMJ;EAAgB;;AAChB;EAAc;;AACd;EAAgB;;AAEhB;EACE;;;ACrsBJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAKJ;EACE;EACA;EACA;EACA;;;AAEA;EACE;EACA;EACA;EACA;;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AC3DJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEA;EACE;EACA;;;AAEA;EACE;;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAEA;EACE;EACA;EACA;;;AAGF;EACE;;;AASJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;ACpEF;EACE;;;AAEA;EACE;EACA;EACA;;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAcF;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAEA;AAAA;EACE;EACA,OApDS;EAqDT;;;AAGF;AAAA;EAvBA;EACA;EAwBE;EACA;EArBF;EAuBE;EACA;;;AAEA;AAAA;EACE,YA/DK;;;AAmET;AAAA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EA/CF;;;AAkDE;AAAA;EACE;;;AAIJ;AAAA;EACE,YA/FY;EAgGZ,cAhGY;EAiGZ;;;AAEA;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAAA;EACE;EACA;EACA;EACA;;;AAGF;AAAA;EACE;EACA,OAxHS;EAsCX;;;AAsFA;AAAA;EACE;;;AAIA;AAAA;EACE,YAhIK;EAiIL,cAhIW;EAiIX;;;AAGF;AAAA;EACE,OArIW;EAsIX;;;AAMN;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;;AC9JJ;AACA;EACE;IACE;IACA;;EAKA;AAAA;IAEE;IACA;;EAIJ;IACE;;EAGF;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAGF;AACE;;EAGF;IACE;IACA;IACA;IACA;IACA;;EAGF;IACE;;EAGF;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;;EAIF;IACE;;EAGF;IACE;;EAGF;IACE;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;;EAIF;IAEE;;;ACrGJ;AAAA;AAAA;AAUE;EACE;;;AAGF;EACE;;;AAKF;EACE;;;AAEA;EACE;EACA;;;AAKN;EACE;EACA;;;AAGF;AAEE;EACE;EACA;EACA;EACA;EACA;;;AAEA;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAEA;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAMN;EAyBE;EACA;EACA;EACA;;;AA1BE;EACE;EACA;EACA;EACA;EACA;EACA;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;ACnGN;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;;AAIJ;EAEE;IAEE;;EAGF;IACE;;;ACtCJ;EACE;EACA;EACA;;;AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAKA;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;;;AAEA;EACE;EACA;EACA;;;APuqBN;EACE;EACA","file":"style.css"}
{"version":3,"sourceRoot":"","sources":["main.scss","_osmose.scss","_recherche.scss","_filters.scss","_mobile.scss","_overrides.scss","_animations.scss","_stats.scss"],"names":[],"mappings":";AAIA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAKA;EACE;;AAGE;EACE;EACA;;AAKJ;EACE;;;AAMN;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;AAAA;AAAA;AAAA;EAIE;EACA;EACA;EACA;EACA;;;AAKA;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;;AAGA;EACE;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EAOE;;AANA;EACE;EACA;EACA;;;AAMJ;EACE;;;AAGF;EACE;IACE;;EAGF;IACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIF;EACE;EACA;EACA;;AAEA;EACE;;;AAIJ;AAAA;AAAA;AAIA;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAGF;AAAA;EAEE;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAIF;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAIA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;;;AAIJ;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AAOF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAIA;EACE;EACA;;;AAKN;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAMA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAIA;EACE;;;AAIJ;EACE;;AAUE;EACE;EACA;EACA;;AAcJ;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAGF;EACE;EACA;EACA;EACA;EACA;;AAIA;EACE;EACA;;;AAMJ;EAAgB;;AAChB;EAAc;;AACd;EAAgB;;AAEhB;EACE;;;ACrsBJ;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAKJ;EACE;EACA;EACA;EACA;;;AAEA;EACE;EACA;EACA;EACA;;;AAEA;EACE;;;AAIJ;EACE;EACA;;;AC3DJ;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAEA;EACE;EACA;;;AAEA;EACE;;;AAKN;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAEA;EACE;EACA;EACA;;;AAGF;EACE;;;AASJ;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;ACpEF;EACE;;;AAEA;EACE;EACA;EACA;;;AAGF;EACE;;;AAIJ;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAcF;AAAA;EAEE;EACA;EACA;EACA;EACA;;;AAEA;AAAA;EACE;EACA,OApDS;EAqDT;;;AAGF;AAAA;EAvBA;EACA;EAwBE;EACA;EArBF;EAuBE;EACA;;;AAEA;AAAA;EACE,YA/DK;;;AAmET;AAAA;EACE;EACA;EACA;EACA;EACA;;;AAGF;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EA/CF;;;AAkDE;AAAA;EACE;;;AAIJ;AAAA;EACE,YA/FY;EAgGZ,cAhGY;EAiGZ;;;AAEA;AAAA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAAA;EACE;EACA;EACA;EACA;;;AAGF;AAAA;EACE;EACA,OAxHS;EAsCX;;;AAsFA;AAAA;EACE;;;AAIA;AAAA;EACE,YAhIK;EAiIL,cAhIW;EAiIX;;;AAGF;AAAA;EACE,OArIW;EAsIX;;;AAMN;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;;AC9JJ;AACA;EACE;IACE;IACA;;EAKA;AAAA;IAEE;IACA;;EAIJ;IACE;;EAGF;IAEE;IACA;IACA;IACA;IACA;IACA;IACA;;EAGF;IACE;IACA;IACA;;EAGF;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAGF;AACE;;EAGF;IACE;IACA;IACA;IACA;IACA;;EAGF;IACE;;EAGF;AAAA;IAEE;IACA;IACA;IACA;IACA;IACA;;EAIF;IACE;;EAGF;IACE;;EAGF;IACE;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;;EAIF;IAEE;;;ACrGJ;AAAA;AAAA;AAME;EACE;;;AAGF;EACE;;;AAKF;EACE;;;AAEA;EACE;EACA;;;AAKN;EACE;EACA;;;AAGF;AAEE;EACE;EACA;EACA;EACA;EACA;;;AAEA;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAIJ;EACE;EACA;EACA;EACA;EACA;;;AAEA;EACE;EACA;EACA;;;AAGF;EACE;EACA;EACA;;;AAMN;EAyBE;EACA;EACA;EACA;;;AA1BE;EACE;EACA;EACA;EACA;EACA;EACA;;;AAKF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAWN;EACE;EACA;EACA;EACA;EACA;EACA;;;AChHF;EACE;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;EAGF;IACE;;;AAIJ;EAEE;IAEE;;EAGF;IACE;;;ACtCJ;EACE;EACA;EACA;;;AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;EACA;;;AAKA;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;;;AAEA;EACE;EACA;EACA;;;APuqBN;EACE;EACA","file":"style.css"}