File size: 9,692 Bytes
d0d3666
 
 
 
 
ff95748
778176a
d0d3666
27d42c0
d0d3666
ff95748
d0d3666
 
 
 
 
 
 
 
 
ff95748
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
778176a
 
 
 
 
 
 
59b39d8
778176a
 
 
1f458a4
ff95748
382813c
 
 
ff95748
 
 
382813c
 
 
 
 
 
d0d3666
 
27d42c0
778176a
27d42c0
778176a
 
ff95748
d0d3666
778176a
 
 
 
 
 
27d42c0
778176a
 
 
27d42c0
778176a
 
 
 
 
 
27d42c0
778176a
 
 
 
 
 
ff95748
778176a
 
 
 
 
 
 
d0d3666
778176a
d0d3666
778176a
f5f0451
27d42c0
ff95748
 
35d533d
 
 
 
27d42c0
778176a
 
 
f5f0451
778176a
 
f5f0451
778176a
ff95748
778176a
 
 
 
ff95748
778176a
 
 
 
ff95748
778176a
 
ff95748
f5f0451
778176a
 
 
 
 
 
 
 
 
 
f5f0451
ff95748
 
 
 
 
 
 
 
 
 
 
 
f5f0451
 
368929a
778176a
 
ff95748
778176a
ff95748
778176a
 
 
 
 
 
 
 
f5f0451
778176a
f5f0451
368929a
ff95748
778176a
 
ff95748
f5f0451
778176a
ff95748
382813c
ff95748
778176a
 
 
f5f0451
778176a
 
 
368929a
f5f0451
ff95748
f5f0451
d0d3666
 
27d42c0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>تحليل النصوص والترجمات – وضع Streaming</title>
  <!-- استيراد Tailwind CSS وFontAwesome -->
  <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
  <style>
    /* تأثيرات الخلفية والحركة */
    @keyframes gradient {
      0% { background-position: 0% 50%; }
      50% { background-position: 100% 50%; }
      100% { background-position: 0% 50%; }
    }
    .animate-gradient {
      background-size: 200% 200%;
      animation: gradient 15s ease infinite;
    }
    .transition-all { transition: all 0.3s ease-in-out; }
    .animate-scale { transition: transform 0.2s ease-in-out; }
    .animate-scale:hover { transform: scale(1.02); }
    .pulse-animation { animation: pulse 2s infinite; }
    @keyframes pulse {
      0% { box-shadow: 0 0 0 0 rgba(0,0,0,0.2); }
      70% { box-shadow: 0 0 0 10px rgba(0,0,0,0); }
      100% { box-shadow: 0 0 0 0 rgba(0,0,0,0); }
    }
    
    /* تنسيق النصوص */
    .text-comparison { line-height: 1.8; white-space: pre-wrap; }
    .highlight { 
      color: white; 
      background-color: #ef4444; 
      padding: 0 3px; 
      border-radius: 3px; 
      font-weight: bold; 
    }
    
    /* تقسيم الأسطر */
    .line-item {
      margin-bottom: 1rem;
      padding: 0.5rem;
      border-bottom: 1px dashed #ccc;
    }
    .line-number {
      font-weight: bold;
      color: #4B5563;
      margin-left: 0.5rem;
    }
    .line-text { display: inline-block; }
    
    /* تصميم البطاقات */
    .card {
      background-color: #fff;
      border-radius: 1rem;
      box-shadow: 0 10px 25px -5px rgba(0,0,0,0.1);
      padding: 2rem;
      border: 1px solid #f3f4f6;
    }
    .card-hover:hover {
      box-shadow: 0 10px 25px -5px rgba(0,0,0,0.2);
      transform: translateY(-3px);
    }
    .icon { margin-left: 0.5rem; }
    .upload-label {
      display: flex;
      flex-direction: row-reverse;
      align-items: center;
      justify-content: center;
    }
    
    /* مؤشر التحميل */
    .spinner {
      border: 4px solid #f3f3f3;
      border-top: 4px solid #4f46e5;
      border-radius: 50%;
      width: 40px;
      height: 40px;
      animation: spin 1s linear infinite;
    }
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
    
    /* منطقة سلسلة التفكير */
    #chainOfThought {
      display: none;
      margin-top: 1rem;
      background-color: #f9fafb;
      padding: 1rem;
      border: 1px solid #e5e7eb;
      border-radius: 0.5rem;
      font-size: 0.9rem;
      direction: ltr;
      text-align: left;
    }
  </style>
</head>
<body class="bg-gradient-to-br from-gray-100 via-blue-100 to-indigo-100 min-h-screen">
  <div class="max-w-5xl mx-auto py-12">
    <!-- رأس الصفحة -->
    <header class="text-center mb-12">
      <h1 class="text-5xl font-bold mb-4 animate-gradient">تحليل النصوص والترجمات</h1>
      <p class="text-2xl">ترجم النص الهدف إلى العربية مع التعليم، ثم قارن مع النص المصدر واخرج الاختلافات (النصوص الناقصة) فقط.</p>
    </header>

    <!-- منطقة الإدخال -->
    <div class="space-y-6">
      <div>
        <label class="block text-2xl font-bold mb-2">النص المصدر</label>
        <textarea id="sourceText" class="w-full p-4 border rounded-lg" rows="6" placeholder="اكتب النص المصدر هنا..."></textarea>
      </div>
      <div>
        <label class="block text-2xl font-bold mb-2">النص الهدف</label>
        <textarea id="targetText" class="w-full p-4 border rounded-lg" rows="6" placeholder="اكتب النص الهدف هنا..."></textarea>
      </div>
    </div>

    <!-- زر التحليل ومؤشر التحميل -->
    <div class="mt-6 flex items-center justify-center space-x-4">
      <button id="analyzeBtn" class="px-8 py-4 bg-indigo-600 text-white font-bold rounded-lg hover:bg-indigo-700 transition">
        تحليل ومراجعة النصوص
      </button>
      <div id="loadingIndicator" class="spinner hidden"></div>
    </div>

    <!-- منطقة سلسلة التفكير -->
    <div id="chainOfThought" class="mt-6">
      <strong>سلسلة التفكير:</strong>
      <pre id="chainText" class="whitespace-pre-wrap text-gray-700"></pre>
    </div>

    <!-- منطقة النتائج -->
    <div id="resultSection" class="mt-8 hidden">
      <h2 class="text-3xl font-bold mb-4">النتائج:</h2>
      <div id="diffResult" class="p-4 border rounded-lg"></div>
    </div>
  </div>

  <script>
    (function(){
      "use strict";
      
      // برومت بسيط: ترجمة النص الهدف إلى العربية مع التعليم، ثم قارن بين النص المصدر والنص الهدف المُترجم واخرج الاختلافات (النصوص الناقصة) فقط مع وضعها بين أقواس.
      const PROMPT = `ترجم النص الهدف إلى العربية مع التعليم، ثم قارن بين النص المصدر والنص الهدف المُترجم واخرج الاختلافات فقط (النصوص الناقصة) مع وضعها بين أقواس ().
النص المصدر:
{source}
النص الهدف:
{target}`;
      
      // دالة عرض مؤشر التحميل
      const showLoading = () => {
        document.getElementById('loadingIndicator').classList.remove('hidden');
      };
      const hideLoading = () => {
        document.getElementById('loadingIndicator').classList.add('hidden');
      };

      // دالة إرسال الطلب إلى DeepSeek مع تفعيل خاصية streaming
      async function analyzeText(source, target) {
        const payload = {
          model: "deepseek-chat",
          messages: [
            { role: "system", content: "أنت نموذج DeepSeek؛ ترجم النص الهدف إلى العربية مع التعليم ثم قارن بينه وبين النص المصدر واخرج الاختلافات (النصوص الناقصة) فقط مع وضعها بين أقواس ()." },
            { role: "user", content: PROMPT.replace("{source}", source).replace("{target}", target) }
          ],
          temperature: 0.3,
          max_tokens: 1024,
          stream: true
        };

        console.log("Payload:", payload);
        try {
          const response = await fetch("https://api.deepseek.com/chat/completions", {
            method: "POST",
            headers: {
              "Authorization": "Bearer sk-15606736ed9e4aea8b7cc11a195d2b01",
              "Content-Type": "application/json"
            },
            body: JSON.stringify(payload)
          });
          if (!response.ok) {
            throw new Error("حدث خطأ في الاتصال: " + response.statusText);
          }
          // قراءة الاستجابة على شكل تدفق
          const reader = response.body.getReader();
          const decoder = new TextDecoder();
          let result = "";
          while (true) {
            const { done, value } = await reader.read();
            if (done) break;
            result += decoder.decode(value, { stream: true });
            // تحديث سلسلة التفكير بشكل مستمر
            document.getElementById('chainText').innerText = result;
          }
          return result;
        } catch (error) {
          throw error;
        }
      }
      
      // دالة بسيطة لمعالجة النتيجة: هنا نضع الاختلافات بين أقواس
      function processResult(source, analysisOutput) {
        // على سبيل المثال: افترض أن الاختلافات تظهر بين علامتي __ للنص المفقود
        let processed = analysisOutput.replace(/__(.*?)__/g, '<span class="highlight">($1)</span>');
        return processed;
      }
      
      // مستمع الزر
      document.getElementById('analyzeBtn').addEventListener('click', async () => {
        const sourceText = document.getElementById('sourceText').value.trim();
        const targetText = document.getElementById('targetText').value.trim();
        if (!sourceText || !targetText) {
          alert("يرجى إدخال كلا النصين.");
          return;
        }
        // إخفاء النتائج الحالية وإظهار مؤشر التحميل
        document.getElementById('resultSection').classList.add('hidden');
        document.getElementById('chainOfThought').style.display = "none";
        showLoading();
        try {
          const analysisOutput = await analyzeText(sourceText, targetText);
          // عرض سلسلة التفكير بعد استقبال البيانات
          document.getElementById('chainOfThought').style.display = "block";
          // معالجة الناتج وتطبيق التظليل
          const diffResult = processResult(sourceText, analysisOutput);
          document.getElementById('diffResult').innerHTML = diffResult;
          document.getElementById('resultSection').classList.remove('hidden');
        } catch (error) {
          alert("خطأ أثناء التحليل: " + error.message);
        } finally {
          hideLoading();
        }
      });
      
    })();
  </script>
</body>
</html>