OUAREDAEK commited on
Commit
a96502b
·
verified ·
1 Parent(s): c561cf3

Upload templates/index-old4.html with huggingface_hub

Browse files
Files changed (1) hide show
  1. templates/index-old4.html +2764 -0
templates/index-old4.html ADDED
@@ -0,0 +1,2764 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Dashboard Réflexif – ReflAgent</title>
7
+
8
+ <style>
9
+ /* ================= STYLES DE BASE ================= */
10
+ body {
11
+ font-family: 'Segoe UI', Arial, sans-serif;
12
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
13
+ margin: 0;
14
+ padding: 20px;
15
+ color: #333;
16
+ }
17
+
18
+ h2, h3, h4 {
19
+ color: #1976D2;
20
+ margin-top: 0;
21
+ }
22
+
23
+ h2 {
24
+ background: linear-gradient(90deg, #1976D2, #2196F3);
25
+ -webkit-background-clip: text;
26
+ -webkit-text-fill-color: transparent;
27
+ padding: 10px 0;
28
+ border-bottom: 2px solid #e3f2fd;
29
+ margin-bottom: 25px;
30
+ }
31
+
32
+ h3 {
33
+ background: #e3f2fd;
34
+ padding: 12px 15px;
35
+ border-radius: 8px;
36
+ margin: 25px 0 15px;
37
+ display: flex;
38
+ align-items: center;
39
+ gap: 10px;
40
+ }
41
+
42
+ h3::before {
43
+ content: '';
44
+ display: inline-block;
45
+ width: 6px;
46
+ height: 24px;
47
+ background: #1976D2;
48
+ border-radius: 3px;
49
+ }
50
+
51
+ #reflection {
52
+ background: white;
53
+ padding: 30px;
54
+ border-radius: 20px;
55
+ max-width: 1400px;
56
+ margin: auto;
57
+ box-shadow: 0 10px 40px rgba(0,0,0,0.08);
58
+ border: 1px solid #e0e0e0;
59
+ }
60
+
61
+ /* ================= SYSTEME D'ONGLETS ================= */
62
+ .tabs-container {
63
+ margin-bottom: 30px;
64
+ }
65
+
66
+ .tabs {
67
+ display: flex;
68
+ background: #f8f9fa;
69
+ border-radius: 12px;
70
+ padding: 5px;
71
+ margin-bottom: 20px;
72
+ border: 1px solid #e0e0e0;
73
+ }
74
+
75
+ .tab-btn {
76
+ flex: 1;
77
+ padding: 15px 20px;
78
+ border: none;
79
+ background: transparent;
80
+ color: #666;
81
+ font-weight: 600;
82
+ font-size: 16px;
83
+ cursor: pointer;
84
+ border-radius: 8px;
85
+ transition: all 0.3s ease;
86
+ display: flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ gap: 10px;
90
+ }
91
+
92
+ .tab-btn:hover {
93
+ background: rgba(25, 118, 210, 0.1);
94
+ color: #1976D2;
95
+ }
96
+
97
+ .tab-btn.active {
98
+ background: #1976D2;
99
+ color: white;
100
+ box-shadow: 0 3px 8px rgba(25, 118, 210, 0.2);
101
+ }
102
+
103
+ .tab-content {
104
+ display: none;
105
+ animation: fadeIn 0.5s ease;
106
+ }
107
+
108
+ .tab-content.active {
109
+ display: block;
110
+ }
111
+
112
+ /* ================= NAVIGATION ================= */
113
+ .nav {
114
+ display: flex;
115
+ justify-content: space-between;
116
+ align-items: center;
117
+ margin-bottom: 30px;
118
+ background: linear-gradient(90deg, #e3f2fd, #f3e5f5);
119
+ padding: 15px 25px;
120
+ border-radius: 12px;
121
+ border: 1px solid #bbdefb;
122
+ }
123
+
124
+ #scenarioTitle {
125
+ font-size: 1.4em;
126
+ color: #333;
127
+ text-align: center;
128
+ flex-grow: 1;
129
+ margin: 0 20px;
130
+ }
131
+
132
+ button {
133
+ background: linear-gradient(135deg, #1976D2, #2196F3);
134
+ color: white;
135
+ border: none;
136
+ padding: 12px 25px;
137
+ border-radius: 10px;
138
+ cursor: pointer;
139
+ font-weight: 600;
140
+ font-size: 15px;
141
+ transition: all 0.3s ease;
142
+ box-shadow: 0 3px 8px rgba(25, 118, 210, 0.2);
143
+ display: flex;
144
+ align-items: center;
145
+ gap: 8px;
146
+ }
147
+
148
+ button:hover:not(:disabled) {
149
+ transform: translateY(-2px);
150
+ box-shadow: 0 5px 15px rgba(25, 118, 210, 0.3);
151
+ }
152
+
153
+ button:active:not(:disabled) {
154
+ transform: translateY(0);
155
+ }
156
+
157
+ button:disabled {
158
+ opacity: 0.5;
159
+ cursor: not-allowed;
160
+ background: #b0bec5;
161
+ }
162
+
163
+ /* ================= BOUTON LECTURE CROISÉE ================= */
164
+ #crossReadersBtn {
165
+ background: linear-gradient(135deg, #43A047, #4CAF50) !important;
166
+ color: white;
167
+ border: none;
168
+ padding: 12px 25px;
169
+ border-radius: 10px;
170
+ cursor: pointer;
171
+ font-weight: 600;
172
+ font-size: 15px;
173
+ transition: all 0.3s ease;
174
+ box-shadow: 0 3px 8px rgba(67, 160, 71, 0.2);
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: center;
178
+ gap: 8px;
179
+ width: 100%;
180
+ }
181
+
182
+ #crossReadersBtn:hover:not(:disabled) {
183
+ transform: translateY(-2px);
184
+ box-shadow: 0 5px 15px rgba(67, 160, 71, 0.3);
185
+ background: linear-gradient(135deg, #388E3C, #43A047) !important;
186
+ }
187
+
188
+ #crossReadersBtn:active:not(:disabled) {
189
+ transform: translateY(0);
190
+ }
191
+
192
+ #crossReadersBtn:disabled {
193
+ opacity: 0.5;
194
+ cursor: not-allowed;
195
+ background: #b0bec5 !important;
196
+ }
197
+
198
+ /* ================= ONGLET 1: ÉVALUATEUR GDPR ================= */
199
+ #tab-evaluator .evaluator-info {
200
+ background: linear-gradient(135deg, #fff3e0, #ffe0b2);
201
+ padding: 25px;
202
+ border-radius: 15px;
203
+ border-left: 6px solid #ff9800;
204
+ margin: 20px 0;
205
+ }
206
+
207
+ #tab-evaluator .evaluator-info h4 {
208
+ color: #ff9800;
209
+ margin-top: 0;
210
+ margin-bottom: 20px;
211
+ display: flex;
212
+ align-items: center;
213
+ gap: 10px;
214
+ font-size: 20px;
215
+ }
216
+
217
+ .evaluator-field {
218
+ margin-bottom: 20px;
219
+ background: white;
220
+ padding: 20px;
221
+ border-radius: 10px;
222
+ border: 1px solid #FFE0B2;
223
+ }
224
+
225
+ .evaluator-field label {
226
+ display: block;
227
+ margin-bottom: 12px;
228
+ color: #333;
229
+ font-weight: 600;
230
+ font-size: 15px;
231
+ }
232
+
233
+ .evaluator-field input[type="text"],
234
+ .evaluator-field select {
235
+ width: 100%;
236
+ padding: 14px 18px;
237
+ border: 2px solid #e0e0e0;
238
+ border-radius: 8px;
239
+ font-size: 15px;
240
+ transition: all 0.3s;
241
+ box-sizing: border-box;
242
+ background: white;
243
+ }
244
+
245
+ .evaluator-field input[type="text"]:focus,
246
+ .evaluator-field select:focus {
247
+ outline: none;
248
+ border-color: #1976D2;
249
+ box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);
250
+ }
251
+
252
+ .evaluator-field input:disabled,
253
+ .evaluator-field select:disabled {
254
+ background: #f5f5f5;
255
+ color: #999;
256
+ cursor: not-allowed;
257
+ }
258
+
259
+ .evaluator-field small {
260
+ display: block;
261
+ margin-top: 8px;
262
+ color: #666;
263
+ font-size: 13px;
264
+ font-style: italic;
265
+ }
266
+
267
+ /* Style pour les boutons radio GDPR */
268
+ .gdpr-options {
269
+ display: flex;
270
+ gap: 30px;
271
+ margin-top: 10px;
272
+ flex-wrap: wrap;
273
+ }
274
+
275
+ .gdpr-option {
276
+ display: flex;
277
+ align-items: center;
278
+ gap: 10px;
279
+ cursor: pointer;
280
+ padding: 12px 20px;
281
+ border-radius: 8px;
282
+ background: white;
283
+ border: 2px solid #e0e0e0;
284
+ transition: all 0.3s;
285
+ flex: 1;
286
+ min-width: 250px;
287
+ }
288
+
289
+ .gdpr-option:hover {
290
+ border-color: #1976D2;
291
+ background: #f0f7ff;
292
+ }
293
+
294
+ .gdpr-option input[type="radio"] {
295
+ width: 20px;
296
+ height: 20px;
297
+ cursor: pointer;
298
+ }
299
+
300
+ .gdpr-option span {
301
+ font-size: 15px;
302
+ font-weight: 500;
303
+ color: #333;
304
+ }
305
+
306
+ #anonymousMessage {
307
+ background: #E3F2FD;
308
+ padding: 18px;
309
+ border-radius: 10px;
310
+ margin-top: 20px;
311
+ border-left: 4px solid #1976D2;
312
+ animation: fadeIn 0.5s ease;
313
+ }
314
+
315
+ #anonymousMessage p {
316
+ margin: 0;
317
+ color: #1976D2;
318
+ font-size: 14px;
319
+ line-height: 1.5;
320
+ }
321
+
322
+ /* ================= ONGLET 2: DASHBOARD ÉTUDIANT COMPACT ================= */
323
+ #tab-dashboard .manifest-item {
324
+ background: linear-gradient(135deg, #f9fbe7, #f0f4c3);
325
+ padding: 15px;
326
+ border-radius: 12px;
327
+ border-left: 6px solid #cddc39;
328
+ margin: 15px 0;
329
+ box-shadow: 0 3px 10px rgba(0,0,0,0.05);
330
+ font-size: 14px;
331
+ }
332
+
333
+ .manifest-item b {
334
+ color: #689f38;
335
+ }
336
+
337
+ /* ================= COMPÉTENCES COMPACTES ================= */
338
+ #competence-bars {
339
+ background: white;
340
+ padding: 15px;
341
+ border-radius: 12px;
342
+ border: 1px solid #e0e0e0;
343
+ margin: 15px 0;
344
+ }
345
+
346
+ .compact-competences-grid {
347
+ display: grid;
348
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
349
+ gap: 12px;
350
+ margin: 10px 0;
351
+ }
352
+
353
+ .compact-competence-item {
354
+ padding: 10px;
355
+ background: #f8f9fa;
356
+ border-radius: 8px;
357
+ border-left: 4px solid #1976D2;
358
+ transition: transform 0.2s;
359
+ }
360
+
361
+ .compact-competence-item:hover {
362
+ transform: translateY(-2px);
363
+ background: #e3f2fd;
364
+ }
365
+
366
+ .compact-competence-label {
367
+ font-size: 12px;
368
+ font-weight: 600;
369
+ color: #333;
370
+ margin-bottom: 8px;
371
+ display: flex;
372
+ justify-content: space-between;
373
+ }
374
+
375
+ .compact-competence-bar {
376
+ height: 10px;
377
+ background: #e0e0e0;
378
+ border-radius: 5px;
379
+ overflow: hidden;
380
+ margin: 5px 0;
381
+ }
382
+
383
+ .compact-competence-fill {
384
+ height: 100%;
385
+ border-radius: 5px;
386
+ color: white;
387
+ font-size: 9px;
388
+ text-align: right;
389
+ padding-right: 5px;
390
+ line-height: 10px;
391
+ font-weight: bold;
392
+ transition: width 0.5s ease;
393
+ }
394
+
395
+ /* ================= LÉGENDE RADAR COMPACTE ================= */
396
+ .compact-radar-legend {
397
+ display: flex;
398
+ justify-content: center;
399
+ gap: 15px;
400
+ margin: 15px 0;
401
+ flex-wrap: wrap;
402
+ padding: 10px;
403
+ background: white;
404
+ border-radius: 8px;
405
+ border: 1px solid #e0e0e0;
406
+ }
407
+
408
+ .compact-legend-item {
409
+ display: flex;
410
+ align-items: center;
411
+ gap: 8px;
412
+ padding: 6px 10px;
413
+ background: #f8f9fa;
414
+ border-radius: 6px;
415
+ font-size: 12px;
416
+ }
417
+
418
+ .compact-legend-color {
419
+ width: 16px;
420
+ height: 16px;
421
+ border-radius: 4px;
422
+ border: 2px solid white;
423
+ }
424
+
425
+ .compact-legend-low { background: linear-gradient(135deg, #e53935, #f44336); }
426
+ .compact-legend-medium { background: linear-gradient(135deg, #fb8c00, #ff9800); }
427
+ .compact-legend-high { background: linear-gradient(135deg, #43a047, #4caf50); }
428
+
429
+ /* ================= RADAR COMPACT ================= */
430
+ #radar-container {
431
+ background: white;
432
+ padding: 15px;
433
+ border-radius: 12px;
434
+ border: 1px solid #e0e0e0;
435
+ margin: 15px 0;
436
+ }
437
+
438
+ #radar {
439
+ max-width: 100%;
440
+ height: auto;
441
+ }
442
+
443
+ /* ================= MESSAGE BOT RADAR COMPACT ================= */
444
+ .compact-radar-bot-message {
445
+ background: linear-gradient(135deg, #E3F2FD, #BBDEFB);
446
+ padding: 15px;
447
+ border-radius: 10px;
448
+ border-left: 4px solid #1976D2;
449
+ margin: 15px 0;
450
+ }
451
+
452
+ .compact-radar-bot-header {
453
+ display: flex;
454
+ align-items: center;
455
+ gap: 10px;
456
+ margin-bottom: 10px;
457
+ }
458
+
459
+ .compact-radar-bot-icon {
460
+ font-size: 20px;
461
+ background: #1976D2;
462
+ color: white;
463
+ width: 40px;
464
+ height: 40px;
465
+ border-radius: 50%;
466
+ display: flex;
467
+ align-items: center;
468
+ justify-content: center;
469
+ }
470
+
471
+ .compact-radar-bot-title {
472
+ font-size: 16px;
473
+ font-weight: 600;
474
+ color: #1976D2;
475
+ margin: 0;
476
+ }
477
+
478
+ .compact-radar-bot-content {
479
+ font-size: 14px;
480
+ line-height: 1.5;
481
+ color: #333;
482
+ margin: 0;
483
+ }
484
+
485
+ .compact-radar-bot-insights {
486
+ background: white;
487
+ padding: 10px;
488
+ border-radius: 8px;
489
+ margin-top: 10px;
490
+ border: 1px solid #E3F2FD;
491
+ }
492
+
493
+ .compact-radar-insight-item {
494
+ display: flex;
495
+ align-items: center;
496
+ gap: 8px;
497
+ margin-bottom: 6px;
498
+ padding: 6px 10px;
499
+ border-radius: 6px;
500
+ background: #F5F5F5;
501
+ font-size: 12px;
502
+ }
503
+
504
+ /* ================= GRILLE DES MÉTRIQUES RADAR COMPACTE ================= */
505
+ .compact-radar-metrics-grid {
506
+ display: grid;
507
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
508
+ gap: 12px;
509
+ margin: 15px 0;
510
+ }
511
+
512
+ .compact-metric-card {
513
+ background: white;
514
+ border-radius: 10px;
515
+ padding: 15px;
516
+ box-shadow: 0 3px 8px rgba(0,0,0,0.08);
517
+ border-left: 4px solid #1976D2;
518
+ transition: transform 0.3s;
519
+ text-align: center;
520
+ }
521
+
522
+ .compact-metric-card:hover {
523
+ transform: translateY(-3px);
524
+ box-shadow: 0 5px 15px rgba(0,0,0,0.12);
525
+ }
526
+
527
+ .compact-metric-icon {
528
+ font-size: 24px;
529
+ margin-bottom: 8px;
530
+ }
531
+
532
+ .compact-metric-name {
533
+ font-weight: 600;
534
+ color: #333;
535
+ margin-bottom: 5px;
536
+ font-size: 14px;
537
+ }
538
+
539
+ .compact-metric-value {
540
+ font-size: 20px;
541
+ font-weight: bold;
542
+ color: #1976D2;
543
+ margin: 5px 0;
544
+ }
545
+
546
+ .compact-metric-value.high { color: #43A047; }
547
+ .compact-metric-value.medium { color: #FB8C00; }
548
+ .compact-metric-value.low { color: #E53935; }
549
+
550
+ .compact-metric-description {
551
+ font-size: 11px;
552
+ color: #666;
553
+ margin-top: 5px;
554
+ line-height: 1.3;
555
+ }
556
+
557
+ /* ================= HEATMAP COMPACT ================= */
558
+ .compact-heatmap-and-indicators {
559
+ background: white;
560
+ padding: 15px;
561
+ border-radius: 12px;
562
+ border: 1px solid #e0e0e0;
563
+ margin: 15px 0;
564
+ }
565
+
566
+ .compact-heatmap-analysis {
567
+ margin-bottom: 15px;
568
+ }
569
+
570
+ .compact-analysis-controls {
571
+ display: flex;
572
+ align-items: center;
573
+ gap: 10px;
574
+ margin-bottom: 15px;
575
+ padding: 10px;
576
+ background: #f8f9fa;
577
+ border-radius: 8px;
578
+ }
579
+
580
+ .compact-analysis-controls label {
581
+ font-weight: 600;
582
+ color: #1976D2;
583
+ font-size: 14px;
584
+ }
585
+
586
+ .compact-analysis-controls select {
587
+ padding: 8px 12px;
588
+ border-radius: 6px;
589
+ border: 2px solid #1976D2;
590
+ background: white;
591
+ color: #333;
592
+ font-weight: 500;
593
+ cursor: pointer;
594
+ flex-grow: 1;
595
+ font-size: 14px;
596
+ }
597
+
598
+ #heatmap {
599
+ max-width: 100%;
600
+ height: auto;
601
+ border-radius: 8px;
602
+ }
603
+
604
+ /* ================= LÉGENDE HEATMAP COMPACTE ================= */
605
+ .compact-enriched-legend {
606
+ background: white;
607
+ padding: 15px;
608
+ border-radius: 10px;
609
+ border: 1px solid #e0e0e0;
610
+ margin: 15px 0;
611
+ }
612
+
613
+ .compact-legend-section h5 {
614
+ color: #1976D2;
615
+ margin-bottom: 10px;
616
+ font-size: 14px;
617
+ display: flex;
618
+ align-items: center;
619
+ gap: 6px;
620
+ }
621
+
622
+ .compact-legend-grid {
623
+ display: grid;
624
+ grid-template-columns: repeat(3, 1fr);
625
+ gap: 8px;
626
+ }
627
+
628
+ .compact-legend-item-small {
629
+ display: flex;
630
+ align-items: center;
631
+ gap: 6px;
632
+ font-size: 11px;
633
+ }
634
+
635
+ .compact-legend-color-small {
636
+ width: 16px;
637
+ height: 16px;
638
+ border-radius: 4px;
639
+ border: 2px solid white;
640
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
641
+ }
642
+
643
+ /* ================= INDICATEURS DE PERSÉVÉRANCE COMPACTS ================= */
644
+ .compact-persistence-analysis {
645
+ background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
646
+ padding: 15px;
647
+ border-radius: 10px;
648
+ border-left: 4px solid #1976D2;
649
+ margin: 15px 0;
650
+ }
651
+
652
+ .compact-persistence-indicators {
653
+ display: flex;
654
+ flex-direction: column;
655
+ gap: 8px;
656
+ margin-bottom: 10px;
657
+ }
658
+
659
+ .compact-indicator {
660
+ display: flex;
661
+ align-items: center;
662
+ gap: 8px;
663
+ padding: 8px 10px;
664
+ background: white;
665
+ border-radius: 6px;
666
+ font-size: 12px;
667
+ border-left: 3px solid #1976D2;
668
+ }
669
+
670
+ .compact-indicator-dot {
671
+ width: 10px;
672
+ height: 10px;
673
+ border-radius: 50%;
674
+ }
675
+
676
+ .compact-persistence-text {
677
+ font-size: 12px;
678
+ line-height: 1.4;
679
+ }
680
+
681
+ .compact-persistence-text > div {
682
+ margin-bottom: 6px;
683
+ padding: 8px;
684
+ background: white;
685
+ border-radius: 6px;
686
+ border-left: 3px solid #1976D2;
687
+ }
688
+
689
+ /* ================= ONGLET 3: MESSAGE RÉFLEXIF ET ÉVALUATION ================= */
690
+ #tab-evaluation #reflagent {
691
+ background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
692
+ padding: 25px;
693
+ border-radius: 15px;
694
+ border-left: 8px solid #43a047;
695
+ margin: 25px 0;
696
+ font-size: 16px;
697
+ line-height: 1.6;
698
+ position: relative;
699
+ overflow: hidden;
700
+ min-height: 100px;
701
+ display: flex;
702
+ align-items: center;
703
+ }
704
+
705
+ #tab-evaluation #reflagent::before {
706
+ content: '🤖';
707
+ position: absolute;
708
+ top: 15px;
709
+ right: 15px;
710
+ font-size: 40px;
711
+ opacity: 0.2;
712
+ }
713
+
714
+ /* ================= MÉTRIQUES DE CONFIANCE ================= */
715
+ #tab-evaluation hr {
716
+ border: none;
717
+ height: 2px;
718
+ background: linear-gradient(90deg, #1976D2, transparent);
719
+ margin: 40px 0;
720
+ }
721
+
722
+ .trust-item {
723
+ margin-bottom: 20px;
724
+ padding: 15px;
725
+ background: #f8f9fa;
726
+ border-radius: 12px;
727
+ transition: transform 0.3s;
728
+ }
729
+
730
+ .trust-item:hover {
731
+ transform: translateX(5px);
732
+ background: #f1f3f4;
733
+ }
734
+
735
+ .trust-item b {
736
+ display: block;
737
+ margin-bottom: 10px;
738
+ color: #1976D2;
739
+ font-size: 15px;
740
+ }
741
+
742
+ .stars {
743
+ display: flex;
744
+ gap: 8px;
745
+ margin: 10px 0;
746
+ }
747
+
748
+ .stars span {
749
+ font-size: 32px;
750
+ cursor: pointer;
751
+ color: #e0e0e0;
752
+ transition: all 0.2s;
753
+ text-shadow: none;
754
+ }
755
+
756
+ .stars span.active {
757
+ color: #ffd54f;
758
+ text-shadow: 0 2px 4px rgba(255, 213, 79, 0.3);
759
+ }
760
+
761
+ .stars span:hover {
762
+ transform: scale(1.2);
763
+ }
764
+
765
+ .stars span.inactive {
766
+ color: #e0e0e0;
767
+ text-shadow: none;
768
+ }
769
+
770
+ .stars span.inactive:hover {
771
+ color: #ffd54f;
772
+ }
773
+
774
+ /* ================= CHAMP COMMENTAIRE ================= */
775
+ textarea {
776
+ width: 100%;
777
+ min-height: 120px;
778
+ border-radius: 12px;
779
+ padding: 15px;
780
+ border: 2px solid #e0e0e0;
781
+ font-family: inherit;
782
+ font-size: 14px;
783
+ resize: vertical;
784
+ transition: all 0.3s;
785
+ margin-bottom: 20px;
786
+ }
787
+
788
+ textarea:focus {
789
+ outline: none;
790
+ border-color: #1976D2;
791
+ box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);
792
+ }
793
+
794
+ /* ================= BARRE DE CONFIANCE ================= */
795
+ #trustBar {
796
+ height: 100%;
797
+ border-radius: 10px;
798
+ color: white;
799
+ font-size: 14px;
800
+ text-align: center;
801
+ line-height: 24px;
802
+ font-weight: bold;
803
+ transition: width 0.5s ease, background 0.5s ease;
804
+ position: relative;
805
+ overflow: hidden;
806
+ width: 0%;
807
+ background: #e0e0e0;
808
+ }
809
+
810
+ #trustBar::after {
811
+ content: '';
812
+ position: absolute;
813
+ top: 0;
814
+ left: 0;
815
+ right: 0;
816
+ bottom: 0;
817
+ background: linear-gradient(90deg,
818
+ transparent,
819
+ rgba(255,255,255,0.4),
820
+ transparent
821
+ );
822
+ animation: shimmer 2s infinite;
823
+ }
824
+
825
+ @keyframes shimmer {
826
+ 0% { transform: translateX(-100%); }
827
+ 100% { transform: translateX(100%); }
828
+ }
829
+
830
+ /* ================= MESSAGES ================= */
831
+ #saveTrustMsg {
832
+ padding: 10px 15px;
833
+ border-radius: 8px;
834
+ margin: 10px 0;
835
+ font-weight: 500;
836
+ text-align: center;
837
+ transition: all 0.3s;
838
+ min-height: 50px;
839
+ display: flex;
840
+ align-items: center;
841
+ justify-content: center;
842
+ }
843
+
844
+ /* ================= STATISTIQUES ================= */
845
+ .stats-grid {
846
+ display: grid;
847
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
848
+ gap: 15px;
849
+ margin: 20px 0;
850
+ }
851
+
852
+ .stat-item {
853
+ background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
854
+ padding: 15px;
855
+ border-radius: 10px;
856
+ text-align: center;
857
+ transition: transform 0.3s;
858
+ }
859
+
860
+ .stat-item:hover {
861
+ transform: translateY(-3px);
862
+ box-shadow: 0 5px 15px rgba(0,0,0,0.1);
863
+ }
864
+
865
+ .stat-value {
866
+ font-size: 28px;
867
+ font-weight: bold;
868
+ color: #1976D2;
869
+ margin: 10px 0;
870
+ }
871
+
872
+ .stat-label {
873
+ font-size: 13px;
874
+ color: #666;
875
+ font-weight: 500;
876
+ }
877
+
878
+ /* ================= ANIMATIONS ================= */
879
+ @keyframes fadeIn {
880
+ from { opacity: 0; transform: translateY(20px); }
881
+ to { opacity: 1; transform: translateY(0); }
882
+ }
883
+
884
+ @keyframes slideIn {
885
+ from { transform: translateX(100%); opacity: 0; }
886
+ to { transform: translateX(0); opacity: 1; }
887
+ }
888
+
889
+ @keyframes slideOut {
890
+ from { transform: translateX(0); opacity: 1; }
891
+ to { transform: translateX(100%); opacity: 0; }
892
+ }
893
+
894
+ @keyframes pulse {
895
+ 0% { transform: scale(1); }
896
+ 50% { transform: scale(1.05); }
897
+ 100% { transform: scale(1); }
898
+ }
899
+
900
+ /* ================= RESPONSIVE ================= */
901
+ @media (max-width: 1200px) {
902
+ #reflection {
903
+ padding: 20px;
904
+ }
905
+
906
+ .tabs {
907
+ flex-direction: column;
908
+ }
909
+
910
+ .tab-btn {
911
+ width: 100%;
912
+ }
913
+ }
914
+
915
+ @media (max-width: 768px) {
916
+ body {
917
+ padding: 10px;
918
+ }
919
+
920
+ .nav {
921
+ flex-direction: column;
922
+ gap: 15px;
923
+ text-align: center;
924
+ }
925
+
926
+ #scenarioTitle {
927
+ margin: 10px 0;
928
+ font-size: 1.2em;
929
+ }
930
+
931
+ button {
932
+ width: 100%;
933
+ justify-content: center;
934
+ }
935
+
936
+ .gdpr-options {
937
+ flex-direction: column;
938
+ gap: 10px;
939
+ }
940
+
941
+ .gdpr-option {
942
+ min-width: 100%;
943
+ }
944
+
945
+ .compact-competences-grid {
946
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
947
+ }
948
+
949
+ .compact-radar-metrics-grid {
950
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
951
+ }
952
+
953
+ .compact-radar-legend {
954
+ flex-direction: column;
955
+ align-items: center;
956
+ gap: 8px;
957
+ }
958
+
959
+ .compact-legend-grid {
960
+ grid-template-columns: repeat(2, 1fr);
961
+ }
962
+
963
+ .compact-analysis-controls {
964
+ flex-direction: column;
965
+ align-items: stretch;
966
+ }
967
+
968
+ .compact-persistence-indicators {
969
+ flex-direction: column;
970
+ }
971
+ }
972
+
973
+ /* ================= PROGRESS BAR CONTAINER ================= */
974
+ .progress-container {
975
+ width: 100%;
976
+ background: #f5f5f5;
977
+ border-radius: 12px;
978
+ height: 24px;
979
+ margin: 8px 0 20px;
980
+ overflow: hidden;
981
+ box-shadow: inset 0 2px 5px rgba(0,0,0,0.1);
982
+ }
983
+
984
+ /* ================= TOOLTIPS ================= */
985
+ .tooltip {
986
+ position: absolute;
987
+ background: rgba(25, 118, 210, 0.95);
988
+ color: white;
989
+ padding: 12px 18px;
990
+ border-radius: 10px;
991
+ font-size: 14px;
992
+ pointer-events: none;
993
+ opacity: 0;
994
+ transition: opacity 0.3s;
995
+ z-index: 1000;
996
+ max-width: 300px;
997
+ box-shadow: 0 6px 20px rgba(0,0,0,0.2);
998
+ border: 2px solid white;
999
+ backdrop-filter: blur(5px);
1000
+ }
1001
+
1002
+ .tooltip::after {
1003
+ content: '';
1004
+ position: absolute;
1005
+ top: 100%;
1006
+ left: 50%;
1007
+ margin-left: -10px;
1008
+ border-width: 10px;
1009
+ border-style: solid;
1010
+ border-color: rgba(25, 118, 210, 0.95) transparent transparent transparent;
1011
+ }
1012
+
1013
+ /* ================= SCROLLBAR ================= */
1014
+ ::-webkit-scrollbar {
1015
+ width: 10px;
1016
+ }
1017
+
1018
+ ::-webkit-scrollbar-track {
1019
+ background: #f1f1f1;
1020
+ border-radius: 5px;
1021
+ }
1022
+
1023
+ ::-webkit-scrollbar-thumb {
1024
+ background: linear-gradient(135deg, #1976D2, #2196F3);
1025
+ border-radius: 5px;
1026
+ }
1027
+
1028
+ ::-webkit-scrollbar-thumb:hover {
1029
+ background: linear-gradient(135deg, #1565c0, #1976D2);
1030
+ }
1031
+
1032
+ /* ================= LOADING ================= */
1033
+ .loading {
1034
+ display: inline-block;
1035
+ width: 20px;
1036
+ height: 20px;
1037
+ border: 3px solid #f3f3f3;
1038
+ border-top: 3px solid #1976D2;
1039
+ border-radius: 50%;
1040
+ animation: spin 1s linear infinite;
1041
+ }
1042
+
1043
+ @keyframes spin {
1044
+ 0% { transform: rotate(0deg); }
1045
+ 100% { transform: rotate(360deg); }
1046
+ }
1047
+
1048
+ /* ================= NOTIFICATIONS ================= */
1049
+ .notification {
1050
+ position: fixed;
1051
+ top: 20px;
1052
+ right: 20px;
1053
+ background: white;
1054
+ padding: 18px;
1055
+ border-radius: 12px;
1056
+ box-shadow: 0 8px 25px rgba(0,0,0,0.15);
1057
+ border-left: 6px solid #1976D2;
1058
+ z-index: 10000;
1059
+ max-width: 320px;
1060
+ animation: slideIn 0.4s ease-out;
1061
+ display: flex;
1062
+ align-items: flex-start;
1063
+ gap: 12px;
1064
+ }
1065
+
1066
+ .notification-icon {
1067
+ font-size: 28px;
1068
+ flex-shrink: 0;
1069
+ }
1070
+
1071
+ .notification-content {
1072
+ flex-grow: 1;
1073
+ }
1074
+
1075
+ .notification-title {
1076
+ font-weight: bold;
1077
+ color: #1976D2;
1078
+ margin-bottom: 5px;
1079
+ font-size: 15px;
1080
+ }
1081
+
1082
+ .notification-message {
1083
+ color: #555;
1084
+ font-size: 13px;
1085
+ line-height: 1.4;
1086
+ }
1087
+
1088
+ .notification-close {
1089
+ background: none;
1090
+ border: none;
1091
+ color: #999;
1092
+ cursor: pointer;
1093
+ padding: 0;
1094
+ font-size: 20px;
1095
+ line-height: 1;
1096
+ }
1097
+ </style>
1098
+ </head>
1099
+
1100
+ <body>
1101
+
1102
+ <div id="reflection">
1103
+
1104
+ <!-- NAVIGATION SCÉNARIOS -->
1105
+ <div class="nav">
1106
+ <button id="prevScenario">⬅️ Scénario précédent</button>
1107
+ <h3 id="scenarioTitle">Chargement...</h3>
1108
+ <button id="nextScenario">Scénario suivant ➡️</button>
1109
+ </div>
1110
+
1111
+ <!-- SYSTEME D'ONGLETS -->
1112
+ <div class="tabs-container">
1113
+ <div class="tabs">
1114
+ <button class="tab-btn active" data-tab="tab-evaluator">
1115
+ <span>👤</span> Évaluateur (RGPD)
1116
+ </button>
1117
+ <button class="tab-btn" data-tab="tab-dashboard">
1118
+ <span>📊</span> Dashboard Étudiant
1119
+ </button>
1120
+ <button class="tab-btn" data-tab="tab-evaluation">
1121
+ <span>🤖</span> Message Réflexif & Évaluation
1122
+ </button>
1123
+ </div>
1124
+
1125
+ <!-- ONGLET 1: INFORMATIONS ÉVALUATEUR GDPR -->
1126
+ <div id="tab-evaluator" class="tab-content active">
1127
+ <h3>👤 Informations de l'évaluateur (RGPD)</h3>
1128
+
1129
+ <div class="evaluator-info">
1130
+ <!-- Consentement RGPD -->
1131
+ <div class="evaluator-field">
1132
+ <label for="gdprConsent">
1133
+ <strong><span style="color: #1976D2; margin-right: 5px;">🔒</span> Consentement RGPD <span style="color: #e53935;">*</span></strong>
1134
+ </label>
1135
+ <div class="gdpr-options">
1136
+ <label class="gdpr-option">
1137
+ <input type="radio" name="gdprConsent" value="accept" id="gdprAccept" required>
1138
+ <span>J'accepte de partager mes informations pour l'évaluation</span>
1139
+ </label>
1140
+ <label class="gdpr-option">
1141
+ <input type="radio" name="gdprConsent" value="decline" id="gdprDecline">
1142
+ <span>Je préfère rester anonyme</span>
1143
+ </label>
1144
+ </div>
1145
+ <small>Veuillez accepter le consentement RGPD pour pouvoir remplir les champs d'identification</small>
1146
+ </div>
1147
+
1148
+ <!-- Champs conditionnels (masqués par défaut) -->
1149
+ <div id="evaluatorFields" style="display: none;">
1150
+ <!-- Nom et prénom -->
1151
+ <div class="evaluator-field">
1152
+ <label for="evaluatorName">
1153
+ <strong><span style="color: #1976D2; margin-right: 5px;">📝</span> Nom et prénom <span style="color: #e53935;">*</span></strong>
1154
+ </label>
1155
+ <input type="text"
1156
+ id="evaluatorName"
1157
+ placeholder="Ex: Dupont Jean ou Marie Curie"
1158
+ maxlength="100"
1159
+ disabled>
1160
+ <small>Veuillez saisir votre nom et prénom</small>
1161
+ </div>
1162
+
1163
+ <!-- Rôle -->
1164
+ <div class="evaluator-field">
1165
+ <label for="evaluatorRole"><strong><span style="color: #1976D2; margin-right: 5px;">👔</span> Rôle principal <span style="color: #e53935;">*</span></strong></label>
1166
+ <select id="evaluatorRole" disabled>
1167
+ <option value="">Sélectionnez votre rôle...</option>
1168
+ <option value="enseignant">Enseignant / Formateur</option>
1169
+ <option value="chercheur">Chercheur / Scientifique</option>
1170
+ <option value="expert_pedago">Expert pédagogique</option>
1171
+ <option value="etudiant_avance">Étudiant avancé / Doctorant</option>
1172
+ <option value="conseiller">Conseiller pédagogique</option>
1173
+ <option value="responsable">Responsable de formation</option>
1174
+ <option value="autre">Autre professionnel de l'éducation</option>
1175
+ </select>
1176
+ <small>Sélectionnez votre rôle principal dans le domaine éducatif</small>
1177
+ </div>
1178
+
1179
+ <!-- Niveau d'expertise en réflexivité -->
1180
+ <div class="evaluator-field">
1181
+ <label for="expertiseLevel"><strong><span style="color: #1976D2; margin-right: 5px;">🎓</span> Niveau d'expertise en réflexivité <span style="color: #e53935;">*</span></strong></label>
1182
+ <select id="expertiseLevel" disabled>
1183
+ <option value="">Sélectionnez votre niveau...</option>
1184
+ <option value="debutant">Débutant - Je découvre la réflexivité</option>
1185
+ <option value="intermediaire">Intermédiaire - J'utilise régulièrement des outils réflexifs</option>
1186
+ <option value="avance">Avancé - Je conçois des dispositifs réflexifs</option>
1187
+ <option value="expert">Expert - Je forme à la réflexivité pédagogique</option>
1188
+ <option value="chercheur_reflex">Chercheur en réflexivité</option>
1189
+ </select>
1190
+ <small>Indiquez votre niveau de maîtrise des concepts et outils de réflexivité</small>
1191
+ </div>
1192
+
1193
+ <!-- Niveau de maîtrise des messages réflexifs -->
1194
+ <div class="evaluator-field">
1195
+ <label for="messageMastery"><strong><span style="color: #1976D2; margin-right: 5px;">💬</span> Niveau de maîtrise des messages réflexifs <span style="color: #e53935;">*</span></strong></label>
1196
+ <select id="messageMastery" disabled>
1197
+ <option value="">Sélectionnez votre niveau...</option>
1198
+ <option value="novice">Novice - Je commence à analyser des messages réflexifs</option>
1199
+ <option value="intermediaire_msg">Intermédiaire - J'évalue régulièrement des feedbacks réflexifs</option>
1200
+ <option value="avance_msg">Avancé - Je rédige des messages réflexifs pour autrui</option>
1201
+ <option value="expert_msg">Expert - Je forme à la conception de messages réflexifs</option>
1202
+ </select>
1203
+ <small>Indiquez votre expérience avec l'analyse et la création de messages réflexifs</small>
1204
+ </div>
1205
+ </div>
1206
+
1207
+ <!-- Message pour utilisateurs anonymes -->
1208
+ <div id="anonymousMessage" style="display: none;">
1209
+ <p>
1210
+ <strong><span style="margin-right: 5px;">🕵️</span> Évaluation anonyme :</strong> Vos évaluations seront enregistrées sans information personnelle.
1211
+ Seules vos réponses aux métriques de confiance seront conservées.
1212
+ </p>
1213
+ </div>
1214
+
1215
+ <!-- Boutons d'action -->
1216
+ <div style="display: flex; gap: 10px; margin-top: 20px;">
1217
+ <button onclick="fillSampleEvaluator()" type="button" style="background: #666; flex: 1;" id="fillExampleBtn">
1218
+ <span style="margin-right: 5px;">📋</span> Remplir exemple
1219
+ </button>
1220
+ <button onclick="clearEvaluatorFields()" type="button" style="background: #9e9e9e; flex: 1;" id="clearFieldsBtn">
1221
+ <span style="margin-right: 5px;">🗑️</span> Effacer
1222
+ </button>
1223
+ </div>
1224
+ </div>
1225
+ </div>
1226
+
1227
+ <!-- ONGLET 2: DASHBOARD ÉTUDIANT COMPACT -->
1228
+ <div id="tab-dashboard" class="tab-content">
1229
+ <h3>📝 Manifeste étudiant</h3>
1230
+ <div id="manifest-list">
1231
+ <div class="manifest-item">
1232
+ <em>Chargement des données...</em>
1233
+ </div>
1234
+ </div>
1235
+
1236
+ <h3>📊 Progression par compétence</h3>
1237
+ <div id="competence-bars">
1238
+ <div id="compact-competences">
1239
+ <em>Chargement des compétences...</em>
1240
+ </div>
1241
+ </div>
1242
+
1243
+ <!-- LÉGENDE RADAR COMPACTE -->
1244
+ <div class="compact-radar-legend">
1245
+ <div class="compact-legend-item">
1246
+ <div class="compact-legend-color compact-legend-low"></div>
1247
+ <span>Faible (0-50%)</span>
1248
+ </div>
1249
+ <div class="compact-legend-item">
1250
+ <div class="compact-legend-color compact-legend-medium"></div>
1251
+ <span>Moyen (50-70%)</span>
1252
+ </div>
1253
+ <div class="compact-legend-item">
1254
+ <div class="compact-legend-color compact-legend-high"></div>
1255
+ <span>Élevé (70-100%)</span>
1256
+ </div>
1257
+ </div>
1258
+
1259
+ <h3>🕸️ Radar – Learning Analytics</h3>
1260
+
1261
+ <!-- Grille des métriques radar compacte -->
1262
+ <div class="compact-radar-metrics-grid" id="compact-radar-metrics-grid">
1263
+ <!-- Les métriques seront ajoutées dynamiquement -->
1264
+ </div>
1265
+
1266
+ <!-- Container Radar et Bot Message -->
1267
+ <div id="radar-container">
1268
+ <div style="display: flex; gap: 20px; flex-wrap: wrap;">
1269
+ <!-- Message Bot Radar Compact -->
1270
+ <div class="compact-radar-bot-message" style="flex: 1; min-width: 300px;">
1271
+ <div class="compact-radar-bot-header">
1272
+ <div class="compact-radar-bot-icon">🎯</div>
1273
+ <h4 class="compact-radar-bot-title">Analyse de Profil</h4>
1274
+ </div>
1275
+ <p class="compact-radar-bot-content" id="compact-radar-bot-content">Analyse en cours...</p>
1276
+ <div class="compact-radar-bot-insights">
1277
+ <div id="compact-radar-bot-insights">
1278
+ <!-- Les insights seront ajoutés dynamiquement -->
1279
+ </div>
1280
+ </div>
1281
+ </div>
1282
+
1283
+ <!-- Canvas Radar Compact -->
1284
+ <div style="flex: 1; min-width: 300px; text-align: center;">
1285
+ <canvas id="radar" width="500" height="500" style="max-width: 100%; height: auto;"></canvas>
1286
+ </div>
1287
+ </div>
1288
+ </div>
1289
+
1290
+ <!-- HEATMAP COMPACTE -->
1291
+ <div class="compact-heatmap-and-indicators">
1292
+ <h3>🔥 Heatmap d'activité - Analyse de Persévérance</h3>
1293
+
1294
+ <div class="compact-heatmap-analysis">
1295
+ <div class="compact-analysis-controls">
1296
+ <label for="persistenceMode">Mode d'analyse :</label>
1297
+ <select id="persistenceMode" onchange="changePersistenceAnalysis()">
1298
+ <option value="regularity">📊 Régularité du travail</option>
1299
+ <option value="effortPattern">🔄 Schéma d'effort</option>
1300
+ <option value="deadline">⏰ Gestion des échéances</option>
1301
+ <option value="combined">🎯 Vue combinée</option>
1302
+ </select>
1303
+ </div>
1304
+
1305
+ <!-- Canvas pour le heatmap -->
1306
+ <canvas id="heatmap" width="800" height="250" style="max-width: 100%; height: auto;"></canvas>
1307
+ </div>
1308
+
1309
+ <!-- Légende des niveaux d'activité compacte -->
1310
+ <div class="compact-enriched-legend">
1311
+ <div class="compact-legend-section">
1312
+ <h5>📈 Niveaux d'activité</h5>
1313
+ <div class="compact-legend-grid">
1314
+ <div class="compact-legend-item-small">
1315
+ <div class="compact-legend-color-small" style="background:#EBEDF0;"></div>
1316
+ <span>Aucune activité</span>
1317
+ </div>
1318
+ <div class="compact-legend-item-small">
1319
+ <div class="compact-legend-color-small" style="background:#C6E48B;"></div>
1320
+ <span>Faible activité</span>
1321
+ </div>
1322
+ <div class="compact-legend-item-small">
1323
+ <div class="compact-legend-color-small" style="background:#7BC96F;"></div>
1324
+ <span>Activité modérée</span>
1325
+ </div>
1326
+ <div class="compact-legend-item-small">
1327
+ <div class="compact-legend-color-small" style="background:#239A3B;"></div>
1328
+ <span>Activité élevée</span>
1329
+ </div>
1330
+ <div class="compact-legend-item-small">
1331
+ <div class="compact-legend-color-small" style="background:#196127;"></div>
1332
+ <span>Activité intense</span>
1333
+ </div>
1334
+ </div>
1335
+ </div>
1336
+ </div>
1337
+
1338
+ <!-- Analyse de persévérance compacte -->
1339
+ <div class="compact-persistence-analysis" id="compact-persistenceAnalysis">
1340
+ <h5>🎯 Indicateurs de Persévérance</h5>
1341
+ <div class="compact-persistence-indicators">
1342
+ <div class="compact-indicator">
1343
+ <span class="compact-indicator-dot" style="background:#FF6B6B;"></span>
1344
+ <span>Régularité calculée : <strong id="compact-regularityScore">-</strong></span>
1345
+ </div>
1346
+ <div class="compact-indicator">
1347
+ <span class="compact-indicator-dot" style="background:#4ECDC4;"></span>
1348
+ <span>Schéma d'effort : <strong id="compact-effortPattern">-</strong></span>
1349
+ </div>
1350
+ <div class="compact-indicator">
1351
+ <span class="compact-indicator-dot" style="background:#FFD166;"></span>
1352
+ <span>Gestion échéances : <strong id="compact-deadlineScore">-</strong></span>
1353
+ </div>
1354
+ </div>
1355
+
1356
+ <div class="compact-persistence-text" style="margin-top: 10px;">
1357
+ <div style="margin-bottom: 10px;">
1358
+ <strong>Schéma d'effort :</strong>
1359
+ <div style="margin-top: 5px; padding: 8px; background: #F5F5F5; border-radius: 6px; font-size: 13px;">
1360
+ <span id="compact-patternText">Analyse en cours...</span>
1361
+ </div>
1362
+ </div>
1363
+ <div>
1364
+ <strong>Persévérance et gestion des efforts :</strong>
1365
+ <div style="margin-top: 5px; padding: 10px; background: #F8F9FA; border-radius: 6px; border-left: 3px solid #1976D2;">
1366
+ <span id="compact-regularityText">Analyse en cours...</span>
1367
+ </div>
1368
+ </div>
1369
+ </div>
1370
+ </div>
1371
+ </div>
1372
+ </div>
1373
+
1374
+ <!-- ONGLET 3: MESSAGE RÉFLEXIF ET ÉVALUATION -->
1375
+ <div id="tab-evaluation" class="tab-content">
1376
+ <h3>🤖 ReflAgent – Analyse & accompagnement</h3>
1377
+ <div id="reflagent">
1378
+ <em>Le message d'analyse apparaîtra ici après chargement...</em>
1379
+ </div>
1380
+
1381
+ <hr>
1382
+
1383
+ <h3>🧑‍⚖️ Volet Expert – Métriques de Confiance</h3>
1384
+ <p style="color: #666; margin-bottom: 20px; font-style: italic;">
1385
+ Évaluez votre confiance dans l'analyse de ReflAgent pour ce scénario :
1386
+ </p>
1387
+
1388
+ <!-- MÉTRIQUES TRADUITES EN FRANÇAIS -->
1389
+ <div class="trust-item">
1390
+ <b>Authenticité Réflexive (AR)</b>
1391
+ <div class="stars" data-metric="AR">
1392
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1393
+ </div>
1394
+ <small style="color: #666; display: block; margin-top: 5px;">
1395
+ L'analyse reflète-t-elle fidèlement la situation réelle de l'étudiant ?
1396
+ </small>
1397
+ </div>
1398
+
1399
+ <div class="trust-item">
1400
+ <b>Alignement Empathique (AE)</b>
1401
+ <div class="stars" data-metric="AE">
1402
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1403
+ </div>
1404
+ <small style="color: #666; display: block; margin-top: 5px;">
1405
+ L'agent comprend-il les émotions, motivations et difficultés de l'étudiant ?
1406
+ </small>
1407
+ </div>
1408
+
1409
+ <div class="trust-item">
1410
+ <b>Encouragement Sensible au Risque (ESR)</b>
1411
+ <div class="stars" data-metric="ESR">
1412
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1413
+ </div>
1414
+ <small style="color: #666; display: block; margin-top: 5px;">
1415
+ Les encouragements tiennent-ils compte des risques et difficultés identifiés ?
1416
+ </small>
1417
+ </div>
1418
+
1419
+ <div class="trust-item">
1420
+ <b>Support aux Défis Mentaux (SDM)</b>
1421
+ <div class="stars" data-metric="SDM">
1422
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1423
+ </div>
1424
+ <small style="color: #666; display: block; margin-top: 5px;">
1425
+ L'agent aide-t-il l'étudiant à développer sa pensée critique et ses compétences cognitives ?
1426
+ </small>
1427
+ </div>
1428
+
1429
+ <div class="trust-item">
1430
+ <b>Support Métacognitif (SM)</b>
1431
+ <div class="stars" data-metric="SM">
1432
+ <!-- Les étoiles seront ajoutées par JavaScript -->
1433
+ </div>
1434
+ <small style="color: #666; display: block; margin-top: 5px;">
1435
+ L'agent aide-t-il l'étudiant à réfléchir sur ses propres stratégies d'apprentissage ?
1436
+ </small>
1437
+ </div>
1438
+
1439
+ <h4>💬 Commentaire expert</h4>
1440
+ <textarea id="trustComment" placeholder="Ajoutez vos observations, suggestions ou critiques concernant l'analyse de ReflAgent..."></textarea>
1441
+
1442
+ <div style="display: flex; justify-content: space-between; align-items: center; margin: 25px 0;">
1443
+ <div style="flex-grow: 1; margin-right: 20px;">
1444
+ <h4 style="margin-bottom: 10px;">🔒 Indice global de confiance</h4>
1445
+ <div class="progress-container">
1446
+ <div class="fill" id="trustBar">0%</div>
1447
+ </div>
1448
+ <div style="display: flex; justify-content: space-between; margin-top: 5px; font-size: 12px; color: #666;">
1449
+ <span>Faible confiance</span>
1450
+ <span>Confidence moyenne</span>
1451
+ <span>Forte confiance</span>
1452
+ </div>
1453
+ </div>
1454
+ <div style="display: flex; flex-direction: column; gap: 10px; align-items: flex-end;">
1455
+ <button id="saveTrustBtn" style="height: fit-content; width: 100%;">💾 Sauvegarder l'évaluation</button>
1456
+ <button id="crossReadersBtn" style="height: fit-content; width: 100%; background: linear-gradient(135deg, #43A047, #4CAF50);">
1457
+ 📊 Lecture croisée
1458
+ </button>
1459
+ </div>
1460
+ </div>
1461
+
1462
+ <div id="saveTrustMsg"></div>
1463
+
1464
+ <!-- Statistiques rapides -->
1465
+ <div class="stats-grid">
1466
+ <div class="stat-item">
1467
+ <div class="stat-label">Scénario actuel</div>
1468
+ <div class="stat-value" id="currentScenarioNum">-</div>
1469
+ </div>
1470
+ <div class="stat-item">
1471
+ <div class="stat-label">Confiance moyenne</div>
1472
+ <div class="stat-value" id="avgTrustScore">0%</div>
1473
+ </div>
1474
+ <div class="stat-item">
1475
+ <div class="stat-label">Niveau de risque</div>
1476
+ <div class="stat-value" id="riskLevel">-</div>
1477
+ </div>
1478
+ <div class="stat-item">
1479
+ <div class="stat-label">Activité moyenne</div>
1480
+ <div class="stat-value" id="avgActivity">-</div>
1481
+ </div>
1482
+ </div>
1483
+ </div>
1484
+ </div>
1485
+ </div>
1486
+
1487
+ <!-- Script principal -->
1488
+ <script>
1489
+ // ================= VARIABLES =================
1490
+ let scenarios = [];
1491
+ let currentScenarioIndex = 0;
1492
+ let radarMetrics = [];
1493
+
1494
+ // Métriques de radar par défaut (sans abréviations)
1495
+ const DEFAULT_RADAR_METRICS = [
1496
+ { label: "Démarrage des activités", value: 85 },
1497
+ { label: "Connaissances validées", value: 72 },
1498
+ { label: "Niveau moyen de compétence", value: 68 },
1499
+ { label: "Taux d'erreur (inversé)", value: 35 },
1500
+ { label: "Achèvement des activités", value: 74 },
1501
+ { label: "Interactions avec les ressources", value: 80 },
1502
+ { label: "Domaines de compétence", value: 78 }
1503
+ ];
1504
+
1505
+ // Noms des métriques traduits en français
1506
+ const trustMetrics = {
1507
+ "AR": 0, // Authenticité Réflexive
1508
+ "AE": 0, // Alignement Empathique
1509
+ "ESR": 0, // Encouragement Sensible au Risque
1510
+ "SDM": 0, // Support aux Défis Mentaux
1511
+ "SM": 0 // Support Métacognitif
1512
+ };
1513
+
1514
+ const trustWeights = {
1515
+ "AR": 0.30,
1516
+ "AE": 0.20,
1517
+ "ESR": 0.20,
1518
+ "SDM": 0.10,
1519
+ "SM": 0.20
1520
+ };
1521
+
1522
+ // MAPPING PERSÉVÉRANCE PAR PROFIL
1523
+ const perseveranceProfiles = {
1524
+ "Étudiant engagé": {
1525
+ level: "Très élevée",
1526
+ interpretation: "Efforts constants et durables, persévère même face aux difficultés",
1527
+ color: "#43A047"
1528
+ },
1529
+ "Étudiant actif mais inefficace": {
1530
+ level: "Moyenne",
1531
+ interpretation: "Efforts importants mais mal régulés, persévérance peu productive",
1532
+ color: "#FB8C00"
1533
+ },
1534
+ "Étudiant orienté vers le succès": {
1535
+ level: "Élevée",
1536
+ interpretation: "Persévérance principalement guidée par l'atteinte des objectifs",
1537
+ color: "#4CAF50"
1538
+ },
1539
+ "Étudiant motivé": {
1540
+ level: "Élevée",
1541
+ interpretation: "Engagement soutenu et continuité stable de l'effort",
1542
+ color: "#4CAF50"
1543
+ },
1544
+ "Étudiant surmotivé": {
1545
+ level: "Très élevée",
1546
+ interpretation: "Effort intense, parfois excessif, avec risque de surcharge",
1547
+ color: "#43A047"
1548
+ },
1549
+ "Étudiant stratégique": {
1550
+ level: "Élevée",
1551
+ interpretation: "Effort bien dosé, persévérance optimisée selon le rendement attendu",
1552
+ color: "#4CAF50"
1553
+ },
1554
+ "Étudiant en amélioration": {
1555
+ level: "Moyenne à élevée",
1556
+ interpretation: "Efforts croissants, persévérance en cours de structuration",
1557
+ color: "#FF9800"
1558
+ },
1559
+ "Étudiant en difficulté": {
1560
+ level: "Faible",
1561
+ interpretation: "Découragement fréquent et difficulté à maintenir l'effort",
1562
+ color: "#E53935"
1563
+ },
1564
+ "Étudiant évitant l'échec": {
1565
+ level: "Moyenne",
1566
+ interpretation: "Persévérance motivée par la peur de l'échec plutôt que par l'apprentissage",
1567
+ color: "#FB8C00"
1568
+ },
1569
+ "Étudiant à risque": {
1570
+ level: "Très faible",
1571
+ interpretation: "Abandon rapide et très faible tolérance à l'effort",
1572
+ color: "#C62828"
1573
+ },
1574
+ "Étudiant en progression": {
1575
+ level: "Élevée",
1576
+ interpretation: "Efforts réguliers et de mieux en mieux maîtrisés",
1577
+ color: "#4CAF50"
1578
+ },
1579
+ "Étudiant acceptant l'échec": {
1580
+ level: "Élevée",
1581
+ interpretation: "Bonne résilience, persévère malgré les erreurs et les échecs",
1582
+ color: "#4CAF50"
1583
+ },
1584
+ "Étudiant inactif": {
1585
+ level: "Très faible",
1586
+ interpretation: "Manque d'engagement, difficulté à initier et maintenir l'effort",
1587
+ color: "#C62828"
1588
+ },
1589
+ "Étudiant non engagé": {
1590
+ level: "Faible",
1591
+ interpretation: "Manque de motivation, efforts sporadiques et peu soutenus",
1592
+ color: "#E53935"
1593
+ },
1594
+ "Étudiant persévérant": {
1595
+ level: "Élevée",
1596
+ interpretation: "Constance dans l'effort malgré les doutes et difficultés",
1597
+ color: "#4CAF50"
1598
+ },
1599
+ "Étudiant actif": {
1600
+ level: "Moyenne",
1601
+ interpretation: "Efforts soutenus mais parfois désorganisés ou mal canalisés",
1602
+ color: "#FB8C00"
1603
+ }
1604
+ };
1605
+
1606
+ // ================= INIT =================
1607
+ document.addEventListener("DOMContentLoaded", () => {
1608
+ console.log("✅ DOM chargé, initialisation...");
1609
+ loadScenarios();
1610
+ initTrustStars();
1611
+ initTrustSave();
1612
+ initTabs();
1613
+ initGDPR();
1614
+
1615
+ // Initialiser la barre de confiance à 0%
1616
+ updateTrustBar();
1617
+ });
1618
+
1619
+ // ================= SYSTEME D'ONGLETS =================
1620
+ function initTabs() {
1621
+ const tabBtns = document.querySelectorAll('.tab-btn');
1622
+ const tabContents = document.querySelectorAll('.tab-content');
1623
+
1624
+ tabBtns.forEach(btn => {
1625
+ btn.addEventListener('click', () => {
1626
+ const tabId = btn.getAttribute('data-tab');
1627
+
1628
+ // Retirer la classe active de tous les boutons et contenus
1629
+ tabBtns.forEach(b => b.classList.remove('active'));
1630
+ tabContents.forEach(c => c.classList.remove('active'));
1631
+
1632
+ // Ajouter la classe active au bouton et au contenu correspondant
1633
+ btn.classList.add('active');
1634
+ document.getElementById(tabId).classList.add('active');
1635
+ });
1636
+ });
1637
+ }
1638
+
1639
+ // ================= GDPR =================
1640
+ function initGDPR() {
1641
+ const gdprAccept = document.getElementById('gdprAccept');
1642
+ const gdprDecline = document.getElementById('gdprDecline');
1643
+ const evaluatorFields = document.getElementById('evaluatorFields');
1644
+ const anonymousMessage = document.getElementById('anonymousMessage');
1645
+
1646
+ // Activer/désactiver les champs selon le choix GDPR
1647
+ function updateGDPRFields() {
1648
+ if (gdprAccept.checked) {
1649
+ // Afficher les champs et les activer
1650
+ evaluatorFields.style.display = 'block';
1651
+ anonymousMessage.style.display = 'none';
1652
+
1653
+ // Activer les champs
1654
+ document.getElementById('evaluatorName').disabled = false;
1655
+ document.getElementById('evaluatorRole').disabled = false;
1656
+ document.getElementById('expertiseLevel').disabled = false;
1657
+ document.getElementById('messageMastery').disabled = false;
1658
+ } else if (gdprDecline.checked) {
1659
+ // Cacher les champs et afficher le message anonyme
1660
+ evaluatorFields.style.display = 'none';
1661
+ anonymousMessage.style.display = 'block';
1662
+
1663
+ // Désactiver et vider les champs
1664
+ document.getElementById('evaluatorName').disabled = true;
1665
+ document.getElementById('evaluatorName').value = '';
1666
+ document.getElementById('evaluatorRole').disabled = true;
1667
+ document.getElementById('evaluatorRole').value = '';
1668
+ document.getElementById('expertiseLevel').disabled = true;
1669
+ document.getElementById('expertiseLevel').value = '';
1670
+ document.getElementById('messageMastery').disabled = true;
1671
+ document.getElementById('messageMastery').value = '';
1672
+ }
1673
+ }
1674
+
1675
+ // Écouter les changements
1676
+ gdprAccept.addEventListener('change', updateGDPRFields);
1677
+ gdprDecline.addEventListener('change', updateGDPRFields);
1678
+
1679
+ // Initialiser
1680
+ updateGDPRFields();
1681
+ }
1682
+
1683
+ // ================= CHARGEMENT JSON =================
1684
+ function loadScenarios() {
1685
+ console.log("Chargement des scénarios...");
1686
+ fetch("/static/scenarios.json")
1687
+ .then(r => {
1688
+ if (!r.ok) throw new Error("Erreur de chargement du fichier JSON");
1689
+ return r.json();
1690
+ })
1691
+ .then(data => {
1692
+ console.log("Scénarios chargés:", data.scenarios.length);
1693
+ scenarios = data.scenarios;
1694
+ loadScenario(0);
1695
+ })
1696
+ .catch(error => {
1697
+ console.error("Erreur:", error);
1698
+ document.getElementById("manifest-list").innerHTML =
1699
+ `<div class="manifest-item" style="background:#FFEBEE;color:#C62828;">
1700
+ Erreur de chargement des scénarios. Vérifiez que le fichier scenarios.json existe.
1701
+ </div>`;
1702
+ });
1703
+ }
1704
+
1705
+ // ================= CHARGER SCÉNARIO =================
1706
+ function loadScenario(index) {
1707
+ console.log("Chargement scénario", index);
1708
+ if (index < 0 || index >= scenarios.length) return;
1709
+ currentScenarioIndex = index;
1710
+ const s = scenarios[index];
1711
+
1712
+ // Mettre à jour le titre
1713
+ const titleElement = document.getElementById("scenarioTitle");
1714
+ titleElement.textContent = `Scénario ${s.id} – ${s.title}`;
1715
+
1716
+ // Mettre à jour le manifeste
1717
+ document.getElementById("manifest-list").innerHTML = `
1718
+ <div class="manifest-item">
1719
+ <b>Type de Manifest :</b> ${s.manifest.type}<br>
1720
+ <b>Manifeste (écrit par l'étudiant) :</b> ${s.manifest.manifeste}<br>
1721
+ <b>Description du Profil :</b> ${s.manifest.description}
1722
+ </div>`;
1723
+
1724
+ // Mettre à jour les compétences compactes
1725
+ updateCompactCompetences(s.competences);
1726
+
1727
+ // Mettre à jour le radar avec les nouvelles métriques
1728
+ if (s.radar && s.radar.length > 0) {
1729
+ radarMetrics = s.radar;
1730
+ } else {
1731
+ // Utiliser les métriques par défaut avec variation pour chaque scénario
1732
+ radarMetrics = DEFAULT_RADAR_METRICS.map(metric => {
1733
+ // Variation de ±15% selon l'index du scénario pour rendre les données plus réalistes
1734
+ const variation = (index % 7) * 5 - 15; // -15 à +15
1735
+ const newValue = Math.max(10, Math.min(95, metric.value + variation));
1736
+ return {
1737
+ label: metric.label,
1738
+ value: newValue
1739
+ };
1740
+ });
1741
+ }
1742
+
1743
+ // Mettre à jour la grille des métriques radar compacte
1744
+ updateCompactRadarMetricsGrid();
1745
+
1746
+ // Mettre à jour le graphique radar
1747
+ drawRadar();
1748
+
1749
+ // Mettre à jour le message bot radar compact
1750
+ updateCompactRadarBotMessage(s);
1751
+
1752
+ // Mettre à jour la heatmap enrichie compacte
1753
+ drawCompactEnrichedHeatmap(s);
1754
+
1755
+ // Mettre à jour la persévérance spécifique au profil
1756
+ updatePerseveranceProfile(s.title);
1757
+
1758
+ // Mettre à jour le message ReflAgent
1759
+ document.getElementById("reflagent").textContent = s.reflAgent;
1760
+
1761
+ // Mettre à jour les boutons de navigation
1762
+ updateNavButtons();
1763
+
1764
+ // Mettre à jour les statistiques
1765
+ updateStats();
1766
+ }
1767
+
1768
+ // ================= FONCTIONS POUR LA VERSION COMPACTE =================
1769
+
1770
+ // Mettre à jour les compétences compactes
1771
+ function updateCompactCompetences(competences) {
1772
+ const container = document.getElementById("compact-competences");
1773
+ if (!container) return;
1774
+
1775
+ container.innerHTML = '';
1776
+
1777
+ competences.forEach(comp => {
1778
+ // Déterminer la couleur selon la valeur
1779
+ let color;
1780
+ if (comp.value < 50) color = '#E53935';
1781
+ else if (comp.value < 70) color = '#FB8C00';
1782
+ else color = '#43A047';
1783
+
1784
+ // Créer l'élément de compétence
1785
+ const compItem = document.createElement('div');
1786
+ compItem.className = 'compact-competence-item';
1787
+ compItem.innerHTML = `
1788
+ <div class="compact-competence-label">
1789
+ <span>${comp.label}</span>
1790
+ <span>${comp.value}%</span>
1791
+ </div>
1792
+ <div class="compact-competence-bar">
1793
+ <div class="compact-competence-fill" style="width: ${comp.value}%; background: ${color};">
1794
+ ${comp.value >= 10 ? comp.value + '%' : ''}
1795
+ </div>
1796
+ </div>
1797
+ `;
1798
+
1799
+ container.appendChild(compItem);
1800
+ });
1801
+ }
1802
+
1803
+ // Mettre à jour la grille des métriques radar compacte
1804
+ function updateCompactRadarMetricsGrid() {
1805
+ const grid = document.getElementById("compact-radar-metrics-grid");
1806
+ if (!grid) return;
1807
+
1808
+ grid.innerHTML = '';
1809
+
1810
+ radarMetrics.forEach(metric => {
1811
+ // Déterminer la classe de couleur selon la valeur
1812
+ let colorClass = "";
1813
+ if (metric.value >= 70) colorClass = "high";
1814
+ else if (metric.value >= 40) colorClass = "medium";
1815
+ else colorClass = "low";
1816
+
1817
+ // Déterminer l'icône selon le type de métrique
1818
+ let icon = "📊";
1819
+ if (metric.label.includes("Démarrage")) icon = "🚀";
1820
+ else if (metric.label.includes("Connaissances")) icon = "🎓";
1821
+ else if (metric.label.includes("Niveau moyen")) icon = "📈";
1822
+ else if (metric.label.includes("Taux d'erreur")) icon = "🎯";
1823
+ else if (metric.label.includes("Achèvement")) icon = "🏁";
1824
+ else if (metric.label.includes("Interactions")) icon = "📚";
1825
+ else if (metric.label.includes("Domaines")) icon = "🔧";
1826
+
1827
+ // Déterminer la description
1828
+ let description = "";
1829
+ if (metric.label.includes("Démarrage")) description = "Rapidité d'initiation";
1830
+ else if (metric.label.includes("Connaissances")) description = "Acquis démontrés";
1831
+ else if (metric.label.includes("Niveau moyen")) description = "Moyenne des compétences";
1832
+ else if (metric.label.includes("Taux d'erreur")) description = "Précision et attention";
1833
+ else if (metric.label.includes("Achèvement")) description = "Terminaison des tâches";
1834
+ else if (metric.label.includes("Interactions")) description = "Utilisation supports";
1835
+ else if (metric.label.includes("Domaines")) description = "Étendue couverte";
1836
+
1837
+ const metricCard = document.createElement("div");
1838
+ metricCard.className = "compact-metric-card";
1839
+ metricCard.innerHTML = `
1840
+ <div class="compact-metric-icon">${icon}</div>
1841
+ <div class="compact-metric-name">${metric.label}</div>
1842
+ <div class="compact-metric-value ${colorClass}">${metric.value}%</div>
1843
+ <div class="compact-metric-description">${description}</div>
1844
+ `;
1845
+
1846
+ grid.appendChild(metricCard);
1847
+ });
1848
+ }
1849
+
1850
+ // Mettre à jour le message bot radar compact
1851
+ function updateCompactRadarBotMessage(scenario) {
1852
+ const radarBotContent = document.getElementById("compact-radar-bot-content");
1853
+ const radarBotInsights = document.getElementById("compact-radar-bot-insights");
1854
+
1855
+ if (!radarBotContent || !radarBotInsights) return;
1856
+
1857
+ // Messages pour chaque profil basé sur le titre du scénario
1858
+ const profileMessages = {
1859
+ "Étudiant engagé": {
1860
+ title: "Étudiant Engagé et Motivé",
1861
+ message: "🎯 Ton engagement est impressionnant ! Tu démontres une forte volonté d'apprendre.",
1862
+ insights: [
1863
+ { icon: "🔥", text: "Motivation élevée" },
1864
+ { icon: "🎯", text: "Objectifs bien définis" },
1865
+ { icon: "📚", text: "Implication active" }
1866
+ ]
1867
+ },
1868
+ "Étudiant actif mais inefficace": {
1869
+ title: "Actif mais Peu Efficace",
1870
+ message: "📊 Tu es très actif mais ton taux d'erreur est élevé. Concentre-toi sur une compétence à la fois.",
1871
+ insights: [
1872
+ { icon: "⚡", text: "Activité élevée" },
1873
+ { icon: "⚠️", text: "Erreurs fréquentes" },
1874
+ { icon: "🎯", text: "Focus nécessaire" }
1875
+ ]
1876
+ },
1877
+ "Étudiant orienté vers le succès": {
1878
+ title: "Orientation Réussite",
1879
+ message: "🏆 Tu vises l'excellence avec détermination. Ta rigueur est exemplaire.",
1880
+ insights: [
1881
+ { icon: "⭐", text: "Excellence visée" },
1882
+ { icon: "🎯", text: "Objectifs ambitieux" },
1883
+ { icon: "📈", text: "Performance supérieure" }
1884
+ ]
1885
+ },
1886
+ "Étudiant motivé": {
1887
+ title: "Nouvellement Motivé",
1888
+ message: "🚀 Ta motivation est un excellent point de départ ! Progresse étape par étape.",
1889
+ insights: [
1890
+ { icon: "🌟", text: "Motivation récente" },
1891
+ { icon: "🧱", text: "Construction des bases" },
1892
+ { icon: "📖", text: "Curiosité ouverte" }
1893
+ ]
1894
+ },
1895
+ "Étudiant surmotivé": {
1896
+ title: "Surmotivé - Attention",
1897
+ message: "💥 Ton niveau d'investissement est exceptionnel, attention au risque de surmenage.",
1898
+ insights: [
1899
+ { icon: "⚡", text: "Investissement maximal" },
1900
+ { icon: "⚠️", text: "Risque de burnout" },
1901
+ { icon: "⚖️", text: "Équilibre nécessaire" }
1902
+ ]
1903
+ },
1904
+ "Étudiant stratégique": {
1905
+ title: "Stratégique et Efficient",
1906
+ message: "♟️ Tu abordes l'apprentissage avec intelligence et planification.",
1907
+ insights: [
1908
+ { icon: "🧠", text: "Approche réfléchie" },
1909
+ { icon: "🎯", text: "Optimisation efforts" },
1910
+ { icon: "📊", text: "Analyse des retours" }
1911
+ ]
1912
+ }
1913
+ };
1914
+
1915
+ // Récupérer le message pour le profil ou utiliser un message par défaut
1916
+ const profileMessage = profileMessages[scenario.title] || {
1917
+ title: "Profil d'Apprentissage",
1918
+ message: "Analyse de votre profil d'apprentissage en cours...",
1919
+ insights: [
1920
+ { icon: "📊", text: "Évaluation indicateurs" },
1921
+ { icon: "🎯", text: "Forces et améliorations" },
1922
+ { icon: "🚀", text: "Recommandations" }
1923
+ ]
1924
+ };
1925
+
1926
+ // Mettre à jour l'interface
1927
+ radarBotContent.innerHTML = `<strong>${profileMessage.title}</strong><br>${profileMessage.message}`;
1928
+
1929
+ // Mettre à jour les insights
1930
+ radarBotInsights.innerHTML = '';
1931
+ profileMessage.insights.forEach(insight => {
1932
+ const insightElement = document.createElement('div');
1933
+ insightElement.className = 'compact-radar-insight-item';
1934
+ insightElement.innerHTML = `
1935
+ <div class="radar-insight-icon">${insight.icon}</div>
1936
+ <div class="radar-insight-text">${insight.text}</div>
1937
+ `;
1938
+ radarBotInsights.appendChild(insightElement);
1939
+ });
1940
+ }
1941
+
1942
+ // Dessiner la heatmap enrichie compacte
1943
+ function drawCompactEnrichedHeatmap(scenario) {
1944
+ const canvas = document.getElementById("heatmap");
1945
+ if (!canvas) return;
1946
+
1947
+ const ctx = canvas.getContext("2d");
1948
+ const cellSize = 15;
1949
+ const padding = 1;
1950
+ const days = ["L", "M", "M", "J", "V", "S", "D"];
1951
+ const weeks = 4;
1952
+ const totalDays = weeks * 7;
1953
+
1954
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
1955
+
1956
+ // Titre enrichi
1957
+ const scenarioTitles = {
1958
+ 1: {
1959
+ title: "Engagé mais désorganisé",
1960
+ emoji: "😅",
1961
+ pattern: "Effort concentré avant échéances"
1962
+ },
1963
+ 2: {
1964
+ title: "Actif mais peu efficace",
1965
+ emoji: "😰",
1966
+ pattern: "Démarrage lent, accélération tardive"
1967
+ },
1968
+ 3: {
1969
+ title: "Autonome et stratégique",
1970
+ emoji: "😊",
1971
+ pattern: "Travail régulier et équilibré"
1972
+ }
1973
+ };
1974
+
1975
+ const scenarioInfo = scenarioTitles[scenario.id] || {
1976
+ title: "Votre activité",
1977
+ emoji: "📊",
1978
+ pattern: "Schéma à analyser"
1979
+ };
1980
+
1981
+ ctx.font = "bold 14px Arial";
1982
+ ctx.fillStyle = "#1976D2";
1983
+ ctx.textAlign = "center";
1984
+ ctx.fillText(`${scenarioInfo.emoji} ${scenarioInfo.title}`, canvas.width / 2, 20);
1985
+
1986
+ ctx.font = "12px Arial";
1987
+ ctx.fillStyle = "#666";
1988
+ ctx.fillText(`${scenarioInfo.pattern}`, canvas.width / 2, 40);
1989
+
1990
+ // Générer les données d'activité selon le scénario
1991
+ const activityData = generateCompactPersistenceData(scenario.id, totalDays);
1992
+
1993
+ // Dessiner la heatmap
1994
+ const colors = ["#EBEDF0", "#C6E48B", "#7BC96F", "#239A3B", "#196127"];
1995
+
1996
+ for (let day = 0; day < totalDays; day++) {
1997
+ const week = Math.floor(day / 7);
1998
+ const weekday = day % 7;
1999
+
2000
+ const x = 30 + week * (cellSize * 7 + padding * 7) + weekday * (cellSize + padding);
2001
+ const y = 60 + weekday * (cellSize + padding);
2002
+
2003
+ const intensity = activityData[day];
2004
+
2005
+ // Dessiner la cellule
2006
+ ctx.fillStyle = colors[intensity];
2007
+ ctx.fillRect(x, y, cellSize, cellSize);
2008
+
2009
+ // Bordure avec indication des échéances (vendredi = jour important)
2010
+ if (weekday === 4) { // Vendredi
2011
+ ctx.strokeStyle = "#FF6B6B";
2012
+ ctx.lineWidth = 1.5;
2013
+ } else {
2014
+ ctx.strokeStyle = intensity > 0 ? "#239A3B" : "#eee";
2015
+ ctx.lineWidth = 0.5;
2016
+ }
2017
+ ctx.strokeRect(x, y, cellSize, cellSize);
2018
+ }
2019
+
2020
+ // Analyser et afficher les métriques de persévérance compactes
2021
+ analyzeCompactPersistenceMetrics(activityData, scenario.id);
2022
+ }
2023
+
2024
+ // Mettre à jour la persévérance spécifique au profil
2025
+ function updatePerseveranceProfile(scenarioTitle) {
2026
+ const profile = perseveranceProfiles[scenarioTitle];
2027
+
2028
+ if (!profile) {
2029
+ console.warn(`Aucun profil de persévérance trouvé pour: ${scenarioTitle}`);
2030
+ return;
2031
+ }
2032
+
2033
+ // Mettre à jour l'interface
2034
+ const regularityText = document.getElementById("compact-regularityText");
2035
+ if (regularityText) {
2036
+ regularityText.innerHTML = `
2037
+ <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 5px;">
2038
+ <div style="width: 12px; height: 12px; border-radius: 50%; background: ${profile.color};"></div>
2039
+ <strong style="color: ${profile.color};">${profile.level}</strong>
2040
+ </div>
2041
+ <div style="font-size: 12px; color: #555; line-height: 1.4;">
2042
+ ${profile.interpretation}
2043
+ </div>
2044
+ `;
2045
+ }
2046
+
2047
+ // Mettre à jour le score de régularité dans les indicateurs
2048
+ const regularityScore = document.getElementById("compact-regularityScore");
2049
+ if (regularityScore) {
2050
+ // Convertir le niveau textuel en pourcentage approximatif
2051
+ let scorePercent;
2052
+ if (profile.level.includes("Très élevée")) scorePercent = "90%";
2053
+ else if (profile.level.includes("Élevée")) scorePercent = "75%";
2054
+ else if (profile.level.includes("Moyenne")) scorePercent = "55%";
2055
+ else if (profile.level.includes("Faible")) scorePercent = "35%";
2056
+ else if (profile.level.includes("Très faible")) scorePercent = "20%";
2057
+ else scorePercent = "50%";
2058
+
2059
+ regularityScore.textContent = scorePercent;
2060
+ regularityScore.style.color = profile.color;
2061
+ }
2062
+ }
2063
+
2064
+ // Générer des données de persévérance compactes
2065
+ function generateCompactPersistenceData(scenarioId, totalDays) {
2066
+ const data = new Array(totalDays).fill(0);
2067
+
2068
+ switch(scenarioId) {
2069
+ case 1: // Scénario désorganisé - Effort concentré avant échéances
2070
+ for (let i = 0; i < totalDays; i++) {
2071
+ const weekday = i % 7;
2072
+ if (weekday === 3 || weekday === 4) { // Jeudi et vendredi
2073
+ data[i] = Math.floor(Math.random() * 2) + 3; // 3-4
2074
+ } else if (weekday === 5 || weekday === 6) { // Weekend
2075
+ data[i] = Math.floor(Math.random() * 2); // 0-1
2076
+ } else {
2077
+ data[i] = Math.floor(Math.random() * 2) + 1; // 1-2
2078
+ }
2079
+ }
2080
+ break;
2081
+
2082
+ case 2: // Scénario peu efficace - Démarrage lent, accélération tardive
2083
+ for (let i = 0; i < totalDays; i++) {
2084
+ const progress = i / totalDays;
2085
+ if (progress < 0.3) {
2086
+ data[i] = Math.floor(Math.random() * 2); // 0-1
2087
+ } else if (progress > 0.7) {
2088
+ data[i] = Math.floor(Math.random() * 2) + 3; // 3-4
2089
+ } else {
2090
+ data[i] = Math.floor(Math.random() * 2) + 1; // 1-2
2091
+ }
2092
+ }
2093
+ break;
2094
+
2095
+ case 3: // Scénario stratégique - Travail régulier
2096
+ for (let i = 0; i < totalDays; i++) {
2097
+ const weekday = i % 7;
2098
+ if (weekday === 5 || weekday === 6) { // Weekend léger
2099
+ data[i] = Math.floor(Math.random() * 2); // 0-1
2100
+ } else {
2101
+ data[i] = Math.floor(Math.random() * 2) + 2; // 2-3
2102
+ }
2103
+ }
2104
+ break;
2105
+
2106
+ default:
2107
+ for (let i = 0; i < totalDays; i++) {
2108
+ data[i] = Math.floor(Math.random() * 5); // 0-4 aléatoire
2109
+ }
2110
+ }
2111
+
2112
+ return data;
2113
+ }
2114
+
2115
+ // Analyser les métriques de persévérance compactes
2116
+ function analyzeCompactPersistenceMetrics(activityData, scenarioId) {
2117
+ const totalDays = activityData.length;
2118
+
2119
+ // 1. Calculer la régularité (écart-type)
2120
+ const avgActivity = activityData.reduce((a, b) => a + b, 0) / totalDays;
2121
+ const variance = activityData.reduce((a, b) => a + Math.pow(b - avgActivity, 2), 0) / totalDays;
2122
+ const stdDev = Math.sqrt(variance);
2123
+ const regularity = Math.max(0, 100 - stdDev * 25);
2124
+
2125
+ // 2. Identifier le schéma d'effort
2126
+ let pattern = "Régulier";
2127
+ let patternDescription = "Effort équilibré toute la semaine";
2128
+
2129
+ // Analyser la distribution
2130
+ const weeklyPatterns = [];
2131
+ for (let w = 0; w < 4; w++) {
2132
+ const weekData = activityData.slice(w * 7, Math.min((w + 1) * 7, totalDays));
2133
+ if (weekData.length < 5) continue;
2134
+
2135
+ const weekAvg = weekData.reduce((a, b) => a + b, 0) / weekData.length;
2136
+
2137
+ if (weekData[4] > weekAvg * 1.5 && weekData[3] > weekAvg * 1.3) {
2138
+ pattern = "Effort concentré";
2139
+ patternDescription = "Pic d'activité jeudi/vendredi";
2140
+ } else if (weekData[0] < weekAvg * 0.7 && weekData[4] > weekAvg * 1.2) {
2141
+ pattern = "Accélération progressive";
2142
+ patternDescription = "Démarrage lent, fin forte";
2143
+ }
2144
+ }
2145
+
2146
+ // 3. Calculer la gestion des échéances
2147
+ const deadlineDays = activityData.filter((_, index) => index % 7 === 3 || index % 7 === 4);
2148
+ const nonDeadlineDays = activityData.filter((_, index) => index % 7 !== 3 && index % 7 !== 4);
2149
+
2150
+ let deadlineScore = 50;
2151
+ if (deadlineDays.length > 0 && nonDeadlineDays.length > 0) {
2152
+ const deadlineAvg = deadlineDays.reduce((a, b) => a + b, 0) / deadlineDays.length;
2153
+ const nonDeadlineAvg = nonDeadlineDays.reduce((a, b) => a + b, 0) / nonDeadlineDays.length;
2154
+ deadlineScore = Math.min(100, Math.max(0, (deadlineAvg / 4) * 100));
2155
+ }
2156
+
2157
+ // Mettre à jour l'interface compacte
2158
+ document.getElementById("compact-regularityScore").textContent = Math.round(regularity) + "%";
2159
+ document.getElementById("compact-effortPattern").textContent = pattern;
2160
+ document.getElementById("compact-deadlineScore").textContent = Math.round(deadlineScore) + "%";
2161
+
2162
+ // Mettre à jour l'analyse textuelle compacte
2163
+ document.getElementById("compact-patternText").textContent = patternDescription;
2164
+ }
2165
+
2166
+ // ================= RADAR =================
2167
+ function drawRadar() {
2168
+ const canvas = document.getElementById("radar");
2169
+ if (!canvas) {
2170
+ console.error("Canvas radar non trouvé!");
2171
+ return;
2172
+ }
2173
+
2174
+ const ctx = canvas.getContext("2d");
2175
+ const cx = canvas.width / 2;
2176
+ const cy = canvas.height / 2;
2177
+ const radius = 200;
2178
+ const n = radarMetrics.length;
2179
+
2180
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
2181
+
2182
+ // Dessiner le radar
2183
+ for (let i = 1; i <= 5; i++) {
2184
+ ctx.beginPath();
2185
+ ctx.arc(cx, cy, (radius / 5) * i, 0, 2 * Math.PI);
2186
+ ctx.strokeStyle = "#e0e0e0";
2187
+ ctx.stroke();
2188
+ }
2189
+
2190
+ // Dessiner les axes
2191
+ radarMetrics.forEach((m, i) => {
2192
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2193
+
2194
+ ctx.beginPath();
2195
+ ctx.moveTo(cx, cy);
2196
+ ctx.lineTo(cx + radius * Math.cos(angle), cy + radius * Math.sin(angle));
2197
+ ctx.strokeStyle = "#b0bec5";
2198
+ ctx.stroke();
2199
+
2200
+ // Labels
2201
+ const tx = cx + (radius + 25) * Math.cos(angle);
2202
+ const ty = cy + (radius + 25) * Math.sin(angle);
2203
+
2204
+ ctx.font = "10px Arial";
2205
+ ctx.fillStyle = "#000";
2206
+ ctx.textAlign = angle > Math.PI / 2 || angle < -Math.PI / 2 ? "right" : "left";
2207
+ ctx.textBaseline = "middle";
2208
+ ctx.fillText(`${m.label.split(' ')[0]}`, tx, ty);
2209
+ });
2210
+
2211
+ // Dessiner le polygone
2212
+ ctx.beginPath();
2213
+ radarMetrics.forEach((m, i) => {
2214
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2215
+ const r = radius * (m.value / 100);
2216
+ const x = cx + r * Math.cos(angle);
2217
+ const y = cy + r * Math.sin(angle);
2218
+ i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
2219
+ });
2220
+ ctx.closePath();
2221
+
2222
+ ctx.fillStyle = "rgba(25,118,210,0.25)";
2223
+ ctx.fill();
2224
+ ctx.strokeStyle = "#1976D2";
2225
+ ctx.lineWidth = 2;
2226
+ ctx.stroke();
2227
+
2228
+ // Dessiner les points
2229
+ radarMetrics.forEach((m, i) => {
2230
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2231
+ const r = radius * (m.value / 100);
2232
+ const x = cx + r * Math.cos(angle);
2233
+ const y = cy + r * Math.sin(angle);
2234
+
2235
+ ctx.beginPath();
2236
+ ctx.arc(x, y, 4, 0, 2 * Math.PI);
2237
+ ctx.fillStyle = "#1976D2";
2238
+ ctx.fill();
2239
+ });
2240
+ }
2241
+
2242
+ // ================= NAVIGATION =================
2243
+ document.getElementById("prevScenario").onclick = () =>
2244
+ loadScenario(currentScenarioIndex - 1);
2245
+
2246
+ document.getElementById("nextScenario").onclick = () =>
2247
+ loadScenario(currentScenarioIndex + 1);
2248
+
2249
+ function updateNavButtons() {
2250
+ document.getElementById("prevScenario").disabled =
2251
+ currentScenarioIndex === 0;
2252
+ document.getElementById("nextScenario").disabled =
2253
+ currentScenarioIndex === scenarios.length - 1;
2254
+ }
2255
+
2256
+ // ================= BOUTON LECTURE CROISÉE =================
2257
+ document.getElementById('crossReadersBtn').onclick = () => {
2258
+ console.log('Navigation vers la page de lecture croisée...');
2259
+
2260
+ // Animation de transition
2261
+ const reflectionDiv = document.getElementById('reflection');
2262
+ if (reflectionDiv) {
2263
+ reflectionDiv.style.opacity = '0.7';
2264
+ reflectionDiv.style.transition = 'opacity 0.3s ease';
2265
+ }
2266
+
2267
+ // Redirection
2268
+ setTimeout(() => {
2269
+ window.location.href = 'cross_reading/cross_readers.html';
2270
+ }, 300);
2271
+ };
2272
+
2273
+ // ================= MÉTRIQUES DE CONFIANCE =================
2274
+ function initTrustStars(){
2275
+ console.log("Initialisation des étoiles...");
2276
+
2277
+ // Réinitialiser toutes les métriques
2278
+ for (const key in trustMetrics) {
2279
+ trustMetrics[key] = 0;
2280
+ }
2281
+
2282
+ let starsCreated = 0;
2283
+
2284
+ document.querySelectorAll(".stars").forEach(div => {
2285
+ const metric = div.dataset.metric;
2286
+ console.log(`Création des étoiles pour: ${metric}`);
2287
+
2288
+ // Vérifier que la métrique existe
2289
+ if (!trustMetrics.hasOwnProperty(metric)) {
2290
+ console.error(`Métrique inconnue: ${metric}`);
2291
+ return;
2292
+ }
2293
+
2294
+ // Vider le conteneur
2295
+ div.innerHTML = '';
2296
+
2297
+ // Créer 5 étoiles
2298
+ for (let i = 1; i <= 5; i++) {
2299
+ const star = document.createElement("span");
2300
+ star.textContent = "★";
2301
+ star.classList.add("inactive");
2302
+ star.style.cursor = "pointer";
2303
+ star.title = `${i} étoile${i > 1 ? 's' : ''}`;
2304
+
2305
+ // Stocker la valeur dans un attribut data
2306
+ star.dataset.value = i;
2307
+
2308
+ star.onclick = function() {
2309
+ const value = parseInt(this.dataset.value);
2310
+ console.log(`Clic sur ${metric}: ${value} étoiles`);
2311
+
2312
+ // Mettre à jour la valeur de la métrique
2313
+ trustMetrics[metric] = value;
2314
+
2315
+ // Mettre à jour l'affichage des étoiles dans ce groupe
2316
+ const allStarsInGroup = this.parentElement.children;
2317
+ for (let j = 0; j < allStarsInGroup.length; j++) {
2318
+ const starElem = allStarsInGroup[j];
2319
+ const starValue = parseInt(starElem.dataset.value);
2320
+
2321
+ if (starValue <= value) {
2322
+ starElem.classList.remove("inactive");
2323
+ starElem.classList.add("active");
2324
+ } else {
2325
+ starElem.classList.add("inactive");
2326
+ starElem.classList.remove("active");
2327
+ }
2328
+ }
2329
+
2330
+ // Mettre à jour la barre de progression
2331
+ updateTrustBar();
2332
+ };
2333
+
2334
+ div.appendChild(star);
2335
+ starsCreated++;
2336
+ }
2337
+ });
2338
+
2339
+ console.log(`${starsCreated} étoiles créées pour ${Object.keys(trustMetrics).length} métriques`);
2340
+ console.log("Métriques initialisées:", trustMetrics);
2341
+ }
2342
+
2343
+ function updateTrustBar(){
2344
+ console.log("=== MISE À JOUR BARRE DE CONFIANCE ===");
2345
+
2346
+ let scoreTotal = 0;
2347
+ let scoreMaxPossible = 0;
2348
+ let details = [];
2349
+
2350
+ // Calcul détaillé
2351
+ for (const metric in trustMetrics) {
2352
+ const valeur = trustMetrics[metric];
2353
+ const poids = trustWeights[metric];
2354
+ const contribution = valeur * poids;
2355
+ const maxContribution = 5 * poids;
2356
+
2357
+ scoreTotal += contribution;
2358
+ scoreMaxPossible += maxContribution;
2359
+
2360
+ details.push({
2361
+ métrique: metric,
2362
+ valeur: valeur,
2363
+ poids: poids,
2364
+ contribution: contribution.toFixed(2),
2365
+ max: maxContribution.toFixed(2)
2366
+ });
2367
+ }
2368
+
2369
+ console.log("Détails du calcul:");
2370
+ details.forEach(d => {
2371
+ console.log(`${d.métrique}: ${d.valeur}/5 × ${d.poids} = ${d.contribution} / ${d.max}`);
2372
+ });
2373
+
2374
+ console.log(`Total: ${scoreTotal.toFixed(2)} / ${scoreMaxPossible.toFixed(2)}`);
2375
+
2376
+ // Calcul du pourcentage
2377
+ let pourcentage = 0;
2378
+ if (scoreMaxPossible > 0) {
2379
+ pourcentage = Math.round((scoreTotal / scoreMaxPossible) * 100);
2380
+ }
2381
+
2382
+ console.log(`Pourcentage calculé: ${pourcentage}%`);
2383
+
2384
+ // Mettre à jour la barre de progression
2385
+ const barre = document.getElementById("trustBar");
2386
+ if (barre) {
2387
+ barre.style.width = pourcentage + "%";
2388
+ barre.textContent = pourcentage + "%";
2389
+
2390
+ // Changer la couleur selon le niveau
2391
+ if (pourcentage < 40) {
2392
+ barre.style.background = "#E53935"; // Rouge - Faible
2393
+ barre.title = `Faible confiance (${pourcentage}%)`;
2394
+ } else if (pourcentage < 70) {
2395
+ barre.style.background = "#FB8C00"; // Orange - Moyen
2396
+ barre.title = `Confiance moyenne (${pourcentage}%)`;
2397
+ } else {
2398
+ barre.style.background = "#43A047"; // Vert - Fort
2399
+ barre.title = `Forte confiance (${pourcentage}%)`;
2400
+ }
2401
+
2402
+ console.log(`Barre mise à jour: ${pourcentage}% (width: ${pourcentage}%)`);
2403
+ } else {
2404
+ console.error("Élément #trustBar non trouvé!");
2405
+ }
2406
+
2407
+ // Mettre à jour la statistique de confiance moyenne
2408
+ const avgTrustElem = document.getElementById("avgTrustScore");
2409
+ if (avgTrustElem) {
2410
+ avgTrustElem.textContent = pourcentage + "%";
2411
+ console.log(`Statistique moyenne mise à jour: ${pourcentage}%`);
2412
+ }
2413
+
2414
+ // Afficher un résumé dans la console
2415
+ console.log("=== RÉSUMÉ FINAL ===");
2416
+ console.log(`Indice global de confiance: ${pourcentage}%`);
2417
+ console.log("Valeurs des métriques:", JSON.stringify(trustMetrics, null, 2));
2418
+ console.log("====================");
2419
+
2420
+ return pourcentage;
2421
+ }
2422
+
2423
+ function initTrustSave(){
2424
+ const saveBtn = document.getElementById("saveTrustBtn");
2425
+ if (!saveBtn) {
2426
+ console.error("Bouton de sauvegarde non trouvé!");
2427
+ return;
2428
+ }
2429
+
2430
+ saveBtn.onclick = () => {
2431
+ console.log("=== DÉBUT SAUVEGARDE ===");
2432
+
2433
+ // Récupérer les informations GDPR
2434
+ const gdprAccept = document.getElementById('gdprAccept').checked;
2435
+ const gdprDecline = document.getElementById('gdprDecline').checked;
2436
+
2437
+ // Récupérer les informations conditionnelles
2438
+ let evaluatorName = "";
2439
+ let evaluatorRole = "";
2440
+ let expertiseLevel = "";
2441
+ let messageMastery = "";
2442
+
2443
+ if (gdprAccept) {
2444
+ evaluatorName = document.getElementById("evaluatorName").value.trim();
2445
+ evaluatorRole = document.getElementById("evaluatorRole").value;
2446
+ expertiseLevel = document.getElementById("expertiseLevel").value;
2447
+ messageMastery = document.getElementById("messageMastery").value;
2448
+ }
2449
+
2450
+ const comment = document.getElementById("trustComment").value;
2451
+ const msgDiv = document.getElementById("saveTrustMsg");
2452
+
2453
+ // Validation : consentement GDPR obligatoire
2454
+ if (!gdprAccept && !gdprDecline) {
2455
+ const message = "❌ Veuillez sélectionner une option de consentement RGPD.";
2456
+ console.error(message);
2457
+
2458
+ if (msgDiv) {
2459
+ msgDiv.textContent = message;
2460
+ msgDiv.style.background = "#FFEBEE";
2461
+ msgDiv.style.color = "#C62828";
2462
+ }
2463
+ return;
2464
+ }
2465
+
2466
+ // Validation : si GDPR accepté, vérifier les champs obligatoires
2467
+ if (gdprAccept) {
2468
+ if (!evaluatorName) {
2469
+ const message = "❌ Veuillez saisir votre nom et prénom.";
2470
+ console.error(message);
2471
+
2472
+ if (msgDiv) {
2473
+ msgDiv.textContent = message;
2474
+ msgDiv.style.background = "#FFEBEE";
2475
+ msgDiv.style.color = "#C62828";
2476
+ }
2477
+
2478
+ const nameField = document.getElementById("evaluatorName");
2479
+ nameField.style.borderColor = "#E53935";
2480
+ nameField.style.boxShadow = "0 0 0 3px rgba(229, 57, 53, 0.1)";
2481
+ nameField.focus();
2482
+
2483
+ setTimeout(() => {
2484
+ nameField.style.borderColor = "#e0e0e0";
2485
+ nameField.style.boxShadow = "none";
2486
+ }, 3000);
2487
+
2488
+ return;
2489
+ }
2490
+
2491
+ if (!evaluatorRole) {
2492
+ const message = "❌ Veuillez sélectionner votre rôle.";
2493
+ console.error(message);
2494
+
2495
+ if (msgDiv) {
2496
+ msgDiv.textContent = message;
2497
+ msgDiv.style.background = "#FFEBEE";
2498
+ msgDiv.style.color = "#C62828";
2499
+ }
2500
+ return;
2501
+ }
2502
+
2503
+ if (!expertiseLevel) {
2504
+ const message = "❌ Veuillez sélectionner votre niveau d'expertise en réflexivité.";
2505
+ console.error(message);
2506
+
2507
+ if (msgDiv) {
2508
+ msgDiv.textContent = message;
2509
+ msgDiv.style.background = "#FFEBEE";
2510
+ msgDiv.style.color = "#C62828";
2511
+ }
2512
+ return;
2513
+ }
2514
+
2515
+ if (!messageMastery) {
2516
+ const message = "❌ Veuillez sélectionner votre niveau de maîtrise des messages réflexifs.";
2517
+ console.error(message);
2518
+
2519
+ if (msgDiv) {
2520
+ msgDiv.textContent = message;
2521
+ msgDiv.style.background = "#FFEBEE";
2522
+ msgDiv.style.color = "#C62828";
2523
+ }
2524
+ return;
2525
+ }
2526
+ }
2527
+
2528
+ // Vérifier si au moins une évaluation
2529
+ let hasEvaluation = false;
2530
+ for (const metric in trustMetrics) {
2531
+ if (trustMetrics[metric] > 0) {
2532
+ hasEvaluation = true;
2533
+ break;
2534
+ }
2535
+ }
2536
+
2537
+ if (!hasEvaluation) {
2538
+ const message = "⚠️ Veuillez évaluer au moins une métrique avant de sauvegarder.";
2539
+ console.warn(message);
2540
+
2541
+ if (msgDiv) {
2542
+ msgDiv.textContent = message;
2543
+ msgDiv.style.background = "#FFF3E0";
2544
+ msgDiv.style.color = "#EF6C00";
2545
+ }
2546
+ return;
2547
+ }
2548
+
2549
+ // Calculer l'indice de confiance
2550
+ const trustScore = updateTrustBar(); // Cette fonction retourne le pourcentage
2551
+
2552
+ console.log(`Indice calculé pour sauvegarde: ${trustScore}%`);
2553
+
2554
+ // Préparer les données
2555
+ const data = {
2556
+ scenario_id: scenarios[currentScenarioIndex].id,
2557
+ scenario_title: scenarios[currentScenarioIndex].title,
2558
+ trust_metrics: {...trustMetrics},
2559
+ trust_score: trustScore,
2560
+ gdpr_consent: gdprAccept ? "accept" : "decline",
2561
+ evaluator_name: gdprAccept ? evaluatorName : null,
2562
+ evaluator_role: gdprAccept ? evaluatorRole : null,
2563
+ expertise_level: gdprAccept ? expertiseLevel : null,
2564
+ message_mastery: gdprAccept ? messageMastery : null,
2565
+ comment: comment || null,
2566
+ timestamp: new Date().toISOString(),
2567
+ trust_weights: {...trustWeights}
2568
+ };
2569
+
2570
+ console.log("Données à envoyer:", JSON.stringify(data, null, 2));
2571
+
2572
+ // Envoyer au serveur
2573
+ fetch("/save_trust", {
2574
+ method: "POST",
2575
+ headers: { "Content-Type": "application/json" },
2576
+ body: JSON.stringify(data)
2577
+ })
2578
+ .then(res => {
2579
+ if (!res.ok) throw new Error(`Erreur HTTP ${res.status}: ${res.statusText}`);
2580
+ return res.json();
2581
+ })
2582
+ .then(responseData => {
2583
+ console.log("✅ Réponse du serveur:", responseData);
2584
+
2585
+ if (msgDiv) {
2586
+ const nameDisplay = gdprAccept ? evaluatorName : "Évaluateur anonyme";
2587
+ msgDiv.innerHTML = `
2588
+ <div style="display: flex; align-items: center; gap: 10px;">
2589
+ <div style="font-size: 24px;">✅</div>
2590
+ <div>
2591
+ <strong>Évaluation sauvegardée avec succès !</strong><br>
2592
+ <small>Merci ${nameDisplay} pour votre contribution.</small><br>
2593
+ <small><em>Indice global: ${trustScore}%</em></small>
2594
+ </div>
2595
+ </div>
2596
+ `;
2597
+ msgDiv.style.background = "#E8F5E9";
2598
+ msgDiv.style.color = "#2E7D32";
2599
+ msgDiv.style.padding = "15px";
2600
+ }
2601
+
2602
+ // Réinitialiser après succès (optionnel)
2603
+ setTimeout(() => {
2604
+ resetTrustEvaluation();
2605
+ }, 3000);
2606
+ })
2607
+ .catch(error => {
2608
+ console.error("❌ Erreur de sauvegarde:", error);
2609
+ if (msgDiv) {
2610
+ msgDiv.textContent = `❌ Erreur: ${error.message}`;
2611
+ msgDiv.style.background = "#FFEBEE";
2612
+ msgDiv.style.color = "#C62828";
2613
+ }
2614
+ });
2615
+ };
2616
+
2617
+ console.log("✅ Bouton de sauvegarde initialisé");
2618
+ }
2619
+
2620
+ // Fonction pour réinitialiser l'évaluation
2621
+ function resetTrustEvaluation() {
2622
+ console.log("Réinitialisation de l'évaluation...");
2623
+
2624
+ // Réinitialiser les métriques
2625
+ for (const key in trustMetrics) {
2626
+ trustMetrics[key] = 0;
2627
+ }
2628
+
2629
+ // Réinitialiser les étoiles
2630
+ document.querySelectorAll(".stars").forEach(div => {
2631
+ Array.from(div.children).forEach(star => {
2632
+ star.classList.add("inactive");
2633
+ star.classList.remove("active");
2634
+ });
2635
+ });
2636
+
2637
+ // Réinitialiser la barre
2638
+ updateTrustBar();
2639
+
2640
+ // Vider le commentaire
2641
+ document.getElementById("trustComment").value = "";
2642
+
2643
+ console.log("Évaluation réinitialisée");
2644
+ }
2645
+
2646
+ // ================= FONCTIONS UTILITAIRES =================
2647
+
2648
+ // Mettre à jour les statistiques
2649
+ function updateStats() {
2650
+ if (!scenarios || scenarios.length === 0) return;
2651
+
2652
+ const currentScenario = scenarios[currentScenarioIndex];
2653
+
2654
+ document.getElementById("currentScenarioNum").textContent = currentScenario.id;
2655
+
2656
+ // Niveau de risque
2657
+ const risk = currentScenario.risk || 50;
2658
+ let riskLevel = "Moyen";
2659
+ let riskColor = "#FB8C00";
2660
+
2661
+ if (risk < 40) {
2662
+ riskLevel = "Faible";
2663
+ riskColor = "#43A047";
2664
+ } else if (risk > 70) {
2665
+ riskLevel = "Élevé";
2666
+ riskColor = "#E53935";
2667
+ }
2668
+
2669
+ document.getElementById("riskLevel").textContent = riskLevel;
2670
+ document.getElementById("riskLevel").style.color = riskColor;
2671
+
2672
+ // Activité moyenne à partir des données radar
2673
+ if (currentScenario.radar && currentScenario.radar.length > 0) {
2674
+ const avgRadar = currentScenario.radar.reduce((sum, item) => sum + item.value, 0) / currentScenario.radar.length;
2675
+ document.getElementById("avgActivity").textContent = Math.round(avgRadar) + "%";
2676
+ }
2677
+ }
2678
+
2679
+ // Fonction pour remplir un exemple d'évaluateur
2680
+ function fillSampleEvaluator() {
2681
+ // Sélectionner l'option GDPR "accept"
2682
+ document.getElementById('gdprAccept').checked = true;
2683
+ document.getElementById('gdprDecline').checked = false;
2684
+
2685
+ // Mettre à jour les champs
2686
+ initGDPR();
2687
+
2688
+ // Remplir les champs
2689
+ document.getElementById("evaluatorName").value = "Martin Sophie";
2690
+ document.getElementById("evaluatorRole").value = "enseignant";
2691
+ document.getElementById("expertiseLevel").value = "avance";
2692
+ document.getElementById("messageMastery").value = "intermediaire_msg";
2693
+
2694
+ showNotification("Exemple", "Champs d'évaluateur remplis avec un exemple", "info");
2695
+ }
2696
+
2697
+ // Fonction pour effacer les champs évaluateur
2698
+ function clearEvaluatorFields() {
2699
+ // Sélectionner l'option GDPR "decline" par défaut
2700
+ document.getElementById('gdprDecline').checked = true;
2701
+ document.getElementById('gdprAccept').checked = false;
2702
+
2703
+ // Mettre à jour les champs
2704
+ initGDPR();
2705
+
2706
+ showNotification("Champs effacés", "Les informations d'évaluateur ont été effacées", "info");
2707
+ }
2708
+
2709
+ // Fonction pour afficher une notification
2710
+ function showNotification(title, message, type = "info") {
2711
+ console.log(`[${type}] ${title}: ${message}`);
2712
+
2713
+ const msgDiv = document.getElementById("saveTrustMsg");
2714
+ if (msgDiv) {
2715
+ msgDiv.textContent = `${title}: ${message}`;
2716
+ msgDiv.style.background = type === "success" ? "#E8F5E9" :
2717
+ type === "error" ? "#FFEBEE" : "#E3F2FD";
2718
+ msgDiv.style.color = type === "success" ? "#2E7D32" :
2719
+ type === "error" ? "#C62828" : "#1565C0";
2720
+ }
2721
+ }
2722
+
2723
+ // Changer le mode d'analyse de persévérance
2724
+ function changePersistenceAnalysis() {
2725
+ const mode = document.getElementById("persistenceMode").value;
2726
+ const currentScenario = scenarios[currentScenarioIndex];
2727
+
2728
+ // Redessiner la heatmap avec le mode sélectionné
2729
+ drawCompactEnrichedHeatmap(currentScenario);
2730
+
2731
+ // Ajouter une annotation selon le mode
2732
+ const canvas = document.getElementById("heatmap");
2733
+ const ctx = canvas.getContext("2d");
2734
+
2735
+ ctx.font = "12px Arial";
2736
+ ctx.fillStyle = "#1976D2";
2737
+ ctx.textAlign = "center";
2738
+
2739
+ switch(mode) {
2740
+ case "regularity":
2741
+ ctx.fillText("📊 Analyse de la régularité", canvas.width / 2, canvas.height - 10);
2742
+ break;
2743
+ case "effortPattern":
2744
+ ctx.fillText("🔄 Schéma d'effort", canvas.width / 2, canvas.height - 10);
2745
+ break;
2746
+ case "deadline":
2747
+ ctx.fillText("⏰ Gestion des échéances", canvas.width / 2, canvas.height - 10);
2748
+ break;
2749
+ case "combined":
2750
+ ctx.fillText("🎯 Vue combinée", canvas.width / 2, canvas.height - 10);
2751
+ break;
2752
+ }
2753
+ }
2754
+
2755
+ // Exposer les fonctions globales
2756
+ window.changePersistenceAnalysis = changePersistenceAnalysis;
2757
+ window.updateStats = updateStats;
2758
+ window.showNotification = showNotification;
2759
+ window.fillSampleEvaluator = fillSampleEvaluator;
2760
+ window.clearEvaluatorFields = clearEvaluatorFields;
2761
+ </script>
2762
+
2763
+ </body>
2764
+ </html>