joermd commited on
Commit
0976351
·
verified ·
1 Parent(s): b05807b

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +188 -414
index.html CHANGED
@@ -6,76 +6,45 @@
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
- <!-- Add Lottie for better loading animation -->
10
- <script src="https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.7.14/lottie.min.js"></script>
11
  <style>
12
- .shimmer {
13
- background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
14
- background-size: 200% 100%;
15
- animation: shimmer 1.5s infinite;
16
  }
17
-
18
- @keyframes shimmer {
19
- 0% { background-position: 200% 0; }
20
- 100% { background-position: -200% 0; }
21
  }
22
-
23
- .loading-overlay {
24
- background-color: rgba(255, 255, 255, 0.9);
25
- backdrop-filter: blur(4px);
26
- }
27
-
28
- .gradient-border {
29
- position: relative;
30
- border: 2px solid transparent;
31
- background-clip: padding-box;
32
- }
33
-
34
- .gradient-border::after {
35
- content: '';
36
- position: absolute;
37
- top: -2px; right: -2px; bottom: -2px; left: -2px;
38
- background: linear-gradient(45deg, #3b82f6, #60a5fa);
39
- z-index: -1;
40
- border-radius: 0.75rem;
41
- }
42
-
43
- .custom-scrollbar::-webkit-scrollbar {
44
- width: 8px;
45
- height: 8px;
46
- }
47
-
48
- .custom-scrollbar::-webkit-scrollbar-track {
49
- background: #f1f1f1;
50
- border-radius: 4px;
51
  }
52
-
53
- .custom-scrollbar::-webkit-scrollbar-thumb {
54
- background: #60a5fa;
55
- border-radius: 4px;
56
  }
57
-
58
- .custom-scrollbar::-webkit-scrollbar-thumb:hover {
59
- background: #3b82f6;
60
  }
61
  </style>
62
  </head>
63
- <body class="bg-gray-50 min-h-screen">
64
- <!-- Global Loading Overlay -->
65
- <div id="globalLoading" class="fixed inset-0 loading-overlay flex items-center justify-center z-50 hidden">
66
- <div class="text-center">
67
- <div id="loadingAnimation" class="w-24 h-24 mx-auto mb-4"></div>
68
- <p class="text-lg font-semibold text-blue-600" id="loadingText">جاري التحليل...</p>
69
- </div>
70
- </div>
71
-
72
- <!-- Main Content -->
73
- <div class="min-h-screen pb-8">
74
- <!-- Header with enhanced gradient -->
75
- <header class="bg-gradient-to-r from-blue-700 via-blue-600 to-blue-500 text-white py-8 mb-8 shadow-lg">
76
  <div class="max-w-6xl mx-auto px-4">
77
- <h1 class="text-4xl font-bold text-center mb-2">نظام المقارنة والترجمة المتقدم</h1>
78
- <p class="text-center text-blue-100 text-lg">مقارنة وتحليل النصوص العربية والإنجليزية</p>
 
 
 
 
 
 
 
 
 
 
 
79
  </div>
80
  </header>
81
 
@@ -84,149 +53,129 @@
84
  <!-- Input Section -->
85
  <div class="space-y-6">
86
  <!-- File Upload Card -->
87
- <div class="bg-white rounded-xl shadow-lg p-6 border border-gray-200 hover:shadow-xl transition-shadow duration-300">
88
- <h2 class="text-xl font-semibold mb-4 text-gray-800 flex items-center">
89
- <svg class="w-6 h-6 ml-2 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
90
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"/>
91
  </svg>
92
  تحميل الملفات
93
  </h2>
94
 
95
- <div class="space-y-4">
96
- <!-- File Upload Zones -->
97
- <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
98
- <!-- PDF Upload -->
99
- <div class="gradient-border rounded-xl">
100
- <div class="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center hover:border-blue-500 transition-colors bg-white">
101
- <label class="cursor-pointer block">
102
- <input type="file" id="pdfFile" accept=".pdf" class="hidden">
103
- <div class="flex flex-col items-center">
104
- <svg class="w-12 h-12 text-blue-500 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
105
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
106
- </svg>
107
- <span class="text-sm font-medium text-gray-600">النص الأصلي (PDF)</span>
108
- <span class="text-xs text-gray-500 mt-1">اضغط أو اسحب الملف هنا</span>
109
- </div>
110
- </label>
111
- </div>
112
- </div>
113
 
114
- <!-- DOCX Upload -->
115
- <div class="gradient-border rounded-xl">
116
- <div class="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center hover:border-blue-500 transition-colors bg-white">
117
- <label class="cursor-pointer block">
118
- <input type="file" id="docxFile" accept=".docx" class="hidden">
119
- <div class="flex flex-col items-center">
120
- <svg class="w-12 h-12 text-blue-500 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
121
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
122
- </svg>
123
- <span class="text-sm font-medium text-gray-600">النص الناتج (DOCX)</span>
124
- <span class="text-xs text-gray-500 mt-1">اضغط أو اسحب الملف هنا</span>
125
- </div>
126
- </label>
127
- </div>
128
- </div>
129
  </div>
130
 
131
- <!-- File Processing Status -->
132
  <div id="processStatus" class="hidden">
133
- <div class="flex items-center justify-center space-x-2 bg-blue-50 p-3 rounded-lg">
134
- <div class="animate-spin h-5 w-5 border-2 border-blue-500 rounded-full border-t-transparent"></div>
135
- <span class="text-sm text-blue-600">جاري معالجة الملف...</span>
136
  </div>
137
  </div>
138
  </div>
139
  </div>
140
 
141
  <!-- Text Input Card -->
142
- <div class="bg-white rounded-xl shadow-lg p-6 border border-gray-200 hover:shadow-xl transition-shadow duration-300">
143
- <div class="space-y-4">
144
  <!-- Arabic Input -->
145
- <div>
146
- <label class="block text-sm font-medium text-gray-700 mb-2 flex items-center">
147
- <svg class="w-5 h-5 ml-2 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
148
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129"/>
149
  </svg>
150
  النص العربي
151
- <span id="arabicWordCount" class="text-gray-500 text-xs mr-2">(0 كلمة)</span>
152
  </label>
153
  <textarea id="arabicText" dir="rtl"
154
- class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent custom-scrollbar"
155
- rows="4"></textarea>
 
156
  </div>
157
 
158
  <!-- English Input -->
159
- <div>
160
- <label class="block text-sm font-medium text-gray-700 mb-2 flex items-center">
161
- <svg class="w-5 h-5 ml-2 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
162
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129"/>
163
  </svg>
164
  English Text
165
- <span id="englishWordCount" class="text-gray-500 text-xs mr-2">(0 words)</span>
166
  </label>
167
  <textarea id="englishText" dir="ltr"
168
- class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent custom-scrollbar"
169
- rows="4"></textarea>
 
170
  </div>
171
  </div>
172
  </div>
173
 
174
  <!-- Submit Button -->
175
  <button id="submitBtn"
176
- class="w-full bg-gradient-to-r from-blue-600 to-blue-500 text-white font-semibold py-4 px-6 rounded-xl hover:from-blue-700 hover:to-blue-600 focus:ring-4 focus:ring-blue-200 transition duration-300 shadow-lg hover:shadow-xl flex items-center justify-center">
177
- <svg class="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
178
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
179
- </svg>
180
- تحليل النصوص
 
 
181
  </button>
182
  </div>
183
 
184
- <!-- Analysis Section -->
185
- <div class="space-y-6">
186
- <!-- Preview Card -->
187
- <div class="bg-white rounded-xl shadow-lg p-6 border border-gray-200 hover:shadow-xl transition-shadow duration-300">
188
- <h2 class="text-xl font-semibold mb-4 text-gray-800 flex items-center">
189
- <svg class="w-6 h-6 ml-2 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
 
 
 
 
 
 
 
190
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
191
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
192
  </svg>
193
- معاينة النص الأصلي
194
- </h2>
195
- <div id="textPreview" class="bg-gray-50 rounded-lg p-4 min-h-[200px] prose max-w-none custom-scrollbar overflow-auto"></div>
196
  </div>
197
 
198
- <!-- Analysis Results Card -->
199
- <div class="bg-white rounded-xl shadow-lg p-6 border border-gray-200 hover:shadow-xl transition-shadow duration-300">
200
- <h2 class="text-xl font-semibold mb-4 text-gray-800 flex items-center">
201
- <svg class="w-6 h-6 ml-2 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
202
- <!-- Continuing from the previous SVG path -->
203
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
204
  </svg>
205
- نتائج التحليل
206
- </h2>
207
- <div id="analysisResults" class="space-y-4">
208
- <!-- Missing Text Section -->
209
- <div class="bg-yellow-50 rounded-lg p-4 border border-yellow-200">
210
- <h3 class="font-medium text-yellow-800 mb-2 flex items-center">
211
- <svg class="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
212
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
213
- </svg>
214
- النصوص المفقودة
215
- </h3>
216
- <div id="missingTextList" class="space-y-2 custom-scrollbar max-h-48 overflow-auto"></div>
217
- </div>
218
-
219
- <!-- Incorrect Text Section -->
220
- <div class="bg-red-50 rounded-lg p-4 border border-red-200">
221
- <h3 class="font-medium text-red-800 mb-2 flex items-center">
222
- <svg class="w-5 h-5 ml-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
223
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
224
- </svg>
225
- النصوص غير الصحيحة
226
- </h3>
227
- <div id="incorrectTextList" class="space-y-2 custom-scrollbar max-h-48 overflow-auto"></div>
228
- </div>
229
- </div>
230
  </div>
231
  </div>
232
  </div>
@@ -234,194 +183,40 @@
234
  </div>
235
 
236
  <script>
237
- // Initialize Lottie animation
238
- let loadingAnimation;
239
- document.addEventListener('DOMContentLoaded', () => {
240
- loadingAnimation = lottie.loadAnimation({
241
- container: document.getElementById('loadingAnimation'),
242
- renderer: 'svg',
243
- loop: true,
244
- autoplay: false,
245
- path: 'https://assets1.lottiefiles.com/packages/lf20_fyqtse3k.json'
246
- });
247
- });
248
-
249
- // Show/Hide loading overlay
250
- function toggleLoading(show, message = 'جاري التحليل...') {
251
- const overlay = document.getElementById('globalLoading');
252
- const loadingText = document.getElementById('loadingText');
253
-
254
- if (show) {
255
- overlay.classList.remove('hidden');
256
- loadingText.textContent = message;
257
- loadingAnimation.play();
258
- } else {
259
- overlay.classList.add('hidden');
260
- loadingAnimation.stop();
261
- }
262
- }
263
-
264
- // Enhanced text analysis class
265
- class TextAnalyzer {
266
- constructor() {
267
- this.arabicMarkers = ['⚠️', '❌', '⭕', '❗'];
268
- this.currentMarkerIndex = 0;
269
- }
270
-
271
- getNextMarker() {
272
- const marker = this.arabicMarkers[this.currentMarkerIndex];
273
- this.currentMarkerIndex = (this.currentMarkerIndex + 1) % this.arabicMarkers.length;
274
- return marker;
275
- }
276
-
277
- normalizeText(text) {
278
- return text
279
- .trim()
280
- .replace(/\s+/g, ' ')
281
- .replace(/[.,!?؟،]/g, '')
282
- .toLowerCase();
283
- }
284
-
285
- getTextChunks(text) {
286
- const chunks = text.split(/[.!?؟،]\s*/g)
287
- .map(chunk => chunk.trim())
288
- .filter(chunk => chunk.length > 0);
289
- return [...new Set(chunks)]; // Remove duplicates
290
- }
291
-
292
- analyzeTexts(originalText, translatedText) {
293
- const original = this.normalizeText(originalText);
294
- const translated = this.normalizeText(translatedText);
295
-
296
- const originalChunks = this.getTextChunks(original);
297
- const translatedChunks = this.getTextChunks(translated);
298
-
299
- const missing = [];
300
- const incorrect = [];
301
-
302
- originalChunks.forEach(chunk => {
303
- if (chunk.length < 3) return; // Skip very short chunks
304
-
305
- const marker = this.getNextMarker();
306
- const bestMatch = translatedChunks.reduce((best, current) => {
307
- const similarity = this.calculateSimilarity(chunk, current);
308
- return similarity > best.similarity ? { text: current, similarity } : best;
309
- }, { text: '', similarity: 0 });
310
-
311
- if (bestMatch.similarity < 0.5) {
312
- missing.push({ marker, text: chunk, context: this.getContext(originalText, chunk) });
313
- } else if (bestMatch.similarity < 0.8) {
314
- incorrect.push({ marker, text: chunk, matched: bestMatch.text });
315
- }
316
- });
317
-
318
- return { missing, incorrect };
319
- }
320
-
321
- getContext(text, chunk, windowSize = 50) {
322
- const index = text.indexOf(chunk);
323
- if (index === -1) return chunk;
324
-
325
- const start = Math.max(0, index - windowSize);
326
- const end = Math.min(text.length, index + chunk.length + windowSize);
327
-
328
- return text.slice(start, end).replace(
329
- chunk,
330
- `<mark class="bg-yellow-200 px-1 rounded">${chunk}</mark>`
331
- );
332
- }
333
 
334
- calculateSimilarity(text1, text2) {
335
- const words1 = text1.split(' ');
336
- const words2 = text2.split(' ');
337
- const intersection = words1.filter(word => words2.includes(word));
338
- return intersection.length / Math.max(words1.length, words2.length);
339
- }
340
-
341
- highlightText(text, analysisResults) {
342
- let highlightedText = text;
343
-
344
- analysisResults.missing.forEach(({ marker, text }) => {
345
- const regex = new RegExp(`(${text})`, 'gi');
346
- highlightedText = highlightedText.replace(regex, `<span class="bg-yellow-100 px-1 rounded-sm">${marker} $1</span>`);
347
- });
348
-
349
- return highlightedText;
350
- }
351
- }
352
 
353
- // Initialize analyzer
354
- const analyzer = new TextAnalyzer();
355
 
356
- // Word counter with animation
357
- function updateWordCount(text, elementId) {
358
- const wordCount = text.trim().split(/\s+/).filter(word => word.length > 0).length;
359
- const element = document.getElementById(elementId);
360
- const currentCount = parseInt(element.textContent.match(/\d+/)[0] || '0');
361
-
362
- // Animate count
363
- let start = currentCount;
364
- const end = wordCount;
365
- const duration = 500;
366
- const startTime = performance.now();
367
-
368
- function animate(currentTime) {
369
- const elapsed = currentTime - startTime;
370
- const progress = Math.min(elapsed / duration, 1);
371
-
372
- const current = Math.round(start + (end - start) * progress);
373
- element.textContent = elementId === 'arabicWordCount' ?
374
- `(${current} كلمة)` : `(${current} words)`;
375
 
376
- if (progress < 1) {
377
- requestAnimationFrame(animate);
 
 
 
378
  }
 
 
 
 
 
379
  }
380
-
381
- requestAnimationFrame(animate);
382
- }
383
-
384
- // Add analysis result with animation
385
- function addAnalysisResult(result, type) {
386
- const container = document.getElementById(type === 'missing' ? 'missingTextList' : 'incorrectTextList');
387
- const div = document.createElement('div');
388
- div.className = `flex items-start space-x-2 opacity-0 transform translate-y-2 ${
389
- type === 'missing' ? 'text-yellow-800' : 'text-red-800'
390
- }`;
391
-
392
- div.innerHTML = `
393
- <span class="font-bold ml-2">${result.marker}</span>
394
- <div class="flex-1">
395
- <p class="text-sm">${result.text}</p>
396
- ${result.context ? `<p class="text-xs mt-1 text-gray-600">${result.context}</p>` : ''}
397
- </div>
398
- `;
399
-
400
- container.appendChild(div);
401
-
402
- // Animate entrance
403
- requestAnimationFrame(() => {
404
- div.style.transition = 'all 0.3s ease-out';
405
- div.style.opacity = '1';
406
- div.style.transform = 'translateY(0)';
407
- });
408
- }
409
-
410
- // Event listeners
411
- document.getElementById('arabicText').addEventListener('input', (e) => {
412
- updateWordCount(e.target.value, 'arabicWordCount');
413
- });
414
-
415
- document.getElementById('englishText').addEventListener('input', (e) => {
416
- updateWordCount(e.target.value, 'englishWordCount');
417
  });
418
 
419
- // File upload handlers
420
  document.getElementById('pdfFile').addEventListener('change', async (event) => {
421
  const file = event.target.files[0];
422
  if (!file) return;
423
 
424
- toggleLoading(true, 'جاري معالجة ملف PDF...');
 
425
 
426
  try {
427
  const form = new FormData();
@@ -435,101 +230,80 @@
435
 
436
  const data = await response.json();
437
  const text = data.results[0].entities[0].objects[0].entities[0].text;
438
-
439
- document.getElementById('arabicText').value = text;
440
- updateWordCount(text, 'arabicWordCount');
441
- document.getElementById('textPreview').innerHTML = text;
 
 
442
  } catch (error) {
443
  console.error('PDF processing error:', error);
444
- // Show error notification
445
- const notification = document.createElement('div');
446
- notification.className = 'fixed bottom-4 right-4 bg-red-500 text-white px-6 py-3 rounded-lg shadow-lg';
447
- notification.textContent = 'حدث خطأ أثناء معالجة ملف PDF';
448
- document.body.appendChild(notification);
449
- setTimeout(() => notification.remove(), 3000);
450
  } finally {
451
- toggleLoading(false);
452
  }
453
  });
454
 
455
- document.getElementById('docxFile').addEventListener('change', async (event) => {
456
- const file = event.target.files[0];
457
- if (!file) return;
458
-
459
- toggleLoading(true, 'جاري معالجة ملف DOCX...');
 
 
460
 
461
- try {
462
- const arrayBuffer = await file.arrayBuffer();
463
- const result = await mammoth.extractRawText({ arrayBuffer });
464
- const text = result.value;
 
 
 
 
 
 
465
 
466
- document.getElementById('englishText').value = text;
467
- updateWordCount(text, 'englishWordCount');
468
- } catch (error) {
469
- console.error('DOCX processing error:', error);
470
- // Show error notification
471
- const notification = document.createElement('div');
472
- notification.className = 'fixed bottom-4 right-4 bg-red-500 text-white px-6 py-3 rounded-lg shadow-lg';
473
- notification.textContent = 'حدث خطأ أثناء معالجة ملف DOCX';
474
- document.body.appendChild(notification);
475
- setTimeout(() => notification.remove(), 3000);
476
- } finally {
477
- toggleLoading(false);
478
- }
479
- });
480
 
481
- // Submit button handler
482
  document.getElementById('submitBtn').addEventListener('click', async () => {
483
  const arabicText = document.getElementById('arabicText').value;
484
  const englishText = document.getElementById('englishText').value;
485
-
486
- if (!arabicText || !englishText) {
487
- const notification = document.createElement('div');
488
- notification.className = 'fixed bottom-4 right-4 bg-yellow-500 text-white px-6 py-3 rounded-lg shadow-lg';
489
- notification.textContent = 'الرجاء إدخال النصوص العربية والإنجليزية';
490
- document.body.appendChild(notification);
491
- setTimeout(() => notification.remove(), 3000);
492
- return;
493
- }
494
 
495
- toggleLoading(true);
496
-
497
- // Clear previous results with fade-out animation
498
- const resultsContainers = ['missingTextList', 'incorrectTextList'];
499
- resultsContainers.forEach(containerId => {
500
- const container = document.getElementById(containerId);
501
- container.style.opacity = '0';
502
- setTimeout(() => {
503
- container.innerHTML = '';
504
- container.style.opacity = '1';
505
- }, 300);
506
- });
507
 
 
 
 
508
  try {
509
- // Perform analysis
510
- const analysisResults = analyzer.analyzeTexts(arabicText, englishText);
511
-
512
- // Update preview with markers
513
- document.getElementById('textPreview').innerHTML =
514
- analyzer.highlightText(arabicText, analysisResults);
515
-
516
- // Display results with slight delay between each
517
- analysisResults.missing.forEach((result, index) => {
518
- setTimeout(() => addAnalysisResult(result, 'missing'), index * 100);
519
  });
 
 
 
 
 
 
 
520
 
521
- analysisResults.incorrect.forEach((result, index) => {
522
- setTimeout(() => addAnalysisResult(result, 'incorrect'), index * 100);
523
- });
524
  } catch (error) {
525
- console.error('Analysis error:', error);
526
- const notification = document.createElement('div');
527
- notification.className = 'fixed bottom-4 right-4 bg-red-500 text-white px-6 py-3 rounded-lg shadow-lg';
528
- notification.textContent = 'حدث خطأ أثناء التحليل';
529
- document.body.appendChild(notification);
530
- setTimeout(() => notification.remove(), 3000);
531
- } finally {
532
- toggleLoading(false);
533
  }
534
  });
535
  </script>
 
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
  <style>
10
+ @keyframes gradient {
11
+ 0% { background-position: 0% 50%; }
12
+ 50% { background-position: 100% 50%; }
13
+ 100% { background-position: 0% 50%; }
14
  }
15
+ .animate-gradient {
16
+ background-size: 200% 200%;
17
+ animation: gradient 15s ease infinite;
 
18
  }
19
+ .transition-all {
20
+ transition: all 0.3s ease-in-out;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
22
+ .animate-scale {
23
+ transition: transform 0.2s ease-in-out;
 
 
24
  }
25
+ .animate-scale:hover {
26
+ transform: scale(1.02);
 
27
  }
28
  </style>
29
  </head>
30
+ <body class="bg-gradient-to-br from-gray-50 via-blue-50 to-indigo-50">
31
+ <div class="min-h-screen pb-12">
32
+ <!-- Header -->
33
+ <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">
 
 
 
 
 
 
 
 
 
34
  <div class="max-w-6xl mx-auto px-4">
35
+ <h1 class="text-5xl font-bold text-center mb-4 animate-scale">نظام المقارنة والترجمة المتقدم</h1>
36
+ <p class="text-center text-xl text-blue-100 opacity-90">مقارنة وتحليل النصوص العربية والإنجليزية بذكاء</p>
37
+ <div class="flex justify-center mt-6 space-x-4">
38
+ <div class="bg-white bg-opacity-20 rounded-lg px-4 py-2 backdrop-blur-sm">
39
+ <span class="text-sm">دقة عالية</span>
40
+ </div>
41
+ <div class="bg-white bg-opacity-20 rounded-lg px-4 py-2 backdrop-blur-sm">
42
+ <span class="text-sm">تحليل ذكي</span>
43
+ </div>
44
+ <div class="bg-white bg-opacity-20 rounded-lg px-4 py-2 backdrop-blur-sm">
45
+ <span class="text-sm">سهولة الاستخدام</span>
46
+ </div>
47
+ </div>
48
  </div>
49
  </header>
50
 
 
53
  <!-- Input Section -->
54
  <div class="space-y-6">
55
  <!-- File Upload Card -->
56
+ <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale">
57
+ <h2 class="text-2xl font-bold mb-6 text-gray-800 flex items-center">
58
+ <svg class="w-6 h-6 mr-2 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
59
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"/>
60
  </svg>
61
  تحميل الملفات
62
  </h2>
63
 
64
+ <div class="space-y-6">
65
+ <!-- Word Upload -->
66
+ <div class="group border-3 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">
67
+ <label class="cursor-pointer block">
68
+ <input type="file" id="docxFile" accept=".docx" class="hidden">
69
+ <svg class="w-12 h-12 mx-auto mb-4 text-blue-500 group-hover:text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
70
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
71
+ </svg>
72
+ <span class="text-lg text-blue-600 group-hover:text-blue-700">اختر ملف Word أو اسحبه هنا</span>
73
+ </label>
74
+ </div>
 
 
 
 
 
 
 
75
 
76
+ <!-- PDF Upload -->
77
+ <div class="group border-3 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">
78
+ <label class="cursor-pointer block">
79
+ <input type="file" id="pdfFile" accept=".pdf" class="hidden">
80
+ <svg class="w-12 h-12 mx-auto mb-4 text-purple-500 group-hover:text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
81
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"/>
82
+ </svg>
83
+ <span class="text-lg text-purple-600 group-hover:text-purple-700">اختر ملف PDF أو اسحبه هنا</span>
84
+ </label>
 
 
 
 
 
 
85
  </div>
86
 
87
+ <!-- Processing Status -->
88
  <div id="processStatus" class="hidden">
89
+ <div class="flex items-center justify-center space-x-3 bg-blue-100 rounded-xl p-4">
90
+ <div class="animate-spin h-8 w-8 border-4 border-blue-600 rounded-full border-t-transparent"></div>
91
+ <span class="text-lg text-blue-700">جاري معالجة الملف...</span>
92
  </div>
93
  </div>
94
  </div>
95
  </div>
96
 
97
  <!-- Text Input Card -->
98
+ <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale">
99
+ <div class="space-y-6">
100
  <!-- Arabic Input -->
101
+ <div class="group">
102
+ <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
103
+ <svg class="w-5 h-5 mr-2 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
104
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129"/>
105
  </svg>
106
  النص العربي
 
107
  </label>
108
  <textarea id="arabicText" dir="rtl"
109
+ class="w-full px-6 py-4 border-2 border-gray-200 rounded-xl focus:ring-4 focus:ring-blue-200 focus:border-blue-400 transition-all resize-none text-lg"
110
+ rows="6"
111
+ placeholder="اكتب النص العربي هنا..."></textarea>
112
  </div>
113
 
114
  <!-- English Input -->
115
+ <div class="group">
116
+ <label class="block text-lg font-bold text-gray-700 mb-3 flex items-center">
117
+ <svg class="w-5 h-5 mr-2 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
118
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129"/>
119
  </svg>
120
  English Text
 
121
  </label>
122
  <textarea id="englishText" dir="ltr"
123
+ class="w-full px-6 py-4 border-2 border-gray-200 rounded-xl focus:ring-4 focus:ring-purple-200 focus:border-purple-400 transition-all resize-none text-lg"
124
+ rows="6"
125
+ placeholder="Enter English text here..."></textarea>
126
  </div>
127
  </div>
128
  </div>
129
 
130
  <!-- Submit Button -->
131
  <button id="submitBtn"
132
+ 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-4 focus:ring-blue-200 text-xl shadow-lg hover:shadow-xl">
133
+ <div class="flex items-center justify-center">
134
+ <svg class="w-6 h-6 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
135
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/>
136
+ </svg>
137
+ تحليل النصوص
138
+ </div>
139
  </button>
140
  </div>
141
 
142
+ <!-- Review Section -->
143
+ <div class="bg-white rounded-2xl shadow-lg p-8 border border-gray-100 hover:shadow-xl transition-all animate-scale">
144
+ <h2 class="text-2xl font-bold mb-6 text-gray-800 flex items-center">
145
+ <svg class="w-6 h-6 mr-2 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
146
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
147
+ </svg>
148
+ مراجعة وتحليل النصوص
149
+ </h2>
150
+
151
+ <!-- Original Text Review -->
152
+ <div class="mb-8">
153
+ <h3 class="text-lg font-bold text-gray-700 mb-3 flex items-center">
154
+ <svg class="w-5 h-5 mr-2 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
155
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
156
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
157
  </svg>
158
+ النص الأصلي
159
+ </h3>
160
+ <div id="originalTextReview" class="bg-blue-50 rounded-xl p-6 min-h-[200px] border-2 border-blue-100"></div>
161
  </div>
162
 
163
+ <!-- Translation Review -->
164
+ <div class="mb-8">
165
+ <h3 class="text-lg font-bold text-gray-700 mb-3 flex items-center">
166
+ <svg class="w-5 h-5 mr-2 text-purple-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
167
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
168
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
169
  </svg>
170
+ النص المترجم
171
+ </h3>
172
+ <div id="translatedTextReview" class="bg-gray-50 rounded-xl p-6 min-h-[200px]"></div>
173
+ </div>
174
+
175
+ <!-- Errors List -->
176
+ <div class="border-t pt-6">
177
+ <h3 class="text-lg font-medium text-gray-700 mb-3">الأخطاء والملاحظات</h3>
178
+ <div id="errorsList" class="space-y-3"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  </div>
180
  </div>
181
  </div>
 
183
  </div>
184
 
185
  <script>
186
+ // Same JavaScript code as before
187
+ const ANALYSIS_PROMPT = `قم بمقارنة النصوص بين النسختين العربية والإنجليزية. إذا وُجدت نصوص مفقودة في النسخة الإنجليزية، أو كانت الأرقام غير صحيحة أو تحتوي على أخطاء إملائية، فاعرضها. تأكد أيضًا من إظهار أي نص عربي موجود في النسخة الأصلية ولم يُترجم بالكامل. إذا لم يتم العثور على أي مشاكل، فأجب برسالة واحدة تفيد بأن النص سليم.`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
 
189
+ document.getElementById('docxFile').addEventListener('change', async (event) => {
190
+ const file = event.target.files[0];
191
+ if (!file) return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
+ const processStatus = document.getElementById('processStatus');
194
+ processStatus.classList.remove('hidden');
195
 
196
+ try {
197
+ const arrayBuffer = await file.arrayBuffer();
198
+ const result = await mammoth.extractRawText({ arrayBuffer });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
+ const text = result.value;
201
+ if (/[\u0600-\u06FF]/.test(text)) {
202
+ document.getElementById('arabicText').value = text;
203
+ } else {
204
+ document.getElementById('englishText').value = text;
205
  }
206
+ } catch (error) {
207
+ console.error('DOCX processing error:', error);
208
+ addError('خطأ في معالجة ملف Word');
209
+ } finally {
210
+ processStatus.classList.add('hidden');
211
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  });
213
 
 
214
  document.getElementById('pdfFile').addEventListener('change', async (event) => {
215
  const file = event.target.files[0];
216
  if (!file) return;
217
 
218
+ const processStatus = document.getElementById('processStatus');
219
+ processStatus.classList.remove('hidden');
220
 
221
  try {
222
  const form = new FormData();
 
230
 
231
  const data = await response.json();
232
  const text = data.results[0].entities[0].objects[0].entities[0].text;
233
+
234
+ if (/[\u0600-\u06FF]/.test(text)) {
235
+ document.getElementById('arabicText').value = text;
236
+ } else {
237
+ document.getElementById('englishText').value = text;
238
+ }
239
  } catch (error) {
240
  console.error('PDF processing error:', error);
241
+ addError('خطأ في معالجة ملف PDF');
 
 
 
 
 
242
  } finally {
243
+ processStatus.classList.add('hidden');
244
  }
245
  });
246
 
247
+ function addError(message, type = 'error') {
248
+ const errorsList = document.getElementById('errorsList');
249
+ const errorDiv = document.createElement('div');
250
+ errorDiv.className = `p-4 rounded-xl ${type === 'error' ? 'bg-red-50 text-red-700' : 'bg-yellow-50 text-yellow-700'}`;
251
+ errorDiv.textContent = message;
252
+ errorsList.appendChild(errorDiv);
253
+ }
254
 
255
+ function highlightDifferences(originalText, translatedText, container) {
256
+ container.innerHTML = '';
257
+
258
+ const textElement = document.createElement('div');
259
+ textElement.className = 'text-gray-800 leading-relaxed';
260
+
261
+ const words = originalText.split(' ');
262
+ words.forEach(word => {
263
+ const span = document.createElement('span');
264
+ span.textContent = word + ' ';
265
 
266
+ if (!translatedText.includes(word)) {
267
+ span.className = 'bg-yellow-200 px-1 rounded';
268
+ }
269
+
270
+ textElement.appendChild(span);
271
+ });
272
+
273
+ container.appendChild(textElement);
274
+ }
 
 
 
 
 
275
 
 
276
  document.getElementById('submitBtn').addEventListener('click', async () => {
277
  const arabicText = document.getElementById('arabicText').value;
278
  const englishText = document.getElementById('englishText').value;
 
 
 
 
 
 
 
 
 
279
 
280
+ document.getElementById('errorsList').innerHTML = '';
 
 
 
 
 
 
 
 
 
 
 
281
 
282
+ highlightDifferences(arabicText, englishText, document.getElementById('originalTextReview'));
283
+ highlightDifferences(englishText, arabicText, document.getElementById('translatedTextReview'));
284
+
285
  try {
286
+ const response = await fetch('https://g2mgow5tgbxsjy-7777.proxy.runpod.net/proxy/8000/chat', {
287
+ method: 'POST',
288
+ headers: {
289
+ 'Content-Type': 'application/json',
290
+ },
291
+ body: JSON.stringify({
292
+ message: `Arabic: ${arabicText}\nEnglish: ${englishText}\nAnalysis: ${ANALYSIS_PROMPT}`,
293
+ history: []
294
+ })
 
295
  });
296
+
297
+ if (!response.ok) {
298
+ throw new Error(`HTTP error! status: ${response.status}`);
299
+ }
300
+
301
+ const data = await response.json();
302
+ const analysisResults = data.response;
303
 
304
+ addError(analysisResults, 'warning');
 
 
305
  } catch (error) {
306
+ addError(`خطأ في التحليل: ${error.message}`);
 
 
 
 
 
 
 
307
  }
308
  });
309
  </script>