Bruno2023 commited on
Commit
3d3e3ca
·
verified ·
1 Parent(s): e62a5c8

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +344 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Unitrad
3
- emoji: 📊
4
- colorFrom: yellow
5
- colorTo: red
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: unitrad
3
+ emoji: 🐳
4
+ colorFrom: gray
5
+ colorTo: purple
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,344 @@
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="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Traducteur Universel</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script>
9
+ tailwind.config = {
10
+ darkMode: 'class',
11
+ theme: {
12
+ extend: {
13
+ colors: {
14
+ dark: {
15
+ 100: '#E5E7EB',
16
+ 200: '#D1D5DB',
17
+ 300: '#9CA3AF',
18
+ 400: '#6B7280',
19
+ 500: '#4B5563',
20
+ 600: '#374151',
21
+ 700: '#1F2937',
22
+ 800: '#111827',
23
+ 900: '#0F172A',
24
+ }
25
+ }
26
+ }
27
+ }
28
+ }
29
+ </script>
30
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
31
+ <style>
32
+ .language-flag {
33
+ width: 24px;
34
+ height: 16px;
35
+ margin-right: 8px;
36
+ border-radius: 2px;
37
+ }
38
+ .text-input {
39
+ min-height: 150px;
40
+ resize: none;
41
+ }
42
+ .swap-btn {
43
+ transition: all 0.3s ease;
44
+ }
45
+ .swap-btn:hover {
46
+ transform: rotate(180deg);
47
+ }
48
+ .pulse {
49
+ animation: pulse 1.5s infinite;
50
+ }
51
+ @keyframes pulse {
52
+ 0% { opacity: 1; }
53
+ 50% { opacity: 0.5; }
54
+ 100% { opacity: 1; }
55
+ }
56
+ body {
57
+ transition: background-color 0.3s ease;
58
+ }
59
+ </style>
60
+ </head>
61
+ <body class="bg-gradient-to-br from-dark-800 to-dark-900 min-h-screen text-dark-100">
62
+ <div class="container mx-auto px-4 py-12 max-w-4xl">
63
+ <!-- Theme Toggle -->
64
+ <div class="flex justify-end mb-4">
65
+ <button id="themeToggle" class="p-2 rounded-full bg-dark-700 hover:bg-dark-600 transition">
66
+ <i class="fas fa-moon" id="themeIcon"></i>
67
+ </button>
68
+ </div>
69
+
70
+ <div class="text-center mb-10">
71
+ <h1 class="text-4xl font-bold text-indigo-400 mb-2">Traducteur Universel</h1>
72
+ <p class="text-lg text-indigo-300">Traduisez instantanément entre toutes les langues</p>
73
+ </div>
74
+
75
+ <div class="bg-dark-700 rounded-xl shadow-xl overflow-hidden border border-dark-600">
76
+ <div class="flex flex-col md:flex-row">
77
+ <!-- Source Language -->
78
+ <div class="w-full md:w-1/2 p-6 border-b md:border-b-0 md:border-r border-dark-600">
79
+ <div class="flex items-center justify-between mb-4">
80
+ <div class="flex items-center">
81
+ <div class="relative w-full">
82
+ <select id="sourceLanguage" class="w-full p-3 border border-dark-500 rounded-lg appearance-none bg-dark-800 text-dark-100 pr-10 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
83
+ <option value="auto">Détection automatique</option>
84
+ <option value="fr">Français</option>
85
+ <option value="en">Anglais</option>
86
+ <option value="es">Espagnol</option>
87
+ <option value="de">Allemand</option>
88
+ <option value="it">Italien</option>
89
+ <option value="pt">Portugais</option>
90
+ <option value="ru">Russe</option>
91
+ <option value="zh">Chinois</option>
92
+ <option value="ja">Japonais</option>
93
+ <option value="ar">Arabe</option>
94
+ </select>
95
+ <div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
96
+ <i class="fas fa-chevron-down text-dark-400"></i>
97
+ </div>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ <textarea id="sourceText" class="w-full text-input p-4 border border-dark-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 bg-dark-800 text-dark-100 placeholder-dark-400" placeholder="Entrez votre texte ici..."></textarea>
102
+ <div class="flex justify-between items-center mt-3">
103
+ <div class="text-sm text-dark-400" id="sourceCharCount">0/5000</div>
104
+ <button id="clearSource" class="text-dark-400 hover:text-indigo-400">
105
+ <i class="fas fa-times"></i> Effacer
106
+ </button>
107
+ </div>
108
+ </div>
109
+
110
+ <!-- Target Language -->
111
+ <div class="w-full md:w-1/2 p-6">
112
+ <div class="flex items-center justify-between mb-4">
113
+ <div class="flex items-center">
114
+ <div class="relative w-full">
115
+ <select id="targetLanguage" class="w-full p-3 border border-dark-500 rounded-lg appearance-none bg-dark-800 text-dark-100 pr-10 focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
116
+ <option value="fr">Français</option>
117
+ <option value="en" selected>Anglais</option>
118
+ <option value="es">Espagnol</option>
119
+ <option value="de">Allemand</option>
120
+ <option value="it">Italien</option>
121
+ <option value="pt">Portugais</option>
122
+ <option value="ru">Russe</option>
123
+ <option value="zh">Chinois</option>
124
+ <option value="ja">Japonais</option>
125
+ <option value="ar">Arabe</option>
126
+ </select>
127
+ <div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none">
128
+ <i class="fas fa-chevron-down text-dark-400"></i>
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ <div id="targetText" class="w-full text-input p-4 border border-dark-600 rounded-lg bg-dark-800 min-h-[150px] text-dark-100">
134
+ <div class="text-dark-400 italic">La traduction apparaîtra ici...</div>
135
+ </div>
136
+ <div class="flex justify-between items-center mt-3">
137
+ <div class="text-sm text-dark-400" id="targetCharCount">0/5000</div>
138
+ <div class="flex space-x-2">
139
+ <button id="copyTranslation" class="text-dark-400 hover:text-indigo-400" title="Copier">
140
+ <i class="far fa-copy"></i>
141
+ </button>
142
+ <button id="speakTranslation" class="text-dark-400 hover:text-indigo-400" title="Écouter">
143
+ <i class="fas fa-volume-up"></i>
144
+ </button>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ </div>
149
+
150
+ <!-- Controls -->
151
+ <div class="bg-dark-800 px-6 py-4 border-t border-dark-600 flex justify-between items-center">
152
+ <div class="flex items-center space-x-2">
153
+ <button id="swapLanguages" class="swap-btn bg-indigo-600 text-white p-3 rounded-full hover:bg-indigo-500">
154
+ <i class="fas fa-exchange-alt"></i>
155
+ </button>
156
+ <span class="text-sm text-dark-300">Échanger les langues</span>
157
+ </div>
158
+ <button id="translateBtn" class="bg-indigo-600 hover:bg-indigo-500 text-white font-medium py-3 px-6 rounded-lg flex items-center">
159
+ <i class="fas fa-language mr-2"></i> Traduire
160
+ </button>
161
+ </div>
162
+ </div>
163
+
164
+ <!-- Translation History -->
165
+ <div class="mt-10 bg-dark-700 rounded-xl shadow-lg overflow-hidden border border-dark-600">
166
+ <div class="p-6">
167
+ <h2 class="text-xl font-semibold text-indigo-400 mb-4 flex items-center">
168
+ <i class="fas fa-history mr-2"></i> Historique des traductions
169
+ </h2>
170
+ <div id="historyList" class="space-y-3 max-h-60 overflow-y-auto">
171
+ <!-- Les éléments d'historique seront ajoutés ici dynamiquement -->
172
+ <div class="text-center text-dark-400 py-4 italic">Aucun historique pour le moment</div>
173
+ </div>
174
+ </div>
175
+ </div>
176
+ </div>
177
+
178
+ <script>
179
+ document.addEventListener('DOMContentLoaded', function() {
180
+ // Éléments du DOM
181
+ const sourceText = document.getElementById('sourceText');
182
+ const targetText = document.getElementById('targetText');
183
+ const sourceLanguage = document.getElementById('sourceLanguage');
184
+ const targetLanguage = document.getElementById('targetLanguage');
185
+ const translateBtn = document.getElementById('translateBtn');
186
+ const swapLanguages = document.getElementById('swapLanguages');
187
+ const clearSource = document.getElementById('clearSource');
188
+ const copyTranslation = document.getElementById('copyTranslation');
189
+ const speakTranslation = document.getElementById('speakTranslation');
190
+ const sourceCharCount = document.getElementById('sourceCharCount');
191
+ const targetCharCount = document.getElementById('targetCharCount');
192
+ const historyList = document.getElementById('historyList');
193
+ const themeToggle = document.getElementById('themeToggle');
194
+ const themeIcon = document.getElementById('themeIcon');
195
+ let isDarkMode = true;
196
+
197
+ // Gestion du thème sombre/clair
198
+ themeToggle.addEventListener('click', function() {
199
+ isDarkMode = !isDarkMode;
200
+ if (isDarkMode) {
201
+ document.documentElement.classList.add('dark');
202
+ themeIcon.classList.remove('fa-sun');
203
+ themeIcon.classList.add('fa-moon');
204
+ } else {
205
+ document.documentElement.classList.remove('dark');
206
+ themeIcon.classList.remove('fa-moon');
207
+ themeIcon.classList.add('fa-sun');
208
+ }
209
+ });
210
+
211
+ // Compteur de caractères
212
+ sourceText.addEventListener('input', function() {
213
+ const count = sourceText.value.length;
214
+ sourceCharCount.textContent = `${count}/5000`;
215
+ if (count > 4500) {
216
+ sourceCharCount.classList.add('text-red-400');
217
+ } else {
218
+ sourceCharCount.classList.remove('text-red-400');
219
+ }
220
+ });
221
+
222
+ // Effacer le texte source
223
+ clearSource.addEventListener('click', function() {
224
+ sourceText.value = '';
225
+ sourceCharCount.textContent = '0/5000';
226
+ targetText.innerHTML = '<div class="text-dark-400 italic">La traduction apparaîtra ici...</div>';
227
+ targetCharCount.textContent = '0/5000';
228
+ });
229
+
230
+ // Échanger les langues
231
+ swapLanguages.addEventListener('click', function() {
232
+ const tempLang = sourceLanguage.value;
233
+ sourceLanguage.value = targetLanguage.value;
234
+ targetLanguage.value = tempLang;
235
+
236
+ // Si le texte source n'est pas vide, on traduit automatiquement
237
+ if (sourceText.value.trim()) {
238
+ translateText();
239
+ }
240
+ });
241
+
242
+ // Copier la traduction
243
+ copyTranslation.addEventListener('click', function() {
244
+ if (targetText.textContent.trim() && !targetText.querySelector('.italic')) {
245
+ navigator.clipboard.writeText(targetText.textContent)
246
+ .then(() => {
247
+ const originalIcon = copyTranslation.innerHTML;
248
+ copyTranslation.innerHTML = '<i class="fas fa-check"></i>';
249
+ setTimeout(() => {
250
+ copyTranslation.innerHTML = originalIcon;
251
+ }, 2000);
252
+ });
253
+ }
254
+ });
255
+
256
+ // Lire la traduction à voix haute
257
+ speakTranslation.addEventListener('click', function() {
258
+ if (targetText.textContent.trim() && !targetText.querySelector('.italic')) {
259
+ const utterance = new SpeechSynthesisUtterance(targetText.textContent);
260
+ utterance.lang = targetLanguage.value;
261
+ speechSynthesis.speak(utterance);
262
+ }
263
+ });
264
+
265
+ // Traduction automatique lors de la saisie (avec délai)
266
+ let translateTimeout;
267
+ sourceText.addEventListener('input', function() {
268
+ clearTimeout(translateTimeout);
269
+ if (sourceText.value.trim()) {
270
+ translateTimeout = setTimeout(translateText, 1000);
271
+ }
272
+ });
273
+
274
+ // Traduction lors du clic sur le bouton
275
+ translateBtn.addEventListener('click', translateText);
276
+
277
+ // Fonction de traduction
278
+ function translateText() {
279
+ const text = sourceText.value.trim();
280
+ if (!text) return;
281
+
282
+ // Afficher l'indicateur de chargement
283
+ targetText.innerHTML = '<div class="flex justify-center items-center h-full"><div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-indigo-500"></div></div>';
284
+ translateBtn.disabled = true;
285
+ translateBtn.classList.add('opacity-75', 'cursor-not-allowed');
286
+
287
+ // Simuler une traduction (dans un vrai projet, vous utiliseriez une API de traduction)
288
+ setTimeout(() => {
289
+ // Ici, nous simulons simplement une traduction en inversant le texte
290
+ // Dans un vrai projet, vous utiliseriez une API comme Google Translate
291
+ const translatedText = `[Traduction simulée de ${sourceLanguage.value} vers ${targetLanguage.value}]\n${text.split('').reverse().join('')}`;
292
+
293
+ targetText.innerHTML = translatedText;
294
+ targetCharCount.textContent = `${translatedText.length}/5000`;
295
+
296
+ // Ajouter à l'historique
297
+ addToHistory(text, translatedText, sourceLanguage.value, targetLanguage.value);
298
+
299
+ translateBtn.disabled = false;
300
+ translateBtn.classList.remove('opacity-75', 'cursor-not-allowed');
301
+ }, 1500);
302
+ }
303
+
304
+ // Ajouter une traduction à l'historique
305
+ function addToHistory(source, translation, fromLang, toLang) {
306
+ // Vérifier si l'historique est vide (avec le message par défaut)
307
+ if (historyList.querySelector('.italic')) {
308
+ historyList.innerHTML = '';
309
+ }
310
+
311
+ const historyItem = document.createElement('div');
312
+ historyItem.className = 'bg-dark-800 p-3 rounded-lg border border-dark-600 hover:bg-dark-600 transition cursor-pointer';
313
+ historyItem.innerHTML = `
314
+ <div class="flex justify-between items-start">
315
+ <div class="flex-1">
316
+ <div class="text-sm font-medium text-dark-100 mb-1">${source.substring(0, 50)}${source.length > 50 ? '...' : ''}</div>
317
+ <div class="text-sm text-indigo-400">${translation.substring(0, 50)}${translation.length > 50 ? '...' : ''}</div>
318
+ </div>
319
+ <div class="text-xs text-dark-400 ml-2">${fromLang} → ${toLang}</div>
320
+ </div>
321
+ `;
322
+
323
+ // Ajouter au début de la liste
324
+ historyList.insertBefore(historyItem, historyList.firstChild);
325
+
326
+ // Limiter l'historique à 10 éléments
327
+ if (historyList.children.length > 10) {
328
+ historyList.removeChild(historyList.lastChild);
329
+ }
330
+
331
+ // Gestion du clic sur un élément d'historique
332
+ historyItem.addEventListener('click', function() {
333
+ sourceText.value = source;
334
+ sourceCharCount.textContent = `${source.length}/5000`;
335
+ targetText.innerHTML = translation;
336
+ targetCharCount.textContent = `${translation.length}/5000`;
337
+ sourceLanguage.value = fromLang;
338
+ targetLanguage.value = toLang;
339
+ });
340
+ }
341
+ });
342
+ </script>
343
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Bruno2023/unitrad" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
344
+ </html>