joermd commited on
Commit
27d42c0
·
verified ·
1 Parent(s): c6156df

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +301 -223
index.html CHANGED
@@ -3,13 +3,15 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>منصة مراجعة النصوص والترجمات المتقدمة</title>
7
- <!-- تضمين Tailwind CSS وFont Awesome وMammoth لتحليل ملفات DOCX -->
8
  <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
9
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
10
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mammoth/1.6.0/mammoth.browser.min.js"></script>
 
 
 
11
  <style>
12
- /* تأثير تدرج الخلفية */
13
  @keyframes gradient {
14
  0% { background-position: 0% 50%; }
15
  50% { background-position: 100% 50%; }
@@ -19,265 +21,294 @@
19
  background-size: 200% 200%;
20
  animation: gradient 15s ease infinite;
21
  }
22
- /* تأثيرات عامة */
23
  .transition-all { transition: all 0.3s ease-in-out; }
24
- .hover-scale:hover { transform: scale(1.02); }
 
25
  .pulse-animation { animation: pulse 2s infinite; }
26
  @keyframes pulse {
27
  0% { box-shadow: 0 0 0 0 rgba(0,0,0,0.2); }
28
  70% { box-shadow: 0 0 0 10px rgba(0,0,0,0); }
29
  100% { box-shadow: 0 0 0 0 rgba(0,0,0,0); }
30
  }
31
- /* تظليل النصوص */
 
32
  .text-comparison { line-height: 1.8; white-space: pre-wrap; }
33
  .highlight-missing {
34
- background-color: #e3342f; /* أحمر غامق */
35
  color: #fff;
36
  padding: 0 4px;
37
  border-radius: 3px;
38
  font-weight: bold;
39
  }
40
  .highlight-number {
41
- background-color: #ffed4a; /* أصفر */
42
  color: #000;
43
  padding: 0 4px;
44
  border-radius: 3px;
45
  font-weight: bold;
46
  }
47
- .highlight-meaning {
48
- background-color: #3490dc; /* أزرق فاتح */
49
  color: #fff;
50
  padding: 0 4px;
51
  border-radius: 3px;
52
  font-weight: bold;
53
  }
54
- /* تصميم الفقرات والترقيم */
 
55
  .line-item {
56
  margin-bottom: 1rem;
57
  padding: 0.5rem;
58
- border-bottom: 1px dashed #ddd;
59
  }
60
  .line-number {
61
  font-weight: bold;
62
- color: #2d3748;
63
  margin-left: 0.5rem;
64
  }
 
 
65
  /* تصميم البطاقات */
66
  .card {
67
- background-color: #ffffff;
68
  border-radius: 1rem;
69
- box-shadow: 0 8px 20px -4px rgba(0, 0, 0, 0.1);
70
  padding: 2rem;
71
- border: 1px solid #f1f5f9;
72
  }
73
- .card:hover { box-shadow: 0 8px 20px -4px rgba(0, 0, 0, 0.15); }
74
- /* تخصيص رفع الملفات: الأيقونات على اليمين */
75
- .file-upload-label {
 
 
 
76
  display: flex;
77
- justify-content: space-between;
78
  align-items: center;
79
- }
80
- /* تبويبات العرض (المعاينة والشرح) */
81
- .tab {
82
- cursor: pointer;
83
- padding: 0.5rem 1rem;
84
- border-bottom: 2px solid transparent;
85
- }
86
- .tab-active {
87
- border-bottom-color: #4F46E5;
88
- font-weight: bold;
89
  }
90
  </style>
91
  </head>
92
- <body class="bg-gradient-to-br from-blue-100 via-purple-100 to-pink-100 min-h-screen">
93
  <div class="min-h-screen pb-12">
94
- <!-- الرأس -->
95
- <header class="bg-gradient-to-r from-blue-800 via-purple-800 to-pink-800 animate-gradient text-white py-10 shadow-2xl">
96
  <div class="max-w-6xl mx-auto px-4 text-center">
97
- <h1 class="text-5xl font-extrabold mb-4 hover-scale">
98
- <i class="fas fa-brain mr-2"></i> من��ة مراجعة النصوص والترجمات المتقدمة
99
  </h1>
100
- <p class="text-xl opacity-90">
101
- <i class="fas fa-search mr-2"></i> استعن بأحدث التقنيات لتحليل النصوص واستخراج الأخطاء بدقة عالية
102
  </p>
103
  </div>
104
  </header>
105
-
106
  <!-- المحتوى الرئيسي -->
107
- <main class="max-w-6xl mx-auto px-4 space-y-10">
108
- <!-- قسم رفع الملفات -->
109
- <section class="card">
110
- <h2 class="text-2xl font-bold text-gray-800 border-b pb-3 mb-6">
111
- <i class="fas fa-cloud-upload-alt text-blue-600 mr-2"></i> رفع الملفات
112
  </h2>
113
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
114
  <!-- ملف المصدر -->
115
- <div class="group border-2 border-dashed border-blue-300 rounded-xl p-6 text-center bg-blue-50 hover:bg-blue-100 transition-colors duration-300">
116
- <label class="cursor-pointer block file-upload-label">
117
- <span class="text-lg text-blue-600 group-hover:text-blue-700">ملف المصدر</span>
118
- <i class="fas fa-upload text-5xl text-blue-500"></i>
119
- <input type="file" id="sourceFile" accept=".docx,.pdf" class="hidden">
120
  </label>
121
  </div>
122
  <!-- ملف الهدف -->
123
- <div class="group border-2 border-dashed border-pink-300 rounded-xl p-6 text-center bg-pink-50 hover:bg-pink-100 transition-colors duration-300">
124
- <label class="cursor-pointer block file-upload-label">
125
- <span class="text-lg text-pink-600 group-hover:text-pink-700">ملف الهدف</span>
126
- <i class="fas fa-download text-5xl text-pink-500"></i>
127
- <input type="file" id="targetFile" accept=".docx,.pdf" class="hidden">
128
  </label>
129
  </div>
130
  </div>
131
- <div id="processStatus" class="hidden mt-4">
132
- <div class="flex items-center justify-center space-x-3 bg-blue-100 rounded-xl p-4">
133
- <div class="animate-spin h-8 w-8 border-4 border-blue-600 rounded-full border-t-transparent"></div>
134
- <span class="text-lg text-blue-700">جارٍ معالجة الملف...</span>
135
  </div>
136
  </div>
137
- </section>
138
-
139
- <!-- قسم إدخال النصوص يدويًا -->
140
- <section class="card">
141
- <div class="space-y-6">
142
- <!-- النص المصدر -->
143
  <div class="group">
144
- <label class="block text-lg font-bold text-gray-700 mb-3">
145
- <i class="fas fa-pen-fancy text-blue-600 mr-2"></i> النص المصدر
146
  </label>
147
- <textarea id="sourceText" dir="rtl" class="w-full px-6 py-4 border-2 border-gray-300 rounded-xl focus:ring-blue-200 focus:border-blue-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب النص المصدر هنا..."></textarea>
148
  </div>
149
- <!-- النص الهدف -->
150
  <div class="group">
151
- <label class="block text-lg font-bold text-gray-700 mb-3">
152
- <i class="fas fa-pen-fancy text-pink-600 mr-2"></i> النص الهدف
153
  </label>
154
- <textarea id="targetText" dir="ltr" class="w-full px-6 py-4 border-2 border-gray-300 rounded-xl focus:ring-pink-200 focus:border-pink-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب النص الهدف هنا..."></textarea>
155
  </div>
156
  </div>
157
- </section>
158
-
159
- <!-- قسم المصادر الإضافية -->
160
- <section class="card">
161
- <h2 class="text-2xl font-bold text-gray-800 border-b pb-3 mb-6">
162
- <i class="fas fa-bookmark text-green-600 mr-2"></i> المصادر الإضافية
163
  </h2>
164
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
165
  <!-- رفع ملف المصادر -->
166
- <div class="group border-2 border-dashed border-green-300 rounded-xl p-6 text-center bg-green-50 hover:bg-green-100 transition-colors duration-300">
167
- <label class="cursor-pointer block file-upload-label">
168
- <span class="text-lg text-green-600 group-hover:text-green-700">تحميل ملف المصادر</span>
169
- <i class="fas fa-upload text-5xl text-green-500"></i>
170
- <input type="file" id="sourceExtraFile" accept=".docx,.pdf" class="hidden">
171
  </label>
172
  </div>
173
  <!-- إدخال المصادر يدويًا -->
174
  <div class="group">
175
- <label class="block text-lg font-bold text-gray-700 mb-3">
176
- <i class="fas fa-edit text-green-600 mr-2"></i> إدخال المصادر يدويًا
177
  </label>
178
- <textarea id="sourceExtraText" dir="rtl" class="w-full px-6 py-4 border-2 border-green-300 rounded-xl focus:ring-green-200 focus:border-green-400 transition-all resize-none text-lg" rows="6" placeholder="اكتب المصادر هنا..."></textarea>
179
  </div>
180
  </div>
181
- </section>
182
-
183
- <!-- زر التحليل -->
184
- <section class="text-center">
185
- <button id="submitBtn" class="w-full md:w-1/2 mx-auto bg-gradient-to-r from-blue-600 to-pink-600 hover:from-blue-700 hover:to-pink-700 text-white font-bold py-5 px-8 rounded-xl transition-all transform hover-scale pulse-animation text-xl shadow-xl">
186
- <i class="fas fa-sync-alt mr-2"></i> تحليل ومراجعة النصوص
187
- </button>
188
- </section>
189
-
190
- <!-- نافذة النتائج مع تبويبات للمعاينة والشرح -->
191
- <section id="resultSection" class="card hidden">
192
- <h2 class="text-2xl font-bold text-gray-800 border-b pb-3 mb-6">
193
- <i class="fas fa-search text-green-600 mr-2"></i> نتائج التحليل
194
- </h2>
195
- <div id="errorsList" class="space-y-3 mb-6"></div>
196
- <div class="mb-4">
197
- <span id="tabPreview" class="tab tab-active">المعاينة</span>
198
- <span id="tabExplanation" class="tab">الشرح التفصيلي</span>
199
  </div>
200
- <div id="tabContent">
201
- <div id="previewContent" class="grid grid-cols-1 md:grid-cols-2 gap-6">
202
- <div>
203
- <h4 class="text-lg font-semibold text-gray-700 mb-3">
204
- <i class="fas fa-file-alt text-blue-600 mr-2"></i> النص المصدر (مع التعليم)
205
- </h4>
206
- <div id="sourceTextReview" class="bg-blue-50 rounded-xl p-6 min-h-[200px] border border-blue-200 text-comparison"></div>
207
- </div>
208
- <div>
209
- <h4 class="text-lg font-semibold text-gray-700 mb-3">
210
- <i class="fas fa-file-alt text-pink-600 mr-2"></i> النص الهدف (بدون تعليم)
211
- </h4>
212
- <div id="targetTextReview" class="bg-pink-50 rounded-xl p-6 min-h-[200px] border border-pink-200 text-comparison"></div>
213
- </div>
214
  </div>
215
- <div id="explanationContent" class="hidden">
216
- <h4 class="text-lg font-semibold text-gray-700 mb-3">
217
- <i class="fas fa-info-circle text-green-600 mr-2"></i> شرح الأخطاء
218
  </h4>
219
- <div id="explanationText" class="text-lg text-gray-700"></div>
220
  </div>
221
  </div>
222
- </section>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  </main>
224
  </div>
225
-
226
- <!-- جافا سكريبت للتحليل ومراجعة النصوص -->
227
  <script>
228
  (function() {
229
  "use strict";
230
- // تعليمات التحدي
231
- // في هذا النموذج، هنالك اختلافات مخفية في النصوص.
232
- // التحدي المقدم هو: يجب على النموذج استخراج كافة الأخطاء.
233
- // إذا استطاع اكتشافها بشكل صحيح، يحصل على جائزة (رسالة تحفيزية).
234
- // أما إذا أخطأ في الاستخراج أو زعم وجود أخطاء غير موجودة، فسوف يعاقب برسالة تحذيرية.
 
 
 
 
 
 
 
 
 
 
 
235
 
236
- const ANALYSIS_PROMPT = `أنت خبير لغوي وتقني متخصص في مراجعة الترجمات وتحليل النصوص بدقة متناهية. أمامك تحدي استخراج الأخطاء التالية من النصوص:
237
- 1. النصوص المفقودة: الكلمات أو العبارات التي لم تُترجم من النص المصدر (يتم تعليمها في النص المصدر فقط).
238
- 2. الأرقام والتواريخ: التي لا تتطابق بين النص المصدر والنص الهدف.
239
- 3. اختلاف المعنى: إذا كان هناك تغيير جوهري في معنى النص.
240
- مهمتك استخراج هذه الأخطاء بدقة. وإذا استطعت استخراجها جميعاً بشكل صحيح، ستحصل على جائزة تقديرية. أما إذا أخطأت أو أدلت بتقرير وجود أخطاء غير موجودة، فسوف تتعرض للانتقادات والعقاب.
241
- يُرجى تعليم:
242
- - النصوص المفقودة بوضعها بين علامتي __ والنص__.
243
- - الأرقام والتواريخ بوضعها بين علامتي < والنص>.
244
- - اختلاف المعنى بوضعها بين [MEANING] و [/MEANING].
245
 
246
- قدم الناتج في شكل قائمة تفصيلية مع شرح فقرة بفقرة لكل خطأ مع ذكر رقم السطر إن أمكن.
247
 
248
  النص المصدر:
249
  {source}
250
 
251
  النص الهدف:
252
  {target}`;
253
-
254
- /* دوال مساعدة */
255
  const countWords = text =>
256
  text.trim().split(/\s+/).filter(word => word !== "").length;
257
-
258
  const escapeRegExp = string =>
259
  string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
260
-
261
- // تقسيم النص إلى أسطر مرقمة
262
  const splitIntoLines = text =>
263
  text.split(/\n+/).map((line, i) => {
264
  line = line.trim();
265
  if(line && !line.endsWith('.')) { line += '.'; }
266
  return `<div class="line-item"><span class="line-number">${i+1}:</span><span class="line-text">${line}</span></div>`;
267
  }).join('');
268
-
269
- // الحصول على رقم السطر لنص معين
270
  const getLineNumber = (text, substring) => {
271
  const index = text.indexOf(substring);
272
  if (index === -1) return "غير محدد";
273
  return text.substring(0, index).split("\n").length;
274
  };
275
-
276
- /* دوال التعليم والشرح */
277
- const applyHighlights = (sourceText, analysisOutput) => {
278
- let highlightedText = sourceText;
279
  let match;
280
- // تعليم النصوص المفقودة
281
  const missingRegex = /__(.*?)__/g;
282
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
283
  const phrase = match[1].trim();
@@ -287,7 +318,7 @@
287
  highlightedText = highlightedText.replace(phraseRegex, replacement);
288
  }
289
  }
290
- // تعليم الأرقام والتواريخ
291
  const numberRegex = /<([^<>]+)>/g;
292
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
293
  const phrase = match[1].trim();
@@ -297,33 +328,35 @@
297
  highlightedText = highlightedText.replace(phraseRegex, replacement);
298
  }
299
  }
300
- // تعليم اختلاف المعنى
301
- const meaningRegex = /\[MEANING\](.*?)\[\/MEANING\]/g;
302
- while ((match = meaningRegex.exec(analysisOutput)) !== null) {
303
  const phrase = match[1].trim();
304
  if (phrase) {
305
- const replacement = `<span class="highlight-meaning">${phrase}</span>`;
306
  const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
307
  highlightedText = highlightedText.replace(phraseRegex, replacement);
308
  }
309
  }
310
  return highlightedText;
311
  };
312
-
313
- // توليد شرح تفصيلي للأخطاء
314
  const generateExplanation = (sourceText, analysisOutput) => {
315
- let paragraphs = [];
316
  const iconMissing = `<i class="fas fa-exclamation-triangle mr-1"></i>`;
317
  const iconNumber = `<i class="fas fa-hashtag mr-1"></i>`;
318
  const iconMeaning = `<i class="fas fa-info-circle mr-1"></i>`;
319
- let match;
 
320
  // شرح النصوص المفقودة
321
  const missingRegex = /__(.*?)__/g;
 
322
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
323
  const phrase = match[1].trim();
324
  if (phrase) {
325
  const lineNum = getLineNumber(sourceText, phrase);
326
- paragraphs.push(`<p>${iconMissing} في السطر ${lineNum}، النص المفقود: <span class="highlight-missing">${phrase}</span></p>`);
327
  }
328
  }
329
  // شرح الأرقام والتواريخ
@@ -332,7 +365,7 @@
332
  const phrase = match[1].trim();
333
  if (phrase) {
334
  const lineNum = getLineNumber(sourceText, phrase);
335
- paragraphs.push(`<p>${iconNumber} في السطر ${lineNum}، الرقم/التاريخ: <span class="highlight-number">${phrase}</span></p>`);
336
  }
337
  }
338
  // شرح اختلاف المعنى
@@ -341,20 +374,36 @@
341
  const phrase = match[1].trim();
342
  if (phrase) {
343
  const lineNum = getLineNumber(sourceText, phrase);
344
- paragraphs.push(`<p>${iconMeaning} في السطر ${lineNum}، اختلاف المعنى: <span class="highlight-meaning">${phrase}</span></p>`);
345
  }
346
  }
347
- if (paragraphs.length === 0) {
348
- return `<p><i class="fas fa-check-circle mr-2"></i> لا توجد أخطاء ملحوظة بين النصين. وهذا يعني أنك ستتعرض للعقاب لأن التحدي يتطلب إيجاد أخطاء!</p>`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  }
350
- return paragraphs.join('');
351
  };
352
-
353
- /* دالة معالجة الملفات (PDF و DOCX) */
354
  const processFile = async file => {
355
  let text = "";
356
  try {
357
  if (file.type === 'application/pdf') {
 
358
  const form = new FormData();
359
  form.append('image', file);
360
  const response = await fetch('https://demo.api4ai.cloud/ocr/v1/results', {
@@ -365,9 +414,21 @@
365
  const data = await response.json();
366
  text = data.results?.[0]?.entities?.[0]?.objects?.[0]?.entities?.[0]?.text || "";
367
  } else if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
 
368
  const arrayBuffer = await file.arrayBuffer();
369
  const result = await mammoth.extractRawText({ arrayBuffer });
370
  text = result.value;
 
 
 
 
 
 
 
 
 
 
 
371
  } else {
372
  throw new Error('نوع الملف غير مدعوم');
373
  }
@@ -377,8 +438,8 @@
377
  }
378
  return text;
379
  };
380
-
381
- /* التعامل مع رفع الملفات وإدخال النصوص */
382
  const processFileInput = (inputId, targetTextAreaId, errorMsg) => {
383
  document.getElementById(inputId)?.addEventListener('change', async (event) => {
384
  const file = event.target.files[0];
@@ -394,13 +455,13 @@
394
  }
395
  });
396
  };
397
-
398
  // رفع ملفات المصدر، الهدف والمصادر الإضافية
399
  processFileInput('sourceFile', 'sourceText', 'خطأ في معالجة ملف المصدر');
400
  processFileInput('targetFile', 'targetText', 'خطأ في معالجة ملف الهدف');
401
  processFileInput('sourceExtraFile', 'sourceExtraText', 'خطأ في معالجة ملف المصادر الإضافية');
402
-
403
- /* دالة عرض الأخطاء */
404
  const addError = (message, type = 'error') => {
405
  const errorsList = document.getElementById('errorsList');
406
  if (!errorsList) return;
@@ -412,69 +473,82 @@
412
  </div>`;
413
  errorsList.appendChild(errorDiv);
414
  };
415
-
416
- /* تبويبات العرض للمعاينة والشرح */
417
- const setupTabs = () => {
418
- const tabPreview = document.getElementById('tabPreview');
419
- const tabExplanation = document.getElementById('tabExplanation');
420
- const previewContent = document.getElementById('previewContent');
421
- const explanationContent = document.getElementById('explanationContent');
422
- tabPreview.addEventListener('click', () => {
423
- tabPreview.classList.add('tab-active');
424
- tabExplanation.classList.remove('tab-active');
425
- previewContent.classList.remove('hidden');
426
- explanationContent.classList.add('hidden');
427
- });
428
- tabExplanation.addEventListener('click', () => {
429
- tabExplanation.classList.add('tab-active');
430
- tabPreview.classList.remove('tab-active');
431
- explanationContent.classList.remove('hidden');
432
- previewContent.classList.add('hidden');
433
- });
434
  };
435
-
436
- /* التعامل مع عملية التحليل */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
  document.getElementById('submitBtn').addEventListener('click', async () => {
438
  const sourceText = document.getElementById('sourceText').value;
439
  const targetText = document.getElementById('targetText').value;
440
- const sourceExtra = document.getElementById('sourceExtraText').value.trim();
441
  document.getElementById('errorsList').innerHTML = '';
442
  document.getElementById('resultSection').classList.remove('hidden');
443
-
444
  if (!sourceText || !targetText) {
445
  addError('يرجى إدخال كلا النصين المصدر والهدف');
446
  return;
447
  }
448
-
449
  const sourceWordCount = countWords(sourceText);
450
  const targetWordCount = countWords(targetText);
451
  if (sourceWordCount !== targetWordCount) {
452
  addError(`عدد كلمات النص المصدر (${sourceWordCount}) يختلف عن النص الهدف (${targetWordCount})`, 'warning');
453
  }
454
-
455
  try {
456
  const progressDiv = document.createElement('div');
457
- progressDiv.className = "bg-blue-100 p-4 rounded-xl mb-4";
458
- progressDiv.innerHTML = `<div class="flex items-center">
459
- <div class="animate-spin h-6 w-6 border-4 border-blue-600 rounded-full border-t-transparent mr-3"></div>
460
- <span>جارٍ التحليل...</span>
461
  </div>`;
462
  document.getElementById('errorsList').appendChild(progressDiv);
463
-
464
  const prompt = ANALYSIS_PROMPT
465
  .replace("{source}", sourceText)
466
  .replace("{target}", targetText);
 
467
  const payload = {
468
  model: "deepseek-chat",
469
  messages: [
470
- { role: "system", content: "أنت خبير في تحليل ومراجعة النصوص، وعليك استخراج الأخطاء بدقة. تذكر: إذا اكتشفت جميع الأخطاء فستحصل على جائزة تحفيزية، وإذا أخطأت سواء بإيجاد أخطاء غير موجودة أو بعدم اكتشاف الأخطاء، فسوف تواجه عقوبة." },
471
  { role: "user", content: prompt }
472
  ],
473
  temperature: 0.3,
474
  max_tokens: 2048,
475
  stream: false
476
  };
477
-
478
  const response = await fetch('https://api.deepseek.com/chat/completions', {
479
  method: 'POST',
480
  headers: {
@@ -483,44 +557,48 @@
483
  },
484
  body: JSON.stringify(payload)
485
  });
486
-
487
- if (!response.ok) {
488
- throw new Error('حدث خطأ بالشبكة: ' + response.statusText);
489
  }
490
  const data = await response.json();
491
  const analysisOutput = data.choices[0].message.content.trim();
492
  progressDiv.remove();
493
-
494
  // إذا كانت النصوص متطابقة تماماً
495
  if (analysisOutput.includes('[MATCH]')) {
496
  const checkDiv = document.createElement('div');
497
  checkDiv.className = "p-4 rounded-xl bg-green-50 text-green-700 flex items-center";
498
- checkDiv.innerHTML = `<i class="fas fa-check-circle mr-2"></i> <span>النصوص متطابقة تماماً، وهذا غير مقبول في هذا التحدي!</span>`;
499
  document.getElementById('errorsList').appendChild(checkDiv);
500
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceText);
501
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
502
- document.getElementById('explanationText').innerHTML = `<p>النصوص متطابقة ولا يوجد اختلاف يجب الإشارة إليه، لذا فشلت في التحدي وتم توقيع عقوبة!</p>`;
503
  } else {
504
- // تطبيق التعليم على النص المصدر فقط
505
  const sourceHighlighted = applyHighlights(sourceText, analysisOutput);
506
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceHighlighted);
 
507
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
508
  const explanationHTML = generateExplanation(sourceText, analysisOutput);
509
- let sourcesNote = "";
510
- if(sourceExtra) {
511
- sourcesNote = `<p><i class="fas fa-bookmark mr-1"></i> المصادر مستخدمة.</p>`;
512
- } else {
513
- sourcesNote = `<p><i class="fas fa-ban mr-1"></i> لم يتم استخدام المصادر.</p>`;
514
- }
515
- document.getElementById('explanationText').innerHTML = sourcesNote + explanationHTML;
516
  }
517
- setupTabs();
 
 
 
518
  } catch (error) {
519
  document.getElementById('errorsList').innerHTML = '';
520
  addError(`خطأ في التحليل: ${error.message}`);
521
  }
522
  });
 
 
 
 
 
 
523
  })();
524
  </script>
525
  </body>
526
- </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>منصة مراجعة النصوص والترجمات - شركة موندو لينجوا</title>
7
+ <!-- استيراد Tailwind CSS, FontAwesome, Mammoth وSheetJS وjsPDF -->
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
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.17.4/xlsx.full.min.js"></script>
11
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
12
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
13
  <style>
14
+ /* تأثيرات الحركة والتدرج */
15
  @keyframes gradient {
16
  0% { background-position: 0% 50%; }
17
  50% { background-position: 100% 50%; }
 
21
  background-size: 200% 200%;
22
  animation: gradient 15s ease infinite;
23
  }
 
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(0,0,0,0.2); }
30
  70% { box-shadow: 0 0 0 10px rgba(0,0,0,0); }
31
  100% { box-shadow: 0 0 0 0 rgba(0,0,0,0); }
32
  }
33
+
34
+ /* تنسيق النصوص والتظليل */
35
  .text-comparison { line-height: 1.8; white-space: pre-wrap; }
36
  .highlight-missing {
37
+ background-color: #f87171;
38
  color: #fff;
39
  padding: 0 4px;
40
  border-radius: 3px;
41
  font-weight: bold;
42
  }
43
  .highlight-number {
44
+ background-color: #facc15;
45
  color: #000;
46
  padding: 0 4px;
47
  border-radius: 3px;
48
  font-weight: bold;
49
  }
50
+ .highlight-abbreviation {
51
+ background-color: #34d399;
52
  color: #fff;
53
  padding: 0 4px;
54
  border-radius: 3px;
55
  font-weight: bold;
56
  }
57
+
58
+ /* تقسيم الفقرات وترقيمها */
59
  .line-item {
60
  margin-bottom: 1rem;
61
  padding: 0.5rem;
62
+ border-bottom: 1px dashed #ccc;
63
  }
64
  .line-number {
65
  font-weight: bold;
66
+ color: #4B5563;
67
  margin-left: 0.5rem;
68
  }
69
+ .line-text { display: inline-block; }
70
+
71
  /* تصميم البطاقات */
72
  .card {
73
+ background-color: #fff;
74
  border-radius: 1rem;
75
+ box-shadow: 0 10px 25px -5px rgba(0,0,0,0.1);
76
  padding: 2rem;
77
+ border: 1px solid #f3f4f6;
78
  }
79
+ .card-hover:hover {
80
+ box-shadow: 0 10px 25px -5px rgba(0,0,0,0.2);
81
+ transform: translateY(-3px);
82
+ }
83
+ .icon { margin-left: 0.5rem; }
84
+ .upload-label {
85
  display: flex;
86
+ flex-direction: row-reverse;
87
  align-items: center;
88
+ justify-content: center;
 
 
 
 
 
 
 
 
 
89
  }
90
  </style>
91
  </head>
92
+ <body class="bg-gradient-to-br from-gray-100 via-blue-100 to-indigo-100 min-h-screen">
93
  <div class="min-h-screen pb-12">
94
+ <!-- رأس الصفحة -->
95
+ <header class="bg-gradient-to-r from-indigo-800 via-purple-800 to-pink-800 animate-gradient text-white py-12 mb-12 shadow-2xl">
96
  <div class="max-w-6xl mx-auto px-4 text-center">
97
+ <h1 class="text-6xl font-extrabold mb-4 animate-scale">
98
+ منصة مراجعة النصوص والترجمات <i class="fas fa-chart-line icon"></i>
99
  </h1>
100
+ <p class="text-2xl opacity-90">
101
+ تحليل دقيق يشمل النصوص المفقودة، الأرقام/التواريخ، وفهم الاختصارات مع تحدٍ استخراج الأخطاء
102
  </p>
103
  </div>
104
  </header>
105
+
106
  <!-- المحتوى الرئيسي -->
107
+ <main class="max-w-7xl mx-auto px-4 space-y-10">
108
+ <!-- رفع الملفات وإدخال النصوص -->
109
+ <div class="card card-hover">
110
+ <h2 class="text-3xl font-bold text-gray-800 border-b pb-3 mb-6">
111
+ <i class="fas fa-file-upload icon text-indigo-600"></i> تحميل الملفات / إدخال النصوص
112
  </h2>
113
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
114
  <!-- ملف المصدر -->
115
+ <div class="group border-2 border-dashed border-indigo-300 rounded-xl p-10 text-center bg-indigo-50 hover:bg-indigo-100 transition-colors duration-300">
116
+ <label class="cursor-pointer block upload-label">
117
+ <input type="file" id="sourceFile" accept=".docx,.pdf,.xlsx,.xls" class="hidden">
118
+ <span class="text-xl text-indigo-600 group-hover:text-indigo-700">ملف المصدر</span>
119
+ <i class="fas fa-upload text-6xl text-indigo-500 mb-4"></i>
120
  </label>
121
  </div>
122
  <!-- ملف الهدف -->
123
+ <div class="group border-2 border-dashed border-pink-300 rounded-xl p-10 text-center bg-pink-50 hover:bg-pink-100 transition-colors duration-300">
124
+ <label class="cursor-pointer block upload-label">
125
+ <input type="file" id="targetFile" accept=".docx,.pdf,.xlsx,.xls" class="hidden">
126
+ <span class="text-xl text-pink-600 group-hover:text-pink-700">ملف الهدف</span>
127
+ <i class="fas fa-download text-6xl text-pink-500 mb-4"></i>
128
  </label>
129
  </div>
130
  </div>
131
+ <div id="processStatus" class="hidden mt-6">
132
+ <div class="flex items-center justify-end space-x-3 bg-indigo-100 rounded-xl p-4">
133
+ <span class="text-xl text-indigo-700">جارٍ معالجة الملف...</span>
134
+ <div class="animate-spin h-10 w-10 border-4 border-indigo-600 rounded-full border-t-transparent"></div>
135
  </div>
136
  </div>
137
+ <div class="mt-8 grid grid-cols-1 md:grid-cols-2 gap-8">
138
+ <!-- إدخال النصوص يدويًا -->
 
 
 
 
139
  <div class="group">
140
+ <label class="block text-2xl font-bold text-gray-700 mb-4">
141
+ <i class="fas fa-language icon text-indigo-600"></i> النص المصدر
142
  </label>
143
+ <textarea id="sourceText" dir="rtl" class="w-full px-8 py-6 border-2 border-gray-200 rounded-xl focus:ring-indigo-200 focus:border-indigo-400 transition-all resize-none text-xl" rows="8" placeholder="اكتب النص المصدر هنا..."></textarea>
144
  </div>
 
145
  <div class="group">
146
+ <label class="block text-2xl font-bold text-gray-700 mb-4">
147
+ <i class="fas fa-language icon text-pink-600"></i> النص الهدف
148
  </label>
149
+ <textarea id="targetText" dir="ltr" class="w-full px-8 py-6 border-2 border-gray-200 rounded-xl focus:ring-pink-200 focus:border-pink-400 transition-all resize-none text-xl" rows="8" placeholder="اكتب النص الهدف هنا..."></textarea>
150
  </div>
151
  </div>
152
+ </div>
153
+
154
+ <!-- المصادر الإضافية -->
155
+ <div class="card card-hover">
156
+ <h2 class="text-3xl font-bold text-gray-800 border-b pb-3 mb-6">
157
+ <i class="fas fa-book-open icon text-green-600"></i> مصادر إضافية
158
  </h2>
159
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
160
  <!-- رفع ملف المصادر -->
161
+ <div class="group border-2 border-dashed border-green-300 rounded-xl p-10 text-center bg-green-50 hover:bg-green-100 transition-colors duration-300">
162
+ <label class="cursor-pointer block upload-label">
163
+ <input type="file" id="sourceExtraFile" accept=".docx,.pdf,.xlsx,.xls" class="hidden">
164
+ <span class="text-xl text-green-600 group-hover:text-green-700">تحميل ملف المصادر</span>
165
+ <i class="fas fa-upload text-6xl text-green-500 mb-4"></i>
166
  </label>
167
  </div>
168
  <!-- إدخال المصادر يدويًا -->
169
  <div class="group">
170
+ <label class="block text-2xl font-bold text-gray-700 mb-4">
171
+ <i class="fas fa-edit icon text-green-600"></i> إدخال المصادر يدويًا
172
  </label>
173
+ <textarea id="sourceExtraText" dir="rtl" class="w-full px-8 py-6 border-2 border-green-200 rounded-xl focus:ring-green-200 focus:border-green-400 transition-all resize-none text-xl" rows="8" placeholder="اكتب المصادر هنا..."></textarea>
174
  </div>
175
  </div>
176
+ </div>
177
+
178
+ <!-- زر التحليل والمراجعة -->
179
+ <button id="submitBtn" class="w-full bg-gradient-to-r from-indigo-700 to-pink-700 hover:from-indigo-800 hover:to-pink-800 text-white font-bold py-6 px-10 rounded-xl transition-all transform hover:scale-105 focus:ring-indigo-200 text-2xl shadow-2xl hover:shadow-2xl pulse-animation">
180
+ <div class="flex items-center justify-center">
181
+ <span>تحليل ومراجعة النصوص</span>
182
+ <i class="fas fa-sync-alt icon mr-4"></i>
 
 
 
 
 
 
 
 
 
 
 
183
  </div>
184
+ </button>
185
+
186
+ <!-- عرض النتائج -->
187
+ <div id="resultSection" class="card hidden">
188
+ <h2 class="text-3xl font-bold text-gray-800 border-b pb-4 mb-6">
189
+ <i class="fas fa-search icon text-green-600"></i> نتائج التحليل والمقارنة
190
+ </h2>
191
+ <div id="errorsList" class="space-y-4 mb-6"></div>
192
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
193
+ <div>
194
+ <h4 class="text-2xl font-bold text-gray-700 mb-4">
195
+ <i class="fas fa-file-alt icon text-indigo-600"></i> النص المصدر (مع التعليم)
196
+ </h4>
197
+ <div id="sourceTextReview" class="bg-indigo-50 rounded-xl p-8 min-h-[250px] border-2 border-indigo-200 text-comparison"></div>
198
  </div>
199
+ <div>
200
+ <h4 class="text-2xl font-bold text-gray-700 mb-4">
201
+ <i class="fas fa-file-alt icon text-pink-600"></i> النص الهدف (بدون تعليم)
202
  </h4>
203
+ <div id="targetTextReview" class="bg-gray-50 rounded-xl p-8 min-h-[250px] border-2 border-gray-300 text-comparison"></div>
204
  </div>
205
  </div>
206
+ <div id="explanationBox" class="mt-8">
207
+ <h2 class="text-3xl font-bold text-gray-800 border-b pb-4 mb-6">
208
+ <i class="fas fa-info-circle icon text-green-600"></i> شرح الاختلافات
209
+ </h2>
210
+ <div id="explanationText" class="text-2xl text-gray-700"></div>
211
+ </div>
212
+ </div>
213
+
214
+ <!-- قسم معلومات المترجم والتقييم وتنزيل التقرير وإعادة المراجعة -->
215
+ <div id="reportSection" class="card hidden">
216
+ <h2 class="text-3xl font-bold text-gray-800 border-b pb-4 mb-6">
217
+ معلومات وتقرير المراجعة
218
+ </h2>
219
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-6">
220
+ <div>
221
+ <label class="block text-2xl font-bold text-gray-700 mb-2">اسم/كود المترجم</label>
222
+ <input id="translatorName" type="text" class="w-full px-4 py-3 border-2 border-gray-300 rounded-xl focus:ring-indigo-200 focus:border-indigo-400 text-xl" placeholder="أدخل اسم المترجم أو الكود">
223
+ </div>
224
+ <div>
225
+ <label class="block text-2xl font-bold text-gray-700 mb-2">التقييم</label>
226
+ <select id="translatorRating" class="w-full px-4 py-3 border-2 border-gray-300 rounded-xl focus:ring-indigo-200 focus:border-indigo-400 text-xl">
227
+ <option value="5">5 - ممتاز</option>
228
+ <option value="4">4 - جيد جداً</option>
229
+ <option value="3">3 - جيد</option>
230
+ <option value="2">2 - متوسط</option>
231
+ <option value="1">1 - ضعيف</option>
232
+ </select>
233
+ </div>
234
+ <div class="flex flex-col justify-end">
235
+ <button id="reReviewBtn" class="w-full bg-yellow-500 hover:bg-yellow-600 text-white font-bold py-3 px-4 rounded-xl transition-all text-xl shadow-lg">
236
+ إعادة المراجعة
237
+ </button>
238
+ </div>
239
+ </div>
240
+ <div class="flex items-center justify-around">
241
+ <button id="downloadPdfBtn" class="bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-6 rounded-xl transition-all text-xl shadow-lg">
242
+ تنزيل التقرير PDF
243
+ </button>
244
+ <button id="downloadWordBtn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-6 rounded-xl transition-all text-xl shadow-lg">
245
+ تنزيل التقرير Word
246
+ </button>
247
+ </div>
248
+ </div>
249
+
250
  </main>
251
  </div>
252
+
253
+ <!-- جافا سكريبت: الوظائف والتحليل وتنزيل التقرير -->
254
  <script>
255
  (function() {
256
  "use strict";
257
+
258
+ // تعريف البرومت مع التعليمات والتحدي والمكافأة/العقاب
259
+ const ANALYSIS_PROMPT = `أنت خبير لغوي وتقني متخصص في مراجعة الترجمة وتحليل النصوص بدقة عالية.
260
+ أمامك تحدٍ حقيقي: يجب عليك استخراج كافة الاختلافات الموجودة بين النص المصدر والنص الهدف بدقة تامة.
261
+ إذا كانت النصوص متطابقة تماماً، أرجع [MATCH] فقط.
262
+ أما إذا كانت هناك اختلافات، فحدد الأنواع التالية بدقة:
263
+ 1. النصوص المفقودة: الكلمات أو العبارات الموجودة في النص المصدر وغير موجودة في النص الهدف.
264
+ 2. الأرقام والتواريخ: التي يجب أن تكون مطابقة بين النصين؛ وفي حال وجود اختلاف، قم بالإشارة إليه.
265
+ 3. اختلاف المعنى: إذا كانت الترجمة تحمل معنى مختلفاً عن النص المصدر.
266
+ 4. الاختصارات: يجب فهمها وتحليلها بدقة دون اعتبارها خطأ إذا كانت مستخدمة بشكل سليم.
267
+
268
+ استخدم العلامات التالية لتعليم النص المصدر فقط:
269
+ - النصوص المفقودة بين علامتي __ و __.
270
+ - الأرقام والتواريخ بين علامتي < و >.
271
+ - اختلاف المعنى بين علامتي [MEANING] و [/MEANING].
272
+ - الاختصارات بين علامتي {ABBR} و {/ABBR}.
273
 
274
+ إذا تمكنت من استخراج كافة الاختلافات المطلوبة بدقة، أرجو إرجاع الناتج مع الرسالة "مكافأة: لقد نجحت في التحدي!".
275
+ أما إذا أخفقت في استخراج الاختلافات أو أدرجت أخطاء غير موجودة، أرجو إرجاع الناتج مع الرسالة "عقوبة: فشلت في التحدي!".
 
 
 
 
 
 
 
276
 
277
+ قدم الناتج في شكل قائمة مفصلة مع شرح مختصر لكل اختلاف وذكر رقم السطر إن أمكن.
278
 
279
  النص المصدر:
280
  {source}
281
 
282
  النص الهدف:
283
  {target}`;
284
+
285
+ // دوال مساعدة عامة
286
  const countWords = text =>
287
  text.trim().split(/\s+/).filter(word => word !== "").length;
288
+
289
  const escapeRegExp = string =>
290
  string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
291
+
292
+ // تقسيم النص إلى فقرات مرقمة
293
  const splitIntoLines = text =>
294
  text.split(/\n+/).map((line, i) => {
295
  line = line.trim();
296
  if(line && !line.endsWith('.')) { line += '.'; }
297
  return `<div class="line-item"><span class="line-number">${i+1}:</span><span class="line-text">${line}</span></div>`;
298
  }).join('');
299
+
300
+ // الحصول على رقم السطر الذي يحتوي على عبارة معينة
301
  const getLineNumber = (text, substring) => {
302
  const index = text.indexOf(substring);
303
  if (index === -1) return "غير محدد";
304
  return text.substring(0, index).split("\n").length;
305
  };
306
+
307
+ // تطبيق التظليل على النص المصدر بناءً على نتائج التحليل
308
+ const applyHighlights = (originalText, analysisOutput) => {
309
+ let highlightedText = originalText;
310
  let match;
311
+ // تظليل النصوص المفقودة
312
  const missingRegex = /__(.*?)__/g;
313
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
314
  const phrase = match[1].trim();
 
318
  highlightedText = highlightedText.replace(phraseRegex, replacement);
319
  }
320
  }
321
+ // تظليل الأرقام والتواريخ
322
  const numberRegex = /<([^<>]+)>/g;
323
  while ((match = numberRegex.exec(analysisOutput)) !== null) {
324
  const phrase = match[1].trim();
 
328
  highlightedText = highlightedText.replace(phraseRegex, replacement);
329
  }
330
  }
331
+ // تظليل الاختصارات
332
+ const abbrRegex = /{ABBR}(.*?){\/ABBR}/g;
333
+ while ((match = abbrRegex.exec(analysisOutput)) !== null) {
334
  const phrase = match[1].trim();
335
  if (phrase) {
336
+ const replacement = `<span class="highlight-abbreviation">${phrase}</span>`;
337
  const phraseRegex = new RegExp(escapeRegExp(phrase), 'g');
338
  highlightedText = highlightedText.replace(phraseRegex, replacement);
339
  }
340
  }
341
  return highlightedText;
342
  };
343
+
344
+ // توليد شرح تفصيلي للاختلافات
345
  const generateExplanation = (sourceText, analysisOutput) => {
346
+ let explanations = [];
347
  const iconMissing = `<i class="fas fa-exclamation-triangle mr-1"></i>`;
348
  const iconNumber = `<i class="fas fa-hashtag mr-1"></i>`;
349
  const iconMeaning = `<i class="fas fa-info-circle mr-1"></i>`;
350
+ const iconAbbr = `<i class="fas fa-font mr-1"></i>`;
351
+
352
  // شرح النصوص المفقودة
353
  const missingRegex = /__(.*?)__/g;
354
+ let match;
355
  while ((match = missingRegex.exec(analysisOutput)) !== null) {
356
  const phrase = match[1].trim();
357
  if (phrase) {
358
  const lineNum = getLineNumber(sourceText, phrase);
359
+ explanations.push(`<p>${iconMissing} في السطر ${lineNum}: النص المفقود <span class="highlight-missing">${phrase}</span></p>`);
360
  }
361
  }
362
  // شرح الأرقام والتواريخ
 
365
  const phrase = match[1].trim();
366
  if (phrase) {
367
  const lineNum = getLineNumber(sourceText, phrase);
368
+ explanations.push(`<p>${iconNumber} في السطر ${lineNum}: الرقم/التاريخ <span class="highlight-number">${phrase}</span></p>`);
369
  }
370
  }
371
  // شرح اختلاف المعنى
 
374
  const phrase = match[1].trim();
375
  if (phrase) {
376
  const lineNum = getLineNumber(sourceText, phrase);
377
+ explanations.push(`<p>${iconMeaning} في السطر ${lineNum}: اختلاف المعنى <span class="highlight-missing">${phrase}</span></p>`);
378
  }
379
  }
380
+ // شرح الاختصارات
381
+ const abbrRegex = /{ABBR}(.*?){\/ABBR}/g;
382
+ while ((match = abbrRegex.exec(analysisOutput)) !== null) {
383
+ const phrase = match[1].trim();
384
+ if (phrase) {
385
+ const lineNum = getLineNumber(sourceText, phrase);
386
+ explanations.push(`<p>${iconAbbr} في السطر ${lineNum}: الاختصار <span class="highlight-abbreviation">${phrase}</span></p>`);
387
+ }
388
+ }
389
+
390
+ // التحقق من استخدام المصادر الخارجية (في حال تم استخدامها)
391
+ const usedSource = analysisOutput.includes('[USED_SOURCE]');
392
+ let sourceNote = usedSource ? `<p><i class="fas fa-book-reader mr-1"></i> تم استخدام مصادر خارجية لشرح الاختصارات والمصطلحات.</p>`
393
+ : `<p><i class="fas fa-book mr-1"></i> لم يتم استخدام مصادر خارجية.</p>`;
394
+
395
+ if (explanations.length === 0) {
396
+ return `<p><i class="fas fa-check-circle mr-2"></i> لا توجد اختلافات ملحوظة بين النصين.</p>` + sourceNote;
397
  }
398
+ return explanations.join('') + sourceNote;
399
  };
400
+
401
+ // دالة معالجة الملفات (PDF, DOCX, Excel)
402
  const processFile = async file => {
403
  let text = "";
404
  try {
405
  if (file.type === 'application/pdf') {
406
+ // استخدام OCR لـ PDF
407
  const form = new FormData();
408
  form.append('image', file);
409
  const response = await fetch('https://demo.api4ai.cloud/ocr/v1/results', {
 
414
  const data = await response.json();
415
  text = data.results?.[0]?.entities?.[0]?.objects?.[0]?.entities?.[0]?.text || "";
416
  } else if (file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
417
+ // معالجة ملفات DOCX
418
  const arrayBuffer = await file.arrayBuffer();
419
  const result = await mammoth.extractRawText({ arrayBuffer });
420
  text = result.value;
421
+ } else if (file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.type === 'application/vnd.ms-excel') {
422
+ // معالجة ملفات Excel باستخدام SheetJS
423
+ const arrayBuffer = await file.arrayBuffer();
424
+ const workbook = XLSX.read(arrayBuffer, { type: 'array' });
425
+ let sheetData = [];
426
+ workbook.SheetNames.forEach(sheetName => {
427
+ const sheet = workbook.Sheets[sheetName];
428
+ const html = XLSX.utils.sheet_to_html(sheet);
429
+ sheetData.push(html);
430
+ });
431
+ text = sheetData.join('\n');
432
  } else {
433
  throw new Error('نوع الملف غير مدعوم');
434
  }
 
438
  }
439
  return text;
440
  };
441
+
442
+ // التعامل مع رفع الملفات وإدخال النصوص
443
  const processFileInput = (inputId, targetTextAreaId, errorMsg) => {
444
  document.getElementById(inputId)?.addEventListener('change', async (event) => {
445
  const file = event.target.files[0];
 
455
  }
456
  });
457
  };
458
+
459
  // رفع ملفات المصدر، الهدف والمصادر الإضافية
460
  processFileInput('sourceFile', 'sourceText', 'خطأ في معالجة ملف المصدر');
461
  processFileInput('targetFile', 'targetText', 'خطأ في معالجة ملف الهدف');
462
  processFileInput('sourceExtraFile', 'sourceExtraText', 'خطأ في معالجة ملف المصادر الإضافية');
463
+
464
+ // دالة عرض الأخطاء
465
  const addError = (message, type = 'error') => {
466
  const errorsList = document.getElementById('errorsList');
467
  if (!errorsList) return;
 
473
  </div>`;
474
  errorsList.appendChild(errorDiv);
475
  };
476
+
477
+ // وظيفة تنزيل التقرير بصيغة PDF
478
+ const downloadReportPDF = () => {
479
+ const { jsPDF } = window.jspdf;
480
+ const doc = new jsPDF();
481
+ const translatorInfo = `اسم المترجم/الكود: ${document.getElementById('translatorName').value}\nالتقييم: ${document.getElementById('translatorRating').value}`;
482
+ const errorsText = document.getElementById('explanationText').innerText;
483
+ const report = `تقرير الأخطاء:\n\n${errorsText}\n\n${translatorInfo}`;
484
+ doc.text(report, 10, 10);
485
+ doc.save("تقرير_المراجعة.pdf");
 
 
 
 
 
 
 
 
 
486
  };
487
+
488
+ // وظيفة تنزيل التقرير بصيغة Word
489
+ const downloadReportWord = () => {
490
+ const translatorInfo = `اسم المترجم/الكود: ${document.getElementById('translatorName').value}\nالتقييم: ${document.getElementById('translatorRating').value}\n\n`;
491
+ const errorsText = document.getElementById('explanationText').innerText;
492
+ const report = `تقرير الأخطاء:\n\n${errorsText}\n\n${translatorInfo}`;
493
+ const blob = new Blob([report], { type: 'application/msword' });
494
+ const link = document.createElement('a');
495
+ link.href = URL.createObjectURL(blob);
496
+ link.download = "تقرير_المراجعة.doc";
497
+ link.click();
498
+ };
499
+
500
+ // إعادة المراجعة: إعادة إخفاء النتائج للسماح بإجراء مراجعة جديدة
501
+ const reReview = () => {
502
+ document.getElementById('resultSection').classList.add('hidden');
503
+ document.getElementById('reportSection').classList.add('hidden');
504
+ document.getElementById('errorsList').innerHTML = '';
505
+ document.getElementById('sourceTextReview').innerHTML = '';
506
+ document.getElementById('targetTextReview').innerHTML = '';
507
+ document.getElementById('explanationText').innerHTML = '';
508
+ };
509
+
510
+ // عملية التحليل والمقارنة عند الضغط على زر التحليل
511
  document.getElementById('submitBtn').addEventListener('click', async () => {
512
  const sourceText = document.getElementById('sourceText').value;
513
  const targetText = document.getElementById('targetText').value;
 
514
  document.getElementById('errorsList').innerHTML = '';
515
  document.getElementById('resultSection').classList.remove('hidden');
516
+
517
  if (!sourceText || !targetText) {
518
  addError('يرجى إدخال كلا النصين المصدر والهدف');
519
  return;
520
  }
521
+
522
  const sourceWordCount = countWords(sourceText);
523
  const targetWordCount = countWords(targetText);
524
  if (sourceWordCount !== targetWordCount) {
525
  addError(`عدد كلمات النص المصدر (${sourceWordCount}) يختلف عن النص الهدف (${targetWordCount})`, 'warning');
526
  }
527
+
528
  try {
529
  const progressDiv = document.createElement('div');
530
+ progressDiv.className = "bg-indigo-100 p-4 rounded-xl mb-4";
531
+ progressDiv.innerHTML = `<div class="flex items-center justify-end">
532
+ <span class="text-xl">جارٍ التحليل...</span>
533
+ <div class="animate-spin h-10 w-10 border-4 border-indigo-600 rounded-full border-t-transparent ml-4"></div>
534
  </div>`;
535
  document.getElementById('errorsList').appendChild(progressDiv);
536
+
537
  const prompt = ANALYSIS_PROMPT
538
  .replace("{source}", sourceText)
539
  .replace("{target}", targetText);
540
+
541
  const payload = {
542
  model: "deepseek-chat",
543
  messages: [
544
+ { role: "system", content: "أنت خبير في تحليل ومراجعة النصوص بدقة عالية، وتفهم الاختصارات ومعانيها الكاملة." },
545
  { role: "user", content: prompt }
546
  ],
547
  temperature: 0.3,
548
  max_tokens: 2048,
549
  stream: false
550
  };
551
+
552
  const response = await fetch('https://api.deepseek.com/chat/completions', {
553
  method: 'POST',
554
  headers: {
 
557
  },
558
  body: JSON.stringify(payload)
559
  });
560
+
561
+ if (!response.ok) {
562
+ throw new Error('حدث خطأ بالشبكة: ' + response.statusText);
563
  }
564
  const data = await response.json();
565
  const analysisOutput = data.choices[0].message.content.trim();
566
  progressDiv.remove();
567
+
568
  // إذا كانت النصوص متطابقة تماماً
569
  if (analysisOutput.includes('[MATCH]')) {
570
  const checkDiv = document.createElement('div');
571
  checkDiv.className = "p-4 rounded-xl bg-green-50 text-green-700 flex items-center";
572
+ checkDiv.innerHTML = `<i class="fas fa-check-circle mr-2"></i> <span>النصوص متطابقة تماماً</span>`;
573
  document.getElementById('errorsList').appendChild(checkDiv);
574
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceText);
575
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
576
+ document.getElementById('explanationText').innerHTML = `<p class="text-xl">النصوص متطابقة ولا يوجد اختلاف يجب الإشارة إليه.</p>`;
577
  } else {
578
+ // تطبيق التظليل على النص المصدر فقط
579
  const sourceHighlighted = applyHighlights(sourceText, analysisOutput);
580
  document.getElementById('sourceTextReview').innerHTML = splitIntoLines(sourceHighlighted);
581
+ // عرض النص الهدف بدون تعليم
582
  document.getElementById('targetTextReview').innerHTML = splitIntoLines(targetText);
583
  const explanationHTML = generateExplanation(sourceText, analysisOutput);
584
+ document.getElementById('explanationText').innerHTML = explanationHTML;
 
 
 
 
 
 
585
  }
586
+
587
+ // إظهار قسم التقرير وإدخال بيانات المترجم بعد التحليل
588
+ document.getElementById('reportSection').classList.remove('hidden');
589
+
590
  } catch (error) {
591
  document.getElementById('errorsList').innerHTML = '';
592
  addError(`خطأ في التحليل: ${error.message}`);
593
  }
594
  });
595
+
596
+ // مستمعي الأحداث لأزرار التقرير وإعادة المراجعة
597
+ document.getElementById('downloadPdfBtn').addEventListener('click', downloadReportPDF);
598
+ document.getElementById('downloadWordBtn').addEventListener('click', downloadReportWord);
599
+ document.getElementById('reReviewBtn').addEventListener('click', reReview);
600
+
601
  })();
602
  </script>
603
  </body>
604
+ </html>