joermd commited on
Commit
d366898
·
verified ·
1 Parent(s): 59b39d8

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +152 -51
index.html CHANGED
@@ -213,6 +213,30 @@
213
  </h2>
214
  <div id="explanationText" class="text-lg text-gray-700"></div>
215
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  </main>
217
  </div>
218
 
@@ -220,15 +244,16 @@
220
  جافا سكريبت: الوظائف والمعالجة
221
  ================================= -->
222
  <script>
 
 
 
 
 
223
  // إعدادات API
224
  const API_URL = 'https://api.deepseek.com/chat/completions';
225
  const API_KEY = 'sk-15606736ed9e4aea8b7cc11a195d2b01';
226
 
227
- /*
228
- البرومبت الجديد: يتم فيه تحديد أن النصوص مليئة بالأخطاء والنواقص،
229
- مع ضرورة الحفاظ على علامات التحديد (التعليم) كما هي.
230
- */
231
- const ANALYSIS_PROMPT = `أنت خبير لغوي متخصص في مراجعة الترجمة التقنية. مهمتك مقارنة النص المصدر والنص الهدف بدقة عالية مع العلم أن النصوص مليانة بالأخطاء والنواقص والنصوص المفقودة.
232
  لا تقم بإزالة أو تعديل العلامات التالية:
233
  • الأرقام: تحافظ على علامات < و >.
234
  • النصوص المفقودة: تحافظ على علامات __ و __.
@@ -245,34 +270,26 @@
245
  النص الهدف:
246
  {target}`;
247
 
248
- /* =====================================
249
- دوال مساعدة للتعامل مع النصوص
250
- ===================================== */
251
- // حساب عدد الكلمات في النص
252
  function countWords(text) {
253
  return text.trim().split(/\s+/).filter(word => word !== "").length;
254
  }
255
- // هروب أحرف Regex الخاصة
256
  function escapeRegExp(string) {
257
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
258
  }
259
- // تقسيم النص إلى أسطر مع عرض رقم السطر
260
  function splitIntoLines(text) {
261
  return text.split('\n').map((line, i) => `<div class="line-item"><span class="line-number">${i+1}:</span> <span class="line-text">${line}</span></div>`).join('');
262
  }
263
- // الحصول على رقم السطر لظهور عبارة معينة
264
  function getLineNumber(text, substring) {
265
  const index = text.indexOf(substring);
266
  if (index === -1) return "غير محدد";
267
  return text.substring(0, index).split("\n").length;
268
  }
269
 
270
- /* =====================================
271
- دوال التمييز (Highlighting) للنتائج
272
- ===================================== */
273
  function applyHighlights(originalText, analysisOutput) {
274
  let highlightedText = originalText;
275
- // تمييز اختلافات الأرقام
276
  const numberRegex = /<([^<>]+)>/g;
277
  let match;
278
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
@@ -283,7 +300,7 @@
283
  highlightedText = highlightedText.replace(phraseRegex, replacement);
284
  }
285
  }
286
- // تمييز النصوص المفقودة
287
  const missingRegex = /__(.*?)__/g;
288
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
289
  const phrase = match[1].trim();
@@ -293,7 +310,7 @@
293
  highlightedText = highlightedText.replace(phraseRegex, replacement);
294
  }
295
  }
296
- // تمييز اختلافات المعنى
297
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
298
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
299
  const phrase = match[1].trim();
@@ -306,13 +323,51 @@
306
  return highlightedText;
307
  }
308
 
309
- /* =====================================
310
- دالة توليد الشرح التفصيلي Organized Explanation
311
- يتم تقسيم الشرح إلى خطوات منظمة
312
- ===================================== */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
  function generateExplanation(sourceText, analysisOutput) {
314
  let steps = [];
315
- // الخطوة 1: النصوص المفقودة
316
  const missingRegex = /__(.*?)__/g;
317
  let match;
318
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
@@ -322,7 +377,6 @@
322
  steps.push(`<li><strong>الخطوة 1:</strong> في السطر ${lineNum}، الجزء "<span class="highlight-missing">__${phrase}__</span>" من النص المصدر مفقود في النص الهدف. تأكد من إضافته لتحسين الدقة.</li>`);
323
  }
324
  }
325
- // الخطوة 2: اختلافات الأرقام
326
  const numberRegex = /<([^<>]+)>/g;
327
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
328
  const phrase = match[1].trim();
@@ -331,7 +385,6 @@
331
  steps.push(`<li><strong>الخطوة 2:</strong> في السطر ${lineNum}، الرقم "<span class="highlight-number">${phrase}</span>" في المصدر لا يتطابق مع الرقم في الهدف. يرجى المراجعة.</li>`);
332
  }
333
  }
334
- // الخطوة 3: اختلافات المعنى
335
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
336
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
337
  const phrase = match[1].trim();
@@ -340,16 +393,55 @@
340
  steps.push(`<li><strong>الخطوة 3:</strong> في السطر ${lineNum}، تم العثور على اختلاف في المعنى مع التعبير "<span class="highlight-meaning">${phrase}</span>". تحقق من الدقة.</li>`);
341
  }
342
  }
343
- // إذا لم يكن هناك اختلافات
344
  if (steps.length === 0) {
345
  return `<p>النصوص متطابقة تماماً ولا توجد فروقات تحتاج للتنبيه.</p>`;
346
  }
347
  return `<ol class="list-decimal ml-6 space-y-2">${steps.join('')}</ol>`;
348
  }
349
 
350
- /* =====================================
351
- دالة معالجة الملفات (PDF و DOCX)
352
- ===================================== */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  async function processFile(file) {
354
  let text = "";
355
  if (file.type === 'application/pdf') {
@@ -372,10 +464,7 @@
372
  return text;
373
  }
374
 
375
- /* =====================================
376
- دوال رفع الملفات وإدخال النصوص
377
- ===================================== */
378
- // رفع ملف السورس
379
  document.getElementById('sourceFile')?.addEventListener('change', async (event) => {
380
  const file = event.target.files[0];
381
  if (!file) return;
@@ -390,7 +479,6 @@
390
  document.getElementById('processStatus').classList.add('hidden');
391
  }
392
  });
393
- // رفع ملف التارجت
394
  document.getElementById('targetFile')?.addEventListener('change', async (event) => {
395
  const file = event.target.files[0];
396
  if (!file) return;
@@ -405,7 +493,6 @@
405
  document.getElementById('processStatus').classList.add('hidden');
406
  }
407
  });
408
- // رفع ملف المصادر الإضافية
409
  document.getElementById('sourceExtraFile')?.addEventListener('change', async (event) => {
410
  const file = event.target.files[0];
411
  if (!file) return;
@@ -421,9 +508,7 @@
421
  }
422
  });
423
 
424
- /* =====================================
425
- دالة عرض الأخطاء والرسائل
426
- ===================================== */
427
  function addError(message, type = 'error') {
428
  const errorsList = document.getElementById('errorsList');
429
  if (!errorsList) return;
@@ -436,13 +521,10 @@
436
  errorsList.appendChild(errorDiv);
437
  }
438
 
439
- /* =====================================
440
- معالجة عملية التحليل عند الضغط على الزر
441
- ===================================== */
442
  document.getElementById('submitBtn').addEventListener('click', async () => {
443
  const sourceText = document.getElementById('sourceText').value;
444
  const targetText = document.getElementById('targetText').value;
445
- // مسح الرسائل السابقة وإظهار النتائج
446
  document.getElementById('errorsList').innerHTML = '';
447
  document.getElementById('resultSection').classList.remove('hidden');
448
  document.getElementById('explanationBox').classList.remove('hidden');
@@ -452,7 +534,6 @@
452
  return;
453
  }
454
 
455
- // مقارنة عدد الكلمات وتنبيه إن وجد اختلاف
456
  const sourceWordCount = countWords(sourceText);
457
  const targetWordCount = countWords(targetText);
458
  if (sourceWordCount !== targetWordCount) {
@@ -460,7 +541,6 @@
460
  }
461
 
462
  try {
463
- // عرض مؤشر التقدم
464
  const progressDiv = document.createElement('div');
465
  progressDiv.className = "bg-indigo-100 p-4 rounded-xl mb-4";
466
  progressDiv.innerHTML = `<div class="flex items-center">
@@ -469,12 +549,10 @@
469
  </div>`;
470
  document.getElementById('errorsList').appendChild(progressDiv);
471
 
472
- // بناء الـ prompt باستخدام النصين المُدخلين
473
  const prompt = ANALYSIS_PROMPT
474
  .replace("{source}", sourceText)
475
  .replace("{target}", targetText);
476
 
477
- // استدعاء DeepSeek API
478
  const payload = {
479
  model: "deepseek-chat",
480
  messages: [
@@ -500,7 +578,11 @@
500
  const analysisOutput = data.choices[0].message.content.trim();
501
  progressDiv.remove();
502
 
503
- // إذا كانت النصوص متطابقة تمامًا
 
 
 
 
504
  if (analysisOutput.includes('[MATCH]')) {
505
  const checkDiv = document.createElement('div');
506
  checkDiv.className = "p-4 rounded-xl bg-green-50 text-green-700 flex items-center";
@@ -510,16 +592,13 @@
510
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
511
  document.getElementById('explanationText').innerHTML = `<p>النصوص متطابقة ولا يوجد اختلاف يجب الإشارة إليه.</p>`;
512
  } else {
513
- // تطبيق التحديد على النصوص
514
  const sourceHighlighted = applyHighlights(sourceText, analysisOutput);
515
  const targetHighlighted = applyHighlights(targetText, analysisOutput);
516
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceHighlighted);
517
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetHighlighted);
518
- // توليد شرح منظم على شكل خطوات
519
  const explanationHTML = generateExplanation(sourceText, analysisOutput);
520
  document.getElementById('explanationText').innerHTML = explanationHTML;
521
 
522
- // عرض ملخص الاختلافات في الأسفل (اختياري)
523
  const numDiffCount = (analysisOutput.match(/<([^<>]+)>/g) || []).length;
524
  const missingDiffCount = (analysisOutput.match(/__(.*?)__/g) || []).length;
525
  const meaningDiffCount = (analysisOutput.match(/\[MEANING\](.*?)\[\/MEANING\]/g) || []).length;
@@ -540,6 +619,28 @@
540
  addError(`خطأ في التحليل: ${error.message}`);
541
  }
542
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
  </script>
544
  </body>
545
- </html>
 
213
  </h2>
214
  <div id="explanationText" class="text-lg text-gray-700"></div>
215
  </div>
216
+
217
+ <!-- زر إعادة المراجعة -->
218
+ <button id="reviewAgainBtn" class="w-full bg-gray-600 hover:bg-gray-700 text-white font-bold py-3 px-6 rounded-xl transition-all transform hover:scale-105 focus:ring-gray-200 text-xl shadow-lg hover:shadow-xl mb-8">
219
+ <div class="flex items-center justify-center">
220
+ <i class="fas fa-redo ml-2"></i> إعادة المراجعة
221
+ </div>
222
+ </button>
223
+
224
+ <!-- قسم إعادة المراجعة: قائمة منسدلة لتحديد نوع المراجعة -->
225
+ <div id="reviewAgainSection" class="hidden bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 card-hover">
226
+ <h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-3 flex items-center">
227
+ <i class="fas fa-redo text-blue-600 ml-2"></i> إعادة المراجعة - اختيار النوع
228
+ </h2>
229
+ <div class="flex items-center space-x-4">
230
+ <select id="reviewType" class="px-4 py-2 border rounded-xl focus:outline-none">
231
+ <option value="all">جميع الاختلافات</option>
232
+ <option value="number">مراجعة رقمية فقط</option>
233
+ <option value="meaning">مراجعة المعنى فقط</option>
234
+ <option value="missing">مراجعة النص المفقود فقط</option>
235
+ </select>
236
+ <button id="confirmReviewBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-xl">تنفيذ إعادة المراجعة</button>
237
+ </div>
238
+ </div>
239
+
240
  </main>
241
  </div>
242
 
 
244
  جافا سكريبت: الوظائف والمعالجة
245
  ================================= -->
246
  <script>
247
+ // متغيرات لتخزين النصوص ونتيجة التحليل لإعادة المراجعة
248
+ let storedAnalysisOutput = "";
249
+ let storedSourceText = "";
250
+ let storedTargetText = "";
251
+
252
  // إعدادات API
253
  const API_URL = 'https://api.deepseek.com/chat/completions';
254
  const API_KEY = 'sk-15606736ed9e4aea8b7cc11a195d2b01';
255
 
256
+ const ANALYSIS_PROMPT = `أنت خبير لغوي متخصص في مراجعة الترجمة التقنية. مهمتك مقارنة النص المصدر والنص الهدف بدقة عالية مع العلم أن النصوص مليانة بالأخطاء والنواقص.
 
 
 
 
257
  لا تقم بإزالة أو تعديل العلامات التالية:
258
  • الأرقام: تحافظ على علامات < و >.
259
  • النصوص المفقودة: تحافظ على علامات __ و __.
 
270
  النص الهدف:
271
  {target}`;
272
 
273
+ // دوال مساعدة للتعامل مع النصوص
 
 
 
274
  function countWords(text) {
275
  return text.trim().split(/\s+/).filter(word => word !== "").length;
276
  }
 
277
  function escapeRegExp(string) {
278
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
279
  }
 
280
  function splitIntoLines(text) {
281
  return text.split('\n').map((line, i) => `<div class="line-item"><span class="line-number">${i+1}:</span> <span class="line-text">${line}</span></div>`).join('');
282
  }
 
283
  function getLineNumber(text, substring) {
284
  const index = text.indexOf(substring);
285
  if (index === -1) return "غير محدد";
286
  return text.substring(0, index).split("\n").length;
287
  }
288
 
289
+ // دوال التمييز (Highlighting)
 
 
290
  function applyHighlights(originalText, analysisOutput) {
291
  let highlightedText = originalText;
292
+ // اختلافات الأرقام
293
  const numberRegex = /<([^<>]+)>/g;
294
  let match;
295
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
 
300
  highlightedText = highlightedText.replace(phraseRegex, replacement);
301
  }
302
  }
303
+ // النصوص المفقودة
304
  const missingRegex = /__(.*?)__/g;
305
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
306
  const phrase = match[1].trim();
 
310
  highlightedText = highlightedText.replace(phraseRegex, replacement);
311
  }
312
  }
313
+ // اختلافات المعنى
314
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
315
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
316
  const phrase = match[1].trim();
 
323
  return highlightedText;
324
  }
325
 
326
+ // تطبيق التمييز بحسب نوع المراجعة
327
+ function applyHighlightsByType(originalText, analysisOutput, reviewType) {
328
+ let highlightedText = originalText;
329
+ if (reviewType === 'meaning') {
330
+ const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
331
+ let match;
332
+ while ((match = meaningRegex.exec(analysisOutput)) !== null) {
333
+ const phrase = match[1].trim();
334
+ if (phrase) {
335
+ const replacement = `<span class="highlight-meaning">${phrase}</span>`;
336
+ const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
337
+ highlightedText = highlightedText.replace(phraseRegex, replacement);
338
+ }
339
+ }
340
+ } else if (reviewType === 'number') {
341
+ const numberRegex = /<([^<>]+)>/g;
342
+ let match;
343
+ while ((match = numberRegex.exec(analysisOutput)) !== null) {
344
+ const phrase = match[1].trim();
345
+ if (phrase) {
346
+ const replacement = `<span class="highlight-number">${phrase}</span>`;
347
+ const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
348
+ highlightedText = highlightedText.replace(phraseRegex, replacement);
349
+ }
350
+ }
351
+ } else if (reviewType === 'missing') {
352
+ const missingRegex = /__(.*?)__/g;
353
+ let match;
354
+ while ((match = missingRegex.exec(analysisOutput)) !== null) {
355
+ const phrase = match[1].trim();
356
+ if (phrase) {
357
+ const replacement = `<span class="highlight-missing">__${phrase}__</span>`;
358
+ const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
359
+ highlightedText = highlightedText.replace(phraseRegex, replacement);
360
+ }
361
+ }
362
+ } else {
363
+ highlightedText = applyHighlights(originalText, analysisOutput);
364
+ }
365
+ return highlightedText;
366
+ }
367
+
368
+ // توليد الشرح التفصيلي
369
  function generateExplanation(sourceText, analysisOutput) {
370
  let steps = [];
 
371
  const missingRegex = /__(.*?)__/g;
372
  let match;
373
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
 
377
  steps.push(`<li><strong>الخطوة 1:</strong> في السطر ${lineNum}، الجزء "<span class="highlight-missing">__${phrase}__</span>" من النص المصدر مفقود في النص الهدف. تأكد من إضافته لتحسين الدقة.</li>`);
378
  }
379
  }
 
380
  const numberRegex = /<([^<>]+)>/g;
381
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
382
  const phrase = match[1].trim();
 
385
  steps.push(`<li><strong>الخطوة 2:</strong> في السطر ${lineNum}، الرقم "<span class="highlight-number">${phrase}</span>" في المصدر لا يتطابق مع الرقم في الهدف. يرجى المراجعة.</li>`);
386
  }
387
  }
 
388
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
389
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
390
  const phrase = match[1].trim();
 
393
  steps.push(`<li><strong>الخطوة 3:</strong> في السطر ${lineNum}، تم العثور على اختلاف في المعنى مع التعبير "<span class="highlight-meaning">${phrase}</span>". تحقق من الدقة.</li>`);
394
  }
395
  }
 
396
  if (steps.length === 0) {
397
  return `<p>النصوص متطابقة تماماً ولا توجد فروقات تحتاج للتنبيه.</p>`;
398
  }
399
  return `<ol class="list-decimal ml-6 space-y-2">${steps.join('')}</ol>`;
400
  }
401
 
402
+ // توليد الشرح بحسب نوع إعادة المراجعة
403
+ function generateExplanationByType(sourceText, analysisOutput, reviewType) {
404
+ let steps = [];
405
+ if (reviewType === 'meaning') {
406
+ const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
407
+ let match;
408
+ while ((match = meaningRegex.exec(analysisOutput)) !== null) {
409
+ const phrase = match[1].trim();
410
+ if (phrase) {
411
+ const lineNum = getLineNumber(sourceText, phrase);
412
+ steps.push(`<li><strong>مراجعة المعنى:</strong> في السطر ${lineNum}، التعبير "<span class="highlight-meaning">${phrase}</span>" يختلف. تحقق من الدقة.</li>`);
413
+ }
414
+ }
415
+ } else if (reviewType === 'number') {
416
+ const numberRegex = /<([^<>]+)>/g;
417
+ let match;
418
+ while ((match = numberRegex.exec(analysisOutput)) !== null) {
419
+ const phrase = match[1].trim();
420
+ if (phrase) {
421
+ const lineNum = getLineNumber(sourceText, phrase);
422
+ steps.push(`<li><strong>مراجعة رقمية:</strong> في السطر ${lineNum}، الرقم "<span class="highlight-number">${phrase}</span>" لا يتطابق. يرجى المراجعة.</li>`);
423
+ }
424
+ }
425
+ } else if (reviewType === 'missing') {
426
+ const missingRegex = /__(.*?)__/g;
427
+ let match;
428
+ while ((match = missingRegex.exec(analysisOutput)) !== null) {
429
+ const phrase = match[1].trim();
430
+ if (phrase) {
431
+ const lineNum = getLineNumber(sourceText, phrase);
432
+ steps.push(`<li><strong>مراجعة النص المفقود:</strong> في السطر ${lineNum}، النص "<span class="highlight-missing">__${phrase}__</span>" مفقود أو مختلف. يرجى المراجعة.</li>`);
433
+ }
434
+ }
435
+ } else {
436
+ return generateExplanation(sourceText, analysisOutput);
437
+ }
438
+ if (steps.length === 0) {
439
+ return `<p>لا توجد اختلافات من النوع المحدد.</p>`;
440
+ }
441
+ return `<ol class="list-decimal ml-6 space-y-2">${steps.join('')}</ol>`;
442
+ }
443
+
444
+ // دالة معالجة الملفات (PDF و DOCX)
445
  async function processFile(file) {
446
  let text = "";
447
  if (file.type === 'application/pdf') {
 
464
  return text;
465
  }
466
 
467
+ // رفع الملفات وإدخال النصوص
 
 
 
468
  document.getElementById('sourceFile')?.addEventListener('change', async (event) => {
469
  const file = event.target.files[0];
470
  if (!file) return;
 
479
  document.getElementById('processStatus').classList.add('hidden');
480
  }
481
  });
 
482
  document.getElementById('targetFile')?.addEventListener('change', async (event) => {
483
  const file = event.target.files[0];
484
  if (!file) return;
 
493
  document.getElementById('processStatus').classList.add('hidden');
494
  }
495
  });
 
496
  document.getElementById('sourceExtraFile')?.addEventListener('change', async (event) => {
497
  const file = event.target.files[0];
498
  if (!file) return;
 
508
  }
509
  });
510
 
511
+ // عرض الأخطاء والرسائل
 
 
512
  function addError(message, type = 'error') {
513
  const errorsList = document.getElementById('errorsList');
514
  if (!errorsList) return;
 
521
  errorsList.appendChild(errorDiv);
522
  }
523
 
524
+ // تنفيذ التحليل عند الضغط على زر التحليل
 
 
525
  document.getElementById('submitBtn').addEventListener('click', async () => {
526
  const sourceText = document.getElementById('sourceText').value;
527
  const targetText = document.getElementById('targetText').value;
 
528
  document.getElementById('errorsList').innerHTML = '';
529
  document.getElementById('resultSection').classList.remove('hidden');
530
  document.getElementById('explanationBox').classList.remove('hidden');
 
534
  return;
535
  }
536
 
 
537
  const sourceWordCount = countWords(sourceText);
538
  const targetWordCount = countWords(targetText);
539
  if (sourceWordCount !== targetWordCount) {
 
541
  }
542
 
543
  try {
 
544
  const progressDiv = document.createElement('div');
545
  progressDiv.className = "bg-indigo-100 p-4 rounded-xl mb-4";
546
  progressDiv.innerHTML = `<div class="flex items-center">
 
549
  </div>`;
550
  document.getElementById('errorsList').appendChild(progressDiv);
551
 
 
552
  const prompt = ANALYSIS_PROMPT
553
  .replace("{source}", sourceText)
554
  .replace("{target}", targetText);
555
 
 
556
  const payload = {
557
  model: "deepseek-chat",
558
  messages: [
 
578
  const analysisOutput = data.choices[0].message.content.trim();
579
  progressDiv.remove();
580
 
581
+ // تخزين النصوص والنتيجة لإعادة المراجعة
582
+ storedAnalysisOutput = analysisOutput;
583
+ storedSourceText = sourceText;
584
+ storedTargetText = targetText;
585
+
586
  if (analysisOutput.includes('[MATCH]')) {
587
  const checkDiv = document.createElement('div');
588
  checkDiv.className = "p-4 rounded-xl bg-green-50 text-green-700 flex items-center";
 
592
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
593
  document.getElementById('explanationText').innerHTML = `<p>النصوص متطابقة ولا يوجد اختلاف يجب الإشارة إليه.</p>`;
594
  } else {
 
595
  const sourceHighlighted = applyHighlights(sourceText, analysisOutput);
596
  const targetHighlighted = applyHighlights(targetText, analysisOutput);
597
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceHighlighted);
598
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetHighlighted);
 
599
  const explanationHTML = generateExplanation(sourceText, analysisOutput);
600
  document.getElementById('explanationText').innerHTML = explanationHTML;
601
 
 
602
  const numDiffCount = (analysisOutput.match(/<([^<>]+)>/g) || []).length;
603
  const missingDiffCount = (analysisOutput.match(/__(.*?)__/g) || []).length;
604
  const meaningDiffCount = (analysisOutput.match(/\[MEANING\](.*?)\[\/MEANING\]/g) || []).length;
 
619
  addError(`خطأ في التحليل: ${error.message}`);
620
  }
621
  });
622
+
623
+ // زر إعادة المراجعة: إخفاء النتائج القديمة وعرض قسم اختيار النوع
624
+ document.getElementById('reviewAgainBtn').addEventListener('click', () => {
625
+ document.getElementById('resultSection').classList.add('hidden');
626
+ document.getElementById('explanationBox').classList.add('hidden');
627
+ document.getElementById('errorsList').innerHTML = '';
628
+ document.getElementById('reviewAgainSection').classList.remove('hidden');
629
+ });
630
+
631
+ // تنفيذ إعادة المراجعة بناءً على النوع المحدد
632
+ document.getElementById('confirmReviewBtn').addEventListener('click', () => {
633
+ const reviewType = document.getElementById('reviewType').value;
634
+ const explanationHTML = generateExplanationByType(storedSourceText, storedAnalysisOutput, reviewType);
635
+ document.getElementById('explanationText').innerHTML = explanationHTML;
636
+ const sourceHighlighted = applyHighlightsByType(storedSourceText, storedAnalysisOutput, reviewType);
637
+ const targetHighlighted = applyHighlightsByType(storedTargetText, storedAnalysisOutput, reviewType);
638
+ document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceHighlighted);
639
+ document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetHighlighted);
640
+ document.getElementById('reviewAgainSection').classList.add('hidden');
641
+ document.getElementById('resultSection').classList.remove('hidden');
642
+ document.getElementById('explanationBox').classList.remove('hidden');
643
+ });
644
  </script>
645
  </body>
646
+ </html>