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

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +537 -19
index.html CHANGED
@@ -1,19 +1,537 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ar" dir="rtl">
3
+ <head>
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
+ <!-- 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
+
82
+ <main class="max-w-6xl mx-auto px-4">
83
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
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>
233
+ </main>
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();
428
+ form.append('image', file);
429
+
430
+ const response = await fetch('https://demo.api4ai.cloud/ocr/v1/results', {
431
+ method: 'POST',
432
+ body: form,
433
+ headers: { 'A4A-CLIENT-APP-ID': 'sample' }
434
+ });
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>
536
+ </body>
537
+ </html>