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

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +177 -186
index.html CHANGED
@@ -4,10 +4,14 @@
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>نظام المقارنة والترجمة الخاص بشركة موندو لينجوا</title>
 
7
  <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
8
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.6.0/mammoth.browser.min.js"></script>
9
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
10
  <style>
 
 
 
11
  @keyframes gradient {
12
  0% { background-position: 0% 50%; }
13
  50% { background-position: 100% 50%; }
@@ -20,37 +24,45 @@
20
  .transition-all { transition: all 0.3s ease-in-out; }
21
  .animate-scale { transition: transform 0.2s ease-in-out; }
22
  .animate-scale:hover { transform: scale(1.02); }
23
- .file-drop-active { border-color: #3B82F6; background-color: rgba(59,130,246,0.1); }
 
 
 
 
 
 
 
 
 
24
  .text-comparison { line-height: 1.8; white-space: pre-wrap; }
25
- /* تمييز اختلاف الأرقام */
26
  .highlight-number {
27
  background-color: #FDE68A;
28
- padding: 0 2px;
29
- border-radius: 2px;
 
30
  }
31
- /* تمييز النصوص الناقصة */
32
  .highlight-missing {
33
  background-color: #BFDBFE;
34
- padding: 0 2px;
35
- border-radius: 2px;
 
36
  }
37
- /* تمييز اختلاف المعنى */
38
  .highlight-meaning {
39
- color: #EF4444;
 
 
 
40
  font-weight: bold;
41
  }
42
- /* تقسيم شاشة المعاينة إلى جزئين */
 
 
 
43
  .split-view {
44
  display: grid;
45
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
46
  gap: 1rem;
47
  }
48
- .result-section {
49
- border-top: 3px solid #E0E7FF;
50
- margin-top: 2rem;
51
- padding-top: 2rem;
52
- }
53
- /* تنسيق كل سطر مع رقم السطر */
54
  .line-item {
55
  display: flex;
56
  align-items: flex-start;
@@ -62,123 +74,139 @@
62
  color: #4B5563;
63
  flex-shrink: 0;
64
  }
65
- .line-text {
66
- flex: 1;
67
- }
68
- /* تحسينات إضافية للواجهة */
 
69
  .card-hover {
70
  transition: all 0.3s ease;
71
  }
72
  .card-hover:hover {
73
- box-shadow: 0 10px 25px -5px rgba(59, 130, 246, 0.1), 0 10px 10px -5px rgba(59, 130, 246, 0.04);
74
  transform: translateY(-2px);
75
  }
76
- .pulse-animation {
77
- animation: pulse 2s infinite;
78
- }
79
- @keyframes pulse {
80
- 0% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0.4); }
81
- 70% { box-shadow: 0 0 0 10px rgba(59, 130, 246, 0); }
82
- 100% { box-shadow: 0 0 0 0 rgba(59, 130, 246, 0); }
83
- }
84
  </style>
85
  </head>
86
- <body class="bg-gradient-to-br from-gray-50 via-blue-50 to-indigo-50 min-h-screen">
87
  <div class="min-h-screen pb-12">
88
- <!-- Header -->
89
- <header class="bg-gradient-to-r from-blue-600 via-indigo-600 to-purple-600 animate-gradient text-white py-10 mb-10 shadow-xl">
90
  <div class="max-w-6xl mx-auto px-4">
91
  <h1 class="text-5xl font-bold text-center mb-4 animate-scale">نظام شركة موندو لينجوا</h1>
92
  <p class="text-center text-xl text-blue-100 opacity-90">مقارنة وتحليل النصوص – المصدر مرجع أساسي</p>
93
  </div>
94
  </header>
95
 
96
- <!-- Main Content -->
97
  <main class="max-w-6xl mx-auto px-4">
98
  <!-- قسم رفع الملفات -->
99
  <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 card-hover">
100
  <h2 class="text-2xl font-bold mb-6 text-gray-800 flex items-center border-b pb-3">
101
- <i class="fas fa-file-upload text-blue-600 ml-2"></i> تحميل الملفات
102
  </h2>
103
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
104
  <!-- ملف السورس -->
105
- <div class="group border-2 border-dashed border-blue-200 rounded-xl p-8 text-center hover:border-blue-500 transition-colors duration-300 bg-blue-50 hover:bg-blue-100">
106
  <label class="cursor-pointer block">
107
  <input type="file" id="sourceFile" accept=".docx,.pdf" class="hidden">
108
- <i class="fas fa-file-upload text-5xl text-blue-500 mb-4"></i>
109
- <span class="text-lg text-blue-600 group-hover:text-blue-700">ملف السورس</span>
110
  </label>
111
  </div>
112
  <!-- ملف التارجت -->
113
- <div class="group border-2 border-dashed border-purple-200 rounded-xl p-8 text-center hover:border-purple-500 transition-colors duration-300 bg-purple-50 hover:bg-purple-100">
114
  <label class="cursor-pointer block">
115
  <input type="file" id="targetFile" accept=".docx,.pdf" class="hidden">
116
- <i class="fas fa-file-download text-5xl text-purple-500 mb-4"></i>
117
- <span class="text-lg text-purple-600 group-hover:text-purple-700">ملف التارجت</span>
118
  </label>
119
  </div>
120
  </div>
121
  <div id="processStatus" class="hidden mt-4">
122
- <div class="flex items-center justify-center space-x-3 bg-blue-100 rounded-xl p-4">
123
- <div class="animate-spin h-8 w-8 border-4 border-blue-600 rounded-full border-t-transparent"></div>
124
- <span class="text-lg text-blue-700">جارٍ معالجة الملف...</span>
125
  </div>
126
  </div>
127
  </div>
128
 
129
- <!-- إدخال النصوص يدويًا -->
130
  <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 card-hover">
131
  <div class="space-y-6">
132
  <!-- النص المصدر -->
133
  <div class="group">
134
  <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
135
- <i class="fas fa-language text-blue-600 ml-2"></i> النص المصدر
136
  </label>
137
- <textarea id="sourceText" dir="rtl" class="w-full px-6 py-4 border-2 border-gray-200 rounded-xl focus:ring-blue-200 focus:border-blue-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب النص المصدر هنا..."></textarea>
138
  </div>
139
  <!-- النص الهدف -->
140
  <div class="group">
141
  <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
142
- <i class="fas fa-language text-purple-600 ml-2"></i> النص الهدف
143
  </label>
144
- <textarea id="targetText" dir="ltr" class="w-full px-6 py-4 border-2 border-gray-200 rounded-xl focus:ring-purple-200 focus:border-purple-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب النص الهدف هنا..."></textarea>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  </div>
146
  </div>
147
  </div>
148
 
149
  <!-- زر التحليل -->
150
- <button id="submitBtn" class="w-full bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 text-white font-bold py-5 px-8 rounded-xl transition-all transform hover:scale-105 focus:ring-blue-200 text-xl shadow-lg hover:shadow-xl mb-8 pulse-animation">
151
  <div class="flex items-center justify-center">
152
  <i class="fas fa-sync-alt ml-2"></i> تحليل النصوص
153
  </div>
154
  </button>
155
 
156
- <!-- شاشة نتائج التحليل (المعاينة المقسمة) -->
157
  <div id="resultSection" class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 hidden card-hover">
158
  <h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-3 flex items-center">
159
  <i class="fas fa-search text-green-600 ml-2"></i> نتائج التحليل والمقارنة
160
  </h2>
161
- <!-- هنا يتم عرض الأخطاء والاختلافات فقط -->
162
  <div id="errorsList" class="space-y-3 mb-6"></div>
163
  <div class="result-section split-view">
164
- <!-- عرض النص المصدر بعد التعليم مع تقسيمه إلى أسطر -->
165
  <div>
166
  <h4 class="text-lg font-bold text-gray-700 mb-3 flex items-center">
167
- <i class="fas fa-file-alt text-blue-600 ml-2"></i> النص المصدر (مع التعليم)
168
  </h4>
169
- <div id="sourceTextReview" class="bg-blue-50 rounded-xl p-6 min-h-[200px] border-2 border-blue-100 text-comparison"></div>
170
  </div>
171
- <!-- عرض النص الهدف بعد التعليم مع تقسيمه إلى أسطر -->
172
  <div>
173
  <h4 class="text-lg font-bold text-gray-700 mb-3 flex items-center">
174
- <i class="fas fa-file-alt text-purple-600 ml-2"></i> النص الهدف (مع التعليم)
175
  </h4>
176
  <div id="targetTextReview" class="bg-gray-50 rounded-xl p-6 min-h-[200px] border-2 border-gray-200 text-comparison"></div>
177
  </div>
178
  </div>
179
  </div>
180
 
181
- <!-- صندوق شرح الاختلافات -->
182
  <div id="explanationBox" class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 hidden card-hover">
183
  <h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-3 flex items-center">
184
  <i class="fas fa-info-circle text-green-600 ml-2"></i> شرح الاختلافات
@@ -188,100 +216,60 @@
188
  </main>
189
  </div>
190
 
191
- <!-- JavaScript -->
 
 
192
  <script>
193
- // API URL ومفتاح API (تم التحديث لاستخدام DeepSeek API)
194
  const API_URL = 'https://api.deepseek.com/chat/completions';
195
  const API_KEY = 'sk-15606736ed9e4aea8b7cc11a195d2b01';
196
 
197
  /*
198
- الـ prompt المحسن:
199
- أنت خبير في تحليل النصوص ومقارنتها. قم بمقارنة النص المصدر والنص الهدف بدقة عالية واكتشف الاختلافات التالية فقط:
200
-
201
- 1. اختلافات الأرقام: ضع الرقم المختلف بين علامتي "<" و ">"
202
- 2. النصوص المفقودة: إذا كان هناك نص موجود في المصدر ومفقود في الهدف، ضع النص المفقود بين "__" و "__"
203
- 3. اختلافات المعنى: إذا كانت هناك كلمة أو عبارة تختلف في المعنى، ضعها بين [MEANING] و [/MEANING]
204
-
205
- إذا كانت النصوص متطابقة تماماً، اكتب [MATCH] فقط. تأكد اكثر من مرة من التطابق اذا كان كامل
206
-
207
- اعتبر النص المصدر هو المرجع الأساسي للمقارنة.
208
- اولا راجع الارقام اولا ثم اجعل في الناتج النهائي جزء خاص بالارقام فقط و ثانيا : راجع السياق والمعنى العام والاجمالي للنصوص لمعرفة اذا وجد نقص او نسيان لجملة معينة او عدم ترجمتها
209
- ثم راجع المحتوى كاملا وانا ارد في الشرح ان تقوم بتقسيمه الى ثلاث عناوين اول عنوان وهو ناتج مراجعة الارقام وثانيا ناتج مراجعة النصوص في السياق وثالثا المحتوى كاملا
210
- النص المصدر:
211
- {source}
212
-
213
- النص الهدف:
214
- {target}
215
-
216
- أخرج فقط الاختلافات المحددة بالعلامات المذكورة أعلاه، دون أي شرح إضافي.
217
  */
218
- const ANALYSIS_PROMPT = `أنت خبير لغوي متخصص في مراجعة الترجمة التقنية ، مهمتك مقارنة النص المصدر والنص الهدف بدقة ميكروسكوبية، وتحديد فقط الاختلافات التالية باستخدام التنسيقات المحددة. لا تفترض أن النص الهدف صحيح إلا إذا تطابق حرفيًّا مع المصدر.
219
-
220
- أنواع الاختلافات:
221
- اختلافات الأرقام :
222
- قارن جميع الأرقام (عادية، عشرية، نسب مئوية، تواريخ، أرقام مكتوبة بالكلمات).
223
- سجل الاختلافات بين علامتي < و > مع إظهار القيمة في المصدر والهدف مفصولة بسهم (→).
224
- تجاهل اختلافات التنسيق (مثل الفواصل) إلا إذا غيرت القيمة.
225
- النصوص المفقودة :
226
- استخرج أي جزء موجود في المصدر ومخالف أو مفقود في الهدف (جمل، أجزاء جمل، كلمات فنية).
227
- ضع النص المفقود بين شرطتين سفليتين __...__ كما ورد حرفيًّا في المصدر.
228
- اختلافات المعنى :
229
- ركز على الاختلافات التي تؤثر على الدقة الفنية، السياق، أو المنطق.
230
- ضع النصين المختلفين بين علامتي [MEANING]...[/MEANING] مع توضيح النسخة المصدر والهدف.
231
- آلية المراجعة:
232
- مسح الأرقام :
233
- افحص كل رقم في النصين وقارنه زوجيًّا، حتى لو اختلفت صيغة كتابته (مثال: <2023> → <٢٠٢٤>).
234
- التحليل السياقي :
235
- قسم النصين إلى وحدات متناسقة وقارنها جانبًا إلى جانب.
236
- استخدم "الظل السياقي" لتحديد الأجزاء المفقودة أو المضافة.
237
- التحقق الدلالي :
238
- حلل كل كلمة/عبارة في السياق الأوسع:
239
- الدقة الفنية (مثال: "الواجهة الخلفية" vs "الواجهة الأمامية").
240
- التناقضات المنطقية (مثال: "يُسمح" vs "ممنوع").
241
- تجاهل المرادفات غير المؤثرة (مثل: "بدأ" vs "انطلق").
242
- المراجعة التكرارية :
243
- افحص النص 7 مرات بتركيز مختلف في كل مرة:
244
- الأرقام.
245
- النصوص المفقودة.
246
- التغييرات الدلالية.
247
- التناقضات المنطقية.
248
- الأخطاء الإملائية.
249
- التنسيق.
250
- الإضافات غير المرتبطة.
251
- هيكلة النتائج:
252
- 🟢 1. ناتج الأرقام :
253
- <القيمة_في_المصدر> → <القيمة_في_الهدف>
254
-
255
- 🟢 2. ناتج النصوص :
256
-
257
- النصوص المفقودة :
258
- __"النص_الحرفي_من_المصدر"__
259
- الاختلافات الدلالية :
260
- [MEANING]الكلمة_في_المصدر[/MEANING] → [MEANING]الكلمة_في_الهدف[/MEANING]
261
- 🟢 3. المحتوى المُظَلَّل :
262
-
263
- أظهر الاختلافات في سياق النص الهدف مع الإشارات:
264
- ❌: نص مفقود.
265
- ↔: اختلاف دلالي.
266
- 🔢: اختلاف رقم.
267
 
 
 
 
 
 
268
  النص المصدر:
269
  {source}
270
-
271
  النص الهدف:
272
  {target}`;
273
 
274
- // دالة لحساب عدد الكلمات
 
 
 
275
  function countWords(text) {
276
  return text.trim().split(/\s+/).filter(word => word !== "").length;
277
  }
278
-
279
- // دالة لمساعدة في الهروب من أحرف regex الخاصة
280
  function escapeRegExp(string) {
281
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
282
  }
 
 
 
 
 
 
 
 
 
 
283
 
284
- // دالة تطبيق التمييز على النص باستخدام العلامات في نتيجة التحليل
 
 
285
  function applyHighlights(originalText, analysisOutput) {
286
  let highlightedText = originalText;
287
  // تمييز اختلافات الأرقام
@@ -295,7 +283,7 @@ __"النص_الحرفي_من_المصدر"__
295
  highlightedText = highlightedText.replace(phraseRegex, replacement);
296
  }
297
  }
298
- // تمييز النصوص الناقصة
299
  const missingRegex = /__(.*?)__/g;
300
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
301
  const phrase = match[1].trim();
@@ -305,7 +293,7 @@ __"النص_الحرفي_من_المصدر"__
305
  highlightedText = highlightedText.replace(phraseRegex, replacement);
306
  }
307
  }
308
- // تمييز اختلاف المعنى
309
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
310
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
311
  const phrase = match[1].trim();
@@ -318,61 +306,50 @@ __"النص_الحرفي_من_المصدر"__
318
  return highlightedText;
319
  }
320
 
321
- // دالة تقسيم النص إلى أسطر مع عرض رقم السطر
322
- function splitIntoLines(text) {
323
- const lines = text.split('\n');
324
- let html = "";
325
- lines.forEach((line, index) => {
326
- html += `<div class="line-item"><span class="line-number">${index + 1}:</span> <span class="line-text">${line}</span></div>`;
327
- });
328
- return html;
329
- }
330
-
331
- // دالة للحصول على رقم السطر لظهور عبارة معينة في النص
332
- function getLineNumber(text, substring) {
333
- const index = text.indexOf(substring);
334
- if (index === -1) return "غير محدد";
335
- return text.substring(0, index).split("\n").length;
336
- }
337
-
338
- // دالة توليد شرح الاختلافات
339
  function generateExplanation(sourceText, analysisOutput) {
340
- let explanation = "";
341
- // شرح النصوص الناقصة
342
  const missingRegex = /__(.*?)__/g;
343
  let match;
344
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
345
  const phrase = match[1].trim();
346
  if (phrase) {
347
  const lineNum = getLineNumber(sourceText, phrase);
348
- explanation += `<p>في السطر ${lineNum}: النص "${phrase}" مفقود في النص الهدف.</p>`;
349
  }
350
  }
351
- // شرح اختلاف الأرقام
352
  const numberRegex = /<([^<>]+)>/g;
353
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
354
  const phrase = match[1].trim();
355
  if (phrase) {
356
  const lineNum = getLineNumber(sourceText, phrase);
357
- explanation += `<p>في السطر ${lineNum}: اختلاف في الرقم "${phrase}".</p>`;
358
  }
359
  }
360
- // شرح اختلاف المعنى
361
  const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
362
  while ((match = meaningRegex.exec(analysisOutput)) !== null) {
363
  const phrase = match[1].trim();
364
  if (phrase) {
365
  const lineNum = getLineNumber(sourceText, phrase);
366
- explanation += `<p>في السطر ${lineNum}: اختلاف في المعنى: "${phrase}".</p>`;
367
  }
368
  }
369
- if (explanation === "") {
370
- explanation = `<p>[MATCH] النصوص متطابقة تماماً.</p>`;
 
371
  }
372
- return explanation;
373
  }
374
 
375
- // دالة موحدة لمعالجة الملفات (PDF و DOCX)
 
 
376
  async function processFile(file) {
377
  let text = "";
378
  if (file.type === 'application/pdf') {
@@ -395,6 +372,9 @@ __"النص_الحرفي_من_المصدر"__
395
  return text;
396
  }
397
 
 
 
 
398
  // رفع ملف السورس
399
  document.getElementById('sourceFile')?.addEventListener('change', async (event) => {
400
  const file = event.target.files[0];
@@ -410,7 +390,6 @@ __"النص_الحرفي_من_المصدر"__
410
  document.getElementById('processStatus').classList.add('hidden');
411
  }
412
  });
413
-
414
  // رفع ملف التارجت
415
  document.getElementById('targetFile')?.addEventListener('change', async (event) => {
416
  const file = event.target.files[0];
@@ -426,8 +405,25 @@ __"النص_الحرفي_من_المصدر"__
426
  document.getElementById('processStatus').classList.add('hidden');
427
  }
428
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429
 
430
- // دالة عرض الأخطاء أو الرسائل
 
 
431
  function addError(message, type = 'error') {
432
  const errorsList = document.getElementById('errorsList');
433
  if (!errorsList) return;
@@ -440,12 +436,13 @@ __"النص_الحرفي_من_المصدر"__
440
  errorsList.appendChild(errorDiv);
441
  }
442
 
443
- // عند الضغط على زر التحليل
 
 
444
  document.getElementById('submitBtn').addEventListener('click', async () => {
445
  const sourceText = document.getElementById('sourceText').value;
446
  const targetText = document.getElementById('targetText').value;
447
-
448
- // مسح الرسائل السابقة وإظهار قسم النتائج
449
  document.getElementById('errorsList').innerHTML = '';
450
  document.getElementById('resultSection').classList.remove('hidden');
451
  document.getElementById('explanationBox').classList.remove('hidden');
@@ -455,7 +452,7 @@ __"النص_الحرفي_من_المصدر"__
455
  return;
456
  }
457
 
458
- // مقارنة عدد الكلمات (تنبيه اختياري)
459
  const sourceWordCount = countWords(sourceText);
460
  const targetWordCount = countWords(targetText);
461
  if (sourceWordCount !== targetWordCount) {
@@ -463,21 +460,21 @@ __"النص_الحرفي_من_المصدر"__
463
  }
464
 
465
  try {
466
- // عرض مؤشر التقدم أثناء انتظار الرد
467
  const progressDiv = document.createElement('div');
468
- progressDiv.className = "bg-blue-100 p-4 rounded-xl mb-4";
469
  progressDiv.innerHTML = `<div class="flex items-center">
470
- <div class="animate-spin h-6 w-6 border-4 border-blue-600 rounded-full border-t-transparent ml-3"></div>
471
  <span>جارٍ التحليل...</span>
472
  </div>`;
473
  document.getElementById('errorsList').appendChild(progressDiv);
474
 
475
- // بناء prompt باستخدام النصين المُدخلين
476
  const prompt = ANALYSIS_PROMPT
477
  .replace("{source}", sourceText)
478
  .replace("{target}", targetText);
479
 
480
- // استخدام DeepSeek API
481
  const payload = {
482
  model: "deepseek-chat",
483
  messages: [
@@ -488,8 +485,6 @@ __"النص_الحرفي_من_المصدر"__
488
  max_tokens: 2048,
489
  stream: false
490
  };
491
-
492
- // استدعاء API التحليل
493
  const response = await fetch(API_URL, {
494
  method: 'POST',
495
  headers: {
@@ -498,16 +493,14 @@ __"النص_الحرفي_من_المصدر"__
498
  },
499
  body: JSON.stringify(payload)
500
  });
501
-
502
  if (!response.ok) {
503
  throw new Error('حدث خطأ بالشبكة: ' + response.statusText);
504
  }
505
-
506
  const data = await response.json();
507
  const analysisOutput = data.choices[0].message.content.trim();
508
-
509
  progressDiv.remove();
510
 
 
511
  if (analysisOutput.includes('[MATCH]')) {
512
  const checkDiv = document.createElement('div');
513
  checkDiv.className = "p-4 rounded-xl bg-green-50 text-green-700 flex items-center";
@@ -515,19 +508,18 @@ __"النص_الحرفي_من_المصدر"__
515
  document.getElementById('errorsList').appendChild(checkDiv);
516
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceText);
517
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
518
- document.getElementById('explanationText').innerHTML = `<p>[MATCH] لا توجد اختلافات.</p>`;
519
  } else {
 
520
  const sourceHighlighted = applyHighlights(sourceText, analysisOutput);
521
  const targetHighlighted = applyHighlights(targetText, analysisOutput);
522
- // تقسيم النصوص المُظّلّة إلى أسطر مع رقم السطر
523
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceHighlighted);
524
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetHighlighted);
525
-
526
- // توليد شرح الاختلافات
527
  const explanationHTML = generateExplanation(sourceText, analysisOutput);
528
  document.getElementById('explanationText').innerHTML = explanationHTML;
529
 
530
- // عرض ملخص الاختلافات إن وُجدت
531
  const numDiffCount = (analysisOutput.match(/<([^<>]+)>/g) || []).length;
532
  const missingDiffCount = (analysisOutput.match(/__(.*?)__/g) || []).length;
533
  const meaningDiffCount = (analysisOutput.match(/\[MEANING\](.*?)\[\/MEANING\]/g) || []).length;
@@ -536,14 +528,13 @@ __"النص_الحرفي_من_المصدر"__
536
  summaryDiv.className = "p-4 rounded-xl bg-yellow-50 text-gray-800";
537
  let summaryText = '<div class="font-bold mb-2">ملخص الاختلافات:</div><ul class="list-disc mr-6 space-y-1">';
538
  if (numDiffCount > 0) summaryText += `<li>اختلاف في الأرقام: ${numDiffCount}</li>`;
539
- if (missingDiffCount > 0) summaryText += `<li>نصوص مفقودة: ${missingDiffCount}</li>`;
540
  if (meaningDiffCount > 0) summaryText += `<li>اختلاف في المعنى: ${meaningDiffCount}</li>`;
541
  summaryText += '</ul>';
542
  summaryDiv.innerHTML = summaryText;
543
  document.getElementById('errorsList').appendChild(summaryDiv);
544
  }
545
  }
546
-
547
  } catch (error) {
548
  document.getElementById('errorsList').innerHTML = '';
549
  addError(`خطأ في التحليل: ${error.message}`);
 
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>نظام المقارنة والترجمة الخاص بشركة موندو لينجوا</title>
7
+ <!-- استيراد مكتبات Tailwind وFont Awesome وMammoth -->
8
  <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.6.0/mammoth.browser.min.js"></script>
10
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
11
  <style>
12
+ /* ================================
13
+ تنسيقات الحركات والتأثيرات
14
+ ================================= */
15
  @keyframes gradient {
16
  0% { background-position: 0% 50%; }
17
  50% { background-position: 100% 50%; }
 
24
  .transition-all { transition: all 0.3s ease-in-out; }
25
  .animate-scale { transition: transform 0.2s ease-in-out; }
26
  .animate-scale:hover { transform: scale(1.02); }
27
+ .pulse-animation { animation: pulse 2s infinite; }
28
+ @keyframes pulse {
29
+ 0% { box-shadow: 0 0 0 0 rgba(156,39,176,0.4); }
30
+ 70% { box-shadow: 0 0 0 10px rgba(156,39,176,0); }
31
+ 100% { box-shadow: 0 0 0 0 rgba(156,39,176,0); }
32
+ }
33
+
34
+ /* ================================
35
+ تنسيقات النصوص والتحديد
36
+ ================================= */
37
  .text-comparison { line-height: 1.8; white-space: pre-wrap; }
 
38
  .highlight-number {
39
  background-color: #FDE68A;
40
+ padding: 0 4px;
41
+ border-radius: 3px;
42
+ font-weight: bold;
43
  }
 
44
  .highlight-missing {
45
  background-color: #BFDBFE;
46
+ padding: 0 4px;
47
+ border-radius: 3px;
48
+ font-style: italic;
49
  }
 
50
  .highlight-meaning {
51
+ background-color: #fecaca;
52
+ color: #B91C1C;
53
+ padding: 0 4px;
54
+ border-radius: 3px;
55
  font-weight: bold;
56
  }
57
+
58
+ /* ================================
59
+ تنسيق عرض السطور في المعاينة
60
+ ================================= */
61
  .split-view {
62
  display: grid;
63
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
64
  gap: 1rem;
65
  }
 
 
 
 
 
 
66
  .line-item {
67
  display: flex;
68
  align-items: flex-start;
 
74
  color: #4B5563;
75
  flex-shrink: 0;
76
  }
77
+ .line-text { flex: 1; }
78
+
79
+ /* ================================
80
+ تحسين تنسيق البطاقات والعناصر
81
+ ================================= */
82
  .card-hover {
83
  transition: all 0.3s ease;
84
  }
85
  .card-hover:hover {
86
+ box-shadow: 0 10px 25px -5px rgba(156,39,176,0.1), 0 10px 10px -5px rgba(156,39,176,0.04);
87
  transform: translateY(-2px);
88
  }
 
 
 
 
 
 
 
 
89
  </style>
90
  </head>
91
+ <body class="bg-gradient-to-br from-gray-100 via-blue-100 to-indigo-100 min-h-screen">
92
  <div class="min-h-screen pb-12">
93
+ <!-- ============ رأس الصفحة ============ -->
94
+ <header class="bg-gradient-to-r from-indigo-700 via-purple-700 to-pink-700 animate-gradient text-white py-10 mb-10 shadow-xl">
95
  <div class="max-w-6xl mx-auto px-4">
96
  <h1 class="text-5xl font-bold text-center mb-4 animate-scale">نظام شركة موندو لينجوا</h1>
97
  <p class="text-center text-xl text-blue-100 opacity-90">مقارنة وتحليل النصوص – المصدر مرجع أساسي</p>
98
  </div>
99
  </header>
100
 
101
+ <!-- ============ المحتوى الرئيسي ============ -->
102
  <main class="max-w-6xl mx-auto px-4">
103
  <!-- قسم رفع الملفات -->
104
  <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 card-hover">
105
  <h2 class="text-2xl font-bold mb-6 text-gray-800 flex items-center border-b pb-3">
106
+ <i class="fas fa-file-upload text-indigo-600 ml-2"></i> تحميل الملفات
107
  </h2>
108
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
109
  <!-- ملف السورس -->
110
+ <div class="group border-2 border-dashed border-indigo-300 rounded-xl p-8 text-center hover:border-indigo-500 transition-colors duration-300 bg-indigo-50 hover:bg-indigo-100">
111
  <label class="cursor-pointer block">
112
  <input type="file" id="sourceFile" accept=".docx,.pdf" class="hidden">
113
+ <i class="fas fa-file-upload text-5xl text-indigo-500 mb-4"></i>
114
+ <span class="text-lg text-indigo-600 group-hover:text-indigo-700">ملف السورس</span>
115
  </label>
116
  </div>
117
  <!-- ملف التارجت -->
118
+ <div class="group border-2 border-dashed border-pink-300 rounded-xl p-8 text-center hover:border-pink-500 transition-colors duration-300 bg-pink-50 hover:bg-pink-100">
119
  <label class="cursor-pointer block">
120
  <input type="file" id="targetFile" accept=".docx,.pdf" class="hidden">
121
+ <i class="fas fa-file-download text-5xl text-pink-500 mb-4"></i>
122
+ <span class="text-lg text-pink-600 group-hover:text-pink-700">ملف التارجت</span>
123
  </label>
124
  </div>
125
  </div>
126
  <div id="processStatus" class="hidden mt-4">
127
+ <div class="flex items-center justify-center space-x-3 bg-indigo-100 rounded-xl p-4">
128
+ <div class="animate-spin h-8 w-8 border-4 border-indigo-600 rounded-full border-t-transparent"></div>
129
+ <span class="text-lg text-indigo-700">جارٍ معالجة الملف...</span>
130
  </div>
131
  </div>
132
  </div>
133
 
134
+ <!-- قسم إدخال النصوص يدويًا -->
135
  <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 card-hover">
136
  <div class="space-y-6">
137
  <!-- النص المصدر -->
138
  <div class="group">
139
  <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
140
+ <i class="fas fa-language text-indigo-600 ml-2"></i> النص المصدر
141
  </label>
142
+ <textarea id="sourceText" dir="rtl" class="w-full px-6 py-4 border-2 border-gray-200 rounded-xl focus:ring-indigo-200 focus:border-indigo-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب النص المصدر هنا..."></textarea>
143
  </div>
144
  <!-- النص الهدف -->
145
  <div class="group">
146
  <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
147
+ <i class="fas fa-language text-pink-600 ml-2"></i> النص الهدف
148
  </label>
149
+ <textarea id="targetText" dir="ltr" class="w-full px-6 py-4 border-2 border-gray-200 rounded-xl focus:ring-pink-200 focus:border-pink-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب النص الهدف هنا..."></textarea>
150
+ </div>
151
+ </div>
152
+ </div>
153
+
154
+ <!-- قسم المصادر الإضافية -->
155
+ <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 card-hover">
156
+ <h2 class="text-2xl font-bold mb-6 text-gray-800 flex items-center border-b pb-3">
157
+ <i class="fas fa-book-open text-green-600 ml-2"></i> مصادر إضافية
158
+ </h2>
159
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
160
+ <!-- رفع ملف المصادر الإضافية -->
161
+ <div class="group border-2 border-dashed border-green-300 rounded-xl p-8 text-center hover:border-green-500 transition-colors duration-300 bg-green-50 hover:bg-green-100">
162
+ <label class="cursor-pointer block">
163
+ <input type="file" id="sourceExtraFile" accept=".docx,.pdf" class="hidden">
164
+ <i class="fas fa-upload text-5xl text-green-500 mb-4"></i>
165
+ <span class="text-lg text-green-600 group-hover:text-green-700">تحميل ملف المصدر</span>
166
+ </label>
167
+ </div>
168
+ <!-- إدخال المصادر يدويًا -->
169
+ <div class="group">
170
+ <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
171
+ <i class="fas fa-edit text-green-600 ml-2"></i> إدخال المصادر يدويًا
172
+ </label>
173
+ <textarea id="sourceExtraText" dir="rtl" class="w-full px-6 py-4 border-2 border-green-200 rounded-xl focus:ring-green-200 focus:border-green-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب المصادر هنا..."></textarea>
174
  </div>
175
  </div>
176
  </div>
177
 
178
  <!-- زر التحليل -->
179
+ <button id="submitBtn" class="w-full bg-gradient-to-r from-indigo-600 to-pink-600 hover:from-indigo-700 hover:to-pink-700 text-white font-bold py-5 px-8 rounded-xl transition-all transform hover:scale-105 focus:ring-indigo-200 text-xl shadow-lg hover:shadow-xl mb-8 pulse-animation">
180
  <div class="flex items-center justify-center">
181
  <i class="fas fa-sync-alt ml-2"></i> تحليل النصوص
182
  </div>
183
  </button>
184
 
185
+ <!-- شاشة عرض نتائج التحليل -->
186
  <div id="resultSection" class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 hidden card-hover">
187
  <h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-3 flex items-center">
188
  <i class="fas fa-search text-green-600 ml-2"></i> نتائج التحليل والمقارنة
189
  </h2>
 
190
  <div id="errorsList" class="space-y-3 mb-6"></div>
191
  <div class="result-section split-view">
192
+ <!-- عرض النص المصدر بعد التحديد مع ترقيم السطور -->
193
  <div>
194
  <h4 class="text-lg font-bold text-gray-700 mb-3 flex items-center">
195
+ <i class="fas fa-file-alt text-indigo-600 ml-2"></i> النص المصدر (مع التعليم)
196
  </h4>
197
+ <div id="sourceTextReview" class="bg-indigo-50 rounded-xl p-6 min-h-[200px] border-2 border-indigo-100 text-comparison"></div>
198
  </div>
199
+ <!-- عرض النص الهدف بعد التحديد مع ترقيم السطور -->
200
  <div>
201
  <h4 class="text-lg font-bold text-gray-700 mb-3 flex items-center">
202
+ <i class="fas fa-file-alt text-pink-600 ml-2"></i> النص الهدف (مع التعليم)
203
  </h4>
204
  <div id="targetTextReview" class="bg-gray-50 rounded-xl p-6 min-h-[200px] border-2 border-gray-200 text-comparison"></div>
205
  </div>
206
  </div>
207
  </div>
208
 
209
+ <!-- صندوق عرض الشرح التفصيلي للنتائج -->
210
  <div id="explanationBox" class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale mb-8 hidden card-hover">
211
  <h2 class="text-2xl font-bold mb-6 text-gray-800 border-b pb-3 flex items-center">
212
  <i class="fas fa-info-circle text-green-600 ml-2"></i> شرح الاختلافات
 
216
  </main>
217
  </div>
218
 
219
+ <!-- ================================
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
+ النصوص المفقودة: تحافظ على علامات __ و __.
235
+ اختلافات المعنى: تحافظ على علامات [MEANING] و [/MEANING].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
+ اعتمد النص المصدر كأساس للمقارنة، وقم بتحديد:
238
+ 1. اختلافات الأرقام باستخدام <الرقم_في_المصدر> → <الرقم_في_الهدف>.
239
+ 2. النصوص المفقودة كما هي بين علامتي __.
240
+ 3. اختلافات المعنى باستخدام [MEANING] مع الحفاظ على التعليم.
241
+
242
  النص المصدر:
243
  {source}
244
+
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
  // تمييز اختلافات الأرقام
 
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
  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
  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) {
319
  const phrase = match[1].trim();
320
  if (phrase) {
321
  const lineNum = getLineNumber(sourceText, phrase);
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();
329
  if (phrase) {
330
  const lineNum = getLineNumber(sourceText, phrase);
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();
338
  if (phrase) {
339
  const lineNum = getLineNumber(sourceText, phrase);
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
  return text;
373
  }
374
 
375
+ /* =====================================
376
+ دوال رفع الملفات وإدخال النصوص
377
+ ===================================== */
378
  // رفع ملف السورس
379
  document.getElementById('sourceFile')?.addEventListener('change', async (event) => {
380
  const file = event.target.files[0];
 
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];
 
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;
412
+ document.getElementById('processStatus').classList.remove('hidden');
413
+ try {
414
+ const text = await processFile(file);
415
+ document.getElementById('sourceExtraText').value = text;
416
+ } catch (error) {
417
+ console.error('Error processing extra source file:', error);
418
+ addError('خطأ في معالجة ملف المصدر الإضافي');
419
+ } finally {
420
+ document.getElementById('processStatus').classList.add('hidden');
421
+ }
422
+ });
423
 
424
+ /* =====================================
425
+ دالة عرض الأخطاء والرسائل
426
+ ===================================== */
427
  function addError(message, type = 'error') {
428
  const errorsList = document.getElementById('errorsList');
429
  if (!errorsList) return;
 
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
  return;
453
  }
454
 
455
+ // مقارنة عدد الكلمات وتنبيه إن وجد اختلاف
456
  const sourceWordCount = countWords(sourceText);
457
  const targetWordCount = countWords(targetText);
458
  if (sourceWordCount !== targetWordCount) {
 
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">
467
+ <div class="animate-spin h-6 w-6 border-4 border-indigo-600 rounded-full border-t-transparent ml-3"></div>
468
  <span>جارٍ التحليل...</span>
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: [
 
485
  max_tokens: 2048,
486
  stream: false
487
  };
 
 
488
  const response = await fetch(API_URL, {
489
  method: 'POST',
490
  headers: {
 
493
  },
494
  body: JSON.stringify(payload)
495
  });
 
496
  if (!response.ok) {
497
  throw new Error('حدث خطأ بالشبكة: ' + response.statusText);
498
  }
 
499
  const data = await response.json();
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";
 
508
  document.getElementById('errorsList').appendChild(checkDiv);
509
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceText);
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;
 
528
  summaryDiv.className = "p-4 rounded-xl bg-yellow-50 text-gray-800";
529
  let summaryText = '<div class="font-bold mb-2">ملخص الاختلافات:</div><ul class="list-disc mr-6 space-y-1">';
530
  if (numDiffCount > 0) summaryText += `<li>اختلاف في الأرقام: ${numDiffCount}</li>`;
531
+ if (missingDiffCount > 0) summaryText += `<li>النصوص المفقودة: ${missingDiffCount}</li>`;
532
  if (meaningDiffCount > 0) summaryText += `<li>اختلاف في المعنى: ${meaningDiffCount}</li>`;
533
  summaryText += '</ul>';
534
  summaryDiv.innerHTML = summaryText;
535
  document.getElementById('errorsList').appendChild(summaryDiv);
536
  }
537
  }
 
538
  } catch (error) {
539
  document.getElementById('errorsList').innerHTML = '';
540
  addError(`خطأ في التحليل: ${error.message}`);