ClemSummer commited on
Commit
5ab0e19
·
1 Parent(s): 7ae475d

Updated cbow UI

Browse files
Files changed (2) hide show
  1. Dockerfile +1 -1
  2. templates/cbow.html +128 -288
Dockerfile CHANGED
@@ -54,4 +54,4 @@ HEALTHCHECK CMD curl --fail http://localhost:7860/ || exit 1
54
  #CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
55
  CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860", "--log-level", "debug"]
56
 
57
- # some change to trigger rebuild 1
 
54
  #CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
55
  CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860", "--log-level", "debug"]
56
 
57
+ # some change to trigger rebuild 2
templates/cbow.html CHANGED
@@ -1,306 +1,146 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <script src="https://cdn.tailwindcss.com"></script>
7
- <title>CBOW Vector Calculator</title>
8
- <style>
9
- body {
10
- font-family: Arial, sans-serif;
11
- max-width: 600px;
12
- margin: auto;
13
- padding: 1rem;
14
- background-color: #f8f9fa;
15
- position: relative;
16
- }
17
-
18
- h2 {
19
- text-align: center;
20
- }
21
-
22
- form {
23
- margin-top: 2rem;
24
- }
25
-
26
- textarea {
27
- width: 100%;
28
- height: 80px;
29
- padding: 0.5rem;
30
- font-size: 1rem;
31
- resize: vertical;
32
- }
33
-
34
- button {
35
- margin-top: 1rem;
36
- width: 100%;
37
- padding: 0.75rem;
38
- font-size: 1rem;
39
- background-color: #007bff;
40
- color: white;
41
- border: none;
42
- border-radius: 4px;
43
- cursor: pointer;
44
- }
45
-
46
- button:hover {
47
- background-color: #0056b3;
48
- }
49
-
50
- .results {
51
- margin-top: 2rem;
52
- background-color: white;
53
- padding: 1rem;
54
- border-radius: 6px;
55
- box-shadow: 0 0 10px rgba(0,0,0,0.1);
56
- }
57
-
58
- .result-row {
59
- margin: 0.5rem 0;
60
- }
61
-
62
- .result-word {
63
- font-weight: bold;
64
- }
65
-
66
- .score {
67
- color: #666;
68
- margin-left: 0.5rem;
69
- }
70
-
71
- .floating-icons {
72
- position: fixed;
73
- bottom: 1rem;
74
- right: 1rem;
75
- display: flex;
76
- gap: 1rem;
77
- }
78
-
79
- .icon-button {
80
- background: white;
81
- border: 1px solid #ccc;
82
- border-radius: 50%;
83
- width: 40px;
84
- height: 40px;
85
- font-size: 1.2rem;
86
- text-align: center;
87
- line-height: 40px;
88
- cursor: pointer;
89
- box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
90
- }
91
-
92
- .modal {
93
- display: none;
94
- position: fixed;
95
- z-index: 1000;
96
- left: 0; top: 0;
97
- width: 100%; height: 100%;
98
- background-color: rgba(0,0,0,0.4);
99
- }
100
-
101
- .use-suggestion {
102
- margin-left: 8px;
103
- padding: 2px 6px;
104
- font-size: 0.8rem;
105
- background-color: #007bff;
106
- color: white;
107
- border: none;
108
- border-radius: 4px;
109
- cursor: pointer;
110
- }
111
- .use-suggestion:hover {
112
- background-color: #0056b3;
113
- }
114
-
115
- .modal-content {
116
- background-color: #fff;
117
- margin: 10% auto;
118
- padding: 2rem;
119
- border-radius: 8px;
120
- max-width: 400px;
121
- position: relative;
122
- }
123
-
124
- .close {
125
- position: absolute;
126
- top: 0.5rem;
127
- right: 0.75rem;
128
- font-size: 1.2rem;
129
- cursor: pointer;
130
- }
131
- </style>
132
  </head>
133
- <body>
134
- <a href="/" class="absolute top-4 left-4 text-blue-600 hover:text-blue-800 text-sm font-semibold flex items-center">
135
- <!-- back arrow -->
136
- <svg class="w-5 h-5 mr-1" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"
137
- xmlns="http://www.w3.org/2000/svg">
138
- <path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path>
139
- </svg>
140
- Back to Home
141
- </a>
142
-
143
- <h2>CBOW Vector Calculator</h2>
144
- <form method="post" action="/cbow">
145
- <label for="expression">Enter a word vector expression <small>(e.g. <code>king - man + woman</code>)</small>:</label><br>
146
- <textarea name="expression" rows="4" style="width: 100%">{{ expression or "" }}</textarea>
147
- <button type="submit">Calculate</button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  </form>
149
 
 
150
  {% if results %}
151
- <div class="results">
152
- {% if results and results|length > 0 %}
153
- <p><strong>{{ expression }}</strong> ≈ <strong>{{ results[0][0] }}</strong></p>
154
- {% endif %}
155
- <h3>Results:</h3>
156
- <table style="width: 100%; border-collapse: collapse;">
157
  <thead>
158
- <tr>
159
- <th style="text-align: left; padding: 0.5rem; border-bottom: 1px solid #ccc;">#</th>
160
- <th style="text-align: left; padding: 0.5rem; border-bottom: 1px solid #ccc;">Result</th>
161
- <th style="text-align: left; padding: 0.5rem; border-bottom: 1px solid #ccc;">Score</th>
162
- </tr>
163
  </thead>
164
  <tbody>
165
- {% for word, score in results %}
166
- <tr>
167
- <td style="padding: 0.5rem;">{{ loop.index }}</td>
168
- <td style="padding: 0.5rem;">{{ word }}</td>
169
- <td style="padding: 0.5rem;">
170
- {% if score >= 0.4 %}
171
- {{ "%.2f"|format(score) }}
172
- {% else %}
173
- Irrelevant result
174
- {% endif %}
175
- </td>
176
- </tr>
177
- {% endfor %}
178
  </tbody>
179
- </table>
180
- </div>
181
- {% endif %}
182
-
183
- <div class="floating-icons">
184
- <div class="icon-button" onclick="openModal('suggestionsModal')">💡</div>
185
- <div class="icon-button" onclick="openModal('aboutModal')">?</div>
186
  </div>
187
-
188
- <div id="suggestionsModal" class="modal">
189
- <div class="modal-content">
190
- <span class="close" onclick="closeModal('suggestionsModal')">&times;</span>
191
- <h3>Suggestions</h3>
192
- <p>What's your guess, before calculating it?</p>
193
- <ul id="suggestions-list"></ul>
194
- <p><strong>Tips:</strong></p>
195
- <ul>
196
- <li>Use <code>-</code> and <code>+</code> operators, with a space before and after each operator.</li>
197
- <li>Link compound words with a hyphen, e.g., <code>new-york</code>.</li>
198
- <li>Got a fun suggestion? Email: <a href="mailto:[email protected]">[email protected]</a></li>
199
- </ul>
200
- </div>
 
 
 
 
 
 
 
 
 
 
201
  </div>
202
-
203
- <div id="aboutModal" class="modal">
204
- <div class="modal-content">
205
- <span class="close" onclick="closeModal('aboutModal')">&times;</span>
206
- <h3>About</h3>
207
- <p>This tool calculates vector arithmetic of words using a pretrained CBOW model glove-twitter-200.</p>
208
- </div>
 
209
  </div>
210
-
211
- <script>
212
- function openModal(id) {
213
- document.getElementById(id).style.display = 'block';
214
- }
215
-
216
- function closeModal(id) {
217
- document.getElementById(id).style.display = 'none';
218
- }
219
-
220
- window.onclick = function(event) {
221
- const modals = document.querySelectorAll('.modal');
222
- modals.forEach(modal => {
223
- if (event.target == modal) {
224
- modal.style.display = "none";
225
- }
226
- });
227
- }
228
- </script>
229
- <script>
230
- document.addEventListener("DOMContentLoaded", function () {
231
- const textarea = document.querySelector("textarea[name='expression']");
232
- const form = document.querySelector("form");
233
-
234
- textarea.addEventListener("keydown", function (event) {
235
- if (event.key === "Enter" && !event.shiftKey) {
236
- event.preventDefault(); // prevent newline
237
- form.submit(); // trigger form submission
238
- }
239
- });
240
- });
241
- </script>
242
-
243
- <script>
244
- document.addEventListener("DOMContentLoaded", function () {
245
- const form = document.querySelector("form");
246
- const textarea = document.querySelector("textarea[name='expression']");
247
- let resultShown = {{ 'true' if results else 'false' }};
248
-
249
- // 1. Validate spacing between tokens
250
- form.addEventListener("submit", function (event) {
251
- const input = textarea.value.trim();
252
-
253
- // Simple regex to find missing spaces (e.g., "word+word", "word-word")
254
- const spacingIssues = input.match(/\b\w+[\+\-]\w+\b/);
255
-
256
- if (spacingIssues) {
257
- event.preventDefault();
258
- const problem = spacingIssues[0];
259
- const suggestion = problem.replace(/([\+\-])/, ' $1 ');
260
- alert(`⚠️ It looks like you missed spacing in: "${problem}".\nDid you mean: "${suggestion}"?`);
261
- }
262
- });
263
-
264
- // 2. Clear textarea when focused again, only if result was shown
265
- if (resultShown) {
266
- textarea.addEventListener("focus", () => {
267
- textarea.value = "";
268
- resultShown = false; // prevent it from clearing again on next focus
269
- });
270
- }
271
- });
272
- </script>
273
- <script>
274
- document.addEventListener("DOMContentLoaded", function () {
275
- const textarea = document.querySelector("textarea[name='expression']");
276
- const modal = document.getElementById("suggestionsModal");
277
- const suggestions = [
278
- "mother - woman + man",
279
- "iphone - phone + tablet",
280
- "hotdog - sausage + beef",
281
- "brisbane - city + capital",
282
- "uk - monarchy",
283
- "kfc - chicken + pork",
284
- "skoda - czech + germany",
285
- "starwars - darthvader + sauron",
286
- "callofduty - gun + knife"
287
- ];
288
-
289
- const list = document.getElementById("suggestions-list");
290
-
291
- // Build the list dynamically
292
- suggestions.forEach(suggestion => {
293
- const li = document.createElement("li");
294
- li.innerHTML = `<code>${suggestion}</code>
295
- <button type="button" class="use-suggestion">Use</button>`;
296
- li.querySelector("button").addEventListener("click", function () {
297
- textarea.value = suggestion; // fill textarea
298
- textarea.focus(); // optional
299
- modal.style.display = "none"; // auto close modal
300
- });
301
- list.appendChild(li);
302
  });
 
 
303
  });
304
- </script>
305
  </body>
306
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <script src="https://cdn.tailwindcss.com"></script>
7
+ <title>🧙‍♂️ Word Alchemy</title>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  </head>
9
+ <body class="bg-gray-100 min-h-screen flex flex-col items-center p-6">
10
+
11
+ <!-- Back Button -->
12
+ <a href="/" class="absolute top-4 left-4 text-blue-600 hover:text-blue-800 text-sm font-semibold flex items-center">
13
+ <svg class="w-5 h-5 mr-1" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"
14
+ xmlns="http://www.w3.org/2000/svg">
15
+ <path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"></path>
16
+ </svg>
17
+ Back to Home
18
+ </a>
19
+
20
+ <!-- Main Container -->
21
+ <div class="bg-white shadow-md rounded-lg p-6 w-full max-w-lg mt-12">
22
+ <h2 class="text-2xl font-bold text-center text-gray-800">CBOW Vector Calculator</h2>
23
+
24
+ <!-- Form -->
25
+ <form method="post" action="/cbow" class="mt-6 space-y-4">
26
+ <label for="expression" class="block text-gray-700 font-medium">
27
+ Enter a word vector expression
28
+ <span class="text-sm text-gray-500">(e.g. <code>king - man + woman</code>)</span>
29
+ </label>
30
+ <textarea
31
+ name="expression"
32
+ rows="4"
33
+ class="w-full border rounded-lg p-3 focus:outline-none focus:ring-2 focus:ring-blue-500"
34
+ >{{ expression or "" }}</textarea>
35
+ <button
36
+ type="submit"
37
+ class="w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-lg transition"
38
+ >
39
+ Calculate
40
+ </button>
41
  </form>
42
 
43
+ <!-- Results -->
44
  {% if results %}
45
+ <div class="mt-6 bg-gray-50 p-4 rounded-lg shadow-inner">
46
+ {% if results and results|length > 0 %}
47
+ <p class="mb-3 text-gray-800"><strong>{{ expression }}</strong> ≈ <strong>{{ results[0][0] }}</strong></p>
48
+ {% endif %}
49
+ <h3 class="font-semibold text-gray-700 mb-2">Results:</h3>
50
+ <table class="w-full text-left border-collapse">
51
  <thead>
52
+ <tr>
53
+ <th class="border-b p-2">#</th>
54
+ <th class="border-b p-2">Result</th>
55
+ <th class="border-b p-2">Score</th>
56
+ </tr>
57
  </thead>
58
  <tbody>
59
+ {% for word, score in results %}
60
+ <tr class="hover:bg-gray-100">
61
+ <td class="p-2">{{ loop.index }}</td>
62
+ <td class="p-2">{{ word }}</td>
63
+ <td class="p-2">
64
+ {% if score >= 0.4 %}
65
+ {{ "%.2f"|format(score) }}
66
+ {% else %}
67
+ <span class="text-gray-500 italic">Irrelevant result</span>
68
+ {% endif %}
69
+ </td>
70
+ </tr>
71
+ {% endfor %}
72
  </tbody>
73
+ </table>
 
 
 
 
 
 
74
  </div>
75
+ {% endif %}
76
+ </div>
77
+
78
+ <!-- Floating Buttons -->
79
+ <div class="fixed bottom-4 right-4 flex gap-3">
80
+ <button onclick="openModal('suggestionsModal')" class="bg-white border rounded-full w-12 h-12 shadow flex items-center justify-center hover:bg-gray-100">💡</button>
81
+ <button onclick="openModal('aboutModal')" class="bg-white border rounded-full w-12 h-12 shadow flex items-center justify-center hover:bg-gray-100">?</button>
82
+ </div>
83
+
84
+ <!-- Suggestions Modal -->
85
+ <div id="suggestionsModal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
86
+ <div class="bg-white rounded-lg p-6 max-w-md w-full shadow-lg relative">
87
+ <button onclick="closeModal('suggestionsModal')" class="absolute top-2 right-3 text-gray-500 hover:text-black">&times;</button>
88
+ <h3 class="text-xl font-semibold mb-4">Suggestions</h3>
89
+ <p class="mb-3 text-gray-700">What's your guess, before calculating it?</p>
90
+ <ul id="suggestions-list" class="space-y-2"></ul>
91
+ <div class="mt-4">
92
+ <h4 class="font-semibold text-gray-700">Tips:</h4>
93
+ <ul class="list-disc list-inside text-sm text-gray-600 mt-2 space-y-1">
94
+ <li>Use <code>-</code> and <code>+</code> with spaces around them.</li>
95
+ <li>Link compound words with a hyphen, e.g., <code>new-york</code>.</li>
96
+ <li>Got a fun suggestion? Email: <a href="mailto:[email protected]" class="text-blue-600 hover:underline">[email protected]</a></li>
97
+ </ul>
98
+ </div>
99
  </div>
100
+ </div>
101
+
102
+ <!-- About Modal -->
103
+ <div id="aboutModal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
104
+ <div class="bg-white rounded-lg p-6 max-w-md w-full shadow-lg relative">
105
+ <button onclick="closeModal('aboutModal')" class="absolute top-2 right-3 text-gray-500 hover:text-black">&times;</button>
106
+ <h3 class="text-xl font-semibold mb-4">About</h3>
107
+ <p class="text-gray-700">This tool calculates vector arithmetic of words using a pretrained CBOW model glove-twitter-200. Just put in your equation and press Calculate to show the result.</p>
108
  </div>
109
+ </div>
110
+
111
+ <script>
112
+ function openModal(id) { document.getElementById(id).classList.remove('hidden'); }
113
+ function closeModal(id) { document.getElementById(id).classList.add('hidden'); }
114
+
115
+ document.addEventListener("DOMContentLoaded", () => {
116
+ const textarea = document.querySelector("textarea[name='expression']");
117
+ const modal = document.getElementById("suggestionsModal");
118
+ const suggestions = [
119
+ "mother - woman + man",
120
+ "iphone - phone + tablet",
121
+ "hotdog - sausage + beef",
122
+ "brisbane - city + capital",
123
+ "uk - monarchy",
124
+ "kfc - chicken + pork",
125
+ "skoda - czech + germany",
126
+ "starwars - darthvader + sauron",
127
+ "callofduty - gun + knife"
128
+ ];
129
+
130
+ const list = document.getElementById("suggestions-list");
131
+ suggestions.forEach(suggestion => {
132
+ const li = document.createElement("li");
133
+ li.className = "flex items-center justify-between bg-gray-100 rounded px-3 py-2";
134
+ li.innerHTML = `<code>${suggestion}</code>
135
+ <button class="bg-blue-600 hover:bg-blue-700 text-white text-xs px-2 py-1 rounded">Use</button>`;
136
+ li.querySelector("button").addEventListener("click", () => {
137
+ textarea.value = suggestion;
138
+ textarea.focus();
139
+ modal.classList.add('hidden');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  });
141
+ list.appendChild(li);
142
+ });
143
  });
144
+ </script>
145
  </body>
146
  </html>