mirror of
https://github.com/tiennm99/loto.git
synced 2026-10-11 03:13:40 +00:00
fix(deps): resolve vite dependabot advisories
This commit is contained in:
1 parent
d31cdcda4a
commit
8f7aad1ba5
4 files changed
+373
-325
No files matched your search
+1
-1
@@ -36,7 +36,7 @@
|
|||||||
"happy-dom": "20.9.0",
|
"happy-dom": "20.9.0",
|
||||||
"svelte": "^5",
|
"svelte": "^5",
|
||||||
"tailwindcss": "^4",
|
"tailwindcss": "^4",
|
||||||
"vite": "^8",
|
"vite": "^8.0.16",
|
||||||
"vitest": "4.1.7"
|
"vitest": "4.1.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Generated
+343
-307
File diff suppressed because it is too large.
Load diff
@@ -1,3 +1,7 @@
|
|||||||
|
<script>
|
||||||
|
const PREVIEW_CELLS = [...Array(99).keys()];
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- Empty-state hero for master mode. Replaces the bare line of text
|
<!-- Empty-state hero for master mode. Replaces the bare line of text
|
||||||
when no game has been started; uses a decorative ghost mock of
|
when no game has been started; uses a decorative ghost mock of
|
||||||
the 11×9 master tracking grid so the page silhouette stays
|
the 11×9 master tracking grid so the page silhouette stays
|
||||||
@@ -10,7 +14,7 @@
|
|||||||
rounded-md overflow-hidden border border-slate-300 dark:border-slate-600"
|
rounded-md overflow-hidden border border-slate-300 dark:border-slate-600"
|
||||||
>
|
>
|
||||||
<div class="grid grid-cols-9 gap-px bg-slate-300 dark:bg-slate-700">
|
<div class="grid grid-cols-9 gap-px bg-slate-300 dark:bg-slate-700">
|
||||||
{#each Array(99) as _, i (i)}
|
{#each PREVIEW_CELLS as i (i)}
|
||||||
{@const filled = i % 11 < 9 && i % 7 === 0}
|
{@const filled = i % 11 < 9 && i % 7 === 0}
|
||||||
<div
|
<div
|
||||||
class="aspect-square text-[0.5rem] flex items-center justify-center
|
class="aspect-square text-[0.5rem] flex items-center justify-center
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { SvelteSet } from "svelte/reactivity";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
generateGrid,
|
generateGrid,
|
||||||
getWaitingNumber,
|
getWaitingNumber,
|
||||||
@@ -16,6 +18,7 @@
|
|||||||
import { cancelPlayback, playBingo, playWaiting } from "$lib/voice.js";
|
import { cancelPlayback, playBingo, playWaiting } from "$lib/voice.js";
|
||||||
|
|
||||||
const STORAGE_PREFIX = "loto";
|
const STORAGE_PREFIX = "loto";
|
||||||
|
const PREVIEW_CELLS = [...Array(27).keys()];
|
||||||
|
|
||||||
function prefersReducedMotion() {
|
function prefersReducedMotion() {
|
||||||
return (
|
return (
|
||||||
@@ -29,7 +32,8 @@
|
|||||||
// Numbers the user explicitly unticked AFTER an auto-cross; suppresses
|
// Numbers the user explicitly unticked AFTER an auto-cross; suppresses
|
||||||
// re-cross on subsequent passes (e.g. regen replay). Manual re-ticks
|
// re-cross on subsequent passes (e.g. regen replay). Manual re-ticks
|
||||||
// remove from the set.
|
// remove from the set.
|
||||||
let manualUnticks = $state(/** @type {Set<number>} */ (new Set()));
|
/** @type {SvelteSet<number>} */
|
||||||
|
const manualUnticks = new SvelteSet();
|
||||||
let showCongrats = $state(false);
|
let showCongrats = $state(false);
|
||||||
let congratsRow = $state(-1);
|
let congratsRow = $state(-1);
|
||||||
let celebrationTier = $state(/** @type {1 | 2} */ (1));
|
let celebrationTier = $state(/** @type {1 | 2} */ (1));
|
||||||
@@ -42,11 +46,17 @@
|
|||||||
// celebration set reads as Vietnamese fair, not generic party.
|
// celebration set reads as Vietnamese fair, not generic party.
|
||||||
const CONFETTI_EMOJI = ["🎊", "✨", "🎉", "🥳", "🥢", "🎋", "🏮"];
|
const CONFETTI_EMOJI = ["🎊", "✨", "🎉", "🥳", "🥢", "🎋", "🏮"];
|
||||||
|
|
||||||
// Plain refs (not reactive)
|
/** @param {Iterable<number>} values */
|
||||||
|
function replaceManualUnticks(values) {
|
||||||
|
manualUnticks.clear();
|
||||||
|
for (const value of values) manualUnticks.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timer handle stays plain; row trackers are reactive so Svelte can observe Set reads.
|
||||||
/** @type {ReturnType<typeof setTimeout> | null} */
|
/** @type {ReturnType<typeof setTimeout> | null} */
|
||||||
let toastTimer = null;
|
let toastTimer = null;
|
||||||
const celebratedRows = new Set();
|
const celebratedRows = new SvelteSet();
|
||||||
const notifiedWaitingRows = new Set();
|
const notifiedWaitingRows = new SvelteSet();
|
||||||
// How many entries of masterState.called we've already replayed.
|
// How many entries of masterState.called we've already replayed.
|
||||||
// Advances strictly even on no-op passes so a single draw never
|
// Advances strictly even on no-op passes so a single draw never
|
||||||
// re-fires (auto-cross effect dedup). Resets to 0 when the host
|
// re-fires (auto-cross effect dedup). Resets to 0 when the host
|
||||||
@@ -82,7 +92,7 @@
|
|||||||
// simultaneously — each gets its own pulsing cell.
|
// simultaneously — each gets its own pulsing cell.
|
||||||
const waitingCells = $derived.by(() => {
|
const waitingCells = $derived.by(() => {
|
||||||
/** @type {Set<string>} */
|
/** @type {Set<string>} */
|
||||||
const set = new Set();
|
const set = new SvelteSet();
|
||||||
if (!grid || crossed.length === 0) return set;
|
if (!grid || crossed.length === 0) return set;
|
||||||
for (let r = 0; r < grid.length; r++) {
|
for (let r = 0; r < grid.length; r++) {
|
||||||
if (rowCompleteness[r]) continue;
|
if (rowCompleteness[r]) continue;
|
||||||
@@ -121,7 +131,7 @@
|
|||||||
loadCrossedState(STORAGE_PREFIX) ??
|
loadCrossedState(STORAGE_PREFIX) ??
|
||||||
savedGrid.map((row) => row.map(() => false));
|
savedGrid.map((row) => row.map(() => false));
|
||||||
crossed = savedCrossed;
|
crossed = savedCrossed;
|
||||||
manualUnticks = loadManualUnticks(STORAGE_PREFIX);
|
replaceManualUnticks(loadManualUnticks(STORAGE_PREFIX));
|
||||||
|
|
||||||
celebratedRows.clear();
|
celebratedRows.clear();
|
||||||
notifiedWaitingRows.clear();
|
notifiedWaitingRows.clear();
|
||||||
@@ -252,7 +262,7 @@
|
|||||||
prevCalledLen = len;
|
prevCalledLen = len;
|
||||||
if (prev > 0 && len === 0 && settings.mode === "both" && grid) {
|
if (prev > 0 && len === 0 && settings.mode === "both" && grid) {
|
||||||
crossed = grid.map((row) => row.map(() => false));
|
crossed = grid.map((row) => row.map(() => false));
|
||||||
manualUnticks = new Set();
|
manualUnticks.clear();
|
||||||
lastHandledIndex = 0;
|
lastHandledIndex = 0;
|
||||||
celebratedRows.clear();
|
celebratedRows.clear();
|
||||||
notifiedWaitingRows.clear();
|
notifiedWaitingRows.clear();
|
||||||
@@ -264,6 +274,7 @@
|
|||||||
cancelPlayback();
|
cancelPlayback();
|
||||||
const newGrid = generateGrid();
|
const newGrid = generateGrid();
|
||||||
let newCrossed = newGrid.map((row) => row.map(() => false));
|
let newCrossed = newGrid.map((row) => row.map(() => false));
|
||||||
|
manualUnticks.clear();
|
||||||
// Replay master's called[] onto the fresh grid so the host doesn't
|
// Replay master's called[] onto the fresh grid so the host doesn't
|
||||||
// restart from zero when they regenerate mid-game (locked decision).
|
// restart from zero when they regenerate mid-game (locked decision).
|
||||||
if (settings.mode === "both") {
|
if (settings.mode === "both") {
|
||||||
@@ -272,7 +283,7 @@
|
|||||||
crossed: newCrossed,
|
crossed: newCrossed,
|
||||||
called: masterState.called,
|
called: masterState.called,
|
||||||
lastHandledIndex: 0,
|
lastHandledIndex: 0,
|
||||||
manualUnticks: new Set(),
|
manualUnticks,
|
||||||
mode: "both",
|
mode: "both",
|
||||||
});
|
});
|
||||||
newCrossed = result.crossed;
|
newCrossed = result.crossed;
|
||||||
@@ -282,7 +293,6 @@
|
|||||||
}
|
}
|
||||||
grid = newGrid;
|
grid = newGrid;
|
||||||
crossed = newCrossed;
|
crossed = newCrossed;
|
||||||
manualUnticks = new Set();
|
|
||||||
saveGrid(newGrid, STORAGE_PREFIX);
|
saveGrid(newGrid, STORAGE_PREFIX);
|
||||||
saveCrossedState(newCrossed, STORAGE_PREFIX);
|
saveCrossedState(newCrossed, STORAGE_PREFIX);
|
||||||
saveManualUnticks(manualUnticks, STORAGE_PREFIX);
|
saveManualUnticks(manualUnticks, STORAGE_PREFIX);
|
||||||
@@ -298,7 +308,7 @@
|
|||||||
if (hasMarks && !confirm("Bạn có muốn xoá tất cả đánh dấu không?")) return;
|
if (hasMarks && !confirm("Bạn có muốn xoá tất cả đánh dấu không?")) return;
|
||||||
cancelPlayback();
|
cancelPlayback();
|
||||||
let cleared = grid.map((row) => row.map(() => false));
|
let cleared = grid.map((row) => row.map(() => false));
|
||||||
manualUnticks = new Set();
|
manualUnticks.clear();
|
||||||
// In both mode, immediately replay master's called[] (locked
|
// In both mode, immediately replay master's called[] (locked
|
||||||
// decision: clear → re-cross all currently-called numbers).
|
// decision: clear → re-cross all currently-called numbers).
|
||||||
if (settings.mode === "both") {
|
if (settings.mode === "both") {
|
||||||
@@ -307,7 +317,7 @@
|
|||||||
crossed: cleared,
|
crossed: cleared,
|
||||||
called: masterState.called,
|
called: masterState.called,
|
||||||
lastHandledIndex: 0,
|
lastHandledIndex: 0,
|
||||||
manualUnticks: new Set(),
|
manualUnticks,
|
||||||
mode: "both",
|
mode: "both",
|
||||||
});
|
});
|
||||||
cleared = result.crossed;
|
cleared = result.crossed;
|
||||||
@@ -342,10 +352,8 @@
|
|||||||
// replays skip them. Untracking uncalled numbers would pollute the
|
// replays skip them. Untracking uncalled numbers would pollute the
|
||||||
// set with no visible effect — auto-cross only acts on called nums.
|
// set with no visible effect — auto-cross only acts on called nums.
|
||||||
if (num > 0 && masterState.called.includes(num)) {
|
if (num > 0 && masterState.called.includes(num)) {
|
||||||
const next = new Set(manualUnticks);
|
if (wasCrossed && !willBeCrossed) manualUnticks.add(num);
|
||||||
if (wasCrossed && !willBeCrossed) next.add(num);
|
else if (!wasCrossed && willBeCrossed) manualUnticks.delete(num);
|
||||||
else if (!wasCrossed && willBeCrossed) next.delete(num);
|
|
||||||
if (next.size !== manualUnticks.size) manualUnticks = next;
|
|
||||||
}
|
}
|
||||||
crossed = crossed.map((r, ri) =>
|
crossed = crossed.map((r, ri) =>
|
||||||
ri === row ? r.map((v, ci) => (ci === col ? !v : v)) : r
|
ri === row ? r.map((v, ci) => (ci === col ? !v : v)) : r
|
||||||
@@ -504,7 +512,7 @@
|
|||||||
rounded-md overflow-hidden border border-slate-300 dark:border-slate-600"
|
rounded-md overflow-hidden border border-slate-300 dark:border-slate-600"
|
||||||
>
|
>
|
||||||
<div class="grid grid-cols-9 gap-px bg-slate-300 dark:bg-slate-700">
|
<div class="grid grid-cols-9 gap-px bg-slate-300 dark:bg-slate-700">
|
||||||
{#each Array(27) as _, i (i)}
|
{#each PREVIEW_CELLS as i (i)}
|
||||||
{@const filled = i % 3 === 0}
|
{@const filled = i % 3 === 0}
|
||||||
<div
|
<div
|
||||||
class="aspect-square text-[0.55rem] flex items-center justify-center
|
class="aspect-square text-[0.55rem] flex items-center justify-center
|
||||||
|
|||||||
Reference in new issue
Block a user