Spaces:
Running
Running
Download index.html from Culturetiming/Test_game: direct link, hf CLI and curl.
- Browser
- Download file 9.66 kB
-
https://huggingface.co/spaces/Culturetiming/Test_game/resolve/main/index.html
- Command line
-
hf download hf://spaces/Culturetiming/Test_game/index.html
-
curl -L -o index.html https://huggingface.co/spaces/Culturetiming/Test_game/resolve/main/index.html
9.66 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Masking Millionaire</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| </head> | |
| <body class="bg-gray-100 min-h-screen flex items-center justify-center p-6"> | |
| <div class="bg-white p-8 rounded-2xl shadow-xl w-full max-w-2xl"> | |
| <h1 class="text-4xl font-bold text-indigo-600 text-center mb-2">Masking Millionaire</h1> | |
| <p class="text-center text-sm text-gray-500 mb-6"> | |
| Content source: | |
| <a href="https://learn.microsoft.com/en-us/fabric/data-warehouse/dynamic-data-masking" | |
| target="_blank" | |
| class="underline hover:text-indigo-700"> | |
| Dynamic Data Masking in Fabric Data Warehouse | |
| </a> | |
| </p> | |
| <div id="board"> | |
| <div id="question" class="text-2xl font-semibold text-gray-800 mb-4"></div> | |
| <div id="choices" class="space-y-3"></div> | |
| <div id="lifelines" class="flex justify-around mt-6"> | |
| <button id="life5050" class="lifeline bg-yellow-400 hover:bg-yellow-500 text-white font-medium py-2 px-4 rounded-lg shadow"> | |
| 50:50 | |
| </button> | |
| <button id="lifePoll" class="lifeline bg-blue-400 hover:bg-blue-500 text-white font-medium py-2 px-4 rounded-lg shadow"> | |
| Ask the Class | |
| </button> | |
| <button id="lifeHint" class="lifeline bg-green-400 hover:bg-green-500 text-white font-medium py-2 px-4 rounded-lg shadow"> | |
| Ask an Expert | |
| </button> | |
| </div> | |
| <div id="poll" class="text-sm text-gray-700 mt-4"></div> | |
| <div id="hint" class="text-sm italic text-gray-600 mt-2"></div> | |
| <button id="next" class="hidden mt-8 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold py-2 px-6 rounded-lg shadow"> | |
| Next Question | |
| </button> | |
| </div> | |
| </div> | |
| <script> | |
| // Masking quiz data | |
| const questions = [ | |
| { q: "Which feature simplifies obfuscation of sensitive data without modifying existing application queries?", choices: ["Column-level security","Dynamic data masking","Row-level security","Transparent data encryption"], correct: 1, hint: "It applies masks at query results, not at storage." }, | |
| { q: "How many built-in masking functions does dynamic data masking provide in Fabric Data Warehouse?", choices: ["2","3","4","5"], correct: 2, hint: "The options: default, email, random, custom string." }, | |
| { q: "Which mask function replaces string data with 'XXXX' based on data type?", choices: ["default()","email()","random()","partial()"], correct: 0, hint: "This is full masking according to the data type." }, | |
| { q: "Which mask function exposes the first letter of an email and the constant suffix '.com'?", choices: ["default()","email()","random()","partial()"], correct: 1, hint: "It formats answer like aXXX@XXXX.com." }, | |
| { q: "Which function masks numeric data with a random value within a specified range?", choices: ["default()","email()","random(start,end)","partial()"], correct: 2, hint: "Syntax: random([start],[end])." }, | |
| { q: "Which masking function allows you to expose prefix and suffix with custom padding?", choices: ["default()","email()","random()","partial(prefix,pad,suffix)"], correct: 3, hint: "It’s called 'partial'." }, | |
| { q: "Which Transact-SQL command is used to add a mask to an existing column?", choices: ["ADD MASK","MASK COLUMN","ALTER COLUMN... ADD MASKED WITH","CREATE MASK"], correct: 2, hint: "Use ALTER COLUMN ... ADD MASKED WITH." }, | |
| { q: "Which permission is required to add, replace, or remove a mask on a column?", choices: ["UNMASK","ALTER ANY MASK","CONTROL","SELECT"], correct: 1, hint: "This permission targets mask operations." }, | |
| { q: "Which permission grants a user the ability to view unmasked data specifically?", choices: ["UNMASK","ALTER ANY MASK","CONTROL","SELECT"], correct: 0, hint: "It’s literally named UNMASK." }, | |
| { q: "The CONTROL permission on the database includes which of the following?", choices: ["UNMASK only","ALTER ANY MASK only","Both UNMASK and ALTER ANY MASK","None of the above"], correct: 2, hint: "It covers full mask management." }, | |
| { q: "Dynamic data masking in Fabric Data Warehouse is complementary to which security feature?", choices: ["Transparent data encryption","Column-level security","Backup encryption","Data classification"], correct: 1, hint: "Think of restricting rows and fields." }, | |
| { q: "By default, what value is used to mask datetime columns?", choices: ["0000-00-00","1900-01-01 00:00:00.0000000","1970-01-01","NULL"], correct: 1, hint: "It uses SQL Server’s default minimal date." }, | |
| { q: "What is a limitation of dynamic data masking regarding security?", choices: ["Cannot mask numeric data","Protects against brute-force inference","Only applies to SELECT queries","Doesn't prevent malicious inference"], correct: 3, hint: "Unprivileged users can still infer data." }, | |
| { q: "Who sees unmasked data by default in a masked table?", choices: ["Contributors","All database users","Unprivileged users","All users"], correct: 0, hint: "Workspace roles like Admin, Member or Contributor." }, | |
| { q: "Which object-level security should you combine with dynamic data masking?", choices: ["Row-level security only","Column-level security only","Both row-level and column-level security","None"], correct: 2, hint: "Use multiple data protection features." } | |
| ]; | |
| const prizes = [100,200,300,500,1000,2000,4000,8000,16000,32000,64000,125000,250000,500000,1000000]; | |
| let idx = 0; | |
| let currentPrize = prizes[0]; | |
| // Redistribute correct answers evenly across A–D | |
| questions.forEach((q, i) => { | |
| const target = i % 4; | |
| if (q.correct !== target) { | |
| [q.choices[target], q.choices[q.correct]] = [q.choices[q.correct], q.choices[target]]; | |
| q.correct = target; | |
| } | |
| }); | |
| const qEl = document.getElementById('question'); | |
| const cEl = document.getElementById('choices'); | |
| const pollEl = document.getElementById('poll'); | |
| const hintEl = document.getElementById('hint'); | |
| const nextBtn = document.getElementById('next'); | |
| const boardEl = document.getElementById('board'); | |
| function updateQuestionDisplay() { | |
| qEl.textContent = `$${currentPrize}: ${questions[idx].q}`; | |
| } | |
| function showQuestion() { | |
| ['life5050','lifePoll','lifeHint'].forEach(id => { | |
| const btn = document.getElementById(id); | |
| btn.disabled = false; | |
| btn.classList.remove('opacity-50'); | |
| }); | |
| pollEl.textContent = ''; | |
| hintEl.textContent = ''; | |
| nextBtn.classList.add('hidden'); | |
| currentPrize = prizes[idx]; | |
| updateQuestionDisplay(); | |
| cEl.innerHTML = questions[idx].choices.map((ch,i) => | |
| `<button class="choice bg-indigo-500 hover:bg-indigo-600 text-white font-medium py-2 px-4 rounded w-full" data-i="${i}">` + | |
| `${String.fromCharCode(65+i)}. ${ch}</button>` | |
| ).join(''); | |
| document.querySelectorAll('.choice').forEach(btn => { | |
| btn.disabled = false; | |
| btn.onclick = selectAnswer; | |
| }); | |
| } | |
| function selectAnswer(e) { | |
| const chosen = +e.target.dataset.i; | |
| const corr = questions[idx].correct; | |
| document.querySelectorAll('.choice').forEach(b => b.disabled = true); | |
| if (chosen === corr) { | |
| e.target.classList.replace('bg-indigo-500','bg-green-500'); | |
| } else { | |
| e.target.classList.replace('bg-indigo-500','bg-red-500'); | |
| document.querySelector(`.choice[data-i="${corr}"]`).classList.replace('bg-indigo-500','bg-green-500'); | |
| } | |
| nextBtn.classList.remove('hidden'); | |
| } | |
| // 50:50 Lifeline | |
| document.getElementById('life5050').onclick = () => { | |
| const btn = document.getElementById('life5050'); | |
| if (btn.disabled) return; | |
| btn.disabled = true; | |
| btn.classList.add('opacity-50'); | |
| const corr = questions[idx].correct; | |
| questions[idx].choices | |
| .map((_, i) => i) | |
| .filter(i => i !== corr) | |
| .sort(() => Math.random() - 0.5) | |
| .slice(0, 2) | |
| .forEach(i => { | |
| const b = document.querySelector(`.choice[data-i="${i}"]`); | |
| b.disabled = true; | |
| b.classList.add('opacity-50'); | |
| }); | |
| currentPrize = Math.floor(currentPrize / 2); | |
| updateQuestionDisplay(); | |
| }; | |
| // Ask the Class | |
| document.getElementById('lifePoll').onclick = () => { | |
| const btn = document.getElementById('lifePoll'); | |
| if (btn.disabled) return; | |
| btn.disabled = true; | |
| btn.classList.add('opacity-50'); | |
| const corr = questions[idx].correct; | |
| const pct = [0,0,0,0]; | |
| pct[corr] = 70 + Math.floor(Math.random() * 21); | |
| let rem = 100 - pct[corr]; | |
| questions[idx].choices.forEach((_, i) => { | |
| if (i !== corr) { | |
| const alloc = Math.floor(rem / 3); | |
| pct[i] = alloc; | |
| rem -= alloc; | |
| } | |
| }); | |
| pollEl.textContent = `Class Poll: A:${pct[0]}% B:${pct[1]}% C:${pct[2]}% D:${pct[3]}%`; | |
| }; | |
| // Ask an Expert | |
| document.getElementById('lifeHint').onclick = () => { | |
| const btn = document.getElementById('lifeHint'); | |
| if (btn.disabled) return; | |
| btn.disabled = true; | |
| btn.classList.add('opacity-50'); | |
| hintEl.textContent = `Expert Hint: ${questions[idx].hint}`; | |
| }; | |
| // Next Question | |
| nextBtn.onclick = () => { | |
| idx++; | |
| if (idx < questions.length) { | |
| showQuestion(); | |
| } else { | |
| boardEl.innerHTML = '<div class="text-3xl font-bold text-green-600 text-center">🎉 Congratulations! You’ve mastered Masking Millionaire! 🎉</div>'; | |
| } | |
| }; | |
| // Start | |
| showQuestion(); | |
| </script> | |
| </body> | |
| </html> | |