Spaces:
Running
Running
Update templates/philosophie.html
Browse files- templates/philosophie.html +494 -492
templates/philosophie.html
CHANGED
|
@@ -18,25 +18,162 @@
|
|
| 18 |
/* Styles pour le Glow Up */
|
| 19 |
:root {
|
| 20 |
font-family: 'Inter', sans-serif;
|
| 21 |
-
/* Variables pour des transitions plus fluides */
|
| 22 |
--transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
| 23 |
--transition-fast: all 0.15s ease-out;
|
|
|
|
| 24 |
}
|
| 25 |
|
| 26 |
-
/* Optimisations pour le scroll fluide */
|
| 27 |
html {
|
| 28 |
scroll-behavior: smooth;
|
| 29 |
-webkit-overflow-scrolling: touch;
|
| 30 |
}
|
| 31 |
|
| 32 |
body {
|
| 33 |
-
/* Prévenir le reflow lors de la génération */
|
| 34 |
will-change: scroll-position;
|
| 35 |
-
/* Améliorer les performances sur mobile */
|
| 36 |
-webkit-font-smoothing: antialiased;
|
| 37 |
-moz-osx-font-smoothing: grayscale;
|
| 38 |
}
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
.collapsible {
|
| 41 |
cursor: pointer;
|
| 42 |
padding: 1rem;
|
|
@@ -45,7 +182,6 @@
|
|
| 45 |
text-align: left;
|
| 46 |
outline: none;
|
| 47 |
transition: var(--transition-fast);
|
| 48 |
-
/* Optimiser pour les interactions tactiles */
|
| 49 |
touch-action: manipulation;
|
| 50 |
-webkit-tap-highlight-color: transparent;
|
| 51 |
}
|
|
@@ -59,14 +195,11 @@
|
|
| 59 |
display: none;
|
| 60 |
overflow: hidden;
|
| 61 |
background-color: white;
|
| 62 |
-
/* Transition plus fluide pour l'ouverture */
|
| 63 |
transition: var(--transition-smooth);
|
| 64 |
}
|
| 65 |
|
| 66 |
-
/* Styles pour la lisibilité du Markdown généré */
|
| 67 |
.prose {
|
| 68 |
max-width: 100% !important;
|
| 69 |
-
/* Optimiser le rendu du texte */
|
| 70 |
text-rendering: optimizeLegibility;
|
| 71 |
}
|
| 72 |
|
|
@@ -74,7 +207,6 @@
|
|
| 74 |
color: #374151;
|
| 75 |
word-wrap: break-word;
|
| 76 |
overflow-wrap: break-word;
|
| 77 |
-
/* Prévenir les débordements sur mobile */
|
| 78 |
hyphens: auto;
|
| 79 |
-webkit-hyphens: auto;
|
| 80 |
-moz-hyphens: auto;
|
|
@@ -90,10 +222,8 @@
|
|
| 90 |
line-height: 1.3;
|
| 91 |
}
|
| 92 |
|
| 93 |
-
/* Animation fadeIn optimisée */
|
| 94 |
.animate-fadeIn {
|
| 95 |
animation: fadeIn 0.4s ease-out forwards;
|
| 96 |
-
/* Utiliser GPU pour l'animation */
|
| 97 |
transform: translateZ(0);
|
| 98 |
will-change: opacity, transform;
|
| 99 |
}
|
|
@@ -108,30 +238,7 @@
|
|
| 108 |
transform: translateY(0) translateZ(0);
|
| 109 |
}
|
| 110 |
}
|
| 111 |
-
|
| 112 |
-
/* Animation de typing pour le streaming fondu */
|
| 113 |
-
@keyframes typing {
|
| 114 |
-
from { width: 0; }
|
| 115 |
-
to { width: 100%; }
|
| 116 |
-
}
|
| 117 |
-
|
| 118 |
-
@keyframes fadeInChar {
|
| 119 |
-
from {
|
| 120 |
-
opacity: 0;
|
| 121 |
-
transform: translateY(10px);
|
| 122 |
-
}
|
| 123 |
-
to {
|
| 124 |
-
opacity: 1;
|
| 125 |
-
transform: translateY(0);
|
| 126 |
-
}
|
| 127 |
-
}
|
| 128 |
-
|
| 129 |
-
.typing-char {
|
| 130 |
-
display: inline-block;
|
| 131 |
-
animation: fadeInChar 0.3s ease-out forwards;
|
| 132 |
-
}
|
| 133 |
|
| 134 |
-
/* Styles pour Select2 */
|
| 135 |
.select2-container--default .select2-selection--single {
|
| 136 |
border: 1px solid #d1d5db;
|
| 137 |
border-radius: 0.75rem;
|
|
@@ -160,14 +267,12 @@
|
|
| 160 |
box-shadow: 0 4px 6px -1px rgba(0,0,0,.1);
|
| 161 |
}
|
| 162 |
|
| 163 |
-
/* Styles pour l'aperçu de l'image */
|
| 164 |
#image-preview {
|
| 165 |
max-height: 200px;
|
| 166 |
border-radius: 0.75rem;
|
| 167 |
box-shadow: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1);
|
| 168 |
}
|
| 169 |
|
| 170 |
-
/* Cacher le marqueur par défaut de <details> */
|
| 171 |
summary {
|
| 172 |
list-style: none;
|
| 173 |
}
|
|
@@ -175,192 +280,44 @@
|
|
| 175 |
summary::-webkit-details-marker {
|
| 176 |
display: none;
|
| 177 |
}
|
| 178 |
-
|
| 179 |
-
/* Styles pour le loader premium */
|
| 180 |
-
.loader-overlay {
|
| 181 |
-
position: fixed;
|
| 182 |
-
top: 0;
|
| 183 |
-
left: 0;
|
| 184 |
-
width: 100%;
|
| 185 |
-
height: 100%;
|
| 186 |
-
background: rgba(0, 0, 0, 0.8);
|
| 187 |
-
backdrop-filter: blur(10px);
|
| 188 |
-
z-index: 9999;
|
| 189 |
-
display: flex;
|
| 190 |
-
align-items: center;
|
| 191 |
-
justify-content: center;
|
| 192 |
-
opacity: 0;
|
| 193 |
-
transition: opacity 0.3s ease-out;
|
| 194 |
-
}
|
| 195 |
-
|
| 196 |
-
.loader-overlay.show {
|
| 197 |
-
opacity: 1;
|
| 198 |
-
}
|
| 199 |
-
|
| 200 |
-
.loader-container {
|
| 201 |
-
background: white;
|
| 202 |
-
border-radius: 20px;
|
| 203 |
-
padding: 2rem;
|
| 204 |
-
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
| 205 |
-
text-align: center;
|
| 206 |
-
max-width: 400px;
|
| 207 |
-
width: 90%;
|
| 208 |
-
transform: scale(0.9);
|
| 209 |
-
transition: transform 0.3s ease-out;
|
| 210 |
-
}
|
| 211 |
-
|
| 212 |
-
.loader-overlay.show .loader-container {
|
| 213 |
-
transform: scale(1);
|
| 214 |
-
}
|
| 215 |
-
|
| 216 |
-
.progress-circle {
|
| 217 |
-
width: 120px;
|
| 218 |
-
height: 120px;
|
| 219 |
-
margin: 0 auto 1.5rem;
|
| 220 |
-
position: relative;
|
| 221 |
-
}
|
| 222 |
-
|
| 223 |
-
.progress-ring {
|
| 224 |
-
transform: rotate(-90deg);
|
| 225 |
-
width: 100%;
|
| 226 |
-
height: 100%;
|
| 227 |
-
}
|
| 228 |
-
|
| 229 |
-
.progress-ring-circle {
|
| 230 |
-
stroke: #e5e7eb;
|
| 231 |
-
stroke-width: 8;
|
| 232 |
-
fill: transparent;
|
| 233 |
-
r: 52;
|
| 234 |
-
cx: 60;
|
| 235 |
-
cy: 60;
|
| 236 |
-
}
|
| 237 |
-
|
| 238 |
-
.progress-ring-progress {
|
| 239 |
-
stroke: #8b5cf6;
|
| 240 |
-
stroke-width: 8;
|
| 241 |
-
fill: transparent;
|
| 242 |
-
r: 52;
|
| 243 |
-
cx: 60;
|
| 244 |
-
cy: 60;
|
| 245 |
-
stroke-dasharray: 326.73;
|
| 246 |
-
stroke-dashoffset: 326.73;
|
| 247 |
-
transition: stroke-dashoffset 0.3s ease-out;
|
| 248 |
-
stroke-linecap: round;
|
| 249 |
-
}
|
| 250 |
-
|
| 251 |
-
.progress-percentage {
|
| 252 |
-
position: absolute;
|
| 253 |
-
top: 50%;
|
| 254 |
-
left: 50%;
|
| 255 |
-
transform: translate(-50%, -50%);
|
| 256 |
-
font-size: 1.5rem;
|
| 257 |
-
font-weight: bold;
|
| 258 |
-
color: #8b5cf6;
|
| 259 |
-
}
|
| 260 |
-
|
| 261 |
-
.loader-brain {
|
| 262 |
-
width: 40px;
|
| 263 |
-
height: 40px;
|
| 264 |
-
margin: 0 auto 1rem;
|
| 265 |
-
animation: pulse 2s infinite;
|
| 266 |
-
}
|
| 267 |
-
|
| 268 |
-
@keyframes pulse {
|
| 269 |
-
0%, 100% { transform: scale(1); opacity: 1; }
|
| 270 |
-
50% { transform: scale(1.1); opacity: 0.8; }
|
| 271 |
-
}
|
| 272 |
-
|
| 273 |
-
.loader-dots {
|
| 274 |
-
display: flex;
|
| 275 |
-
justify-content: center;
|
| 276 |
-
gap: 0.5rem;
|
| 277 |
-
margin-top: 1rem;
|
| 278 |
-
}
|
| 279 |
-
|
| 280 |
-
.loader-dot {
|
| 281 |
-
width: 8px;
|
| 282 |
-
height: 8px;
|
| 283 |
-
background: #8b5cf6;
|
| 284 |
-
border-radius: 50%;
|
| 285 |
-
animation: loadingDots 1.4s infinite ease-in-out both;
|
| 286 |
-
}
|
| 287 |
-
|
| 288 |
-
.loader-dot:nth-child(1) { animation-delay: -0.32s; }
|
| 289 |
-
.loader-dot:nth-child(2) { animation-delay: -0.16s; }
|
| 290 |
-
.loader-dot:nth-child(3) { animation-delay: 0s; }
|
| 291 |
-
|
| 292 |
-
@keyframes loadingDots {
|
| 293 |
-
0%, 80%, 100% { transform: scale(0.8); opacity: 0.5; }
|
| 294 |
-
40% { transform: scale(1); opacity: 1; }
|
| 295 |
-
}
|
| 296 |
-
|
| 297 |
-
.status-messages {
|
| 298 |
-
min-height: 1.5rem;
|
| 299 |
-
color: #6b7280;
|
| 300 |
-
font-size: 0.9rem;
|
| 301 |
-
margin-top: 1rem;
|
| 302 |
-
}
|
| 303 |
|
| 304 |
-
/* Optimisations mobiles */
|
| 305 |
@media (max-width: 640px) {
|
| 306 |
-
/* Réduire les marges sur mobile pour plus d'espace */
|
| 307 |
.max-w-3xl {
|
| 308 |
max-width: 100%;
|
| 309 |
margin-left: 0.5rem;
|
| 310 |
margin-right: 0.5rem;
|
| 311 |
}
|
| 312 |
|
| 313 |
-
/* Optimiser l'affichage des sections de contenu */
|
| 314 |
#response, #thinking-wrapper {
|
| 315 |
-
/* Éviter les débordements horizontaux */
|
| 316 |
overflow-x: hidden;
|
| 317 |
}
|
| 318 |
|
| 319 |
-
/* Améliorer la lisibilité du texte généré */
|
| 320 |
.prose {
|
| 321 |
font-size: 0.95rem;
|
| 322 |
line-height: 1.6;
|
| 323 |
}
|
| 324 |
|
| 325 |
-
/* Réduire l'animation pour économiser la batterie */
|
| 326 |
.animate-fadeIn {
|
| 327 |
animation-duration: 0.2s;
|
| 328 |
}
|
| 329 |
-
|
| 330 |
-
.loader-container {
|
| 331 |
-
padding: 1.5rem;
|
| 332 |
-
}
|
| 333 |
-
|
| 334 |
-
.progress-circle {
|
| 335 |
-
width: 100px;
|
| 336 |
-
height: 100px;
|
| 337 |
-
}
|
| 338 |
}
|
| 339 |
|
| 340 |
-
/* Conteneur de génération avec scroll optimisé */
|
| 341 |
.generation-container {
|
| 342 |
-
/* Conteneur stable pour éviter les recalculs de layout */
|
| 343 |
contain: layout style;
|
| 344 |
-
/* Optimiser les performances de scroll */
|
| 345 |
transform: translateZ(0);
|
| 346 |
}
|
| 347 |
|
| 348 |
-
/* Améliorer les performances du textarea */
|
| 349 |
textarea {
|
| 350 |
-
/* Éviter les reflows pendant la saisie */
|
| 351 |
resize: none;
|
| 352 |
-
/* Optimiser sur mobile */
|
| 353 |
-webkit-appearance: none;
|
| 354 |
}
|
| 355 |
|
| 356 |
-
/* Optimiser les boutons pour le tactile */
|
| 357 |
button {
|
| 358 |
touch-action: manipulation;
|
| 359 |
-webkit-tap-highlight-color: transparent;
|
| 360 |
transition: var(--transition-fast);
|
| 361 |
}
|
| 362 |
|
| 363 |
-
/* Scroll fluide pour les éléments avec beaucoup de contenu */
|
| 364 |
.content-scrollable {
|
| 365 |
-webkit-overflow-scrolling: touch;
|
| 366 |
scroll-behavior: smooth;
|
|
@@ -368,34 +325,6 @@
|
|
| 368 |
</style>
|
| 369 |
</head>
|
| 370 |
<body class="bg-gray-50 text-gray-900">
|
| 371 |
-
<!-- Loader Overlay -->
|
| 372 |
-
<div id="loader-overlay" class="loader-overlay">
|
| 373 |
-
<div class="loader-container">
|
| 374 |
-
<div class="loader-brain">
|
| 375 |
-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-full h-full text-violet-600">
|
| 376 |
-
<path stroke-linecap="round" stroke-linejoin="round" d="M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09zM18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456zM16.898 20.562L16.25 22.5l-.648-1.938a3.375 3.375 0 00-2.672-2.672L11.25 18l1.938-.648a3.375 3.375 0 002.672-2.672L16.25 13.5l.648 1.938a3.375 3.375 0 002.672 2.672L21.75 18l-1.938.648a3.375 3.375 0 00-2.672 2.672z" />
|
| 377 |
-
</svg>
|
| 378 |
-
</div>
|
| 379 |
-
|
| 380 |
-
<div class="progress-circle">
|
| 381 |
-
<svg class="progress-ring">
|
| 382 |
-
<circle class="progress-ring-circle"></circle>
|
| 383 |
-
<circle class="progress-ring-progress" id="progress-ring"></circle>
|
| 384 |
-
</svg>
|
| 385 |
-
<div class="progress-percentage" id="progress-percentage">0%</div>
|
| 386 |
-
</div>
|
| 387 |
-
|
| 388 |
-
<h3 class="text-xl font-semibold text-gray-800 mb-2">Génération en cours...</h3>
|
| 389 |
-
<div class="status-messages" id="status-message">Initialisation de l'IA philosophique...</div>
|
| 390 |
-
|
| 391 |
-
<div class="loader-dots">
|
| 392 |
-
<div class="loader-dot"></div>
|
| 393 |
-
<div class="loader-dot"></div>
|
| 394 |
-
<div class="loader-dot"></div>
|
| 395 |
-
</div>
|
| 396 |
-
</div>
|
| 397 |
-
</div>
|
| 398 |
-
|
| 399 |
<!-- Navbar -->
|
| 400 |
<nav class="bg-white/90 backdrop-blur-lg border-b border-gray-200 fixed w-full z-50">
|
| 401 |
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
@@ -437,7 +366,7 @@
|
|
| 437 |
</select>
|
| 438 |
</div>
|
| 439 |
|
| 440 |
-
<!-- Conteneur pour les champs texte
|
| 441 |
<div id="text-input-container">
|
| 442 |
<!-- Course Selection -->
|
| 443 |
<div class="space-y-2">
|
|
@@ -453,7 +382,7 @@
|
|
| 453 |
</div>
|
| 454 |
</div>
|
| 455 |
|
| 456 |
-
<!-- Conteneur pour l'upload d'image
|
| 457 |
<div id="image-input-container" class="hidden">
|
| 458 |
<div class="space-y-2">
|
| 459 |
<label for="image-upload" class="block text-sm font-medium text-gray-700">Charger un document pour analyse</label>
|
|
@@ -471,8 +400,43 @@
|
|
| 471 |
</div>
|
| 472 |
</div>
|
| 473 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 474 |
|
| 475 |
-
<!-- Thinking Process Section
|
| 476 |
<div id="thinking-wrapper" class="hidden mt-8 generation-container">
|
| 477 |
<details id="thinking-container" class="bg-white border border-gray-200 rounded-xl shadow-sm">
|
| 478 |
<summary class="flex justify-between items-center p-4 cursor-pointer">
|
|
@@ -482,7 +446,6 @@
|
|
| 482 |
</svg>
|
| 483 |
</summary>
|
| 484 |
<div id="thinking-process" class="p-4 border-t border-gray-200 text-sm text-gray-600 prose prose-sm max-w-none max-h-64 overflow-y-auto content-scrollable">
|
| 485 |
-
<!-- Le contenu du processus de pensée sera injecté ici -->
|
| 486 |
</div>
|
| 487 |
</details>
|
| 488 |
</div>
|
|
@@ -490,11 +453,10 @@
|
|
| 490 |
<!-- Response Section -->
|
| 491 |
<div id="response" class="hidden mt-6 generation-container">
|
| 492 |
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-6 sm:p-8 prose prose-violet max-w-none">
|
| 493 |
-
<!-- Le contenu de la réponse sera injecté ici -->
|
| 494 |
</div>
|
| 495 |
</div>
|
| 496 |
|
| 497 |
-
<!-- Action Buttons
|
| 498 |
<div id="action-buttons" class="hidden mt-6 grid grid-cols-1 sm:grid-cols-2 gap-4">
|
| 499 |
<button id="copy-btn" class="w-full flex items-center justify-center py-3 px-6 rounded-xl bg-gray-100 text-gray-800 font-medium border border-gray-200 hover:bg-gray-200 transition-colors focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2">
|
| 500 |
<svg class="h-5 w-5 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75" /></svg>
|
|
@@ -506,7 +468,6 @@
|
|
| 506 |
<div class="mt-12">
|
| 507 |
<h3 class="text-xl font-bold text-gray-800 mb-4">Historique</h3>
|
| 508 |
<div id="dissertations-list" class="space-y-3">
|
| 509 |
-
<!-- La liste des dissertations sauvegardées sera injectée ici -->
|
| 510 |
</div>
|
| 511 |
</div>
|
| 512 |
</div>
|
|
@@ -524,182 +485,263 @@ $(document).ready(function() {
|
|
| 524 |
$('#course-select').select2({
|
| 525 |
placeholder: 'Optionnel : choisir un cours...',
|
| 526 |
allowClear: true,
|
| 527 |
-
templateResult: function (course) {
|
|
|
|
|
|
|
|
|
|
| 528 |
templateSelection: function (course) { return course.text; },
|
| 529 |
});
|
| 530 |
marked.setOptions({ breaks: true, gfm: true, headerIds: false, mangle: false });
|
| 531 |
moment.locale('fr');
|
| 532 |
const Toast = Swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000, timerProgressBar: true });
|
| 533 |
|
| 534 |
-
//
|
| 535 |
-
const statusMessages = [
|
| 536 |
-
"Initialisation de l'IA philosophique...",
|
| 537 |
-
"Analyse du sujet en cours...",
|
| 538 |
-
"Recherche de concepts philosophiques...",
|
| 539 |
-
"Construction de l'argumentation...",
|
| 540 |
-
"Structuration de la dissertation...",
|
| 541 |
-
"Rédaction de l'introduction...",
|
| 542 |
-
"Développement des parties principales...",
|
| 543 |
-
"Formulation de la conclusion...",
|
| 544 |
-
"Révision et finalisation..."
|
| 545 |
-
];
|
| 546 |
-
|
| 547 |
let currentProgress = 0;
|
| 548 |
let progressInterval;
|
| 549 |
-
let
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 550 |
|
| 551 |
-
|
| 552 |
-
|
| 553 |
currentProgress = 0;
|
| 554 |
-
|
| 555 |
|
| 556 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 557 |
progressInterval = setInterval(() => {
|
| 558 |
if (currentProgress < 95) {
|
| 559 |
-
|
| 560 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 561 |
}
|
| 562 |
-
},
|
| 563 |
|
| 564 |
-
//
|
| 565 |
-
|
| 566 |
-
|
| 567 |
-
|
| 568 |
-
|
| 569 |
-
|
| 570 |
-
$(this).text(statusMessages[messageIndex]).fadeIn(200);
|
| 571 |
-
});
|
| 572 |
-
}, 2000);
|
| 573 |
}
|
| 574 |
|
| 575 |
-
function
|
| 576 |
-
|
| 577 |
-
|
|
|
|
|
|
|
|
|
|
| 578 |
clearInterval(progressInterval);
|
| 579 |
-
|
| 580 |
-
|
| 581 |
-
$('#status-message').fadeOut(200, function() {
|
| 582 |
-
$(this).text('Génération terminée !').fadeIn(200);
|
| 583 |
-
});
|
| 584 |
|
| 585 |
setTimeout(() => {
|
| 586 |
-
$('#
|
| 587 |
-
|
|
|
|
|
|
|
| 588 |
}
|
| 589 |
|
| 590 |
-
|
| 591 |
-
|
| 592 |
-
|
| 593 |
-
|
| 594 |
-
|
| 595 |
-
circle.style.strokeDashoffset = offset;
|
| 596 |
-
$('#progress-percentage').text(Math.round(currentProgress) + '%');
|
| 597 |
}
|
| 598 |
|
| 599 |
-
//
|
| 600 |
-
function
|
| 601 |
-
|
| 602 |
-
|
| 603 |
-
|
| 604 |
-
|
| 605 |
-
|
| 606 |
-
|
| 607 |
-
|
| 608 |
-
|
| 609 |
-
|
| 610 |
-
|
| 611 |
-
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
|
| 615 |
-
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 619 |
}
|
| 620 |
|
| 621 |
-
// Fonction
|
| 622 |
-
function
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
|
| 632 |
-
|
| 633 |
-
|
| 634 |
-
|
| 635 |
-
|
| 636 |
-
|
| 637 |
-
|
| 638 |
-
setTimeout(addWord, 1000 / wordsPerSecond);
|
| 639 |
} else {
|
| 640 |
-
|
| 641 |
}
|
| 642 |
-
|
| 643 |
-
|
| 644 |
-
addWord();
|
| 645 |
});
|
| 646 |
}
|
| 647 |
|
| 648 |
-
//
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
// Fonction de scroll optimisée avec throttling
|
| 654 |
-
function smoothScrollToBottom(force = false) {
|
| 655 |
-
const now = Date.now();
|
| 656 |
|
| 657 |
-
//
|
| 658 |
-
|
| 659 |
-
return;
|
| 660 |
-
}
|
| 661 |
|
| 662 |
-
|
|
|
|
| 663 |
|
| 664 |
-
//
|
| 665 |
-
|
| 666 |
-
|
| 667 |
-
|
| 668 |
-
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 676 |
|
| 677 |
-
|
| 678 |
-
|
| 679 |
-
|
| 680 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 681 |
});
|
| 682 |
|
| 683 |
-
|
| 684 |
-
|
| 685 |
-
|
| 686 |
-
|
| 687 |
-
|
|
|
|
|
|
|
| 688 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 689 |
}
|
| 690 |
|
| 691 |
// --- Gestion de l'interface ---
|
| 692 |
$('#type-select').change(function() {
|
| 693 |
const type = $(this).val();
|
| 694 |
// Cacher les sections de résultat lors du changement de type
|
| 695 |
-
$('#thinking-wrapper, #response, #action-buttons').addClass('hidden');
|
| 696 |
|
| 697 |
if (type === '3') { // Sujet Type 3
|
| 698 |
$('#text-input-container').hide();
|
| 699 |
$('#image-input-container').show().addClass('animate-fadeIn');
|
| 700 |
$('#deepthink-btn').hide();
|
| 701 |
$('#submit-btn').html('<svg class="h-5 w-5 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" /></svg>Analyser le sujet');
|
| 702 |
-
$('label[for="image-upload"]').text("Charger un document pour analyse (image, etc.)");
|
| 703 |
} else { // Dissertation texte
|
| 704 |
$('#text-input-container').show().addClass('animate-fadeIn');
|
| 705 |
$('#image-input-container').hide();
|
|
@@ -716,129 +758,7 @@ $(document).ready(function() {
|
|
| 716 |
}
|
| 717 |
});
|
| 718 |
|
| 719 |
-
// ---
|
| 720 |
-
async function simulateGeneration(data, isDeepThink = false) {
|
| 721 |
-
showLoader();
|
| 722 |
-
|
| 723 |
-
// Cacher les sections de résultat
|
| 724 |
-
$('#thinking-wrapper, #response, #action-buttons').addClass('hidden');
|
| 725 |
-
$('#thinking-container').prop('open', false);
|
| 726 |
-
const thinkingDiv = $('#thinking-process');
|
| 727 |
-
const responseDiv = $('#response > div');
|
| 728 |
-
thinkingDiv.html('');
|
| 729 |
-
responseDiv.html('');
|
| 730 |
-
|
| 731 |
-
try {
|
| 732 |
-
// Simulation du temps de traitement (3-6 secondes)
|
| 733 |
-
const processingTime = Math.random() * 3000 + 3000;
|
| 734 |
-
|
| 735 |
-
await new Promise(resolve => setTimeout(resolve, processingTime));
|
| 736 |
-
|
| 737 |
-
// Texte simulé pour la démonstration
|
| 738 |
-
const sampleThinking = `
|
| 739 |
-
## Analyse du sujet
|
| 740 |
-
|
| 741 |
-
Je vais commencer par analyser les termes clés de ce sujet philosophique.
|
| 742 |
-
|
| 743 |
-
**Concepts centraux :**
|
| 744 |
-
- La notion de liberté
|
| 745 |
-
- L'idée de contrainte
|
| 746 |
-
- La dimension morale et politique
|
| 747 |
-
|
| 748 |
-
**Problématique :** Ce sujet interroge la nature même de la liberté humaine et ses limites.
|
| 749 |
-
|
| 750 |
-
**Plan envisagé :**
|
| 751 |
-
1. La liberté comme absence de contrainte
|
| 752 |
-
2. Les limites nécessaires à la liberté
|
| 753 |
-
3. La liberté authentique et la responsabilité
|
| 754 |
-
`;
|
| 755 |
-
|
| 756 |
-
const sampleResponse = `
|
| 757 |
-
# La liberté consiste-t-elle à faire tout ce que l'on veut ?
|
| 758 |
-
|
| 759 |
-
## Introduction
|
| 760 |
-
|
| 761 |
-
La liberté apparaît spontanément comme la capacité de faire ce que l'on désire, sans entrave ni contrainte. Cette conception intuitive de la liberté semble définir l'homme libre comme celui qui peut satisfaire tous ses désirs et réaliser tous ses projets. Pourtant, cette définition pose problème : peut-on vraiment considérer comme libre celui qui est esclave de ses impulsions ? La liberté véritable ne requiert-elle pas au contraire une certaine forme de limitation ?
|
| 762 |
-
|
| 763 |
-
**Problématique :** La liberté se résume-t-elle à l'absence de contraintes extérieures, ou implique-t-elle une maîtrise de soi qui suppose des limites ?
|
| 764 |
-
|
| 765 |
-
## I. La liberté comme absence de contrainte
|
| 766 |
-
|
| 767 |
-
### A. La conception spontanée de la liberté
|
| 768 |
-
|
| 769 |
-
La liberté se présente d'abord négativement comme l'absence d'obstacles à nos actions. Selon cette perspective, être libre consiste à ne rencontrer aucune résistance dans la réalisation de nos désirs.
|
| 770 |
-
|
| 771 |
-
### B. La liberté politique et juridique
|
| 772 |
-
|
| 773 |
-
Dans le domaine politique, la liberté se définit effectivement par l'absence de contraintes arbitraires. Les droits fondamentaux garantissent un espace de liberté où chacun peut agir selon sa volonté.
|
| 774 |
-
|
| 775 |
-
### C. Les limites de cette conception
|
| 776 |
-
|
| 777 |
-
Cependant, cette vision purement négative de la liberté conduit à des paradoxes. Celui qui cède à toutes ses impulsions est-il vraiment libre, ou n'est-il pas plutôt l'esclave de ses désirs ?
|
| 778 |
-
|
| 779 |
-
## II. La nécessité des limites pour la liberté authentique
|
| 780 |
-
|
| 781 |
-
### A. La liberté et la raison
|
| 782 |
-
|
| 783 |
-
Pour les philosophes comme Kant, la vraie liberté ne consiste pas à suivre ses inclinations, mais à agir selon la raison et le devoir moral. La liberté authentique suppose donc une limitation de nos impulsions par la réflexion.
|
| 784 |
-
|
| 785 |
-
### B. La liberté sociale
|
| 786 |
-
|
| 787 |
-
Rousseau montre que la liberté en société ne peut exister sans lois. Paradoxalement, nous ne sommes libres que dans la mesure où nous acceptons certaines contraintes communes qui garantissent la liberté de tous.
|
| 788 |
-
|
| 789 |
-
### C. La liberté comme conquête de soi
|
| 790 |
-
|
| 791 |
-
La liberté véritable implique une victoire sur nos déterminations naturelles et sociales. Elle se conquiert par l'éducation, la réflexion et l'effort moral.
|
| 792 |
-
|
| 793 |
-
## Conclusion
|
| 794 |
-
|
| 795 |
-
La liberté ne saurait se réduire à la simple capacité de faire tout ce que l'on veut. Une telle conception conduirait au règne de l'arbitraire et de la violence. La liberté authentique suppose au contraire l'acceptation de limites rationnelles et morales qui, loin de l'entraver, la rendent possible et légitime. Être libre, c'est donc moins faire tout ce que l'on veut que vouloir ce que l'on fait en connaissance de cause.
|
| 796 |
-
|
| 797 |
-
La liberté se révèle ainsi comme un idéal exigeant qui suppose éducation, réflexion et responsabilité morale.
|
| 798 |
-
`;
|
| 799 |
-
|
| 800 |
-
hideLoader();
|
| 801 |
-
|
| 802 |
-
// Affichage avec effet de streaming fondu
|
| 803 |
-
setTimeout(async () => {
|
| 804 |
-
// Afficher la section de pensée
|
| 805 |
-
$('#thinking-wrapper').removeClass('hidden').addClass('animate-fadeIn');
|
| 806 |
-
await smoothStreamText(thinkingDiv, sampleThinking, 12);
|
| 807 |
-
|
| 808 |
-
// Petit délai puis afficher la réponse
|
| 809 |
-
setTimeout(async () => {
|
| 810 |
-
$('#response').removeClass('hidden').addClass('animate-fadeIn');
|
| 811 |
-
|
| 812 |
-
// Convertir en HTML et afficher avec streaming
|
| 813 |
-
const htmlContent = marked.parse(sampleResponse);
|
| 814 |
-
await smoothStreamText(responseDiv, htmlContent, 8);
|
| 815 |
-
|
| 816 |
-
// Afficher les boutons d'action
|
| 817 |
-
$('#action-buttons').removeClass('hidden').addClass('animate-fadeIn');
|
| 818 |
-
Toast.fire({ icon: 'success', title: 'Génération terminée !' });
|
| 819 |
-
|
| 820 |
-
// Sauvegarder
|
| 821 |
-
let title;
|
| 822 |
-
if ($('#type-select').val() === '3') {
|
| 823 |
-
const fileName = $('#image-upload')[0].files[0]?.name || "Analyse de document";
|
| 824 |
-
title = `Analyse (Sujet Type 3): ${fileName}`;
|
| 825 |
-
} else {
|
| 826 |
-
title = $('#question').val().trim();
|
| 827 |
-
}
|
| 828 |
-
saveDissertation(title, sampleResponse);
|
| 829 |
-
|
| 830 |
-
smoothScrollToBottom(true);
|
| 831 |
-
}, 1000);
|
| 832 |
-
|
| 833 |
-
}, 500);
|
| 834 |
-
|
| 835 |
-
} catch (error) {
|
| 836 |
-
hideLoader();
|
| 837 |
-
Swal.fire({ icon: 'error', title: 'Erreur', text: error.message || "Une erreur inconnue est survenue." });
|
| 838 |
-
}
|
| 839 |
-
}
|
| 840 |
-
|
| 841 |
-
// --- Gestion des Clics ---
|
| 842 |
$('#submit-btn, #deepthink-btn').click(function() {
|
| 843 |
const type = $('#type-select').val();
|
| 844 |
const isDeepThink = $(this).attr('id') === 'deepthink-btn';
|
|
@@ -849,43 +769,127 @@ La liberté se révèle ainsi comme un idéal exigeant qui suppose éducation, r
|
|
| 849 |
Swal.fire('Erreur', 'Veuillez sélectionner un document.', 'error');
|
| 850 |
return;
|
| 851 |
}
|
| 852 |
-
const data = { type: 'image', file: imageFile };
|
| 853 |
-
simulateGeneration(data);
|
| 854 |
} else {
|
| 855 |
const question = $('#question').val().trim();
|
| 856 |
if (!question) {
|
| 857 |
Swal.fire('Erreur', 'Veuillez saisir un sujet.', 'error');
|
| 858 |
return;
|
| 859 |
}
|
| 860 |
-
const data = {
|
| 861 |
-
question,
|
| 862 |
-
type,
|
| 863 |
-
courseId: $('#course-select').val() || null,
|
| 864 |
-
isDeepThink
|
| 865 |
-
};
|
| 866 |
-
simulateGeneration(data, isDeepThink);
|
| 867 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 868 |
});
|
| 869 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 870 |
// --- Fonctions de gestion de l'historique ---
|
| 871 |
function loadCourses() {
|
| 872 |
-
//
|
| 873 |
-
const
|
| 874 |
-
{ id: '1', title: '
|
| 875 |
-
{ id: '2', title: '
|
| 876 |
-
{ id: '3', title: 'Métaphysique', author: '
|
| 877 |
-
{ id: '4', title: 'Éthique', author: 'Spinoza' }
|
| 878 |
];
|
| 879 |
|
| 880 |
const select = $('#course-select');
|
| 881 |
-
|
| 882 |
const newOption = new Option(course.title, course.id, false, false);
|
| 883 |
$(newOption).data('author', course.author);
|
| 884 |
select.append(newOption);
|
| 885 |
});
|
| 886 |
select.trigger('change');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 887 |
}
|
| 888 |
-
loadCourses();
|
| 889 |
|
| 890 |
function saveDissertation(title, content) {
|
| 891 |
if (!title || !content) return;
|
|
@@ -936,12 +940,11 @@ La liberté se révèle ainsi comme un idéal exigeant qui suppose éducation, r
|
|
| 936 |
});
|
| 937 |
}
|
| 938 |
|
| 939 |
-
//
|
| 940 |
$('#dissertations-list').on('click', '.collapsible', function() {
|
| 941 |
const content = $(this).next('.content');
|
| 942 |
const isVisible = content.is(':visible');
|
| 943 |
|
| 944 |
-
// Animation plus fluide avec easing
|
| 945 |
content.stop(true, true).slideToggle({
|
| 946 |
duration: 300,
|
| 947 |
easing: 'swing',
|
|
@@ -972,7 +975,7 @@ La liberté se révèle ainsi comme un idéal exigeant qui suppose éducation, r
|
|
| 972 |
});
|
| 973 |
});
|
| 974 |
|
| 975 |
-
//
|
| 976 |
let ticking = false;
|
| 977 |
|
| 978 |
function updateScrollPosition() {
|
|
@@ -986,7 +989,6 @@ La liberté se révèle ainsi comme un idéal exigeant qui suppose éducation, r
|
|
| 986 |
}
|
| 987 |
}, { passive: true });
|
| 988 |
|
| 989 |
-
// Optimisation du resize pour mobile
|
| 990 |
let resizeTimer;
|
| 991 |
window.addEventListener('resize', function() {
|
| 992 |
clearTimeout(resizeTimer);
|
|
@@ -999,7 +1001,6 @@ La liberté se révèle ainsi comme un idéal exigeant qui suppose éducation, r
|
|
| 999 |
}, 250);
|
| 1000 |
}, { passive: true });
|
| 1001 |
|
| 1002 |
-
// Optimisation tactile pour mobile
|
| 1003 |
if ('ontouchstart' in window) {
|
| 1004 |
$('body').addClass('touch-device');
|
| 1005 |
|
|
@@ -1013,7 +1014,8 @@ La liberté se révèle ainsi comme un idéal exigeant qui suppose éducation, r
|
|
| 1013 |
});
|
| 1014 |
}
|
| 1015 |
|
| 1016 |
-
//
|
|
|
|
| 1017 |
updateSavedDissertationsList();
|
| 1018 |
});
|
| 1019 |
</script>
|
|
|
|
| 18 |
/* Styles pour le Glow Up */
|
| 19 |
:root {
|
| 20 |
font-family: 'Inter', sans-serif;
|
|
|
|
| 21 |
--transition-smooth: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
| 22 |
--transition-fast: all 0.15s ease-out;
|
| 23 |
+
--violet-gradient: linear-gradient(135deg, #8b5cf6 0%, #a855f7 50%, #c084fc 100%);
|
| 24 |
}
|
| 25 |
|
|
|
|
| 26 |
html {
|
| 27 |
scroll-behavior: smooth;
|
| 28 |
-webkit-overflow-scrolling: touch;
|
| 29 |
}
|
| 30 |
|
| 31 |
body {
|
|
|
|
| 32 |
will-change: scroll-position;
|
|
|
|
| 33 |
-webkit-font-smoothing: antialiased;
|
| 34 |
-moz-osx-font-smoothing: grayscale;
|
| 35 |
}
|
| 36 |
+
|
| 37 |
+
/* Loader magnifique avec animations */
|
| 38 |
+
.progress-container {
|
| 39 |
+
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
|
| 40 |
+
border: 2px solid #e2e8f0;
|
| 41 |
+
position: relative;
|
| 42 |
+
overflow: hidden;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
.progress-container::before {
|
| 46 |
+
content: '';
|
| 47 |
+
position: absolute;
|
| 48 |
+
top: 0;
|
| 49 |
+
left: -100%;
|
| 50 |
+
width: 100%;
|
| 51 |
+
height: 100%;
|
| 52 |
+
background: linear-gradient(90deg, transparent, rgba(139, 92, 246, 0.1), transparent);
|
| 53 |
+
animation: shimmer 2s infinite;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
@keyframes shimmer {
|
| 57 |
+
0% { left: -100%; }
|
| 58 |
+
100% { left: 100%; }
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
.progress-bar {
|
| 62 |
+
background: var(--violet-gradient);
|
| 63 |
+
height: 100%;
|
| 64 |
+
transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1);
|
| 65 |
+
position: relative;
|
| 66 |
+
overflow: hidden;
|
| 67 |
+
box-shadow: 0 0 20px rgba(139, 92, 246, 0.3);
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
.progress-bar::after {
|
| 71 |
+
content: '';
|
| 72 |
+
position: absolute;
|
| 73 |
+
top: 0;
|
| 74 |
+
left: 0;
|
| 75 |
+
right: 0;
|
| 76 |
+
bottom: 0;
|
| 77 |
+
background: linear-gradient(45deg, transparent 30%, rgba(255,255,255,0.3) 50%, transparent 70%);
|
| 78 |
+
animation: progressGlow 2s ease-in-out infinite;
|
| 79 |
+
}
|
| 80 |
+
|
| 81 |
+
@keyframes progressGlow {
|
| 82 |
+
0%, 100% { transform: translateX(-100%) skewX(-15deg); }
|
| 83 |
+
50% { transform: translateX(200%) skewX(-15deg); }
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
.loading-dots {
|
| 87 |
+
display: inline-flex;
|
| 88 |
+
align-items: center;
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
.loading-dots span {
|
| 92 |
+
width: 8px;
|
| 93 |
+
height: 8px;
|
| 94 |
+
border-radius: 50%;
|
| 95 |
+
background: #8b5cf6;
|
| 96 |
+
margin: 0 2px;
|
| 97 |
+
animation: loadingDots 1.4s infinite ease-in-out both;
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
.loading-dots span:nth-child(1) { animation-delay: -0.32s; }
|
| 101 |
+
.loading-dots span:nth-child(2) { animation-delay: -0.16s; }
|
| 102 |
+
|
| 103 |
+
@keyframes loadingDots {
|
| 104 |
+
0%, 80%, 100% {
|
| 105 |
+
transform: scale(0.8);
|
| 106 |
+
opacity: 0.5;
|
| 107 |
+
}
|
| 108 |
+
40% {
|
| 109 |
+
transform: scale(1.2);
|
| 110 |
+
opacity: 1;
|
| 111 |
+
}
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
/* Animation de fondu pour le streaming */
|
| 115 |
+
.streaming-text {
|
| 116 |
+
opacity: 0;
|
| 117 |
+
animation: fadeInUp 0.6s ease-out forwards;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
@keyframes fadeInUp {
|
| 121 |
+
from {
|
| 122 |
+
opacity: 0;
|
| 123 |
+
transform: translateY(20px);
|
| 124 |
+
}
|
| 125 |
+
to {
|
| 126 |
+
opacity: 1;
|
| 127 |
+
transform: translateY(0);
|
| 128 |
+
}
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
.word-by-word {
|
| 132 |
+
display: inline;
|
| 133 |
+
opacity: 0;
|
| 134 |
+
animation: wordFadeIn 0.3s ease-out forwards;
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
@keyframes wordFadeIn {
|
| 138 |
+
from {
|
| 139 |
+
opacity: 0;
|
| 140 |
+
transform: translateY(10px) scale(0.95);
|
| 141 |
+
}
|
| 142 |
+
to {
|
| 143 |
+
opacity: 1;
|
| 144 |
+
transform: translateY(0) scale(1);
|
| 145 |
+
}
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
/* Pulse effect pour le contenu en cours de génération */
|
| 149 |
+
.generating-pulse {
|
| 150 |
+
animation: pulseGlow 2s ease-in-out infinite;
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
@keyframes pulseGlow {
|
| 154 |
+
0%, 100% {
|
| 155 |
+
box-shadow: 0 0 20px rgba(139, 92, 246, 0.1);
|
| 156 |
+
transform: scale(1);
|
| 157 |
+
}
|
| 158 |
+
50% {
|
| 159 |
+
box-shadow: 0 0 30px rgba(139, 92, 246, 0.2);
|
| 160 |
+
transform: scale(1.01);
|
| 161 |
+
}
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
/* Styles pour le texte en cours de streaming */
|
| 165 |
+
.streaming-cursor::after {
|
| 166 |
+
content: '|';
|
| 167 |
+
animation: cursorBlink 1s infinite;
|
| 168 |
+
color: #8b5cf6;
|
| 169 |
+
margin-left: 2px;
|
| 170 |
+
}
|
| 171 |
+
|
| 172 |
+
@keyframes cursorBlink {
|
| 173 |
+
0%, 50% { opacity: 1; }
|
| 174 |
+
51%, 100% { opacity: 0; }
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
.collapsible {
|
| 178 |
cursor: pointer;
|
| 179 |
padding: 1rem;
|
|
|
|
| 182 |
text-align: left;
|
| 183 |
outline: none;
|
| 184 |
transition: var(--transition-fast);
|
|
|
|
| 185 |
touch-action: manipulation;
|
| 186 |
-webkit-tap-highlight-color: transparent;
|
| 187 |
}
|
|
|
|
| 195 |
display: none;
|
| 196 |
overflow: hidden;
|
| 197 |
background-color: white;
|
|
|
|
| 198 |
transition: var(--transition-smooth);
|
| 199 |
}
|
| 200 |
|
|
|
|
| 201 |
.prose {
|
| 202 |
max-width: 100% !important;
|
|
|
|
| 203 |
text-rendering: optimizeLegibility;
|
| 204 |
}
|
| 205 |
|
|
|
|
| 207 |
color: #374151;
|
| 208 |
word-wrap: break-word;
|
| 209 |
overflow-wrap: break-word;
|
|
|
|
| 210 |
hyphens: auto;
|
| 211 |
-webkit-hyphens: auto;
|
| 212 |
-moz-hyphens: auto;
|
|
|
|
| 222 |
line-height: 1.3;
|
| 223 |
}
|
| 224 |
|
|
|
|
| 225 |
.animate-fadeIn {
|
| 226 |
animation: fadeIn 0.4s ease-out forwards;
|
|
|
|
| 227 |
transform: translateZ(0);
|
| 228 |
will-change: opacity, transform;
|
| 229 |
}
|
|
|
|
| 238 |
transform: translateY(0) translateZ(0);
|
| 239 |
}
|
| 240 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
|
|
|
|
| 242 |
.select2-container--default .select2-selection--single {
|
| 243 |
border: 1px solid #d1d5db;
|
| 244 |
border-radius: 0.75rem;
|
|
|
|
| 267 |
box-shadow: 0 4px 6px -1px rgba(0,0,0,.1);
|
| 268 |
}
|
| 269 |
|
|
|
|
| 270 |
#image-preview {
|
| 271 |
max-height: 200px;
|
| 272 |
border-radius: 0.75rem;
|
| 273 |
box-shadow: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1);
|
| 274 |
}
|
| 275 |
|
|
|
|
| 276 |
summary {
|
| 277 |
list-style: none;
|
| 278 |
}
|
|
|
|
| 280 |
summary::-webkit-details-marker {
|
| 281 |
display: none;
|
| 282 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 283 |
|
|
|
|
| 284 |
@media (max-width: 640px) {
|
|
|
|
| 285 |
.max-w-3xl {
|
| 286 |
max-width: 100%;
|
| 287 |
margin-left: 0.5rem;
|
| 288 |
margin-right: 0.5rem;
|
| 289 |
}
|
| 290 |
|
|
|
|
| 291 |
#response, #thinking-wrapper {
|
|
|
|
| 292 |
overflow-x: hidden;
|
| 293 |
}
|
| 294 |
|
|
|
|
| 295 |
.prose {
|
| 296 |
font-size: 0.95rem;
|
| 297 |
line-height: 1.6;
|
| 298 |
}
|
| 299 |
|
|
|
|
| 300 |
.animate-fadeIn {
|
| 301 |
animation-duration: 0.2s;
|
| 302 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 303 |
}
|
| 304 |
|
|
|
|
| 305 |
.generation-container {
|
|
|
|
| 306 |
contain: layout style;
|
|
|
|
| 307 |
transform: translateZ(0);
|
| 308 |
}
|
| 309 |
|
|
|
|
| 310 |
textarea {
|
|
|
|
| 311 |
resize: none;
|
|
|
|
| 312 |
-webkit-appearance: none;
|
| 313 |
}
|
| 314 |
|
|
|
|
| 315 |
button {
|
| 316 |
touch-action: manipulation;
|
| 317 |
-webkit-tap-highlight-color: transparent;
|
| 318 |
transition: var(--transition-fast);
|
| 319 |
}
|
| 320 |
|
|
|
|
| 321 |
.content-scrollable {
|
| 322 |
-webkit-overflow-scrolling: touch;
|
| 323 |
scroll-behavior: smooth;
|
|
|
|
| 325 |
</style>
|
| 326 |
</head>
|
| 327 |
<body class="bg-gray-50 text-gray-900">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
<!-- Navbar -->
|
| 329 |
<nav class="bg-white/90 backdrop-blur-lg border-b border-gray-200 fixed w-full z-50">
|
| 330 |
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
|
|
| 366 |
</select>
|
| 367 |
</div>
|
| 368 |
|
| 369 |
+
<!-- Conteneur pour les champs texte -->
|
| 370 |
<div id="text-input-container">
|
| 371 |
<!-- Course Selection -->
|
| 372 |
<div class="space-y-2">
|
|
|
|
| 382 |
</div>
|
| 383 |
</div>
|
| 384 |
|
| 385 |
+
<!-- Conteneur pour l'upload d'image -->
|
| 386 |
<div id="image-input-container" class="hidden">
|
| 387 |
<div class="space-y-2">
|
| 388 |
<label for="image-upload" class="block text-sm font-medium text-gray-700">Charger un document pour analyse</label>
|
|
|
|
| 400 |
</div>
|
| 401 |
</div>
|
| 402 |
</div>
|
| 403 |
+
|
| 404 |
+
<!-- Loading Section -->
|
| 405 |
+
<div id="loading-section" class="hidden mt-8 generation-container">
|
| 406 |
+
<div class="bg-white border border-gray-200 rounded-xl shadow-lg p-8 generating-pulse">
|
| 407 |
+
<div class="text-center space-y-6">
|
| 408 |
+
<div class="mx-auto w-16 h-16 relative">
|
| 409 |
+
<svg class="w-16 h-16 text-violet-600 animate-spin" fill="none" viewBox="0 0 24 24">
|
| 410 |
+
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
| 411 |
+
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
| 412 |
+
</svg>
|
| 413 |
+
</div>
|
| 414 |
+
|
| 415 |
+
<div class="space-y-3">
|
| 416 |
+
<h3 class="text-xl font-semibold text-gray-800">Génération en cours</h3>
|
| 417 |
+
<p id="loading-message" class="text-gray-600">Initialisation de l'IA philosophique</p>
|
| 418 |
+
<div class="loading-dots">
|
| 419 |
+
<span></span>
|
| 420 |
+
<span></span>
|
| 421 |
+
<span></span>
|
| 422 |
+
</div>
|
| 423 |
+
</div>
|
| 424 |
+
|
| 425 |
+
<!-- Barre de progression -->
|
| 426 |
+
<div class="space-y-2">
|
| 427 |
+
<div class="flex justify-between text-sm text-gray-600">
|
| 428 |
+
<span>Progression</span>
|
| 429 |
+
<span id="progress-percentage">0%</span>
|
| 430 |
+
</div>
|
| 431 |
+
<div class="progress-container w-full h-3 rounded-full">
|
| 432 |
+
<div id="progress-bar" class="progress-bar w-0 rounded-full"></div>
|
| 433 |
+
</div>
|
| 434 |
+
</div>
|
| 435 |
+
</div>
|
| 436 |
+
</div>
|
| 437 |
+
</div>
|
| 438 |
|
| 439 |
+
<!-- Thinking Process Section -->
|
| 440 |
<div id="thinking-wrapper" class="hidden mt-8 generation-container">
|
| 441 |
<details id="thinking-container" class="bg-white border border-gray-200 rounded-xl shadow-sm">
|
| 442 |
<summary class="flex justify-between items-center p-4 cursor-pointer">
|
|
|
|
| 446 |
</svg>
|
| 447 |
</summary>
|
| 448 |
<div id="thinking-process" class="p-4 border-t border-gray-200 text-sm text-gray-600 prose prose-sm max-w-none max-h-64 overflow-y-auto content-scrollable">
|
|
|
|
| 449 |
</div>
|
| 450 |
</details>
|
| 451 |
</div>
|
|
|
|
| 453 |
<!-- Response Section -->
|
| 454 |
<div id="response" class="hidden mt-6 generation-container">
|
| 455 |
<div class="bg-white border border-gray-200 rounded-xl shadow-sm p-6 sm:p-8 prose prose-violet max-w-none">
|
|
|
|
| 456 |
</div>
|
| 457 |
</div>
|
| 458 |
|
| 459 |
+
<!-- Action Buttons -->
|
| 460 |
<div id="action-buttons" class="hidden mt-6 grid grid-cols-1 sm:grid-cols-2 gap-4">
|
| 461 |
<button id="copy-btn" class="w-full flex items-center justify-center py-3 px-6 rounded-xl bg-gray-100 text-gray-800 font-medium border border-gray-200 hover:bg-gray-200 transition-colors focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2">
|
| 462 |
<svg class="h-5 w-5 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75" /></svg>
|
|
|
|
| 468 |
<div class="mt-12">
|
| 469 |
<h3 class="text-xl font-bold text-gray-800 mb-4">Historique</h3>
|
| 470 |
<div id="dissertations-list" class="space-y-3">
|
|
|
|
| 471 |
</div>
|
| 472 |
</div>
|
| 473 |
</div>
|
|
|
|
| 485 |
$('#course-select').select2({
|
| 486 |
placeholder: 'Optionnel : choisir un cours...',
|
| 487 |
allowClear: true,
|
| 488 |
+
templateResult: function (course) {
|
| 489 |
+
if (!course.id) { return course.text; }
|
| 490 |
+
return $(`<span>${course.text}</span><span class="course-author">Pr. ${$(course.element).data('author')}</span>`);
|
| 491 |
+
},
|
| 492 |
templateSelection: function (course) { return course.text; },
|
| 493 |
});
|
| 494 |
marked.setOptions({ breaks: true, gfm: true, headerIds: false, mangle: false });
|
| 495 |
moment.locale('fr');
|
| 496 |
const Toast = Swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000, timerProgressBar: true });
|
| 497 |
|
| 498 |
+
// Variables pour le loader et streaming
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 499 |
let currentProgress = 0;
|
| 500 |
let progressInterval;
|
| 501 |
+
let streamingTimeout;
|
| 502 |
+
|
| 503 |
+
// Messages de chargement rotatifs
|
| 504 |
+
const loadingMessages = [
|
| 505 |
+
"Initialisation de l'IA philosophique",
|
| 506 |
+
"Analyse du sujet proposé",
|
| 507 |
+
"Recherche des concepts clés",
|
| 508 |
+
"Construction de l'argumentation",
|
| 509 |
+
"Structuration de la dissertation",
|
| 510 |
+
"Vérification de la cohérence",
|
| 511 |
+
"Finalisation de la réponse"
|
| 512 |
+
];
|
| 513 |
|
| 514 |
+
// Fonction pour simuler le progress loader
|
| 515 |
+
function startProgressLoader() {
|
| 516 |
currentProgress = 0;
|
| 517 |
+
let messageIndex = 0;
|
| 518 |
|
| 519 |
+
$('#loading-section').removeClass('hidden').addClass('animate-fadeIn');
|
| 520 |
+
$('#progress-bar').css('width', '0%');
|
| 521 |
+
$('#progress-percentage').text('0%');
|
| 522 |
+
|
| 523 |
+
// Animation du message
|
| 524 |
+
const messageInterval = setInterval(() => {
|
| 525 |
+
$('#loading-message').fadeOut(300, function() {
|
| 526 |
+
$(this).text(loadingMessages[messageIndex]).fadeIn(300);
|
| 527 |
+
messageIndex = (messageIndex + 1) % loadingMessages.length;
|
| 528 |
+
});
|
| 529 |
+
}, 2000);
|
| 530 |
+
|
| 531 |
+
// Animation de la barre de progression
|
| 532 |
progressInterval = setInterval(() => {
|
| 533 |
if (currentProgress < 95) {
|
| 534 |
+
// Progression plus rapide au début, plus lente vers la fin
|
| 535 |
+
const increment = currentProgress < 30 ? Math.random() * 8 + 3 :
|
| 536 |
+
currentProgress < 60 ? Math.random() * 4 + 2 :
|
| 537 |
+
Math.random() * 2 + 0.5;
|
| 538 |
+
|
| 539 |
+
currentProgress = Math.min(currentProgress + increment, 95);
|
| 540 |
+
updateProgressBar(currentProgress);
|
| 541 |
}
|
| 542 |
+
}, 300);
|
| 543 |
|
| 544 |
+
// Nettoyer après 30 secondes max
|
| 545 |
+
setTimeout(() => {
|
| 546 |
+
clearInterval(messageInterval);
|
| 547 |
+
clearInterval(progressInterval);
|
| 548 |
+
completeProgress();
|
| 549 |
+
}, 30000);
|
|
|
|
|
|
|
|
|
|
| 550 |
}
|
| 551 |
|
| 552 |
+
function updateProgressBar(progress) {
|
| 553 |
+
$('#progress-bar').css('width', progress + '%');
|
| 554 |
+
$('#progress-percentage').text(Math.round(progress) + '%');
|
| 555 |
+
}
|
| 556 |
+
|
| 557 |
+
function completeProgress() {
|
| 558 |
clearInterval(progressInterval);
|
| 559 |
+
currentProgress = 100;
|
| 560 |
+
updateProgressBar(100);
|
|
|
|
|
|
|
|
|
|
| 561 |
|
| 562 |
setTimeout(() => {
|
| 563 |
+
$('#loading-section').fadeOut(500, function() {
|
| 564 |
+
startStreamingDisplay();
|
| 565 |
+
});
|
| 566 |
+
}, 800);
|
| 567 |
}
|
| 568 |
|
| 569 |
+
// Fonction pour démarrer l'affichage en streaming avec effet de fondu
|
| 570 |
+
function startStreamingDisplay() {
|
| 571 |
+
// Simuler des données reçues (remplacer par vraies données de l'API)
|
| 572 |
+
simulateStreamingData();
|
|
|
|
|
|
|
|
|
|
| 573 |
}
|
| 574 |
|
| 575 |
+
// Simulation du streaming avec de vraies données (remplacer par l'appel API réel)
|
| 576 |
+
function simulateStreamingData() {
|
| 577 |
+
// Exemple de données - remplacer par les vraies données de votre API
|
| 578 |
+
const sampleThinking = `## Analyse du sujet
|
| 579 |
+
|
| 580 |
+
Le sujet "La liberté consiste-t-elle à faire tout ce que l'on veut ?" interroge la nature même de la liberté. Il faut distinguer entre liberté et licence, entre pouvoir et droit.
|
| 581 |
+
|
| 582 |
+
## Plan envisagé
|
| 583 |
+
1. La liberté comme absence de contraintes
|
| 584 |
+
2. Les limites nécessaires à la liberté
|
| 585 |
+
3. La liberté authentique comme autodétermination`;
|
| 586 |
+
|
| 587 |
+
const sampleResponse = `# La liberté consiste-t-elle à faire tout ce que l'on veut ?
|
| 588 |
+
|
| 589 |
+
## Introduction
|
| 590 |
+
|
| 591 |
+
La question de la liberté traverse toute l'histoire de la philosophie. À première vue, être libre semble signifier pouvoir agir selon ses désirs, sans contrainte. Cependant, cette conception spontanée de la liberté pose problème : peut-on vraiment identifier liberté et licence ? La liberté véritable ne suppose-t-elle pas au contraire certaines limites ?
|
| 592 |
+
|
| 593 |
+
## I. La liberté comme absence de contraintes
|
| 594 |
+
|
| 595 |
+
### A. La conception commune de la liberté
|
| 596 |
+
|
| 597 |
+
Dans l'usage courant, être libre c'est faire ce que l'on veut, quand on le veut. Cette conception négative de la liberté la définit par l'absence d'obstacles extérieurs à nos actions.
|
| 598 |
+
|
| 599 |
+
### B. La liberté naturelle selon Hobbes
|
| 600 |
+
|
| 601 |
+
Thomas Hobbes définit la liberté comme "l'absence d'obstacles extérieurs". Dans l'état de nature, chaque individu a le droit à tout, y compris au corps d'autrui.
|
| 602 |
+
|
| 603 |
+
## II. Les limites nécessaires à la liberté
|
| 604 |
+
|
| 605 |
+
### A. La liberté des uns s'arrête où commence celle des autres
|
| 606 |
+
|
| 607 |
+
John Stuart Mill, dans "De la liberté", établit le principe de non-nuisance : ma liberté ne doit pas porter atteinte à celle d'autrui.
|
| 608 |
+
|
| 609 |
+
### B. Les contraintes comme conditions de la liberté
|
| 610 |
+
|
| 611 |
+
Paradoxalement, certaines contraintes peuvent être libératrices. Les règles du jeu au tennis ne limitent pas le joueur, elles rendent le jeu possible.
|
| 612 |
+
|
| 613 |
+
## III. La liberté authentique comme autodétermination
|
| 614 |
+
|
| 615 |
+
### A. La liberté selon Kant
|
| 616 |
+
|
| 617 |
+
Pour Kant, la vraie liberté n'est pas de suivre ses inclinations, mais d'agir selon des principes rationnels que l'on s'est donnés à soi-même.
|
| 618 |
+
|
| 619 |
+
### B. L'autonomie comme essence de la liberté
|
| 620 |
+
|
| 621 |
+
Être libre, c'est être autonome, c'est-à-dire se donner ses propres lois. Cela implique une maîtrise de soi et une réflexion sur ses actes.
|
| 622 |
+
|
| 623 |
+
## Conclusion
|
| 624 |
+
|
| 625 |
+
La liberté ne peut se réduire à la simple capacité de faire tout ce que l'on veut. Une telle conception conduirait au chaos et à la négation même de la liberté. La véritable liberté réside dans l'autodétermination rationnelle, dans la capacité à agir selon des principes que l'on s'est librement choisis. Ainsi, les contraintes ne s'opposent pas nécessairement à la liberté ; elles peuvent même la rendre possible.`;
|
| 626 |
+
|
| 627 |
+
// Démarrer le streaming avec effet de fondu
|
| 628 |
+
startWordByWordStreaming(sampleThinking, sampleResponse);
|
| 629 |
}
|
| 630 |
|
| 631 |
+
// Fonction pour l'affichage mot par mot avec effet de fondu
|
| 632 |
+
function startWordByWordStreaming(thinkingText, responseText) {
|
| 633 |
+
// Afficher d'abord la section de pensée
|
| 634 |
+
$('#thinking-wrapper').removeClass('hidden').addClass('animate-fadeIn');
|
| 635 |
+
streamTextWordByWord('#thinking-process', thinkingText, 50, () => {
|
| 636 |
+
// Une fois la pensée terminée, afficher la réponse
|
| 637 |
+
$('#response').removeClass('hidden').addClass('animate-fadeIn');
|
| 638 |
+
streamTextWordByWord('#response > div', responseText, 30, () => {
|
| 639 |
+
// Une fois terminé, afficher les boutons d'action
|
| 640 |
+
$('#action-buttons').removeClass('hidden').addClass('animate-fadeIn');
|
| 641 |
+
Toast.fire({ icon: 'success', title: 'Génération terminée !' });
|
| 642 |
+
|
| 643 |
+
// Sauvegarder la dissertation
|
| 644 |
+
let title;
|
| 645 |
+
if ($('#type-select').val() === '3') {
|
| 646 |
+
const fileName = $('#image-upload')[0].files[0]?.name || "Analyse de document";
|
| 647 |
+
title = `Analyse (Sujet Type 3): ${fileName}`;
|
|
|
|
| 648 |
} else {
|
| 649 |
+
title = $('#question').val().trim();
|
| 650 |
}
|
| 651 |
+
saveDissertation(title, responseText);
|
| 652 |
+
});
|
|
|
|
| 653 |
});
|
| 654 |
}
|
| 655 |
|
| 656 |
+
// Fonction pour streamer le texte mot par mot
|
| 657 |
+
function streamTextWordByWord(selector, text, delay = 50, callback) {
|
| 658 |
+
const container = $(selector);
|
| 659 |
+
container.empty();
|
|
|
|
|
|
|
|
|
|
|
|
|
| 660 |
|
| 661 |
+
// Convertir le markdown en HTML
|
| 662 |
+
const htmlContent = marked.parse(text);
|
|
|
|
|
|
|
| 663 |
|
| 664 |
+
// Créer un élément temporaire pour extraire le texte
|
| 665 |
+
const tempDiv = $('<div>').html(htmlContent);
|
| 666 |
|
| 667 |
+
// Fonction récursive pour traiter chaque nœud
|
| 668 |
+
function processNode(node, targetContainer) {
|
| 669 |
+
if (node.nodeType === Node.TEXT_NODE) {
|
| 670 |
+
// Nœud texte - streamer mot par mot
|
| 671 |
+
const words = node.textContent.split(/(\s+)/);
|
| 672 |
+
let wordIndex = 0;
|
| 673 |
+
|
| 674 |
+
function addNextWord() {
|
| 675 |
+
if (wordIndex < words.length) {
|
| 676 |
+
const word = words[wordIndex];
|
| 677 |
+
const span = $('<span>').addClass('word-by-word').text(word);
|
| 678 |
+
span.css('animation-delay', '0s');
|
| 679 |
+
targetContainer.append(span);
|
| 680 |
+
|
| 681 |
+
setTimeout(() => {
|
| 682 |
+
wordIndex++;
|
| 683 |
+
addNextWord();
|
| 684 |
+
}, delay);
|
| 685 |
+
} else if (callback && node === tempDiv.get(0).lastChild) {
|
| 686 |
+
setTimeout(callback, 500);
|
| 687 |
+
}
|
| 688 |
+
}
|
| 689 |
|
| 690 |
+
addNextWord();
|
| 691 |
+
|
| 692 |
+
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
| 693 |
+
// Nœud élément - recréer l'élément et traiter ses enfants
|
| 694 |
+
const newElement = $(`<${node.tagName.toLowerCase()}>`);
|
| 695 |
+
|
| 696 |
+
// Copier les attributs
|
| 697 |
+
Array.from(node.attributes).forEach(attr => {
|
| 698 |
+
newElement.attr(attr.name, attr.value);
|
| 699 |
});
|
| 700 |
|
| 701 |
+
targetContainer.append(newElement);
|
| 702 |
+
|
| 703 |
+
// Traiter les enfants
|
| 704 |
+
Array.from(node.childNodes).forEach(child => {
|
| 705 |
+
processNode(child, newElement);
|
| 706 |
+
});
|
| 707 |
+
}
|
| 708 |
}
|
| 709 |
+
|
| 710 |
+
// Démarrer le traitement
|
| 711 |
+
Array.from(tempDiv.get(0).childNodes).forEach(child => {
|
| 712 |
+
processNode(child, container);
|
| 713 |
+
});
|
| 714 |
+
|
| 715 |
+
// Auto-scroll pendant le streaming
|
| 716 |
+
const scrollInterval = setInterval(() => {
|
| 717 |
+
smoothScrollToBottom();
|
| 718 |
+
}, 200);
|
| 719 |
+
|
| 720 |
+
setTimeout(() => {
|
| 721 |
+
clearInterval(scrollInterval);
|
| 722 |
+
}, (text.split(' ').length * delay) + 2000);
|
| 723 |
+
}
|
| 724 |
+
|
| 725 |
+
// Fonction de scroll optimisée
|
| 726 |
+
function smoothScrollToBottom() {
|
| 727 |
+
const targetScrollTop = Math.max(0, document.documentElement.scrollHeight - window.innerHeight - 50);
|
| 728 |
+
window.scrollTo({
|
| 729 |
+
top: targetScrollTop,
|
| 730 |
+
behavior: 'smooth'
|
| 731 |
+
});
|
| 732 |
}
|
| 733 |
|
| 734 |
// --- Gestion de l'interface ---
|
| 735 |
$('#type-select').change(function() {
|
| 736 |
const type = $(this).val();
|
| 737 |
// Cacher les sections de résultat lors du changement de type
|
| 738 |
+
$('#loading-section, #thinking-wrapper, #response, #action-buttons').addClass('hidden');
|
| 739 |
|
| 740 |
if (type === '3') { // Sujet Type 3
|
| 741 |
$('#text-input-container').hide();
|
| 742 |
$('#image-input-container').show().addClass('animate-fadeIn');
|
| 743 |
$('#deepthink-btn').hide();
|
| 744 |
$('#submit-btn').html('<svg class="h-5 w-5 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" /></svg>Analyser le sujet');
|
|
|
|
| 745 |
} else { // Dissertation texte
|
| 746 |
$('#text-input-container').show().addClass('animate-fadeIn');
|
| 747 |
$('#image-input-container').hide();
|
|
|
|
| 758 |
}
|
| 759 |
});
|
| 760 |
|
| 761 |
+
// --- Gestion des clics pour démarrer la génération ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 762 |
$('#submit-btn, #deepthink-btn').click(function() {
|
| 763 |
const type = $('#type-select').val();
|
| 764 |
const isDeepThink = $(this).attr('id') === 'deepthink-btn';
|
|
|
|
| 769 |
Swal.fire('Erreur', 'Veuillez sélectionner un document.', 'error');
|
| 770 |
return;
|
| 771 |
}
|
|
|
|
|
|
|
| 772 |
} else {
|
| 773 |
const question = $('#question').val().trim();
|
| 774 |
if (!question) {
|
| 775 |
Swal.fire('Erreur', 'Veuillez saisir un sujet.', 'error');
|
| 776 |
return;
|
| 777 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 778 |
}
|
| 779 |
+
|
| 780 |
+
// Cacher les sections précédentes et démarrer le loader
|
| 781 |
+
$('#thinking-wrapper, #response, #action-buttons').addClass('hidden');
|
| 782 |
+
startProgressLoader();
|
| 783 |
+
|
| 784 |
+
// Simuler une génération (remplacer par l'appel API réel)
|
| 785 |
+
setTimeout(() => {
|
| 786 |
+
completeProgress();
|
| 787 |
+
}, Math.random() * 3000 + 2000); // Entre 2 et 5 secondes
|
| 788 |
+
|
| 789 |
+
/*
|
| 790 |
+
// Code pour l'appel API réel (décommenter et adapter) :
|
| 791 |
+
const data = type === '3' ?
|
| 792 |
+
new FormData().append('image', $('#image-upload')[0].files[0]) :
|
| 793 |
+
{ question: $('#question').val().trim(), type, courseId: $('#course-select').val() || null };
|
| 794 |
+
|
| 795 |
+
const url = type === '3' ? '/stream_philo_image' :
|
| 796 |
+
isDeepThink ? '/stream_philo_deepthink' : '/stream_philo';
|
| 797 |
+
|
| 798 |
+
handleRealStreamedGeneration(url, {
|
| 799 |
+
method: 'POST',
|
| 800 |
+
headers: type !== '3' ? { 'Content-Type': 'application/json' } : undefined,
|
| 801 |
+
body: type === '3' ? data : JSON.stringify(data)
|
| 802 |
+
});
|
| 803 |
+
*/
|
| 804 |
});
|
| 805 |
|
| 806 |
+
// Fonction pour les vrais appels API streamés (à utiliser quand l'API est prête)
|
| 807 |
+
async function handleRealStreamedGeneration(url, options) {
|
| 808 |
+
startProgressLoader();
|
| 809 |
+
|
| 810 |
+
let fullResponseText = '', fullThinkingText = '';
|
| 811 |
+
|
| 812 |
+
try {
|
| 813 |
+
const response = await fetch(url, options);
|
| 814 |
+
if (!response.ok) throw new Error(await response.text());
|
| 815 |
+
|
| 816 |
+
// Compléter la barre de progression
|
| 817 |
+
completeProgress();
|
| 818 |
+
|
| 819 |
+
const reader = response.body.getReader();
|
| 820 |
+
const decoder = new TextDecoder();
|
| 821 |
+
let buffer = '';
|
| 822 |
+
|
| 823 |
+
while (true) {
|
| 824 |
+
const { value, done } = await reader.read();
|
| 825 |
+
if (done) break;
|
| 826 |
+
|
| 827 |
+
buffer += decoder.decode(value, { stream: true });
|
| 828 |
+
const lines = buffer.split('\n');
|
| 829 |
+
buffer = lines.pop();
|
| 830 |
+
|
| 831 |
+
for (const line of lines) {
|
| 832 |
+
if (line.trim() === '') continue;
|
| 833 |
+
try {
|
| 834 |
+
const data = JSON.parse(line.trim());
|
| 835 |
+
|
| 836 |
+
if (data.type === 'thought') {
|
| 837 |
+
fullThinkingText += data.content;
|
| 838 |
+
} else if (data.type === 'answer') {
|
| 839 |
+
fullResponseText += data.content;
|
| 840 |
+
} else if (data.type === 'error') {
|
| 841 |
+
throw new Error(data.content);
|
| 842 |
+
}
|
| 843 |
+
} catch (e) {
|
| 844 |
+
console.error("Erreur JSON parse:", line, e);
|
| 845 |
+
}
|
| 846 |
+
}
|
| 847 |
+
}
|
| 848 |
+
|
| 849 |
+
// Démarrer l'affichage streaming avec les vraies données
|
| 850 |
+
startWordByWordStreaming(fullThinkingText, fullResponseText);
|
| 851 |
+
|
| 852 |
+
} catch (error) {
|
| 853 |
+
$('#loading-section').addClass('hidden');
|
| 854 |
+
Swal.fire({ icon: 'error', title: 'Erreur', text: error.message || "Une erreur inconnue est survenue." });
|
| 855 |
+
}
|
| 856 |
+
}
|
| 857 |
+
|
| 858 |
// --- Fonctions de gestion de l'historique ---
|
| 859 |
function loadCourses() {
|
| 860 |
+
// Simuler le chargement des cours
|
| 861 |
+
const sampleCourses = [
|
| 862 |
+
{ id: '1', title: 'Introduction à la philosophie politique', author: 'Martin' },
|
| 863 |
+
{ id: '2', title: 'Éthique et morale', author: 'Dubois' },
|
| 864 |
+
{ id: '3', title: 'Métaphysique contemporaine', author: 'Laurent' }
|
|
|
|
| 865 |
];
|
| 866 |
|
| 867 |
const select = $('#course-select');
|
| 868 |
+
sampleCourses.forEach(course => {
|
| 869 |
const newOption = new Option(course.title, course.id, false, false);
|
| 870 |
$(newOption).data('author', course.author);
|
| 871 |
select.append(newOption);
|
| 872 |
});
|
| 873 |
select.trigger('change');
|
| 874 |
+
|
| 875 |
+
/*
|
| 876 |
+
// Code pour l'appel API réel :
|
| 877 |
+
$.ajax({
|
| 878 |
+
url: '/api/philosophy/courses',
|
| 879 |
+
method: 'GET',
|
| 880 |
+
}).done(function(courses) {
|
| 881 |
+
const select = $('#course-select');
|
| 882 |
+
courses.forEach(course => {
|
| 883 |
+
const newOption = new Option(course.title, course.id, false, false);
|
| 884 |
+
$(newOption).data('author', course.author);
|
| 885 |
+
select.append(newOption);
|
| 886 |
+
});
|
| 887 |
+
select.trigger('change');
|
| 888 |
+
}).fail(function() {
|
| 889 |
+
Toast.fire({ icon: 'error', title: 'Erreur de chargement des cours' });
|
| 890 |
+
});
|
| 891 |
+
*/
|
| 892 |
}
|
|
|
|
| 893 |
|
| 894 |
function saveDissertation(title, content) {
|
| 895 |
if (!title || !content) return;
|
|
|
|
| 940 |
});
|
| 941 |
}
|
| 942 |
|
| 943 |
+
// Gestion des interactions avec l'historique
|
| 944 |
$('#dissertations-list').on('click', '.collapsible', function() {
|
| 945 |
const content = $(this).next('.content');
|
| 946 |
const isVisible = content.is(':visible');
|
| 947 |
|
|
|
|
| 948 |
content.stop(true, true).slideToggle({
|
| 949 |
duration: 300,
|
| 950 |
easing: 'swing',
|
|
|
|
| 975 |
});
|
| 976 |
});
|
| 977 |
|
| 978 |
+
// Optimisations mobiles
|
| 979 |
let ticking = false;
|
| 980 |
|
| 981 |
function updateScrollPosition() {
|
|
|
|
| 989 |
}
|
| 990 |
}, { passive: true });
|
| 991 |
|
|
|
|
| 992 |
let resizeTimer;
|
| 993 |
window.addEventListener('resize', function() {
|
| 994 |
clearTimeout(resizeTimer);
|
|
|
|
| 1001 |
}, 250);
|
| 1002 |
}, { passive: true });
|
| 1003 |
|
|
|
|
| 1004 |
if ('ontouchstart' in window) {
|
| 1005 |
$('body').addClass('touch-device');
|
| 1006 |
|
|
|
|
| 1014 |
});
|
| 1015 |
}
|
| 1016 |
|
| 1017 |
+
// Initialisation
|
| 1018 |
+
loadCourses();
|
| 1019 |
updateSavedDissertationsList();
|
| 1020 |
});
|
| 1021 |
</script>
|