Docfile commited on
Commit
15ed921
·
verified ·
1 Parent(s): fa7810f

Update templates/maj.html

Browse files
Files changed (1) hide show
  1. templates/maj.html +45 -74
templates/maj.html CHANGED
@@ -6,7 +6,6 @@
6
  <title>Math Solver - Version Gratuite (MathJax)</title>
7
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
8
  <link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css" rel="stylesheet">
9
- <!-- REMOVED KaTeX CSS -->
10
  <style>
11
  :root {
12
  --primary-color: #4a6fa5;
@@ -84,23 +83,19 @@
84
  footer { text-align: center; padding: 30px 0 20px 0; color: #666; font-size: 0.9rem; border-top: 1px solid #eee; margin-top: 40px; }
85
 
86
  #solutionOutput { margin-top: 30px; text-align: left; display: none; }
87
- #solution { background: #fff; padding: 20px; border-radius: 8px; text-align: left; line-height: 1.8; font-size: 1rem; border: 1px solid #eee; margin-top: 15px; overflow-x: hidden; /* Prevent container scroll, let MathJax handle internal scroll */ }
88
 
89
- /* Code Block Styling */
90
  .code-section { margin: 20px 0; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
91
  .code-header { background-color: #343a40; color: white; padding: 10px 15px; font-size: 0.9em; font-family: 'Courier New', monospace; }
92
  .code-content { margin: 0; padding: 15px; background-color: var(--code-bg); color: #e6e6e6; overflow-x: auto; font-family: 'Courier New', monospace; font-size: 0.9em; line-height: 1.5; }
93
  .code-content pre, .code-content code { margin: 0; padding: 0; background: none; white-space: pre; }
94
 
95
- /* Output Block Styling */
96
  .output-section { background-color: var(--output-bg); padding: 15px; margin: 15px 0; border-radius: 8px; border: 1px solid #d6e0e2; color: #333; font-family: 'Courier New', monospace; font-size: 0.9em; white-space: pre-wrap; overflow-x: auto; box-shadow: inset 0 1px 3px rgba(0,0,0,0.05); }
97
 
98
- /* Step Styling */
99
  .step-section { margin: 20px 0; padding: 15px; background-color: #fdfdfd; border-left: 4px solid var(--accent-color); border-radius: 0 5px 5px 0; overflow-wrap: break-word; }
100
  .step-section:first-child { margin-top: 0; }
101
  .step-section:last-child { margin-bottom: 0; }
102
 
103
- /* Indicator Styling */
104
  .indicator { display: flex; align-items: center; padding: 12px 15px; margin: 15px 0; border-radius: 8px; font-size: 0.95rem; border: 1px solid transparent; }
105
  .indicator.thinking-indicator { background-color: #e3f2fd; color: #1565c0; border-color: #bde0fe; }
106
  .indicator.executing-indicator { background-color: #ede7f6; color: #5e35b1; border-color: #d1c4e9; }
@@ -108,27 +103,21 @@
108
  .indicator i { margin-right: 10px; font-size: 1.1em; animation: pulse 1.5s infinite ease-in-out; }
109
  @keyframes pulse { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } }
110
 
111
- /* --- MathJax Specific Styles --- */
112
- /* Ensure container allows for potential horizontal scrolling of large equations */
113
- .mjx-chtml { /* Target MathJax CommonHTML output */
114
  overflow-x: auto;
115
  overflow-y: hidden;
116
  }
117
- /* Improve spacing for display math */
118
  mjx-container[display="true"] {
119
  display: block;
120
  margin: 1em 0;
121
  text-align: center;
122
  }
123
- /* Handle potential overflow within display math specifically */
124
  mjx-container[display="true"] > .mjx-chtml {
125
  overflow-x: auto;
126
  overflow-y: hidden;
127
- padding: 0.2em 0; /* Add slight padding if scrollbar appears */
128
  }
129
 
130
-
131
- /* --- Responsive Design --- */
132
  @media (max-width: 992px) { .container { max-width: 90%; } }
133
  @media (max-width: 768px) {
134
  .container { padding: 15px; }
@@ -149,48 +138,36 @@
149
  .content-box { padding: 15px; }
150
  #solution { padding: 15px; }
151
  .code-header, .code-content, .output-section { font-size: 0.85em; }
152
- /* Ensure MathJax equations can still scroll on small screens */
153
  .mjx-chtml {
154
- font-size: 0.95em; /* Slightly smaller math on mobile if needed */
155
  }
156
  }
157
  </style>
158
 
159
- <!-- MathJax Configuration -->
160
  <script>
161
  window.MathJax = {
162
  tex: {
163
- inlineMath: [['$', '$'], ['\\(', '\\)']], // Define inline math delimiters
164
- displayMath: [['$$', '$$'], ['\\[', '\\]']], // Define display math delimiters
165
- processEscapes: true, // Process \$ etc.
166
- tags: 'ams', // Use AMS numbering convention
167
- macros: {
168
- // Define custom macros here if needed
169
- // R: "\\mathbb{R}",
170
- // C: "\\mathbb{C}"
171
- }
172
  },
173
  chtml: {
174
- matchFontHeight: true, // Match surrounding text font size
175
- scale: 1.0 // Adjust global scaling if necessary
176
  },
177
  options: {
178
- ignoreHtmlClass: 'tex2jax_ignore', // Class to ignore processing inside
179
- processHtmlClass: 'tex2jax_process', // Class to explicitly process inside
180
- skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'] // Tags to skip
181
  },
182
  startup: {
183
- // Don't automatically typeset on page load, we'll trigger it manually
184
  typeset: false,
185
- // pageReady: () => {
186
- // console.log("MathJax is ready to process content.");
187
- // }
188
  }
189
  };
190
  </script>
191
- <!-- Load MathJax -->
192
  <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
193
- <!-- REMOVED KaTeX JS -->
194
 
195
  </head>
196
  <body>
@@ -237,17 +214,14 @@
237
  <div id="solutionOutput" style="display: none;">
238
  <h3>Solution Détaillée :</h3>
239
  <div id="loadingIndicator" class="indicator" style="display: none;">
240
- <!-- Content set by JS -->
241
  </div>
242
  <div id="solution">
243
- <!-- Solution content will be injected here -->
244
  </div>
245
  <div id="mathjaxProcessingIndicator" class="indicator answering-indicator" style="display: none; margin-top: 10px;">
246
  <i class="fas fa-magic indicator-icon"></i><span>Mise en forme des équations...</span>
247
  </div>
248
  </div>
249
 
250
-
251
  <div class="upgrade-section">
252
  <h2>Besoin de plus ?</h2>
253
  <p>Passez à la version Pro pour des fonctionnalités avancées et des résolutions illimitées.</p>
@@ -260,7 +234,6 @@
260
  </footer>
261
  </div>
262
 
263
- <!-- Dependencies: Highlight.js -->
264
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
265
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/python.min.js"></script>
266
 
@@ -289,7 +262,13 @@
289
  uploadStatus.textContent = `Image sélectionnée : ${file.name}`;
290
  solutionOutput.style.display = 'none';
291
  solutionDiv.innerHTML = '';
292
- mathjaxIndicator.style.display = 'none'; // Reset MathJax indicator
 
 
 
 
 
 
293
  }
294
  reader.readAsDataURL(file);
295
  } else {
@@ -301,18 +280,29 @@
301
  });
302
 
303
  solveButton.addEventListener('click', function() {
304
- const formData = new FormData(imageForm);
305
- if (!imageInput.files[0]) {
306
  alert("Veuillez d'abord sélectionner une image.");
307
  return;
308
  }
309
 
 
 
 
 
 
 
 
 
 
 
 
 
310
  solutionOutput.style.display = 'block';
311
  loadingIndicator.style.display = 'flex';
312
  loadingIndicator.className = 'indicator thinking-indicator';
313
  loadingIndicator.innerHTML = '<i class="fas fa-brain indicator-icon"></i><span>Préparation de la requête...</span>';
314
  solutionDiv.innerHTML = '';
315
- mathjaxIndicator.style.display = 'none'; // Hide MathJax indicator
316
 
317
  fetch('/solved', {
318
  method: 'POST',
@@ -325,52 +315,39 @@
325
  const reader = response.body.getReader();
326
  const decoder = new TextDecoder();
327
  let buffer = '';
328
- // No need for accumulatedContent if rendering at the end
329
 
330
  function processStream({ done, value }) {
331
  if (done) {
332
  loadingIndicator.style.display = 'none';
333
 
334
- // Process any remaining buffer content
335
  if (buffer.trim()) {
336
- // Append the final chunk - assumes it's a regular step
337
  const finalStepDiv = document.createElement('div');
338
  finalStepDiv.className = 'step-section';
339
- finalStepDiv.innerHTML = buffer; // Use innerHTML
340
  solutionDiv.appendChild(finalStepDiv);
341
  }
342
 
343
- // --- Trigger MathJax Rendering ---
344
  if (typeof MathJax !== 'undefined' && MathJax.typesetPromise) {
345
- // Show MathJax processing indicator
346
  mathjaxIndicator.style.display = 'flex';
347
-
348
- MathJax.typesetPromise([solutionDiv]) // Target specific container
349
  .then(() => {
350
- console.log('MathJax typesetting complete.');
351
- mathjaxIndicator.style.display = 'none'; // Hide indicator on success
352
- // Optional: Re-apply highlight.js if MathJax altered code blocks (unlikely but possible)
353
- // document.querySelectorAll('#solution pre code').forEach((block) => {
354
- // hljs.highlightElement(block);
355
- // });
356
  })
357
  .catch((err) => {
358
  console.error('Erreur de rendu MathJax:', err);
359
- mathjaxIndicator.style.display = 'none'; // Hide indicator on error
360
  solutionDiv.innerHTML += `<div style="color: orange; margin-top: 10px;">Erreur lors de l'affichage des formules mathématiques (MathJax).</div>`;
361
  })
362
  .finally(() => {
363
- // Scroll to the solution area after rendering attempt
364
  solutionOutput.scrollIntoView({ behavior: 'smooth', block: 'start' });
365
  });
366
  } else {
367
  console.warn("MathJax n'est pas prêt ou n'a pas pu être chargé.");
368
  solutionDiv.innerHTML += `<div style="color: orange; margin-top: 10px;">Impossible de charger le module d'affichage mathématique (MathJax).</div>`;
369
- // Scroll anyway
370
  solutionOutput.scrollIntoView({ behavior: 'smooth', block: 'start' });
371
  }
372
- return; // End of stream processing
373
- } // end if(done)
374
 
375
  buffer += decoder.decode(value, { stream: true });
376
  const parts = buffer.split('\n\n');
@@ -381,7 +358,6 @@
381
  try {
382
  const jsonData = JSON.parse(part.substring(6));
383
 
384
- // Update Indicator (same as before)
385
  if (jsonData.mode) {
386
  loadingIndicator.style.display = 'flex';
387
  if (jsonData.mode === 'thinking') {
@@ -399,7 +375,6 @@
399
  }
400
  }
401
 
402
- // Append Content (same as before, but NO LaTeX rendering here)
403
  if (jsonData.content) {
404
  const content = jsonData.content;
405
  let elementToAppend;
@@ -411,7 +386,7 @@
411
  elementToAppend.innerHTML = `
412
  <div class="code-header">Code Python</div>
413
  <div class="code-content"><pre><code class="language-python tex2jax_ignore">${escapeHtml(code)}</code></pre></div>
414
- `; // Added tex2jax_ignore to prevent MathJax trying to process code
415
  solutionDiv.appendChild(elementToAppend);
416
  const codeBlock = elementToAppend.querySelector('code');
417
  if (codeBlock && hljs) { hljs.highlightElement(codeBlock); }
@@ -419,15 +394,14 @@
419
  } else if (content.startsWith('Résultat d\'exécution:\n```')) {
420
  const output = content.replace(/^Résultat d'exécution:\n```\n?([\s\S]*?)\n?```$/, '$1');
421
  elementToAppend = document.createElement('div');
422
- elementToAppend.className = 'output-section tex2jax_ignore'; // Ignore MathJax here too
423
  elementToAppend.textContent = output;
424
  solutionDiv.appendChild(elementToAppend);
425
 
426
  } else {
427
- // Regular step, potentially with LaTeX delimiters inside
428
  elementToAppend = document.createElement('div');
429
  elementToAppend.className = 'step-section';
430
- elementToAppend.innerHTML = content; // Add raw content
431
  solutionDiv.appendChild(elementToAppend);
432
  }
433
  }
@@ -446,14 +420,11 @@
446
  }
447
  });
448
 
449
- // Scroll down as content arrives
450
  solutionDiv.lastChild?.scrollIntoView({ behavior: 'smooth', block: 'end' });
451
 
452
- // Continue reading the stream
453
  return reader.read().then(processStream);
454
- } // end processStream function
455
 
456
- // Start processing the stream
457
  return reader.read().then(processStream);
458
  })
459
  .catch(error => {
 
6
  <title>Math Solver - Version Gratuite (MathJax)</title>
7
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
8
  <link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css" rel="stylesheet">
 
9
  <style>
10
  :root {
11
  --primary-color: #4a6fa5;
 
83
  footer { text-align: center; padding: 30px 0 20px 0; color: #666; font-size: 0.9rem; border-top: 1px solid #eee; margin-top: 40px; }
84
 
85
  #solutionOutput { margin-top: 30px; text-align: left; display: none; }
86
+ #solution { background: #fff; padding: 20px; border-radius: 8px; text-align: left; line-height: 1.8; font-size: 1rem; border: 1px solid #eee; margin-top: 15px; overflow-x: hidden; }
87
 
 
88
  .code-section { margin: 20px 0; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
89
  .code-header { background-color: #343a40; color: white; padding: 10px 15px; font-size: 0.9em; font-family: 'Courier New', monospace; }
90
  .code-content { margin: 0; padding: 15px; background-color: var(--code-bg); color: #e6e6e6; overflow-x: auto; font-family: 'Courier New', monospace; font-size: 0.9em; line-height: 1.5; }
91
  .code-content pre, .code-content code { margin: 0; padding: 0; background: none; white-space: pre; }
92
 
 
93
  .output-section { background-color: var(--output-bg); padding: 15px; margin: 15px 0; border-radius: 8px; border: 1px solid #d6e0e2; color: #333; font-family: 'Courier New', monospace; font-size: 0.9em; white-space: pre-wrap; overflow-x: auto; box-shadow: inset 0 1px 3px rgba(0,0,0,0.05); }
94
 
 
95
  .step-section { margin: 20px 0; padding: 15px; background-color: #fdfdfd; border-left: 4px solid var(--accent-color); border-radius: 0 5px 5px 0; overflow-wrap: break-word; }
96
  .step-section:first-child { margin-top: 0; }
97
  .step-section:last-child { margin-bottom: 0; }
98
 
 
99
  .indicator { display: flex; align-items: center; padding: 12px 15px; margin: 15px 0; border-radius: 8px; font-size: 0.95rem; border: 1px solid transparent; }
100
  .indicator.thinking-indicator { background-color: #e3f2fd; color: #1565c0; border-color: #bde0fe; }
101
  .indicator.executing-indicator { background-color: #ede7f6; color: #5e35b1; border-color: #d1c4e9; }
 
103
  .indicator i { margin-right: 10px; font-size: 1.1em; animation: pulse 1.5s infinite ease-in-out; }
104
  @keyframes pulse { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } }
105
 
106
+ .mjx-chtml {
 
 
107
  overflow-x: auto;
108
  overflow-y: hidden;
109
  }
 
110
  mjx-container[display="true"] {
111
  display: block;
112
  margin: 1em 0;
113
  text-align: center;
114
  }
 
115
  mjx-container[display="true"] > .mjx-chtml {
116
  overflow-x: auto;
117
  overflow-y: hidden;
118
+ padding: 0.2em 0;
119
  }
120
 
 
 
121
  @media (max-width: 992px) { .container { max-width: 90%; } }
122
  @media (max-width: 768px) {
123
  .container { padding: 15px; }
 
138
  .content-box { padding: 15px; }
139
  #solution { padding: 15px; }
140
  .code-header, .code-content, .output-section { font-size: 0.85em; }
 
141
  .mjx-chtml {
142
+ font-size: 0.95em;
143
  }
144
  }
145
  </style>
146
 
 
147
  <script>
148
  window.MathJax = {
149
  tex: {
150
+ inlineMath: [['$', '$'], ['\\(', '\\)']],
151
+ displayMath: [['$$', '$$'], ['\\[', '\\]']],
152
+ processEscapes: true,
153
+ tags: 'ams',
154
+ macros: {}
 
 
 
 
155
  },
156
  chtml: {
157
+ matchFontHeight: true,
158
+ scale: 1.0
159
  },
160
  options: {
161
+ ignoreHtmlClass: 'tex2jax_ignore',
162
+ processHtmlClass: 'tex2jax_process',
163
+ skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
164
  },
165
  startup: {
 
166
  typeset: false,
 
 
 
167
  }
168
  };
169
  </script>
 
170
  <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
 
171
 
172
  </head>
173
  <body>
 
214
  <div id="solutionOutput" style="display: none;">
215
  <h3>Solution Détaillée :</h3>
216
  <div id="loadingIndicator" class="indicator" style="display: none;">
 
217
  </div>
218
  <div id="solution">
 
219
  </div>
220
  <div id="mathjaxProcessingIndicator" class="indicator answering-indicator" style="display: none; margin-top: 10px;">
221
  <i class="fas fa-magic indicator-icon"></i><span>Mise en forme des équations...</span>
222
  </div>
223
  </div>
224
 
 
225
  <div class="upgrade-section">
226
  <h2>Besoin de plus ?</h2>
227
  <p>Passez à la version Pro pour des fonctionnalités avancées et des résolutions illimitées.</p>
 
234
  </footer>
235
  </div>
236
 
 
237
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
238
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/python.min.js"></script>
239
 
 
262
  uploadStatus.textContent = `Image sélectionnée : ${file.name}`;
263
  solutionOutput.style.display = 'none';
264
  solutionDiv.innerHTML = '';
265
+ mathjaxIndicator.style.display = 'none';
266
+ }
267
+ reader.onerror = function(e) {
268
+ console.error("FileReader error:", e);
269
+ uploadStatus.textContent = "Erreur lors de la lecture de l'image.";
270
+ imagePreview.style.display = 'none';
271
+ solveButton.style.display = 'none';
272
  }
273
  reader.readAsDataURL(file);
274
  } else {
 
280
  });
281
 
282
  solveButton.addEventListener('click', function() {
283
+ if (!imageInput.files || imageInput.files.length === 0) {
 
284
  alert("Veuillez d'abord sélectionner une image.");
285
  return;
286
  }
287
 
288
+ if (!imageForm) {
289
+ alert("Erreur interne: Le formulaire d'upload est introuvable.");
290
+ return;
291
+ }
292
+ const formData = new FormData(imageForm);
293
+
294
+ const fileData = formData.get('image');
295
+ if (!fileData || fileData.size === 0) {
296
+ alert("Erreur lors de la préparation de l'image pour l'envoi.");
297
+ return;
298
+ }
299
+
300
  solutionOutput.style.display = 'block';
301
  loadingIndicator.style.display = 'flex';
302
  loadingIndicator.className = 'indicator thinking-indicator';
303
  loadingIndicator.innerHTML = '<i class="fas fa-brain indicator-icon"></i><span>Préparation de la requête...</span>';
304
  solutionDiv.innerHTML = '';
305
+ mathjaxIndicator.style.display = 'none';
306
 
307
  fetch('/solved', {
308
  method: 'POST',
 
315
  const reader = response.body.getReader();
316
  const decoder = new TextDecoder();
317
  let buffer = '';
 
318
 
319
  function processStream({ done, value }) {
320
  if (done) {
321
  loadingIndicator.style.display = 'none';
322
 
 
323
  if (buffer.trim()) {
 
324
  const finalStepDiv = document.createElement('div');
325
  finalStepDiv.className = 'step-section';
326
+ finalStepDiv.innerHTML = buffer;
327
  solutionDiv.appendChild(finalStepDiv);
328
  }
329
 
 
330
  if (typeof MathJax !== 'undefined' && MathJax.typesetPromise) {
 
331
  mathjaxIndicator.style.display = 'flex';
332
+ MathJax.typesetPromise([solutionDiv])
 
333
  .then(() => {
334
+ mathjaxIndicator.style.display = 'none';
 
 
 
 
 
335
  })
336
  .catch((err) => {
337
  console.error('Erreur de rendu MathJax:', err);
338
+ mathjaxIndicator.style.display = 'none';
339
  solutionDiv.innerHTML += `<div style="color: orange; margin-top: 10px;">Erreur lors de l'affichage des formules mathématiques (MathJax).</div>`;
340
  })
341
  .finally(() => {
 
342
  solutionOutput.scrollIntoView({ behavior: 'smooth', block: 'start' });
343
  });
344
  } else {
345
  console.warn("MathJax n'est pas prêt ou n'a pas pu être chargé.");
346
  solutionDiv.innerHTML += `<div style="color: orange; margin-top: 10px;">Impossible de charger le module d'affichage mathématique (MathJax).</div>`;
 
347
  solutionOutput.scrollIntoView({ behavior: 'smooth', block: 'start' });
348
  }
349
+ return;
350
+ }
351
 
352
  buffer += decoder.decode(value, { stream: true });
353
  const parts = buffer.split('\n\n');
 
358
  try {
359
  const jsonData = JSON.parse(part.substring(6));
360
 
 
361
  if (jsonData.mode) {
362
  loadingIndicator.style.display = 'flex';
363
  if (jsonData.mode === 'thinking') {
 
375
  }
376
  }
377
 
 
378
  if (jsonData.content) {
379
  const content = jsonData.content;
380
  let elementToAppend;
 
386
  elementToAppend.innerHTML = `
387
  <div class="code-header">Code Python</div>
388
  <div class="code-content"><pre><code class="language-python tex2jax_ignore">${escapeHtml(code)}</code></pre></div>
389
+ `;
390
  solutionDiv.appendChild(elementToAppend);
391
  const codeBlock = elementToAppend.querySelector('code');
392
  if (codeBlock && hljs) { hljs.highlightElement(codeBlock); }
 
394
  } else if (content.startsWith('Résultat d\'exécution:\n```')) {
395
  const output = content.replace(/^Résultat d'exécution:\n```\n?([\s\S]*?)\n?```$/, '$1');
396
  elementToAppend = document.createElement('div');
397
+ elementToAppend.className = 'output-section tex2jax_ignore';
398
  elementToAppend.textContent = output;
399
  solutionDiv.appendChild(elementToAppend);
400
 
401
  } else {
 
402
  elementToAppend = document.createElement('div');
403
  elementToAppend.className = 'step-section';
404
+ elementToAppend.innerHTML = content;
405
  solutionDiv.appendChild(elementToAppend);
406
  }
407
  }
 
420
  }
421
  });
422
 
 
423
  solutionDiv.lastChild?.scrollIntoView({ behavior: 'smooth', block: 'end' });
424
 
 
425
  return reader.read().then(processStream);
426
+ }
427
 
 
428
  return reader.read().then(processStream);
429
  })
430
  .catch(error => {