eaglelandsonce commited on
Commit
b451ad4
·
verified ·
1 Parent(s): d181783

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +383 -19
index.html CHANGED
@@ -1,19 +1,383 @@
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="en">
3
+ <head>
4
+ <meta charset="UTF-8"/>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
6
+ <title>Vectorizing Words Jeopardy</title>
7
+ <style>
8
+ :root{
9
+ --blue:#0a49a6;
10
+ --blue-dark:#073a84;
11
+ --gold:#ffd24a;
12
+ --board-gap:10px;
13
+ --card-depth:28px;
14
+ }
15
+ *{box-sizing:border-box}
16
+ body{
17
+ font-family: system-ui, Arial, sans-serif;
18
+ display:flex;flex-direction:column;align-items:center;
19
+ background: radial-gradient(1200px 700px at 50% -200px, #f2f6ff 0%, #e9efff 30%, #cfdafc 100%) fixed;
20
+ margin:0; min-height:100vh;
21
+ }
22
+ h1{ color:#173e8c; margin:22px 0 6px; text-shadow:0 2px 0 #fff;}
23
+ a.source{ font-size:14px; color:#334; margin-bottom:8px; text-decoration:none}
24
+ a.source:hover{ text-decoration:underline }
25
+ .topbar {
26
+ width:min(1100px,95vw);
27
+ display:flex;
28
+ justify-content:space-between;
29
+ align-items:center;
30
+ gap:10px;
31
+ margin-bottom:8px;
32
+ }
33
+ .btn-reset{
34
+ padding:8px 12px; border-radius:10px; font-weight:800; cursor:pointer;
35
+ border:2px solid #0d3a85; color:#fff; background:linear-gradient(180deg,#1362ff,#0d3a85);
36
+ box-shadow:0 8px 18px rgba(0,0,0,.25);
37
+ }
38
+ .btn-reset:hover{ transform: translateY(-1px) }
39
+ .btn-reset:active{ transform: translateY(0) }
40
+ /* Stage / Board */
41
+ .stage{ perspective: 1200px; width:min(1100px, 95vw); }
42
+ #game-board{
43
+ display:grid;
44
+ grid-template-columns: repeat(5, 1fr);
45
+ grid-auto-rows: 120px;
46
+ gap: var(--board-gap);
47
+ padding: var(--board-gap);
48
+ border-radius:18px;
49
+ background: linear-gradient(180deg, #0e1a3a, #01060f);
50
+ box-shadow:
51
+ 0 20px 45px rgba(0,0,0,.35),
52
+ inset 0 0 0 4px #000;
53
+ transform: rotateX(8deg);
54
+ transform-origin: top center;
55
+ }
56
+ .category, .card{
57
+ position:relative;
58
+ border-radius:14px;
59
+ user-select:none;
60
+ transform-style: preserve-3d;
61
+ transition: transform .2s ease, box-shadow .2s ease, filter .2s ease;
62
+ box-shadow:
63
+ 0 var(--card-depth) calc(var(--card-depth) + 12px) rgba(0,0,0,.35),
64
+ inset 0 0 0 1px rgba(255,255,255,.15);
65
+ }
66
+ .category{
67
+ background: linear-gradient(180deg, #004fbf 0%, #003d93 60%, #003684 100%);
68
+ color:#fff; font-weight:800; text-transform:uppercase; letter-spacing:.3px;
69
+ display:flex; justify-content:center; align-items:center; text-align:center;
70
+ border:1px solid #00122c;
71
+ text-shadow:0 2px 0 rgba(0,0,0,.35);
72
+ }
73
+ .card{
74
+ cursor:pointer; font-weight:900; color: var(--gold);
75
+ background:
76
+ radial-gradient(80% 80% at 50% 25%, rgba(255,255,255,.18), rgba(255,255,255,0) 60%),
77
+ linear-gradient(180deg, var(--blue) 0%, var(--blue-dark) 100%);
78
+ border:1px solid #031b3f;
79
+ display:flex; justify-content:center; align-items:center; text-align:center;
80
+ font-size: clamp(16px, 2.4vw, 26px);
81
+ text-shadow: 0 2px 0 #000, 0 0 10px rgba(255,210,74,.35);
82
+ }
83
+ .card.tilt:hover{
84
+ transform: translateZ(10px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
85
+ box-shadow:
86
+ 0 24px 48px rgba(0,0,0,.4),
87
+ 0 0 24px rgba(255,210,74,.15),
88
+ inset 0 0 0 1px rgba(255,255,255,.18);
89
+ filter: saturate(1.1);
90
+ }
91
+ .card:active{ transform: translateZ(0) scale(.985); box-shadow: 0 12px 18px rgba(0,0,0,.45), inset 0 0 0 1px rgba(255,255,255,.12); }
92
+ .card.disabled{ cursor:default; color:#bfc7da; background: linear-gradient(180deg,#6b7aa6,#4e5b85); text-shadow:none; filter:grayscale(.2) brightness(.92); }
93
+ #question-display{ width:min(1000px, 92vw); text-align:center; margin:16px 0 6px; }
94
+ #question-display h2{ margin:8px 0 6px; color:#0d2b6f }
95
+ #question-display p { font-size: 22px; line-height: 1.4; }
96
+ #score{ font-size:24px; font-weight:800; color:#0d2b6f; margin:0 0 8px 0 }
97
+ .answer-container{ display:flex; justify-content:center; flex-wrap:wrap; gap:10px; margin-top:14px }
98
+ .answer-btn{
99
+ margin:0; padding:10px 16px; font-size:18px; cursor:pointer;
100
+ border:2px solid #0d3a85; border-radius:10px; font-weight:800; color:#fff;
101
+ background: linear-gradient(180deg,#1362ff,#0d3a85);
102
+ box-shadow: 0 8px 18px rgba(0,0,0,.25);
103
+ transition: transform .12s ease, box-shadow .12s ease, filter .12s ease;
104
+ }
105
+ .answer-btn:hover{ transform: translateY(-2px); box-shadow:0 12px 26px rgba(0,0,0,.28) }
106
+ .answer-btn:active{ transform: translateY(0); box-shadow:0 8px 18px rgba(0,0,0,.25) }
107
+ .answer-btn.disabled{ background:#aab4cc; color:#445; cursor:not-allowed; border-color:#889 }
108
+ .feedback{ margin-top:10px; font-size:18px; font-weight:800 }
109
+ .dd-overlay{
110
+ position: fixed; inset:0; display:none; align-items:center; justify-content:center;
111
+ z-index: 9999; pointer-events:none;
112
+ background: radial-gradient(60% 60% at 50% 50%, rgba(255,255,255,.08), rgba(0,0,0,.7));
113
+ animation: dd-bg 1.2s ease-in-out 2;
114
+ }
115
+ .dd-text{
116
+ font-size: clamp(40px, 7vw, 120px);
117
+ font-weight: 900; color:#ffe17a; letter-spacing:2px;
118
+ text-shadow:
119
+ 0 0 12px rgba(255,225,122,.9),
120
+ 0 0 40px rgba(255,225,122,.6),
121
+ 0 6px 0 #000;
122
+ animation: flash 1.2s steps(2, jump-none) 2, wobble .9s ease-in-out 2;
123
+ }
124
+ @keyframes flash{ 0%,49%{opacity:1;filter:drop-shadow(0 0 24px rgba(255,225,122,.85));} 50%,100%{opacity:0;filter:none;} }
125
+ @keyframes wobble{ 0%{transform:scale(1) rotate(0)} 50%{transform:scale(1.06) rotate(-2deg)} 100%{transform:scale(1) rotate(0)} }
126
+ @keyframes dd-bg{ 0%{background: radial-gradient(40% 40% at 50% 50%, rgba(255,255,255,.12), rgba(0,0,0,.9));} 100%{background: radial-gradient(60% 60% at 50% 50%, rgba(255,255,255,.08), rgba(0,0,0,.7));} }
127
+ .flash-ring{ position:absolute; inset:-3px; border-radius:14px; pointer-events:none; box-shadow:0 0 0 3px rgba(255,225,122,.95), 0 0 30px 6px rgba(255,225,122,.6); animation: ring 1.2s ease-in-out 2; }
128
+ @keyframes ring{ 0%{opacity:1;transform:scale(1)} 50%{opacity:.1;transform:scale(.96)} 100%{opacity:1;transform:scale(1)} }
129
+ .daily-double-banner{ color:#b30000; font-weight:900; font-size:22px; margin:8px 0 }
130
+ /* Review */
131
+ #review{
132
+ width:min(1000px, 92vw);
133
+ margin:14px 0 24px 0;
134
+ padding:12px;
135
+ background:#fff;
136
+ border:1px solid #ccd3e0;
137
+ border-radius:12px;
138
+ box-shadow:0 6px 20px rgba(0,0,0,.08);
139
+ }
140
+ #review h3{ margin:0 0 8px 0; color:#0d2b6f }
141
+ .missed{ margin:8px 0; text-align:left }
142
+ .missed .q{ font-weight:700 }
143
+ .missed .a{ margin-left:8px }
144
+ </style>
145
+ </head>
146
+ <body>
147
+ <h1>Vectorizing Words Jeopardy</h1>
148
+ <a class="source" href="https://www.linkedin.com/pulse/turning-text-numbers-word2vec-glove-fasttext-michael-lively-vtwde/" target="_blank">
149
+ Source: Turning Text Into Numbers — Word2Vec, GloVe, FastText
150
+ </a>
151
+
152
+ <div class="topbar">
153
+ <div id="score">Score: 0</div>
154
+ <button class="btn-reset" id="reset-btn" title="Start a fresh round">Reset Game</button>
155
+ </div>
156
+
157
+ <div class="stage">
158
+ <div id="game-board">
159
+ <div class="category">Embedding Basics</div>
160
+ <div class="category">Word2Vec: CBOW & Skip-gram</div>
161
+ <div class="category">GloVe & Global Stats</div>
162
+ <div class="category">FastText & Subwords</div>
163
+ <div class="category">Training & Tools</div>
164
+ <!-- cards will be injected -->
165
+ </div>
166
+ </div>
167
+
168
+ <div id="question-display"></div>
169
+ <div id="review" style="display:none;"></div>
170
+
171
+ <audio id="dd-audio" preload="auto">
172
+ <source src="daily-double.mp3" type="audio/mpeg">
173
+ </audio>
174
+ <div id="dd-overlay" class="dd-overlay"><div class="dd-text">DAILY&nbsp;DOUBLE!</div></div>
175
+
176
+ <script>
177
+ const categories = [
178
+ "Embedding Basics",
179
+ "Word2Vec: CBOW & Skip-gram",
180
+ "GloVe & Global Stats",
181
+ "FastText & Subwords",
182
+ "Training & Tools"
183
+ ];
184
+ // ✅ Corrected answer keys included
185
+ const questions = [
186
+ // Embedding Basics
187
+ [
188
+ { q: "Compared to Bag of Words/TF-IDF, word embeddings primarily:", a: ["Capture meaning via context, not just frequency", "Apply hand-written linguistic rules", "Ignore context entirely"], correct: 0 },
189
+ { q: "Which metric measures similarity by the angle between vectors?", a: ["Euclidean distance", "Cosine similarity", "Jaccard index"], correct: 1 },
190
+ { q: "A common way to visualize high-dimensional embeddings in 2D is:", a: ["Gradient Descent", "Backpropagation", "PCA or t-SNE"], correct: 2 }
191
+ ],
192
+ // Word2Vec: CBOW & Skip-gram
193
+ [
194
+ { q: "CBOW’s training objective is to:", a: ["Predict the target word from surrounding context words", "Predict the context from the target word", "Factorize the co-occurrence matrix"], correct: 0 },
195
+ { q: "Skip-gram’s training objective is to:", a: ["Count word frequencies", "Predict surrounding context words from a target word", "Remove stopwords before training"], correct: 1 },
196
+ { q: "Which techniques speed up Word2Vec training?", a: ["Bag-of-Words and TF-IDF", "Count vectors and hashing", "Negative sampling and/or hierarchical softmax"], correct: 2 }
197
+ ],
198
+ // GloVe & Global Stats
199
+ [
200
+ { q: "GloVe learns embeddings mainly by:", a: ["Matrix factorization of a word co-occurrence matrix", "Predicting characters from bytes", "Labeling sentences with topics"], correct: 0 },
201
+ { q: "In GloVe, a weighting function is used to:", a: ["Increase the window size automatically", "Balance frequent and rare words so common terms don't dominate", "Normalize vectors to unit length"], correct: 1 },
202
+ { q: "Compared with Word2Vec, GloVe is especially strong at capturing:", a: ["Local syntactic patterns only", "Character-level morphology", "Global relationships across the entire corpus"], correct: 2 }
203
+ ],
204
+ // FastText & Subwords
205
+ [
206
+ { q: "FastText represents a word as:", a: ["A single one-hot vector", "Character n-grams (subword units) combined", "Only its stem or lemma"], correct: 1 }, // fixed
207
+ { q: "A key advantage of FastText over Word2Vec is that it:", a: ["Requires no training data", "Handles out-of-vocabulary words via subwords", "Eliminates the need for context windows"], correct: 1 },
208
+ { q: "FastText training generally uses the same framework as Word2Vec:", a: ["No, it uses topic modeling only", "Partly, but only with CBOW", "Yes, CBOW and/or Skip-gram with subwords"], correct: 2 }
209
+ ],
210
+ // Training & Tools
211
+ [
212
+ { q: "Embedding quality generally improves with:", a: ["Smaller, single-topic corpora", "Random word shuffling", "Larger and more diverse corpora and well-chosen window sizes"], correct: 2 }, // fixed
213
+ { q: "Which library is optimized for production-grade NLP with pretrained vectors?", a: ["NLTK", "spaCy", "A spreadsheet"], correct: 1 },
214
+ { q: "Which statement about classic embeddings is most accurate?", a: ["They are rule-based representations", "They fully model document-level structure like Transformers", "They learn from context but don’t capture full sequence structure; Transformers handle that"], correct: 2 }
215
+ ]
216
+ ];
217
+ let score = 0, answered = 0;
218
+ const total = 15;
219
+ const board = document.getElementById("game-board"),
220
+ qdisp = document.getElementById("question-display"),
221
+ sdisp = document.getElementById("score"),
222
+ review = document.getElementById("review");
223
+ const ddOverlay = document.getElementById("dd-overlay");
224
+ const ddAudio = document.getElementById("dd-audio");
225
+ // Track where the correct answer ended up after shuffling, per "c-r" key
226
+ const shuffleRegistry = new Map();
227
+ const missedQuestions = [];
228
+ const dailyDouble = { col: Math.floor(Math.random() * 5), row: Math.floor(Math.random() * 3) };
229
+ document.getElementById('reset-btn').addEventListener('click', () => {
230
+ // simple reset: reload page to fresh state
231
+ location.reload();
232
+ });
233
+ function createBoard() {
234
+ // inject 15 cards (3 rows x 5 columns)
235
+ for (let row = 0; row < 3; row++) {
236
+ for (let col = 0; col < 5; col++) {
237
+ const card = document.createElement("div");
238
+ card.className = "card tilt";
239
+ card.textContent = `$${(row + 1) * 100}`;
240
+ card.dataset.col = col;
241
+ card.dataset.row = row;
242
+ // tilt effect
243
+ card.addEventListener("mousemove", (e) => {
244
+ const r = card.getBoundingClientRect();
245
+ const x = (e.clientX - r.left) / r.width;
246
+ const y = (e.clientY - r.top) / r.height;
247
+ const ry = (x - 0.5) * 10;
248
+ const rx = (0.5 - y) * 10;
249
+ card.style.setProperty("--ry", `${ry}deg`);
250
+ card.style.setProperty("--rx", `${rx}deg`);
251
+ });
252
+ card.addEventListener("mouseleave", () => {
253
+ card.style.removeProperty("--ry");
254
+ card.style.removeProperty("--rx");
255
+ });
256
+ card.onclick = () => handleCardClick(card);
257
+ board.appendChild(card);
258
+ }
259
+ }
260
+ }
261
+ function handleCardClick(card){
262
+ if (card.classList.contains("disabled")) return;
263
+ const col = +card.dataset.col;
264
+ const row = +card.dataset.row;
265
+ const isDD = (col === dailyDouble.col && row === dailyDouble.row);
266
+ if (isDD){
267
+ triggerDailyDouble(card, () => showQuestion(col, row, card, true));
268
+ } else {
269
+ showQuestion(col, row, card, false);
270
+ }
271
+ }
272
+ function triggerDailyDouble(card, onDone){
273
+ const ring = document.createElement("div");
274
+ ring.className = "flash-ring";
275
+ card.appendChild(ring);
276
+ ddAudio.currentTime = 0;
277
+ ddAudio.play().catch(()=>{});
278
+ ddOverlay.style.display = "flex";
279
+ setTimeout(() => {
280
+ ddOverlay.style.display = "none";
281
+ ring.remove();
282
+ onDone();
283
+ }, 2400);
284
+ }
285
+ function showQuestion(categoryIndex, difficulty, card, isDailyDouble){
286
+ const q = questions[categoryIndex][difficulty];
287
+ // Build shuffled options and record where the correct one ended up
288
+ const options = q.a.map((text, origIdx) => ({ text, origIdx }));
289
+ for (let i = options.length - 1; i > 0; i--) {
290
+ const j = Math.floor(Math.random() * (i + 1));
291
+ [options[i], options[j]] = [options[j], options[i]];
292
+ }
293
+ const shuffledCorrectIndex = options.findIndex(o => o.origIdx === q.correct);
294
+ const key = `${categoryIndex}-${difficulty}`;
295
+ shuffleRegistry.set(key, { shuffledCorrectIndex, isDailyDouble });
296
+ const dailyDoubleBanner = isDailyDouble ? `<div class="daily-double-banner">🎉 DAILY DOUBLE! 🎉</div>` : "";
297
+ qdisp.innerHTML = `
298
+ ${dailyDoubleBanner}
299
+ <h2>${categories[categoryIndex]} for $${(difficulty + 1) * 100}${isDailyDouble ? " (x2)" : ""}</h2>
300
+ <p>${q.q}</p>
301
+ <div class="answer-container">
302
+ ${options.map((opt, i) =>
303
+ `<button class="answer-btn" data-ans="${i}" data-key="${key}">${opt.text}</button>`
304
+ ).join("")}
305
+ </div>
306
+ `;
307
+ // disable the card so it can't be opened again
308
+ card.classList.add("disabled");
309
+ // attach click handlers to answers (no inline booleans)
310
+ document.querySelectorAll('.answer-btn').forEach(btn => {
311
+ btn.addEventListener('click', () => {
312
+ if (btn.classList.contains('disabled')) return;
313
+ const chosenIndex = parseInt(btn.getAttribute('data-ans'), 10);
314
+ const k = btn.getAttribute('data-key');
315
+ checkAnswer(categoryIndex, difficulty, chosenIndex, k);
316
+ }, { once: true });
317
+ });
318
+ }
319
+ function checkAnswer(cat, diff, chosenShuffledIndex, key){
320
+ const q = questions[cat][diff];
321
+ const reg = shuffleRegistry.get(key);
322
+ const isCorrect = (chosenShuffledIndex === reg.shuffledCorrectIndex);
323
+ let val = (diff + 1) * 100;
324
+ if (reg.isDailyDouble) val *= 2;
325
+ // lock buttons (prevent multiple scoring)
326
+ document.querySelectorAll(".answer-btn").forEach(b => {
327
+ b.disabled = true; b.classList.add("disabled");
328
+ });
329
+ if (isCorrect) {
330
+ score += val;
331
+ qdisp.innerHTML += `<p class="feedback" style="color:green;">✅ Correct! +$${val.toLocaleString()}</p>`;
332
+ } else {
333
+ score -= val;
334
+ const correctText = q.a[q.correct];
335
+ const chosenText = q.a[
336
+ // translate shuffled index back to original by comparing text (safe here; could also carry mapping)
337
+ q.a.findIndex((orig, idx) => {
338
+ // find the text for chosenShuffledIndex by looking up the rendered button text
339
+ // simpler: we recorded only shuffled index; to show user's text, just read from DOM:
340
+ return false; // placeholder, we'll get from DOM below
341
+ })
342
+ ];
343
+ // Grab the chosen text from the DOM directly
344
+ const chosenBtn = document.querySelector(`.answer-btn[data-ans="${chosenShuffledIndex}"][data-key="${key}"]`);
345
+ const chosenPretty = chosenBtn ? chosenBtn.textContent : "(your choice)";
346
+ qdisp.innerHTML += `<p class="feedback" style="color:#b00020;">❌ Wrong! −$${val.toLocaleString()}<br/>Correct answer: <em>${correctText}</em></p>`;
347
+ // record for review
348
+ missedQuestions.push({
349
+ category: categories[cat],
350
+ value: `$${(diff+1)*100}${reg.isDailyDouble ? " (x2)" : ""}`,
351
+ question: q.q,
352
+ yourAnswer: chosenPretty,
353
+ correctAnswer: correctText
354
+ });
355
+ }
356
+ sdisp.textContent = `Score: ${score}`;
357
+ answered++; // increment only after answering
358
+ if (answered === total) {
359
+ endGame();
360
+ }
361
+ }
362
+ function endGame(){
363
+ qdisp.innerHTML += `<h2 style="margin-top:12px">Game Over!</h2><p>Your final score: $${score.toLocaleString()}</p>`;
364
+ if (missedQuestions.length){
365
+ const items = missedQuestions.map(m =>
366
+ `<div class="missed">
367
+ <div class="q">(${m.category} • ${m.value}) ${m.question}</div>
368
+ <div class="a">Your answer: <em>${m.yourAnswer}</em></div>
369
+ <div class="a">Correct: <strong>${m.correctAnswer}</strong></div>
370
+ </div>`
371
+ ).join("");
372
+ review.style.display = "block";
373
+ review.innerHTML = `<h3>Review: Questions to Revisit (${missedQuestions.length})</h3>${items}`;
374
+ } else {
375
+ review.style.display = "block";
376
+ review.innerHTML = `<h3>Perfect Round!</h3><p>You answered all questions correctly 🎉</p>`;
377
+ }
378
+ }
379
+ // Build the board
380
+ createBoard();
381
+ </script>
382
+ </body>
383
+ </html>