wasmdashai commited on
Commit
f7a3016
·
verified ·
1 Parent(s): 8034c5e

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +197 -130
index.html CHANGED
@@ -1,10 +1,9 @@
1
-
2
  <!DOCTYPE html>
3
- <html lang="ar" dir="rtl">
4
  <head>
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>نظام توليد المسارات البحرية المتقدم</title>
8
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
9
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
10
  <style>
@@ -450,7 +449,7 @@
450
  color: var(--primary);
451
  }
452
 
453
- /* تحسينات للشريط الجانبي */
454
  .control-panel::-webkit-scrollbar {
455
  width: 8px;
456
  }
@@ -465,7 +464,7 @@
465
  border-radius: 10px;
466
  }
467
 
468
- /* تصميم متجاوب */
469
  @media (max-width: 1200px) {
470
  .app-container {
471
  grid-template-columns: 1fr;
@@ -518,6 +517,33 @@
518
  border-radius: 12px;
519
  border: 1px solid var(--border);
520
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
521
  </style>
522
  </head>
523
  <body>
@@ -526,12 +552,12 @@
526
  <div class="logo">
527
  <i class="fas fa-ship"></i>
528
  <div class="logo-text">
529
- <h1>نظام توليد المسارات البحرية المتقدم</h1>
530
- <p>توليد مسارات بحرية باستخدام نماذج الذكاء الاصطناعي</p>
531
  </div>
532
  </div>
533
  <div class="header-controls">
534
- <button class="btn-secondary" id="exportBtn"><i class="fas fa-download"></i> تصدير التقرير</button>
535
  </div>
536
  </header>
537
 
@@ -540,35 +566,35 @@
540
  <div class="panel-section">
541
  <div class="section-title">
542
  <i class="fas fa-brain"></i>
543
- <h3>اختيار النموذج</h3>
544
  </div>
545
  <div class="model-cards">
546
  <div class="model-card active" data-model="TrAISformer">
547
  <div class="model-name">TrAISformer</div>
548
- <div class="model-desc">نموذج Transformer متخصص</div>
549
  </div>
550
  <div class="model-card" data-model="EnhcTrAISformer">
551
  <div class="model-name">EnhcTrAISformer</div>
552
- <div class="model-desc">نموذج Transformer محسن</div>
553
  </div>
554
  <div class="model-card" data-model="eDQTI-GRU">
555
  <div class="model-name">eDQTI-GRU</div>
556
- <div class="model-desc">نموذج GRU مع DQTI</div>
557
  </div>
558
  <div class="model-card" data-model="eDQTI-LSTM">
559
  <div class="model-name">eDQTI-LSTM</div>
560
- <div class="model-desc">نموذج LSTM مع DQTI</div>
561
  </div>
562
  <div class="model-card" data-model="eDQTI-HYPER">
563
  <div class="model-name">eDQTI-HYPER</div>
564
- <div class="model-desc">نموذج هجين متقدم</div>
565
  </div>
566
  </div>
567
 
568
  <div class="form-group">
569
- <label for="anomalyModel"><i class="fas fa-exclamation-triangle"></i> نموذج كشف الشذوذ</label>
570
  <select id="anomalyModel">
571
- <option value="auto">تلقائي (بناءً على النموذج الرئيسي)</option>
572
  <option value="isolation-forest">Isolation Forest</option>
573
  <option value="local-outlier">Local Outlier Factor</option>
574
  <option value="svm">One-Class SVM</option>
@@ -580,95 +606,114 @@
580
  <div class="panel-section">
581
  <div class="section-title">
582
  <i class="fas fa-route"></i>
583
- <h3>إعدادات التوليد</h3>
584
  </div>
585
 
586
  <div class="form-group">
587
- <label for="contextInput"><i class="fas fa-code"></i> بيانات السياق (Context)</label>
588
- <textarea id="contextInput" class="context-input" placeholder="أدخل بيانات المسار السياقي هنا..."></textarea>
589
  </div>
590
 
591
  <div class="form-group">
592
- <label><i class="fas fa-map-marker-alt"></i> نقطة البداية</label>
593
  <div class="coordinates-input">
594
  <div class="input-group">
595
- <label>خط العرض</label>
596
  <input type="number" id="startLat" step="0.0001" value="12.6" placeholder="12.6">
597
  </div>
598
  <div class="input-group">
599
- <label>خط الطول</label>
600
  <input type="number" id="startLon" step="0.0001" value="43.0" placeholder="43.0">
601
  </div>
602
  </div>
603
  </div>
604
 
605
  <div class="form-group">
606
- <label><i class="fas fa-flag-checkered"></i> نقطة النهاية</label>
607
  <div class="coordinates-input">
608
  <div class="input-group">
609
- <label>خط العرض</label>
610
  <input type="number" id="endLat" step="0.0001" value="30.5" placeholder="30.5">
611
  </div>
612
  <div class="input-group">
613
- <label>خط الطول</label>
614
  <input type="number" id="endLon" step="0.0001" value="32.3" placeholder="32.3">
615
  </div>
616
  </div>
617
  </div>
618
 
619
  <div class="form-group">
620
- <label for="hours"><i class="fas fa-clock"></i> عدد الساعات للتوليد</label>
621
  <input type="number" id="hours" min="1" max="168" value="24" placeholder="24">
622
  </div>
623
 
624
  <div class="form-group">
625
- <label for="pointsPerHour"><i class="fas fa-map-pin"></i> عدد النقاط في كل ساعة</label>
626
  <input type="number" id="pointsPerHour" min="1" max="10" value="2" placeholder="2">
627
  </div>
628
 
629
- <button id="generateBtn"><i class="fas fa-play"></i> بدء توليد المسار</button>
630
  </div>
631
 
632
  <div class="panel-section">
633
  <div class="section-title">
634
  <i class="fas fa-chart-bar"></i>
635
- <h3>نتائج التوليد</h3>
636
  </div>
637
  <div class="stats-grid">
638
  <div class="stat-card">
639
- <div class="stat-label">النموذج المستخدم</div>
640
  <div class="stat-value" id="usedModel">TrAISformer</div>
641
- <div class="stat-label">نموذج</div>
642
  </div>
643
  <div class="stat-card">
644
- <div class="stat-label">إجمالي النقاط</div>
645
  <div class="stat-value" id="totalPoints">48</div>
646
- <div class="stat-label">نقطة</div>
647
  </div>
648
  <div class="stat-card">
649
- <div class="stat-label">المسافة الإجمالية</div>
650
  <div class="stat-value" id="totalDistance">1,845</div>
651
- <div class="stat-label">كم</div>
652
  </div>
653
  <div class="stat-card">
654
- <div class="stat-label">مستوى الشذوذ</div>
655
  <div class="stat-value" id="anomalyLevel">3.2%</div>
656
- <div class="stat-label">نسبة</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
657
  </div>
658
  </div>
659
 
660
  <div class="anomaly-indicator anomaly-low" id="anomalyIndicator">
661
  <i class="fas fa-check-circle"></i>
662
- <span>المسار طبيعي - لا توجد شذوذات كبيرة</span>
663
  </div>
664
 
665
  <div class="generation-results">
666
- <h4>تفاصيل التوليد:</h4>
667
  <div id="generationDetails">
668
- <p>• النموذج: TrAISformer</p>
669
- <p>• وقت التوليد: 2.3 ثانية</p>
670
- <p>• الدقة: 94.7%</p>
671
- <p>• نقاط الشذوذ: 2 من 48 نقطة</p>
672
  </div>
673
  </div>
674
  </div>
@@ -676,10 +721,10 @@
676
  <div class="panel-section">
677
  <div class="section-title">
678
  <i class="fas fa-history"></i>
679
- <h3>سجل التوليد</h3>
680
  </div>
681
  <div id="generationHistory">
682
- <!-- سيتم ملؤها ديناميكياً -->
683
  </div>
684
  </div>
685
  </div>
@@ -690,7 +735,7 @@
690
  <div class="map-overlay">
691
  <div class="search-box">
692
  <i class="fas fa-search"></i>
693
- <input type="text" placeholder="ابحث عن موقع أو مسار...">
694
  </div>
695
  <div class="map-controls">
696
  <div class="control-btn" id="zoomIn">
@@ -706,27 +751,27 @@
706
  </div>
707
 
708
  <div class="legend">
709
- <div class="legend-title">مفتاح الخريطة</div>
710
  <div class="legend-items">
711
  <div class="legend-item">
712
  <div class="legend-color" style="background: #1e3a8a;"></div>
713
- <span>مسار السياق</span>
714
  </div>
715
  <div class="legend-item">
716
  <div class="legend-color" style="background: #dc2626;"></div>
717
- <span>مسار متولد</span>
718
  </div>
719
  <div class="legend-item">
720
  <div class="legend-color" style="background: #3b82f6;"></div>
721
- <span>نقطة سياق</span>
722
  </div>
723
  <div class="legend-item">
724
  <div class="legend-color" style="background: #ef4444;"></div>
725
- <span>نقطة متولدة</span>
726
  </div>
727
  <div class="legend-item">
728
  <div class="legend-color" style="background: #f59e0b;"></div>
729
- <span>نقطة شذوذ</span>
730
  </div>
731
  </div>
732
  </div>
@@ -736,18 +781,18 @@
736
 
737
  <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
738
  <script>
739
- // تهيئة الخريطة مع طبقة بحر نظيفة
740
  const map = L.map('map', {
741
  zoomControl: false,
742
  attributionControl: false
743
  }).setView([20.0, 38.0], 6);
744
 
745
- // إضافة طبقة خريطة بحرية نظيفة (بدون أسماء الدول)
746
  L.tileLayer('https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
747
  maxZoom: 10
748
  }).addTo(map);
749
 
750
- // إضافة طبقة خاصة بالبحر الأحمر
751
  const redSeaBounds = L.rectangle([[12, 32], [31, 44]], {
752
  color: "#1e3a8a",
753
  fillColor: "#1e3a8a",
@@ -756,18 +801,18 @@
756
  dashArray: '5, 5'
757
  }).addTo(map);
758
 
759
- // النقاط الرئيسية
760
- const babMandeb = [12.6, 43.0]; // باب المندب
761
- const suezCanal = [30.5, 32.3]; // قناة السويس
762
 
763
- // إضافة نقاط البداية والنهاية
764
  L.marker(babMandeb, {
765
  icon: L.divIcon({
766
  className: 'ship-marker',
767
  html: '🚢',
768
  iconSize: [30, 30]
769
  })
770
- }).addTo(map).bindPopup('<div class="route-popup"><div class="popup-title">باب المندب</div><div>نقطة البداية للملاحة في البحر الأحمر</div></div>').openPopup();
771
 
772
  L.marker(suezCanal, {
773
  icon: L.divIcon({
@@ -775,15 +820,15 @@
775
  html: '⚓',
776
  iconSize: [30, 30]
777
  })
778
- }).addTo(map).bindPopup('<div class="route-popup"><div class="popup-title">قناة السويس</div><div>نقطة النهاية للملاحة في البحر الأحمر</div></div>');
779
 
780
- // المتغيرات لتخزين المسارات
781
  let contextRoute = [];
782
  let generatedRoute = [];
783
  let routeLayers = [];
784
  let currentModel = 'TrAISformer';
785
 
786
- // عناصر واجهة المستخدم
787
  const modelCards = document.querySelectorAll('.model-card');
788
  const generateBtn = document.getElementById('generateBtn');
789
  const contextInput = document.getElementById('contextInput');
@@ -803,18 +848,39 @@
803
  const zoomInBtn = document.getElementById('zoomIn');
804
  const zoomOutBtn = document.getElementById('zoomOut');
805
  const locateRedSeaBtn = document.getElementById('locateRedSea');
 
 
 
 
806
 
807
- // معالجة اختيار النموذج
808
  modelCards.forEach(card => {
809
  card.addEventListener('click', () => {
810
  modelCards.forEach(c => c.classList.remove('active'));
811
  card.classList.add('active');
812
  currentModel = card.getAttribute('data-model');
813
  usedModelElem.textContent = currentModel;
 
814
  });
815
  });
816
 
817
- // دالة توليد مسار السياق من الإحداثيات
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
818
  function generateContextRoute() {
819
  const start = [parseFloat(startLat.value), parseFloat(startLon.value)];
820
  const end = [parseFloat(endLat.value), parseFloat(endLon.value)];
@@ -822,10 +888,10 @@
822
  const route = [];
823
  const numPoints = 8;
824
 
825
- // إضافة نقطة البداية
826
  route.push([start[0], start[1]]);
827
 
828
- // توليد نقاط وسيطة
829
  for (let i = 1; i < numPoints - 1; i++) {
830
  const progress = i / (numPoints - 1);
831
  const lat = start[0] + (end[0] - start[0]) * progress + (Math.random() - 0.5) * 0.2;
@@ -834,21 +900,21 @@
834
  route.push([lat, lon]);
835
  }
836
 
837
- // إضافة نقطة النهاية
838
  route.push([end[0], end[1]]);
839
 
840
  return route;
841
  }
842
 
843
- // دالة توليد مسار بناءً على النموذج المختار
844
  function generateRouteWithModel(contextRoute, model, totalHours, pointsPerHour) {
845
  const totalPoints = totalHours * pointsPerHour;
846
  const route = [];
847
 
848
- // إضافة نقطة البداية (نفس بداية السياق)
849
  route.push([contextRoute[0][0], contextRoute[0][1]]);
850
 
851
- // توليد المسار بناءً على النموذج المختار
852
  for (let i = 1; i < totalPoints - 1; i++) {
853
  const progress = i / (totalPoints - 1);
854
  const contextIndex = Math.floor(progress * (contextRoute.length - 1));
@@ -856,30 +922,30 @@
856
 
857
  let lat, lon;
858
 
859
- // محاكاة سلوكيات مختلفة للنماذج
860
  switch(model) {
861
  case 'TrAISformer':
862
- // نمط مباشر مع تحسينات طفيفة
863
  lat = contextPoint[0] + (Math.random() - 0.5) * 0.3;
864
  lon = contextPoint[1] + (Math.random() - 0.5) * 0.4;
865
  break;
866
  case 'EnhcTrAISformer':
867
- // نمط أكثر دقة مع انحرافات أقل
868
  lat = contextPoint[0] + (Math.random() - 0.5) * 0.2;
869
  lon = contextPoint[1] + (Math.random() - 0.5) * 0.3;
870
  break;
871
  case 'eDQTI-GRU':
872
- // نمط مع تذبذبات متوسطة
873
  lat = contextPoint[0] + (Math.random() - 0.5) * 0.4;
874
  lon = contextPoint[1] + (Math.random() - 0.5) * 0.5;
875
  break;
876
  case 'eDQTI-LSTM':
877
- // نمط مع تذبذبات أكبر
878
  lat = contextPoint[0] + (Math.random() - 0.5) * 0.5;
879
  lon = contextPoint[1] + (Math.random() - 0.5) * 0.6;
880
  break;
881
  case 'eDQTI-HYPER':
882
- // نمط هجين مع سلوك متغير
883
  const pattern = Math.sin(progress * Math.PI * 3) * 0.3;
884
  lat = contextPoint[0] + (Math.random() - 0.5) * 0.3 + pattern;
885
  lon = contextPoint[1] + (Math.random() - 0.5) * 0.4 + pattern;
@@ -889,19 +955,19 @@
889
  route.push([lat, lon]);
890
  }
891
 
892
- // إضافة نقطة النهاية (نفس نهاية السياق)
893
  route.push([contextRoute[contextRoute.length - 1][0], contextRoute[contextRoute.length - 1][1]]);
894
 
895
  return route;
896
  }
897
 
898
- // دالة كشف الشذوذ في المسار المتولد
899
  function detectAnomalies(generatedRoute) {
900
  const anomalies = [];
901
 
902
- // محاكاة كشف الشذوذ
903
  for (let i = 0; i < generatedRoute.length; i++) {
904
- // احتمال 10% أن تكون النقطة شاذة
905
  if (Math.random() < 0.1) {
906
  anomalies.push(i);
907
  }
@@ -910,9 +976,9 @@
910
  return anomalies;
911
  }
912
 
913
- // دالة حساب المسافة بين نقطتين
914
  function calculateDistance(lat1, lon1, lat2, lon2) {
915
- const R = 6371; // نصف قطر الأرض بالكيلومترات
916
  const dLat = (lat2 - lat1) * Math.PI / 180;
917
  const dLon = (lon2 - lon1) * Math.PI / 180;
918
  const a =
@@ -923,7 +989,7 @@
923
  return R * c;
924
  }
925
 
926
- // دالة حساب طول المسار
927
  function calculateRouteLength(route) {
928
  let totalDistance = 0;
929
  for (let i = 0; i < route.length - 1; i++) {
@@ -935,12 +1001,12 @@
935
  return Math.round(totalDistance);
936
  }
937
 
938
- // دالة رسم المسارات على الخريطة
939
  function drawRoutes(contextRoute, generatedRoute, anomalies) {
940
- // مسح المسارات السابقة
941
  clearRoutes();
942
 
943
- // رسم مسار السياق
944
  const contextPolyline = L.polyline(contextRoute, {
945
  color: '#1e3a8a',
946
  weight: 3,
@@ -950,9 +1016,9 @@
950
  }).addTo(map);
951
  routeLayers.push(contextPolyline);
952
 
953
- // رسم نقاط السياق
954
  contextRoute.forEach((point, index) => {
955
- if (index % 2 === 0) { // نقاط أقل للسياق
956
  const pointMarker = L.circleMarker(point, {
957
  color: '#3b82f6',
958
  fillColor: '#3b82f6',
@@ -961,11 +1027,11 @@
961
  }).addTo(map);
962
 
963
  pointMarker.bindPopup(`<div class="route-popup">
964
- <div class="popup-title">نقطة السياق ${index + 1}</div>
965
  <div class="popup-details">
966
- <div class="popup-detail"><span class="popup-label">خط العرض:</span> ${point[0].toFixed(4)}</div>
967
- <div class="popup-detail"><span class="popup-label">خط الطول:</span> ${point[1].toFixed(4)}</div>
968
- <div class="popup-detail"><span class="popup-label">النوع:</span> سياق</div>
969
  </div>
970
  </div>`);
971
 
@@ -973,7 +1039,7 @@
973
  }
974
  });
975
 
976
- // رسم المسار المتولد
977
  const generatedPolyline = L.polyline(generatedRoute, {
978
  color: '#dc2626',
979
  weight: 4,
@@ -982,7 +1048,7 @@
982
  }).addTo(map);
983
  routeLayers.push(generatedPolyline);
984
 
985
- // رسم نقاط المسار المتولد
986
  generatedRoute.forEach((point, index) => {
987
  const isAnomaly = anomalies.includes(index);
988
  const pointMarker = L.circleMarker(point, {
@@ -993,31 +1059,31 @@
993
  }).addTo(map);
994
 
995
  pointMarker.bindPopup(`<div class="route-popup">
996
- <div class="popup-title">${isAnomaly ? 'نقطة شذوذ' : 'نقطة متولدة'} ${index + 1}</div>
997
  <div class="popup-details">
998
- <div class="popup-detail"><span class="popup-label">خط العرض:</span> ${point[0].toFixed(4)}</div>
999
- <div class="popup-detail"><span class="popup-label">خط الطول:</span> ${point[1].toFixed(4)}</div>
1000
- <div class="popup-detail"><span class="popup-label">النوع:</span> ${isAnomaly ? 'شذوذ' : 'متولد'}</div>
1001
- <div class="popup-detail"><span class="popup-label">النموذج:</span> ${currentModel}</div>
1002
  </div>
1003
  </div>`);
1004
 
1005
  routeLayers.push(pointMarker);
1006
  });
1007
 
1008
- // ضبط حدود الخريطة لتناسب المسارات
1009
  const allPoints = [...contextRoute, ...generatedRoute];
1010
  const group = L.featureGroup(routeLayers);
1011
  map.fitBounds(group.getBounds().pad(0.1));
1012
  }
1013
 
1014
- // دالة مسح جميع المسارات
1015
  function clearRoutes() {
1016
  routeLayers.forEach(layer => map.removeLayer(layer));
1017
  routeLayers = [];
1018
  }
1019
 
1020
- // دالة تحديث واجهة النتائج
1021
  function updateResults(generatedRoute, anomalies, generationTime) {
1022
  const totalPoints = generatedRoute.length;
1023
  const anomalyPercentage = ((anomalies.length / totalPoints) * 100).toFixed(1);
@@ -1026,41 +1092,42 @@
1026
  totalPointsElem.textContent = totalPoints;
1027
  totalDistanceElem.textContent = distance.toLocaleString();
1028
  anomalyLevelElem.textContent = `${anomalyPercentage}%`;
 
1029
 
1030
- // تحديث مؤشر الشذوذ
1031
  anomalyIndicator.className = 'anomaly-indicator';
1032
  if (anomalyPercentage < 5) {
1033
  anomalyIndicator.classList.add('anomaly-low');
1034
- anomalyIndicator.innerHTML = '<i class="fas fa-check-circle"></i><span>المسار طبيعي - لا توجد شذوذات كبيرة</span>';
1035
  } else if (anomalyPercentage < 15) {
1036
  anomalyIndicator.classList.add('anomaly-medium');
1037
- anomalyIndicator.innerHTML = '<i class="fas fa-exclamation-triangle"></i><span>شذوذ متوسط - يحتاج للمراقبة</span>';
1038
  } else {
1039
  anomalyIndicator.classList.add('anomaly-high');
1040
- anomalyIndicator.innerHTML = '<i class="fas fa-skull-crossbones"></i><span>شذوذ عالي - يحتاج للتدخل الفوري</span>';
1041
  }
1042
 
1043
- // تحديث تفاصيل التوليد
1044
  generationDetails.innerHTML = `
1045
- <p>• النموذج: ${currentModel}</p>
1046
- <p>• وقت التوليد: ${generationTime.toFixed(1)} ثانية</p>
1047
- <p>• الدقة: ${(100 - anomalyPercentage).toFixed(1)}%</p>
1048
- <p>• نقاط الشذوذ: ${anomalies.length} من ${totalPoints} نقطة</p>
1049
- <p>• الساعات: ${hours.value}</p>
1050
- <p>• النقاط/ساعة: ${pointsPerHour.value}</p>
1051
  `;
1052
 
1053
- // إضافة إلى سجل التوليد
1054
  const historyItem = document.createElement('div');
1055
  historyItem.className = 'route-item';
1056
  historyItem.innerHTML = `
1057
  <div class="route-header">
1058
- <div class="route-name">توليد ${new Date().toLocaleString('ar-SA')}</div>
1059
  <div class="route-type">${currentModel}</div>
1060
  </div>
1061
  <div class="route-details">
1062
- <span>النقاط: ${totalPoints}</span>
1063
- <span>الشذوذ: ${anomalyPercentage}%</span>
1064
  </div>
1065
  `;
1066
 
@@ -1070,18 +1137,18 @@
1070
 
1071
  generationHistory.insertBefore(historyItem, generationHistory.firstChild);
1072
 
1073
- // الاحتفاظ بعدد محدود من العناصر في السجل
1074
  if (generationHistory.children.length > 5) {
1075
  generationHistory.removeChild(generationHistory.lastChild);
1076
  }
1077
  }
1078
 
1079
- // معالجة زر التوليد
1080
  generateBtn.addEventListener('click', () => {
1081
- // توليد مسار السياق
1082
  contextRoute = generateContextRoute();
1083
 
1084
- // توليد المسار باستخدام النموذج المختار
1085
  const startTime = performance.now();
1086
  generatedRoute = generateRouteWithModel(
1087
  contextRoute,
@@ -1092,17 +1159,17 @@
1092
  const endTime = performance.now();
1093
  const generationTime = (endTime - startTime) / 1000;
1094
 
1095
- // كشف الشذوذ
1096
  const anomalies = detectAnomalies(generatedRoute);
1097
 
1098
- // رسم المسارات
1099
  drawRoutes(contextRoute, generatedRoute, anomalies);
1100
 
1101
- // تحديث النتائج
1102
  updateResults(generatedRoute, anomalies, generationTime);
1103
  });
1104
 
1105
- // إضافة عناصر التحكم في الخريطة
1106
  zoomInBtn.addEventListener('click', () => {
1107
  map.zoomIn();
1108
  });
@@ -1115,12 +1182,12 @@
1115
  map.setView([20.0, 38.0], 6);
1116
  });
1117
 
1118
- // تحميل بعض البيانات الافتراضية عند بدء التشغيل
1119
  window.addEventListener('load', () => {
1120
- // تعبئة حقل السياق بمثال
1121
- contextInput.value = "مسار تاريخي من باب المندب إلى قناة السويس مع بيانات AIS";
1122
 
1123
- // توليد وعرض مثال أولي
1124
  setTimeout(() => {
1125
  generateBtn.click();
1126
  }, 1000);
 
 
1
  <!DOCTYPE html>
2
+ <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AI-Powered Maritime Route Generation Platform</title>
7
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
 
449
  color: var(--primary);
450
  }
451
 
452
+ /* Scrollbar improvements */
453
  .control-panel::-webkit-scrollbar {
454
  width: 8px;
455
  }
 
464
  border-radius: 10px;
465
  }
466
 
467
+ /* Responsive design */
468
  @media (max-width: 1200px) {
469
  .app-container {
470
  grid-template-columns: 1fr;
 
517
  border-radius: 12px;
518
  border: 1px solid var(--border);
519
  }
520
+
521
+ .performance-metrics {
522
+ display: grid;
523
+ grid-template-columns: 1fr 1fr;
524
+ gap: 10px;
525
+ margin-top: 15px;
526
+ }
527
+
528
+ .metric {
529
+ text-align: center;
530
+ padding: 10px;
531
+ background: var(--background);
532
+ border-radius: 8px;
533
+ border: 1px solid var(--border);
534
+ }
535
+
536
+ .metric-value {
537
+ font-weight: bold;
538
+ font-size: 1.2rem;
539
+ color: var(--primary);
540
+ }
541
+
542
+ .metric-label {
543
+ font-size: 0.8rem;
544
+ color: var(--dark);
545
+ opacity: 0.8;
546
+ }
547
  </style>
548
  </head>
549
  <body>
 
552
  <div class="logo">
553
  <i class="fas fa-ship"></i>
554
  <div class="logo-text">
555
+ <h1>AI-Powered Maritime Route Generation</h1>
556
+ <p>Advanced route prediction and anomaly detection</p>
557
  </div>
558
  </div>
559
  <div class="header-controls">
560
+ <button class="btn-secondary" id="exportBtn"><i class="fas fa-download"></i> Export Report</button>
561
  </div>
562
  </header>
563
 
 
566
  <div class="panel-section">
567
  <div class="section-title">
568
  <i class="fas fa-brain"></i>
569
+ <h3>AI Model Selection</h3>
570
  </div>
571
  <div class="model-cards">
572
  <div class="model-card active" data-model="TrAISformer">
573
  <div class="model-name">TrAISformer</div>
574
+ <div class="model-desc">Transformer-based model</div>
575
  </div>
576
  <div class="model-card" data-model="EnhcTrAISformer">
577
  <div class="model-name">EnhcTrAISformer</div>
578
+ <div class="model-desc">Enhanced Transformer</div>
579
  </div>
580
  <div class="model-card" data-model="eDQTI-GRU">
581
  <div class="model-name">eDQTI-GRU</div>
582
+ <div class="model-desc">GRU with DQTI</div>
583
  </div>
584
  <div class="model-card" data-model="eDQTI-LSTM">
585
  <div class="model-name">eDQTI-LSTM</div>
586
+ <div class="model-desc">LSTM with DQTI</div>
587
  </div>
588
  <div class="model-card" data-model="eDQTI-HYPER">
589
  <div class="model-name">eDQTI-HYPER</div>
590
+ <div class="model-desc">Advanced hybrid model</div>
591
  </div>
592
  </div>
593
 
594
  <div class="form-group">
595
+ <label for="anomalyModel"><i class="fas fa-exclamation-triangle"></i> Anomaly Detection Model</label>
596
  <select id="anomalyModel">
597
+ <option value="auto">Auto (Based on main model)</option>
598
  <option value="isolation-forest">Isolation Forest</option>
599
  <option value="local-outlier">Local Outlier Factor</option>
600
  <option value="svm">One-Class SVM</option>
 
606
  <div class="panel-section">
607
  <div class="section-title">
608
  <i class="fas fa-route"></i>
609
+ <h3>Generation Settings</h3>
610
  </div>
611
 
612
  <div class="form-group">
613
+ <label for="contextInput"><i class="fas fa-code"></i> Context Data</label>
614
+ <textarea id="contextInput" class="context-input" placeholder="Enter route context data here...">Historical route from Bab el Mandeb to Suez Canal with AIS data</textarea>
615
  </div>
616
 
617
  <div class="form-group">
618
+ <label><i class="fas fa-map-marker-alt"></i> Start Point</label>
619
  <div class="coordinates-input">
620
  <div class="input-group">
621
+ <label>Latitude</label>
622
  <input type="number" id="startLat" step="0.0001" value="12.6" placeholder="12.6">
623
  </div>
624
  <div class="input-group">
625
+ <label>Longitude</label>
626
  <input type="number" id="startLon" step="0.0001" value="43.0" placeholder="43.0">
627
  </div>
628
  </div>
629
  </div>
630
 
631
  <div class="form-group">
632
+ <label><i class="fas fa-flag-checkered"></i> End Point</label>
633
  <div class="coordinates-input">
634
  <div class="input-group">
635
+ <label>Latitude</label>
636
  <input type="number" id="endLat" step="0.0001" value="30.5" placeholder="30.5">
637
  </div>
638
  <div class="input-group">
639
+ <label>Longitude</label>
640
  <input type="number" id="endLon" step="0.0001" value="32.3" placeholder="32.3">
641
  </div>
642
  </div>
643
  </div>
644
 
645
  <div class="form-group">
646
+ <label for="hours"><i class="fas fa-clock"></i> Hours to Generate</label>
647
  <input type="number" id="hours" min="1" max="168" value="24" placeholder="24">
648
  </div>
649
 
650
  <div class="form-group">
651
+ <label for="pointsPerHour"><i class="fas fa-map-pin"></i> Points per Hour</label>
652
  <input type="number" id="pointsPerHour" min="1" max="10" value="2" placeholder="2">
653
  </div>
654
 
655
+ <button id="generateBtn"><i class="fas fa-play"></i> Generate Route</button>
656
  </div>
657
 
658
  <div class="panel-section">
659
  <div class="section-title">
660
  <i class="fas fa-chart-bar"></i>
661
+ <h3>Generation Results</h3>
662
  </div>
663
  <div class="stats-grid">
664
  <div class="stat-card">
665
+ <div class="stat-label">Model Used</div>
666
  <div class="stat-value" id="usedModel">TrAISformer</div>
667
+ <div class="stat-label">Model</div>
668
  </div>
669
  <div class="stat-card">
670
+ <div class="stat-label">Total Points</div>
671
  <div class="stat-value" id="totalPoints">48</div>
672
+ <div class="stat-label">Points</div>
673
  </div>
674
  <div class="stat-card">
675
+ <div class="stat-label">Total Distance</div>
676
  <div class="stat-value" id="totalDistance">1,845</div>
677
+ <div class="stat-label">km</div>
678
  </div>
679
  <div class="stat-card">
680
+ <div class="stat-label">Anomaly Level</div>
681
  <div class="stat-value" id="anomalyLevel">3.2%</div>
682
+ <div class="stat-label">Ratio</div>
683
+ </div>
684
+ </div>
685
+
686
+ <div class="performance-metrics">
687
+ <div class="metric">
688
+ <div class="metric-value" id="accuracy">94.7%</div>
689
+ <div class="metric-label">Accuracy</div>
690
+ </div>
691
+ <div class="metric">
692
+ <div class="metric-value" id="confidence">87%</div>
693
+ <div class="metric-label">Confidence</div>
694
+ </div>
695
+ <div class="metric">
696
+ <div class="metric-value" id="generationTime">2.3s</div>
697
+ <div class="metric-label">Generation Time</div>
698
+ </div>
699
+ <div class="metric">
700
+ <div class="metric-value" id="modelScore">92</div>
701
+ <div class="metric-label">Model Score</div>
702
  </div>
703
  </div>
704
 
705
  <div class="anomaly-indicator anomaly-low" id="anomalyIndicator">
706
  <i class="fas fa-check-circle"></i>
707
+ <span>Route Normal - No Significant Anomalies</span>
708
  </div>
709
 
710
  <div class="generation-results">
711
+ <h4>Generation Details:</h4>
712
  <div id="generationDetails">
713
+ <p>• Model: TrAISformer</p>
714
+ <p>• Generation Time: 2.3 seconds</p>
715
+ <p>• Accuracy: 94.7%</p>
716
+ <p>• Anomaly Points: 2 of 48 points</p>
717
  </div>
718
  </div>
719
  </div>
 
721
  <div class="panel-section">
722
  <div class="section-title">
723
  <i class="fas fa-history"></i>
724
+ <h3>Generation History</h3>
725
  </div>
726
  <div id="generationHistory">
727
+ <!-- Will be populated dynamically -->
728
  </div>
729
  </div>
730
  </div>
 
735
  <div class="map-overlay">
736
  <div class="search-box">
737
  <i class="fas fa-search"></i>
738
+ <input type="text" placeholder="Search for location or route...">
739
  </div>
740
  <div class="map-controls">
741
  <div class="control-btn" id="zoomIn">
 
751
  </div>
752
 
753
  <div class="legend">
754
+ <div class="legend-title">Map Legend</div>
755
  <div class="legend-items">
756
  <div class="legend-item">
757
  <div class="legend-color" style="background: #1e3a8a;"></div>
758
+ <span>Context Route</span>
759
  </div>
760
  <div class="legend-item">
761
  <div class="legend-color" style="background: #dc2626;"></div>
762
+ <span>Generated Route</span>
763
  </div>
764
  <div class="legend-item">
765
  <div class="legend-color" style="background: #3b82f6;"></div>
766
+ <span>Context Point</span>
767
  </div>
768
  <div class="legend-item">
769
  <div class="legend-color" style="background: #ef4444;"></div>
770
+ <span>Generated Point</span>
771
  </div>
772
  <div class="legend-item">
773
  <div class="legend-color" style="background: #f59e0b;"></div>
774
+ <span>Anomaly Point</span>
775
  </div>
776
  </div>
777
  </div>
 
781
 
782
  <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
783
  <script>
784
+ // Initialize map with clean sea layer
785
  const map = L.map('map', {
786
  zoomControl: false,
787
  attributionControl: false
788
  }).setView([20.0, 38.0], 6);
789
 
790
+ // Add clean maritime map layer (no country names)
791
  L.tileLayer('https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
792
  maxZoom: 10
793
  }).addTo(map);
794
 
795
+ // Add Red Sea specific layer
796
  const redSeaBounds = L.rectangle([[12, 32], [31, 44]], {
797
  color: "#1e3a8a",
798
  fillColor: "#1e3a8a",
 
801
  dashArray: '5, 5'
802
  }).addTo(map);
803
 
804
+ // Key points
805
+ const babMandeb = [12.6, 43.0]; // Bab el Mandeb
806
+ const suezCanal = [30.5, 32.3]; // Suez Canal
807
 
808
+ // Add start and end points
809
  L.marker(babMandeb, {
810
  icon: L.divIcon({
811
  className: 'ship-marker',
812
  html: '🚢',
813
  iconSize: [30, 30]
814
  })
815
+ }).addTo(map).bindPopup('<div class="route-popup"><div class="popup-title">Bab el Mandeb</div><div>Starting point for Red Sea navigation</div></div>').openPopup();
816
 
817
  L.marker(suezCanal, {
818
  icon: L.divIcon({
 
820
  html: '⚓',
821
  iconSize: [30, 30]
822
  })
823
+ }).addTo(map).bindPopup('<div class="route-popup"><div class="popup-title">Suez Canal</div><div>End point for Red Sea navigation</div></div>');
824
 
825
+ // Variables to store routes
826
  let contextRoute = [];
827
  let generatedRoute = [];
828
  let routeLayers = [];
829
  let currentModel = 'TrAISformer';
830
 
831
+ // UI Elements
832
  const modelCards = document.querySelectorAll('.model-card');
833
  const generateBtn = document.getElementById('generateBtn');
834
  const contextInput = document.getElementById('contextInput');
 
848
  const zoomInBtn = document.getElementById('zoomIn');
849
  const zoomOutBtn = document.getElementById('zoomOut');
850
  const locateRedSeaBtn = document.getElementById('locateRedSea');
851
+ const accuracyElem = document.getElementById('accuracy');
852
+ const confidenceElem = document.getElementById('confidence');
853
+ const generationTimeElem = document.getElementById('generationTime');
854
+ const modelScoreElem = document.getElementById('modelScore');
855
 
856
+ // Model selection handling
857
  modelCards.forEach(card => {
858
  card.addEventListener('click', () => {
859
  modelCards.forEach(c => c.classList.remove('active'));
860
  card.classList.add('active');
861
  currentModel = card.getAttribute('data-model');
862
  usedModelElem.textContent = currentModel;
863
+ updateModelMetrics(currentModel);
864
  });
865
  });
866
 
867
+ // Update metrics based on selected model
868
+ function updateModelMetrics(model) {
869
+ const metrics = {
870
+ 'TrAISformer': { accuracy: '94.7%', confidence: '87%', score: 92 },
871
+ 'EnhcTrAISformer': { accuracy: '96.2%', confidence: '91%', score: 95 },
872
+ 'eDQTI-GRU': { accuracy: '92.1%', confidence: '84%', score: 88 },
873
+ 'eDQTI-LSTM': { accuracy: '93.5%', confidence: '86%', score: 90 },
874
+ 'eDQTI-HYPER': { accuracy: '95.8%', confidence: '89%', score: 93 }
875
+ };
876
+
877
+ const metric = metrics[model];
878
+ accuracyElem.textContent = metric.accuracy;
879
+ confidenceElem.textContent = metric.confidence;
880
+ modelScoreElem.textContent = metric.score;
881
+ }
882
+
883
+ // Generate context route from coordinates
884
  function generateContextRoute() {
885
  const start = [parseFloat(startLat.value), parseFloat(startLon.value)];
886
  const end = [parseFloat(endLat.value), parseFloat(endLon.value)];
 
888
  const route = [];
889
  const numPoints = 8;
890
 
891
+ // Add starting point
892
  route.push([start[0], start[1]]);
893
 
894
+ // Generate intermediate points
895
  for (let i = 1; i < numPoints - 1; i++) {
896
  const progress = i / (numPoints - 1);
897
  const lat = start[0] + (end[0] - start[0]) * progress + (Math.random() - 0.5) * 0.2;
 
900
  route.push([lat, lon]);
901
  }
902
 
903
+ // Add end point
904
  route.push([end[0], end[1]]);
905
 
906
  return route;
907
  }
908
 
909
+ // Generate route based on selected model
910
  function generateRouteWithModel(contextRoute, model, totalHours, pointsPerHour) {
911
  const totalPoints = totalHours * pointsPerHour;
912
  const route = [];
913
 
914
+ // Add starting point (same as context start)
915
  route.push([contextRoute[0][0], contextRoute[0][1]]);
916
 
917
+ // Generate route based on selected model
918
  for (let i = 1; i < totalPoints - 1; i++) {
919
  const progress = i / (totalPoints - 1);
920
  const contextIndex = Math.floor(progress * (contextRoute.length - 1));
 
922
 
923
  let lat, lon;
924
 
925
+ // Simulate different model behaviors
926
  switch(model) {
927
  case 'TrAISformer':
928
+ // Direct pattern with minor improvements
929
  lat = contextPoint[0] + (Math.random() - 0.5) * 0.3;
930
  lon = contextPoint[1] + (Math.random() - 0.5) * 0.4;
931
  break;
932
  case 'EnhcTrAISformer':
933
+ // More precise pattern with less deviation
934
  lat = contextPoint[0] + (Math.random() - 0.5) * 0.2;
935
  lon = contextPoint[1] + (Math.random() - 0.5) * 0.3;
936
  break;
937
  case 'eDQTI-GRU':
938
+ // Pattern with medium oscillations
939
  lat = contextPoint[0] + (Math.random() - 0.5) * 0.4;
940
  lon = contextPoint[1] + (Math.random() - 0.5) * 0.5;
941
  break;
942
  case 'eDQTI-LSTM':
943
+ // Pattern with larger oscillations
944
  lat = contextPoint[0] + (Math.random() - 0.5) * 0.5;
945
  lon = contextPoint[1] + (Math.random() - 0.5) * 0.6;
946
  break;
947
  case 'eDQTI-HYPER':
948
+ // Hybrid pattern with varying behavior
949
  const pattern = Math.sin(progress * Math.PI * 3) * 0.3;
950
  lat = contextPoint[0] + (Math.random() - 0.5) * 0.3 + pattern;
951
  lon = contextPoint[1] + (Math.random() - 0.5) * 0.4 + pattern;
 
955
  route.push([lat, lon]);
956
  }
957
 
958
+ // Add end point (same as context end)
959
  route.push([contextRoute[contextRoute.length - 1][0], contextRoute[contextRoute.length - 1][1]]);
960
 
961
  return route;
962
  }
963
 
964
+ // Detect anomalies in generated route
965
  function detectAnomalies(generatedRoute) {
966
  const anomalies = [];
967
 
968
+ // Simulate anomaly detection
969
  for (let i = 0; i < generatedRoute.length; i++) {
970
+ // 10% chance of being an anomaly point
971
  if (Math.random() < 0.1) {
972
  anomalies.push(i);
973
  }
 
976
  return anomalies;
977
  }
978
 
979
+ // Calculate distance between two points
980
  function calculateDistance(lat1, lon1, lat2, lon2) {
981
+ const R = 6371; // Earth radius in kilometers
982
  const dLat = (lat2 - lat1) * Math.PI / 180;
983
  const dLon = (lon2 - lon1) * Math.PI / 180;
984
  const a =
 
989
  return R * c;
990
  }
991
 
992
+ // Calculate route length
993
  function calculateRouteLength(route) {
994
  let totalDistance = 0;
995
  for (let i = 0; i < route.length - 1; i++) {
 
1001
  return Math.round(totalDistance);
1002
  }
1003
 
1004
+ // Draw routes on map
1005
  function drawRoutes(contextRoute, generatedRoute, anomalies) {
1006
+ // Clear previous routes
1007
  clearRoutes();
1008
 
1009
+ // Draw context route
1010
  const contextPolyline = L.polyline(contextRoute, {
1011
  color: '#1e3a8a',
1012
  weight: 3,
 
1016
  }).addTo(map);
1017
  routeLayers.push(contextPolyline);
1018
 
1019
+ // Draw context points
1020
  contextRoute.forEach((point, index) => {
1021
+ if (index % 2 === 0) { // Fewer points for context
1022
  const pointMarker = L.circleMarker(point, {
1023
  color: '#3b82f6',
1024
  fillColor: '#3b82f6',
 
1027
  }).addTo(map);
1028
 
1029
  pointMarker.bindPopup(`<div class="route-popup">
1030
+ <div class="popup-title">Context Point ${index + 1}</div>
1031
  <div class="popup-details">
1032
+ <div class="popup-detail"><span class="popup-label">Latitude:</span> ${point[0].toFixed(4)}</div>
1033
+ <div class="popup-detail"><span class="popup-label">Longitude:</span> ${point[1].toFixed(4)}</div>
1034
+ <div class="popup-detail"><span class="popup-label">Type:</span> Context</div>
1035
  </div>
1036
  </div>`);
1037
 
 
1039
  }
1040
  });
1041
 
1042
+ // Draw generated route
1043
  const generatedPolyline = L.polyline(generatedRoute, {
1044
  color: '#dc2626',
1045
  weight: 4,
 
1048
  }).addTo(map);
1049
  routeLayers.push(generatedPolyline);
1050
 
1051
+ // Draw generated route points
1052
  generatedRoute.forEach((point, index) => {
1053
  const isAnomaly = anomalies.includes(index);
1054
  const pointMarker = L.circleMarker(point, {
 
1059
  }).addTo(map);
1060
 
1061
  pointMarker.bindPopup(`<div class="route-popup">
1062
+ <div class="popup-title">${isAnomaly ? 'Anomaly Point' : 'Generated Point'} ${index + 1}</div>
1063
  <div class="popup-details">
1064
+ <div class="popup-detail"><span class="popup-label">Latitude:</span> ${point[0].toFixed(4)}</div>
1065
+ <div class="popup-detail"><span class="popup-label">Longitude:</span> ${point[1].toFixed(4)}</div>
1066
+ <div class="popup-detail"><span class="popup-label">Type:</span> ${isAnomaly ? 'Anomaly' : 'Generated'}</div>
1067
+ <div class="popup-detail"><span class="popup-label">Model:</span> ${currentModel}</div>
1068
  </div>
1069
  </div>`);
1070
 
1071
  routeLayers.push(pointMarker);
1072
  });
1073
 
1074
+ // Adjust map bounds to fit routes
1075
  const allPoints = [...contextRoute, ...generatedRoute];
1076
  const group = L.featureGroup(routeLayers);
1077
  map.fitBounds(group.getBounds().pad(0.1));
1078
  }
1079
 
1080
+ // Clear all routes
1081
  function clearRoutes() {
1082
  routeLayers.forEach(layer => map.removeLayer(layer));
1083
  routeLayers = [];
1084
  }
1085
 
1086
+ // Update results interface
1087
  function updateResults(generatedRoute, anomalies, generationTime) {
1088
  const totalPoints = generatedRoute.length;
1089
  const anomalyPercentage = ((anomalies.length / totalPoints) * 100).toFixed(1);
 
1092
  totalPointsElem.textContent = totalPoints;
1093
  totalDistanceElem.textContent = distance.toLocaleString();
1094
  anomalyLevelElem.textContent = `${anomalyPercentage}%`;
1095
+ generationTimeElem.textContent = `${generationTime.toFixed(1)}s`;
1096
 
1097
+ // Update anomaly indicator
1098
  anomalyIndicator.className = 'anomaly-indicator';
1099
  if (anomalyPercentage < 5) {
1100
  anomalyIndicator.classList.add('anomaly-low');
1101
+ anomalyIndicator.innerHTML = '<i class="fas fa-check-circle"></i><span>Route Normal - No Significant Anomalies</span>';
1102
  } else if (anomalyPercentage < 15) {
1103
  anomalyIndicator.classList.add('anomaly-medium');
1104
+ anomalyIndicator.innerHTML = '<i class="fas fa-exclamation-triangle"></i><span>Medium Anomaly - Requires Monitoring</span>';
1105
  } else {
1106
  anomalyIndicator.classList.add('anomaly-high');
1107
+ anomalyIndicator.innerHTML = '<i class="fas fa-skull-crossbones"></i><span>High Anomaly - Immediate Intervention Required</span>';
1108
  }
1109
 
1110
+ // Update generation details
1111
  generationDetails.innerHTML = `
1112
+ <p>• Model: ${currentModel}</p>
1113
+ <p>• Generation Time: ${generationTime.toFixed(1)} seconds</p>
1114
+ <p>• Accuracy: ${(100 - anomalyPercentage).toFixed(1)}%</p>
1115
+ <p>• Anomaly Points: ${anomalies.length} of ${totalPoints} points</p>
1116
+ <p>• Hours: ${hours.value}</p>
1117
+ <p>• Points/Hour: ${pointsPerHour.value}</p>
1118
  `;
1119
 
1120
+ // Add to generation history
1121
  const historyItem = document.createElement('div');
1122
  historyItem.className = 'route-item';
1123
  historyItem.innerHTML = `
1124
  <div class="route-header">
1125
+ <div class="route-name">Generation ${new Date().toLocaleString()}</div>
1126
  <div class="route-type">${currentModel}</div>
1127
  </div>
1128
  <div class="route-details">
1129
+ <span>Points: ${totalPoints}</span>
1130
+ <span>Anomaly: ${anomalyPercentage}%</span>
1131
  </div>
1132
  `;
1133
 
 
1137
 
1138
  generationHistory.insertBefore(historyItem, generationHistory.firstChild);
1139
 
1140
+ // Keep limited items in history
1141
  if (generationHistory.children.length > 5) {
1142
  generationHistory.removeChild(generationHistory.lastChild);
1143
  }
1144
  }
1145
 
1146
+ // Generate button handler
1147
  generateBtn.addEventListener('click', () => {
1148
+ // Generate context route
1149
  contextRoute = generateContextRoute();
1150
 
1151
+ // Generate route using selected model
1152
  const startTime = performance.now();
1153
  generatedRoute = generateRouteWithModel(
1154
  contextRoute,
 
1159
  const endTime = performance.now();
1160
  const generationTime = (endTime - startTime) / 1000;
1161
 
1162
+ // Detect anomalies
1163
  const anomalies = detectAnomalies(generatedRoute);
1164
 
1165
+ // Draw routes
1166
  drawRoutes(contextRoute, generatedRoute, anomalies);
1167
 
1168
+ // Update results
1169
  updateResults(generatedRoute, anomalies, generationTime);
1170
  });
1171
 
1172
+ // Map control elements
1173
  zoomInBtn.addEventListener('click', () => {
1174
  map.zoomIn();
1175
  });
 
1182
  map.setView([20.0, 38.0], 6);
1183
  });
1184
 
1185
+ // Load default data on startup
1186
  window.addEventListener('load', () => {
1187
+ // Update metrics for initial model
1188
+ updateModelMetrics(currentModel);
1189
 
1190
+ // Generate and display initial example
1191
  setTimeout(() => {
1192
  generateBtn.click();
1193
  }, 1000);