From 15a46e05c05e8a01706262fb909b86203017e536 Mon Sep 17 00:00:00 2001 From: uku Date: Wed, 30 Oct 2024 13:16:52 +0100 Subject: [PATCH 01/44] feat(nix): add derivation --- .gitignore | 1 + flake.nix | 2 ++ nix/derivation.nix | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 nix/derivation.nix diff --git a/.gitignore b/.gitignore index 3a213aa..3e784db 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ vite.config.ts.timestamp-* # Nix /.direnv +result* diff --git a/flake.nix b/flake.nix index 1ec8e7a..31a7207 100644 --- a/flake.nix +++ b/flake.nix @@ -17,6 +17,8 @@ pkgs, ... }: { + packages.default = pkgs.callPackage ./nix/derivation.nix {}; + devShells.default = with pkgs; mkShellNoCC { buildInputs = [bun wrangler]; diff --git a/nix/derivation.nix b/nix/derivation.nix new file mode 100644 index 0000000..6c1888a --- /dev/null +++ b/nix/derivation.nix @@ -0,0 +1,63 @@ +{ + lib, + stdenvNoCC, + bun, + nodejs, +}: stdenvNoCC.mkDerivation (finalAttrs: { + pname = "tcl-guessr"; + version = "0.0.1"; + + src = ../.; + + nativeBuildInputs = [bun nodejs]; + + bunDeps = stdenvNoCC.mkDerivation { + pname = "${finalAttrs.pname}-bun-deps"; + inherit (finalAttrs) version; + + nativeBuildInputs = [bun]; + + src = lib.fileset.toSource { + root = finalAttrs.src; + fileset = lib.fileset.unions [ + ../package.json + ../bun.lockb + ../patches + ]; + }; + + dontConfigure = true; + dontBuild = true; + + installPhase = '' + bun install \ + --frozen-lockfile \ + --ignore-scripts \ + --backend copyfile \ + --force + + cp -r node_modules/ $out + ''; + + outputHashMode = "recursive"; + outputHash = "sha256-cYbyVt2Hc96WRAIsNkgnG0vUB47m1ixbhYhHmXetaII="; + }; + + configurePhase = '' + cp -r $bunDeps node_modules + chmod -R +w node_modules + patchShebangs node_modules/{*,.*} + ''; + + buildPhase = '' + bun run build + ''; + + installPhase = '' + cp -r .svelte-kit/cloudflare $out + ''; + + passthru = { + inherit (finalAttrs) bunDeps; + }; + }) From 0065a9f9a97f214899bdf86c54e51523ee71da3c Mon Sep 17 00:00:00 2001 From: uku Date: Fri, 1 Nov 2024 13:48:25 +0100 Subject: [PATCH 02/44] chore: clean setMarker --- src/routes/game/+page.svelte | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/routes/game/+page.svelte b/src/routes/game/+page.svelte index b4bb2c3..d71aae0 100644 --- a/src/routes/game/+page.svelte +++ b/src/routes/game/+page.svelte @@ -58,11 +58,7 @@ function setMarker(pos: L.LatLng) { if (map && !results) { - if (playerMarker) { - playerMarker = playerMarker.setLatLng(pos); - } else { - playerMarker = L.marker(pos).addTo(map); - } + playerMarker = (playerMarker ?? L.marker(pos).addTo(map)).setLatLng(pos); } } From b318f77438f8d74dea8c83783dddf942440af151 Mon Sep 17 00:00:00 2001 From: uku Date: Fri, 1 Nov 2024 13:50:12 +0100 Subject: [PATCH 03/44] fix: avoid race condition when checking results --- src/routes/game/+page.svelte | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/routes/game/+page.svelte b/src/routes/game/+page.svelte index d71aae0..2cecb12 100644 --- a/src/routes/game/+page.svelte +++ b/src/routes/game/+page.svelte @@ -13,6 +13,7 @@ let mapPromise = $state(fetchMap()); let gamePromise = $state(fetchGame()); + let isChecking = $state(false); let results: CheckResponse | null = $state(null); let currentIndex = $state(0); @@ -63,7 +64,8 @@ } async function checkLocation() { - if (!playerMarker || results) return; + if (!playerMarker || results || isChecking) return; + isChecking = true; const gameData = await gamePromise; @@ -96,6 +98,8 @@ } else { alert("it seems than an error occurred"); } + + isChecking = false; } async function restartGame() { @@ -132,7 +136,7 @@
{#if results === null} - + {:else} {/if} From b775ee5d03f9383a4d55aac61db270cd985dfab0 Mon Sep 17 00:00:00 2001 From: uku Date: Tue, 19 Nov 2024 09:55:37 +0100 Subject: [PATCH 04/44] chore: replace flake with shell.nix --- .envrc | 2 +- flake.lock | 48 ------------------------------------------------ flake.nix | 28 ---------------------------- shell.nix | 9 +++++++++ 4 files changed, 10 insertions(+), 77 deletions(-) delete mode 100644 flake.lock delete mode 100644 flake.nix create mode 100644 shell.nix diff --git a/.envrc b/.envrc index 3550a30..1d953f4 100644 --- a/.envrc +++ b/.envrc @@ -1 +1 @@ -use flake +use nix diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 36803a4..0000000 --- a/flake.lock +++ /dev/null @@ -1,48 +0,0 @@ -{ - "nodes": { - "flake-parts": { - "inputs": { - "nixpkgs-lib": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1727826117, - "narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=", - "owner": "hercules-ci", - "repo": "flake-parts", - "rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "flake-parts", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1729665710, - "narHash": "sha256-AlcmCXJZPIlO5dmFzV3V2XF6x/OpNWUV8Y/FMPGd8Z4=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "2768c7d042a37de65bb1b5b3268fc987e534c49d", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-parts": "flake-parts", - "nixpkgs": "nixpkgs" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 1ec8e7a..0000000 --- a/flake.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - - flake-parts = { - url = "github:hercules-ci/flake-parts"; - inputs.nixpkgs-lib.follows = "nixpkgs"; - }; - }; - - outputs = {flake-parts, ...} @ inputs: - flake-parts.lib.mkFlake {inherit inputs;} { - systems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"]; - - perSystem = { - lib, - pkgs, - ... - }: { - devShells.default = with pkgs; - mkShellNoCC { - buildInputs = [bun wrangler]; - }; - - formatter = pkgs.alejandra; - }; - }; -} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..1479462 --- /dev/null +++ b/shell.nix @@ -0,0 +1,9 @@ +{ + pkgs ? import { }, +}: +pkgs.mkShellNoCC { + buildInputs = with pkgs; [ + bun + wrangler + ]; +} From 7c2c68a7b8dbbb8024ad5618ba5bb23d52ab7f45 Mon Sep 17 00:00:00 2001 From: uku Date: Tue, 19 Nov 2024 09:56:08 +0100 Subject: [PATCH 05/44] chore(deps): update --- bun.lockb | Bin 129904 -> 136864 bytes package.json | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bun.lockb b/bun.lockb index 6084e67b77d4db72ba36796a8d37e13ce6e3a57a..5ccfe2be3f324579e28a81dffeb02b4e97008e79 100755 GIT binary patch delta 28850 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 delta 25792 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 Date: Tue, 19 Nov 2024 16:16:23 +0100 Subject: [PATCH 06/44] fix: set body margin only on /game --- src/app.html | 8 -------- src/routes/+page.svelte | 2 +- src/routes/game/+page.svelte | 6 ++++++ src/routes/results/+page.svelte | 4 ++-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/app.html b/src/app.html index 2e7a40f..77a5ff5 100644 --- a/src/app.html +++ b/src/app.html @@ -9,12 +9,4 @@
%sveltekit.body%
- - diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 2a9d3ed..271c903 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -26,7 +26,7 @@ From 8d7b3d6dc27f8f07e96860f06d0e259b56c1f5bd Mon Sep 17 00:00:00 2001 From: uku Date: Wed, 20 Nov 2024 09:30:57 +0100 Subject: [PATCH 07/44] feat: add discord login --- bun.lockb | Bin 136864 -> 139464 bytes migrations/0001_init.sql | 12 +++++ package.json | 3 ++ src/app.d.ts | 8 ++- src/hooks.server.ts | 25 +++++++++ src/lib/auth/cookie.ts | 19 +++++++ src/lib/auth/discord.ts | 14 +++++ src/lib/auth/index.ts | 15 ++++++ src/lib/auth/session.ts | 76 +++++++++++++++++++++++++++ src/routes/+page.server.ts | 5 ++ src/routes/+page.svelte | 20 +++++++ src/routes/login/+server.ts | 19 +++++++ src/routes/login/callback/+server.ts | 53 +++++++++++++++++++ src/routes/logout/+server.ts | 16 ++++++ wrangler.toml | 5 ++ 15 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 migrations/0001_init.sql create mode 100644 src/hooks.server.ts create mode 100644 src/lib/auth/cookie.ts create mode 100644 src/lib/auth/discord.ts create mode 100644 src/lib/auth/index.ts create mode 100644 src/lib/auth/session.ts create mode 100644 src/routes/+page.server.ts create mode 100644 src/routes/login/+server.ts create mode 100644 src/routes/login/callback/+server.ts create mode 100644 src/routes/logout/+server.ts diff --git a/bun.lockb b/bun.lockb index 5ccfe2be3f324579e28a81dffeb02b4e97008e79..3cfcf9cc256fd4ab2e525f5a3466d019de7c8a52 100755 GIT binary patch delta 25479 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 Xrq_ls%1pm5%B0A2B6s>PQKn@8U!=lo delta 24073 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 Iq` { + const db = event.platform?.env?.TCL_GUESSR_D1 ?? null; + const token = event.cookies.get("session") ?? null; + + if (db === null || token === null) { + event.locals.session = null; + event.locals.user = null; + return resolve(event); + } + + const { session, user } = await validateSessionToken(token, db); + if (session !== null) { + setSessionTokenCookie(event.cookies, token, session.expiresAt); + } else { + deleteSessionTokenCookie(event.cookies); + } + + event.locals.session = session; + event.locals.user = user; + return resolve(event); +}; diff --git a/src/lib/auth/cookie.ts b/src/lib/auth/cookie.ts new file mode 100644 index 0000000..68acc60 --- /dev/null +++ b/src/lib/auth/cookie.ts @@ -0,0 +1,19 @@ +import type { Cookies } from "@sveltejs/kit"; + +export function setSessionTokenCookie(cookies: Cookies, token: string, expiresAt: Date): void { + cookies.set("session", token, { + httpOnly: true, + sameSite: "lax", + expires: expiresAt, + path: "/", + }); +} + +export function deleteSessionTokenCookie(cookies: Cookies): void { + cookies.set("session", "", { + httpOnly: true, + sameSite: "lax", + maxAge: 0, + path: "/", + }); +} diff --git a/src/lib/auth/discord.ts b/src/lib/auth/discord.ts new file mode 100644 index 0000000..6994872 --- /dev/null +++ b/src/lib/auth/discord.ts @@ -0,0 +1,14 @@ +import { Discord } from "arctic"; +import { DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET } from "$env/static/private"; + +export interface DiscordUser { + id: string; + username: string; + avatar: string; +} + +export const discord = new Discord( + DISCORD_CLIENT_ID, + DISCORD_CLIENT_SECRET, + "http://localhost:8788/login/callback", +); diff --git a/src/lib/auth/index.ts b/src/lib/auth/index.ts new file mode 100644 index 0000000..2f5b7a6 --- /dev/null +++ b/src/lib/auth/index.ts @@ -0,0 +1,15 @@ +export type SessionValidationResult = + | { session: Session; user: User } + | { session: null; user: null }; + +export interface Session { + id: string; + userId: string; + expiresAt: Date; +} + +export interface User { + id: string; + name: string; + avatarHash: string; +} diff --git a/src/lib/auth/session.ts b/src/lib/auth/session.ts new file mode 100644 index 0000000..11256e0 --- /dev/null +++ b/src/lib/auth/session.ts @@ -0,0 +1,76 @@ +import { encodeBase32LowerCaseNoPadding, encodeHexLowerCase } from "@oslojs/encoding"; +import { sha256 } from "@oslojs/crypto/sha2"; +import type { Session, SessionValidationResult, User } from "."; + +interface ValidateResponse { + id: string; + user_id: string; + expires_at: number; + name: string; + avatar_hash: string; +} + +export function generateSessionToken(): string { + const bytes = new Uint8Array(40); + crypto.getRandomValues(bytes); + return encodeBase32LowerCaseNoPadding(bytes); +} + +export async function createSession( + token: string, + userId: string, + db: D1Database, +): Promise { + const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); + const session: Session = { + id: sessionId, + userId, + expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7), // 7 days + }; + + await db + .prepare("INSERT INTO session (id, user_id, expires_at) VALUES (?, ?, ?)") + .bind(session.id, session.userId, Math.floor(session.expiresAt.getTime() / 1000)) + .run(); + + return session; +} + +export async function validateSessionToken( + token: string, + db: D1Database, +): Promise { + const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); + + const row = await db + .prepare( + "SELECT session.id, session.user_id, session.expires_at, user.name, user.avatar_hash FROM session INNER JOIN user ON user.id = session.user_id WHERE session.id = ?", + ) + .bind(sessionId) + .first(); + + if (row === null) return { session: null, user: null }; + + const session: Session = { + id: row.id, + userId: row.user_id, + expiresAt: new Date(row.expires_at * 1000), + }; + + const user: User = { + id: row.user_id, + name: row.name, + avatarHash: row.avatar_hash, + }; + + if (Date.now() >= session.expiresAt.getTime()) { + await invalidateSession(sessionId, db); + return { session: null, user: null }; + } else { + return { session, user }; + } +} + +export async function invalidateSession(sessionId: string, db: D1Database): Promise { + await db.prepare("DELETE FROM session WHERE id = ?").bind(sessionId).run(); +} diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts new file mode 100644 index 0000000..353be24 --- /dev/null +++ b/src/routes/+page.server.ts @@ -0,0 +1,5 @@ +import type { PageServerLoad } from "./$types"; + +export const load: PageServerLoad = async ({ locals }) => { + return { user: locals.user }; +}; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 271c903..267ec96 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,9 +1,29 @@

TCL-Guessr

+ + + +
From d1a3772f6c4513fbcc0971529fecf7afabc49aac Mon Sep 17 00:00:00 2001 From: uku Date: Fri, 22 Nov 2024 09:55:21 +0100 Subject: [PATCH 16/44] fix: make tram work again --- src/lib/index.ts | 5 +++-- src/routes/api/game/+server.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/lib/index.ts b/src/lib/index.ts index 82d276c..a18e6dc 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -15,6 +15,7 @@ let lazyStops: GeoJSON.Feature[] | null = null; export async function createGame( userId: string, mode: string, + stopsType: string, stops: GeoJSON.Feature[], db: D1Database, ): Promise { @@ -23,9 +24,9 @@ export async function createGame( const gameSql = db .prepare( - "INSERT INTO game (id, user_id, mode, time, total_score) VALUES (?, ?, ?, unixepoch('now'), 0)", + "INSERT INTO game (id, user_id, mode, stops_type, time, total_score) VALUES (?, ?, ?, ?, unixepoch('now'), 0)", ) - .bind(uuid, userId, mode); + .bind(uuid, userId, mode, stopsType); const roundSql = db.prepare( "INSERT INTO round (game_id, points, distance, stop_name) VALUES (?, -1, -1, ?)", diff --git a/src/routes/api/game/+server.ts b/src/routes/api/game/+server.ts index 9c859b3..0ee5b31 100644 --- a/src/routes/api/game/+server.ts +++ b/src/routes/api/game/+server.ts @@ -18,7 +18,7 @@ export const GET: RequestHandler = async ({ url, platform, locals }) => { error(400, "could not select random stop"); } - const gameData = await createGame(user.id, options.mode, randomStops, db); + const gameData = await createGame(user.id, options.mode, options.stopsType, randomStops, db); return Response.json(gameData); }; From 67d2358a373f9c0d66eddb493d2f3e18afa4c938 Mon Sep 17 00:00:00 2001 From: uku Date: Mon, 25 Nov 2024 12:17:27 +0100 Subject: [PATCH 17/44] fix: make logging in not mandatory --- bun.lockb | Bin 139464 -> 139800 bytes migrations/0004_fix_tables.sql | 44 +++++++++++++++++++++++++++ package.json | 1 + src/lib/auth/index.ts | 5 +++ src/lib/index.ts | 2 +- src/routes/+page.server.ts | 7 +---- src/routes/api/game/+server.ts | 6 ++-- src/routes/api/save/+server.ts | 16 ++++++++++ src/routes/login/+server.ts | 12 +++++--- src/routes/login/callback/+server.ts | 12 +++++--- src/routes/results/+page.server.ts | 7 +++-- src/routes/results/+page.svelte | 11 +++++++ 12 files changed, 99 insertions(+), 24 deletions(-) create mode 100644 migrations/0004_fix_tables.sql create mode 100644 src/routes/api/save/+server.ts diff --git a/bun.lockb b/bun.lockb index 3cfcf9cc256fd4ab2e525f5a3466d019de7c8a52..a59d4e69710a3146c9cd33f7821f5c106a309edf 100755 GIT binary patch delta 23269 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 O&!ousYr3KW({cdO!)ROp delta 22919 zcmbPngyY0PjtP32Z_ginpxqL(eDf2B-EJqtn`i9Uvcl-hkMA9~E~o8SFMrEIfr$YG z5+{bsGsVVEtWe-gEJ`lPOlDx60={6``1f}C3bbW&tgwbFIrIpzj7=#%Z8U UseeJ6_mcg%D^DR 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 { - if (locals.user === null) { - redirect(302, "/login"); - } else { - return { user: locals.user }; - } + return { user: locals.user }; }; diff --git a/src/routes/api/game/+server.ts b/src/routes/api/game/+server.ts index 0ee5b31..30e6730 100644 --- a/src/routes/api/game/+server.ts +++ b/src/routes/api/game/+server.ts @@ -6,9 +6,7 @@ export const GET: RequestHandler = async ({ url, platform, locals }) => { const db = platform?.env?.TCL_GUESSR_D1 ?? null; if (db === null) error(500, "could not connect to d1"); - const user = locals.user; - if (user === null) error(401, "not logged in"); - + const userId = locals.user?.id ?? null; const options = parseOptions(url); const crossingStops = await getMergedStops(options.stopsType); @@ -18,7 +16,7 @@ export const GET: RequestHandler = async ({ url, platform, locals }) => { error(400, "could not select random stop"); } - const gameData = await createGame(user.id, options.mode, options.stopsType, randomStops, db); + const gameData = await createGame(userId, options.mode, options.stopsType, randomStops, db); return Response.json(gameData); }; diff --git a/src/routes/api/save/+server.ts b/src/routes/api/save/+server.ts new file mode 100644 index 0000000..d57992b --- /dev/null +++ b/src/routes/api/save/+server.ts @@ -0,0 +1,16 @@ +import { error, redirect } from "@sveltejs/kit"; +import type { RequestHandler } from "./$types"; + +export const GET: RequestHandler = async ({ locals, platform, url }) => { + const db = platform?.env?.TCL_GUESSR_D1 ?? null; + if (db === null) error(500, "could not connect to d1"); + + const gameId = url.searchParams.get("id") ?? null; + if (gameId === null) error(400, "no game id specified"); + + if (locals.user === null) error(401); + + await db.prepare("UPDATE game SET user_id = ? WHERE id = ?").bind(locals.user.id, gameId).run(); + + redirect(302, `/results?gameId=${gameId}`); +}; diff --git a/src/routes/login/+server.ts b/src/routes/login/+server.ts index b32ac72..12361bf 100644 --- a/src/routes/login/+server.ts +++ b/src/routes/login/+server.ts @@ -2,18 +2,20 @@ import { redirect } from "@sveltejs/kit"; import { generateState } from "arctic"; import { discord } from "$lib/auth/discord"; import type { RequestHandler } from "./$types"; +import type { CookieData } from "$lib/auth"; + +export const GET: RequestHandler = async ({ cookies, url }) => { + const cookie: CookieData = { state: generateState(), next: url.searchParams.get("next") ?? "/" }; -export const GET: RequestHandler = async ({ cookies }) => { - const state = generateState(); const scopes = ["identify"]; - const url = discord.createAuthorizationURL(state, scopes); + const authUrl = discord.createAuthorizationURL(cookie.state, scopes); - cookies.set("discord_oauth_state", state, { + cookies.set("discord_oauth_state", JSON.stringify(cookie), { path: "/", httpOnly: true, maxAge: 60 * 10, sameSite: "lax", }); - redirect(302, url); + redirect(302, authUrl); }; diff --git a/src/routes/login/callback/+server.ts b/src/routes/login/callback/+server.ts index 46ada4a..2d82b19 100644 --- a/src/routes/login/callback/+server.ts +++ b/src/routes/login/callback/+server.ts @@ -1,9 +1,11 @@ import { error, redirect } from "@sveltejs/kit"; -import type { RequestHandler } from "./$types"; import { discord, type DiscordUser } from "$lib/auth/discord"; import { OAuth2RequestError, type OAuth2Tokens } from "arctic"; import { createSession, generateSessionToken } from "$lib/auth/session"; import { setSessionTokenCookie } from "$lib/auth/cookie"; +import { destr } from "destr"; +import type { RequestHandler } from "./$types"; +import type { CookieData } from "$lib/auth"; export const GET: RequestHandler = async ({ platform, url, cookies, fetch }) => { const db = platform?.env?.TCL_GUESSR_D1 ?? null; @@ -11,13 +13,13 @@ export const GET: RequestHandler = async ({ platform, url, cookies, fetch }) => const code = url.searchParams.get("code"); const state = url.searchParams.get("state"); - const storedState = cookies.get("discord_oauth_state") ?? null; + const cookie = destr(cookies.get("discord_oauth_state")) ?? null; - if (code === null || state === null || storedState === null) { + if (code === null || state === null || cookie === null) { error(400, "missing things from oauth2 response"); } - if (state !== storedState) { + if (state !== cookie.state) { error(400, "state does not match"); } @@ -49,5 +51,5 @@ export const GET: RequestHandler = async ({ platform, url, cookies, fetch }) => const session = await createSession(sessionToken, discordUser.id, db); setSessionTokenCookie(cookies, sessionToken, session.expiresAt); - redirect(302, "/"); + redirect(302, cookie.next); }; diff --git a/src/routes/results/+page.server.ts b/src/routes/results/+page.server.ts index 61c10eb..d37b0ea 100644 --- a/src/routes/results/+page.server.ts +++ b/src/routes/results/+page.server.ts @@ -4,12 +4,13 @@ import { error } from "@sveltejs/kit"; interface JoinedRoundScore { mode: string; total_score: number; + name: string; points: number; distance: number; stop_name: string; } -export const load: PageServerLoad = async ({ url, platform }) => { +export const load: PageServerLoad = async ({ locals, url, platform }) => { const db = platform?.env?.TCL_GUESSR_D1; if (!db) error(500, "could not connect to d1"); @@ -18,10 +19,10 @@ export const load: PageServerLoad = async ({ url, platform }) => { const { results } = await db .prepare( - "SELECT game.mode, game.total_score, round.points, round.distance, round.stop_name FROM game INNER JOIN round ON round.game_id = game.id WHERE game.id = ?;", + "SELECT game.mode, game.total_score, user.name, round.points, round.distance, round.stop_name FROM game INNER JOIN round ON round.game_id = game.id LEFT JOIN user ON user.id = game.user_id WHERE game.id = ?;", ) .bind(gameId) .all(); - return { rounds: results, gameId }; + return { rounds: results, gameId, loggedIn: locals.user !== null }; }; diff --git a/src/routes/results/+page.svelte b/src/routes/results/+page.svelte index fd84395..12f416f 100644 --- a/src/routes/results/+page.svelte +++ b/src/routes/results/+page.svelte @@ -10,6 +10,9 @@ const totalScore = props.data.rounds[0].total_score; const mode = props.data.rounds[0].mode; + const name = props.data.rounds[0].name; + + const saveParams = new URLSearchParams({ next: `/api/save?id=${props.data.gameId}` });
@@ -19,6 +22,14 @@ mode: {mode} + {#if name !== null} + joué par {name} + {:else if props.data.loggedIn} + joué par un inconnu... + {:else} + connectez vous pour sauvegarder votre score! + {/if} + {#each props.data.rounds as round} From 06c0dc82710ee63b4955cb048c94528fe040af37 Mon Sep 17 00:00:00 2001 From: uku Date: Mon, 25 Nov 2024 16:36:34 +0100 Subject: [PATCH 18/44] fix: add beforeunload listener to game page --- src/routes/game/+page.svelte | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/routes/game/+page.svelte b/src/routes/game/+page.svelte index 32bc598..4e24f90 100644 --- a/src/routes/game/+page.svelte +++ b/src/routes/game/+page.svelte @@ -2,6 +2,7 @@ import type { CheckData, CheckResponse, ClientGameData, MapData } from "$lib/types"; import { goto } from "$app/navigation"; import { page } from "$app/stores"; + import { onMount } from "svelte"; import L from "leaflet"; import "leaflet/dist/leaflet.css"; @@ -23,6 +24,10 @@ let solutionMarker: L.Marker | null = $state(null); let solutionLine: L.Polyline | null = $state(null); + onMount(() => { + window.addEventListener("beforeunload", (e) => e.preventDefault()); + }); + async function fetchMap(): Promise { return fetch("/api/map?" + $page.url.searchParams).then((r) => r.json()); } From e8dcdd37ea6c27088ef8d5885b576dff2ac1f8b3 Mon Sep 17 00:00:00 2001 From: uku Date: Mon, 25 Nov 2024 16:43:19 +0100 Subject: [PATCH 19/44] fix(nix): add nodejs to shell --- shell.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/shell.nix b/shell.nix index 1479462..2209731 100644 --- a/shell.nix +++ b/shell.nix @@ -4,6 +4,7 @@ pkgs.mkShellNoCC { buildInputs = with pkgs; [ bun + nodejs wrangler ]; } From 8275253adfc606d28ceccec2a375e9913de8c8fb Mon Sep 17 00:00:00 2001 From: uku Date: Mon, 25 Nov 2024 17:22:13 +0100 Subject: [PATCH 20/44] feat: add some css --- bun.lockb | Bin 139800 -> 140184 bytes package.json | 1 + src/app.css | 20 ++++++ src/app.html | 2 +- src/routes/+layout.svelte | 5 ++ src/routes/+page.svelte | 95 ++++++++++++++++------------ src/routes/game/+page.svelte | 44 ++++++------- src/routes/leaderboard/+page.svelte | 12 +++- src/routes/results/+page.svelte | 63 +++++++----------- 9 files changed, 135 insertions(+), 107 deletions(-) create mode 100644 src/app.css create mode 100644 src/routes/+layout.svelte diff --git a/bun.lockb b/bun.lockb index a59d4e69710a3146c9cd33f7821f5c106a309edf..5231fea335ebcf33434bcec721e47654ea05530c 100755 GIT binary patch delta 23517 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 diff --git a/package.json b/package.json index feed405..6da5926 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "format": "prettier --write ." }, "dependencies": { + "@fontsource-variable/inter": "^5.1.0", "@oslojs/crypto": "^1.0.1", "@oslojs/encoding": "^1.1.0", "arctic": "^2.2.2", diff --git a/src/app.css b/src/app.css new file mode 100644 index 0000000..677f3ac --- /dev/null +++ b/src/app.css @@ -0,0 +1,20 @@ +@import "@fontsource-variable/inter"; +@import "@fontsource-variable/inter/wght-italic.css"; + +body { + font-family: "Inter Variable", sans-serif; +} + +.contents { + display: flex; + flex-direction: column; + gap: 8px; + height: 100%; + text-align: center; + max-width: 70ch; + margin: auto; +} + +hr { + width: 100%; +} diff --git a/src/app.html b/src/app.html index 77a5ff5..d168691 100644 --- a/src/app.html +++ b/src/app.html @@ -7,6 +7,6 @@ %sveltekit.head% -
%sveltekit.body%
+
%sveltekit.body%
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..9e20eb0 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,5 @@ + + + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index c9547de..f28656a 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -8,57 +8,74 @@ const props: Props = $props(); -
-

TCL-Guessr

+

TCL-Guessr

- - -
- - - - - - - -

Leaderboard

+ +

Meilleurs scores

+ +
+ +

Jouer

+ +
+ + + + + + + diff --git a/src/routes/game/+page.svelte b/src/routes/game/+page.svelte index 4e24f90..32382b4 100644 --- a/src/routes/game/+page.svelte +++ b/src/routes/game/+page.svelte @@ -131,29 +131,27 @@ } -
- {#await Promise.all([mapPromise, gamePromise])} -

Loading...

+{#await Promise.all([mapPromise, gamePromise])} +

Loading...

-
- {:then [, gameData]} -

{gameData.stopNames[currentIndex]}

+
+{:then [, gameData]} +

{gameData.stopNames[currentIndex]}

-
- {#if results === null} - - {:else} - - {/if} -
- {/await} +
+ {#if results === null} + + {:else} + + {/if} +
+{/await} - + -
-
+
From de5600899dfd59a2c1726f4dc828fbe600db9ff8 Mon Sep 17 00:00:00 2001 From: uku Date: Mon, 25 Nov 2024 17:22:23 +0100 Subject: [PATCH 21/44] fix: remove unused page load script --- src/routes/leaderboard/+page.server.ts | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 src/routes/leaderboard/+page.server.ts diff --git a/src/routes/leaderboard/+page.server.ts b/src/routes/leaderboard/+page.server.ts deleted file mode 100644 index ced3c9b..0000000 --- a/src/routes/leaderboard/+page.server.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { error } from "@sveltejs/kit"; -import type { PageServerLoad } from "./$types"; - -export const load: PageServerLoad = async ({ platform }) => { - const db = platform?.env?.TCL_GUESSR_D1 ?? null; - if (db === null) error(500, "could not access d1"); - - const statement = db.prepare( - "SELECT game.id, game.total_score, user.name FROM game INNER JOIN user ON user.id = game.user_id WHERE game.mode = ? ORDER BY game.total_score DESC, game.time ASC LIMIT 10", - ); - - const { results: easy } = await statement.bind("easy").all(); - const { results: hard } = await statement.bind("hard").all(); - const { results: miguel } = await statement.bind("extreme demon ultra miguel").all(); - - return { - "EXTREME DEMON ULTRA MIGUEL DE LA MORT QUI TUE": miguel, - Difficile: hard, - Facile: easy, - }; -}; From ef25e178bf8ad264c0865bef712d644da194644e Mon Sep 17 00:00:00 2001 From: uku Date: Tue, 26 Nov 2024 11:55:48 +0100 Subject: [PATCH 22/44] chore: add example .env --- .env.example | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2fd0c54 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +DISCORD_CLIENT_ID= +DISCORD_CLIENT_SECRET= +PUBLIC_BASE_URL=http://localhost:5173 From e986e23767d955019e8d004c34cfcac99bd39fa9 Mon Sep 17 00:00:00 2001 From: uku Date: Tue, 26 Nov 2024 12:26:46 +0100 Subject: [PATCH 23/44] fix: make page navigation not kill css --- src/routes/game/+page.svelte | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/routes/game/+page.svelte b/src/routes/game/+page.svelte index 32382b4..6fc4d4f 100644 --- a/src/routes/game/+page.svelte +++ b/src/routes/game/+page.svelte @@ -25,7 +25,12 @@ let solutionLine: L.Polyline | null = $state(null); onMount(() => { - window.addEventListener("beforeunload", (e) => e.preventDefault()); + window.addEventListener("beforeunload", async (e) => { + const gameData = await gamePromise; + if (gameData.stopNames.length > currentIndex + 1) { + e.preventDefault(); + } + }); }); async function fetchMap(): Promise { @@ -124,7 +129,7 @@ results = null; if (gameData.stopNames.length <= currentIndex + 1) { - goto("/results?" + new URLSearchParams({ gameId: gameData.gameId })); + window.location.href = "/results?" + new URLSearchParams({ gameId: gameData.gameId }); } else { currentIndex++; } From 007eda1b8c71395b826dc2a165ba16a00ce2cb89 Mon Sep 17 00:00:00 2001 From: uku Date: Tue, 26 Nov 2024 14:11:59 +0100 Subject: [PATCH 24/44] chore(deps): update --- bun.lockb | Bin 140184 -> 140608 bytes package.json | 18 +++++++++--------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bun.lockb b/bun.lockb index 5231fea335ebcf33434bcec721e47654ea05530c..822d29c37e803a45579d140f46440875de8807f7 100755 GIT binary patch delta 9324 zcmbPnoa4YLjtP320jr`-_bgD@$COfAe@|wQbndhj7uUt@IMTPQSxfHC=ei9lObj59 zGBI49DI{TI#Sd1?I}8jATnr2i7Z?~Aco-NOipx@SN>UjZX4^6_a5FG8^xHzj4Qv@0 zq!}0*>TMYq1VHL0FJu$9OtocT;A3EDh_;28;tiFRwq;-tWngI7Zo|MJ$-vNX*MWgS zoPnXC97=ag{>YZjImv~AL4<*!;nL(pcJat+7l@h{ZV)q*i;Gi>lNlH?To@RH85kNu zp|pqx0|O@mLqla^ZVt#dj!;wdpz;$K7#PGD7#f-wAm$vNe34z8@!(`e4sq6EkZ&g6 zWtR?I>;*B!hk=2Cmw}<-urGw4o|B(clv=?c>j&{sab{5&$d;1)lEj?M;*#8=+|1lm z28QcU`AxnI41x>{4f7`#a){SY@`adYz`(#D1M+WCVqSVqYEg9%1A`g^LxW&2M7%c` z;`4vO3=BdH3=JQHA^KpUeLsYOfgj{&s6NXeh(3tj3=Hx?3=C2X3=LKJDImu&2n2!E z*EcW)K|K9E5E6ZFp!B0ah<9#4Y0U@-Um^nH{BjnE`qvSV=sq6^36AxV3=FbJ5xFoD zV*d07ZfkB>up&=lKfkBRep}{x?Vw89c#4n|J zDVfQc3=DhYz;17-%r8yOU|?Xdj)yp3B#OB^K+JBqrsgCQWAKQWrdx2yw_B zD4j6bl1pBrH5p=ObuvV6ZZbqwMq+V(c^(79{uD?!PZnU@!Pqm|lG~ke`Q}D$b~cXr zstr2Yt*J?yI|M5jCrb!xOcIvZ>>%92GPy<1Wb+U4GrWuflN+_QCw~y**!)BFj0B8p zCjw<{h~b=UY0nMieGucATw%|H#M^<)+x)}chZRY(!WBg+g6HbNscpl+V8g)Bz&hD6 z*_^Z7hJnF>fuVtAa-)Pf=W`nd1`~*!vpMH7TLuO@28IU4$&AhxlYhF|GpX54wsN=Q ztgvHX@L*tQV4mElZO(bX4q^oJk7rI$UYuoDA=9@q{>33EIJ; z4@#JGu7vX#HO)C6Ix#SWfX!~yGUv>7hNxto>?mQ*xfIIdpUh}&&UklnrH?)1{mDCh z?3qMdC-3sHWAvPC>1)r}IJwf-p6Q$j6mVx%HLS76E)|3DGT66k(L9Az) z4D#`RF9wDzu=$PJ=1g_olYa%-ajx@*IEED*eUH2$u4e{oQ1XFk2Ss0n4@4y+Smkve zNJO(tW^^&<GQdYZSx~ zj>!ij%~?N2F)&z7u9dLn)Q*P4G}C0p2n)vO$yUC0jB_Vj#@jRAnp_!g&$>1S!7SZ428L)5i?L(!&jfqcGjR+Iwv+#AT61#7 zLlPD<$YMsf$vYG68T%&xOtj~`8_&St1I`hkNYG4}T$N{@bL6?D{fn#!`wK-=?B18!@I2qhXgoH38xyd9!cue4=SeOJ$T8(<< zoV$~d^s#;h@h0!pwPrF)o@|wB$GIe#fgufC{D3kQSIXpFsdkKRlYge#b9Sdd5*`yc zGo49+q!z}>jN;}@e5sRnrP;B%r7|%1Pu`nm%{n!efx#EddIV?br!g=<#A@KIlW7bL z-e7ei=?n~>U{)-cWt(op0%m}Wdk<$>WPp^_X4|lU86e41aF%c;ND?F#lgYr~4mNEu zob?LMGR%U>R%9_SxPsN~g|nElVPftumgI(P28Jk5WPzI$2x8{si8<<=Tse?P1_uVG z4V(um`0{cfnT2gKh&L|>R=hjvnlql6yffFHi6wXPuUtD$(_BdSvVuaCF>`Wdo;~Nr zTu8D7$1CI8$v^Y#8J#v;=4-QUE@^0Bv}9pmVA#wEZk90YX9U;Z3}+Y_7#JBC7|t>> zFmNz1FkFT5uYm*^7#P6xX5FSz=FMGIpI9k3=mm>|Que&$h_2aw7ITgkI%IS2H)++| z^k#*U=B8hYX|qn6)ihTvRc~GM z=Hk@uu(@9KyDiuqUdXdSdwyN8>%e-lM5~s~p z;F?_Wv--Wy%YFJ^C3Msb#ioBqdcd$sCTVrgtZIiIakkTM!J+k!{~sd*!$L$nGqCV) zxZRMLyJ-=>LNLEN!>sa)^SggIUHICvR>WPbtSPFIIY}?q(czJ#ipn!dw}Tyf9gV=m?|CBOExz>FzDZlXFBTfhy{^5Nd~!OYvXnWJ>lP!sZrR$}#%(=Ti7t24 zPG6i*qkh1Zt9Q=Cj|XcP>0~@hU}>xnY7$au_m+&G6WDr}RYI0~N=cll^yUS#c%-I0 zUVX5PbMoK45)S58$NN_&vM^5)Zm-QdJ<;U!lONKzoPN%Dc;Ue`P6Y{FmgwJ(ca|@m zH}@^W!ar{k4bJr>RC4~Uxj6Aekk5bdI?2tU`vTbOXLCzNJ-e_+Qt8&c%Ga|uiaSc| z$!|S)G5X_XUA~7CbT2f`Nq)`a@P2lLZoTF^t;m;W9|W$v=rrN@-#*^>IZS&tA^CAP zvLBU}xl80PxLPnR{&LZ(BKr%fKXvxoUq80NY2}hs&9YOKf5i7Ke!f3el3m@TPyDJ^ z$@12JpZD)urXiyLrG!=M!=a|hw#OtKxMMD!{@JI0`0@35$2#j&viTmJ6gpKi^`Lvv zpIefa6ZMasDCZN)*^%hA|LnKi?!6t~Io~;5u>UP{e|rxT_u-QzlcydlsPCR#^-}O7 z-&fzqj`w-*`fqS~C~@rR|a_=38II>HgX6Up%F_ zIb?aYWbwOmyPh38yCXqTRLj&nfOCFZ_Ps@}h4Qy1&pj^T6Y6*Ca_EOS5xWkSrpQl` zxDzJsI(2p1(V49aZ5Ugv0-s5iopiZtnBcT-pUke?M#kL}BVx7g{V++qktY}@v_;?* zlIspmUU@uxa>NPV$-F1L84pj6JP|&b<0S9oy(hdGk51-189sT(N#4o1C%qYuPu_Vl zd~(Jq-pR73ycthU&O8-9S>iPBlX)+DGd`Xic{zMC#}(emdoO!4KAp^YC4BOZE4-6) zuXr;)pS<%*_~eYMypv_GdNaP9oOv~Tvcxss$!D*6GrpcIc`bbMiEF%*Yp;3xzC{kU zOIF_+AIj{61d>L;M`ne9;=1w^X$H7@SS-2b$T=3)k8tY zo%c!2El+%W`Dvll{g>jGC+A+5m~48(oALeR#v9?2HE!@uetN^3@#AE}o8gmh+~A!& z^` zeczLGfpJ?*JF90h^V)08vLajKc|4x*Nll609&E>XFZ=APe-{-~mrXISVgglckfQnf zWXoIOlV9B8ojmuJH{;LAFK>lUo^hLZvhQtg#@~}?-VUGaaff&E-`n1dePB}$-MWx8JQlUc#$(>ey^p;a zg(u&996q_@3GZavC*F*rlRKY;Pquik>B%#ng-`Z)&O7<u;fyMiH@*yKRGrNEDx6Vma^kCSM)k=%UxhPjOcs0{ z&Zs##^L6-Si8s8H&%X9%)SfK)CVcXVH@uT;-*_|XPCof2d~(HG-pRUey&3flcs2p8LU@(Q@+358;z%eB_<%`_Y@xdh*PV;gdZ+@lO8x(VNkBvgfDp z$v-~vPG0-To6&yq&rji#SA6E39Q)au(Q)$1&*76JzVJ@w{o>8&JUQ}9IHSwtjbFkU zT_$(~oe*fXNqsgfj+C*8CaH7&N)@XE`NG52sli>?g%o$2^F)%QEg_`FI)yvJmz%YT4 zfq{*Ifx!(b#>2qCUDfq~%_0|SFC0|UcL1_p*33=9m{L7f6nM}dKX;Q#{z1E@u^ zZ~M+P#^o%!XBZe5E;BGNTw(wZZ8LxpB1p|X1_p-H3=9m1L4%SE3=E*5)>G3vvl*r9 z4>2$>97K|WDM@BvU^vIXzyLDxEL8qHln+vKk%58X|NsC0uRxsxvIaC>4U&7oz`zj8 zz`*bvGH%WAgn@zKF#`j`0|o|$oeT^Nppklz-kYFA0n#*yfq`K%0|Uct1_p*{3=9mn zrrYK)Rtw%|U|^Wfz`$@1YR=v1CvzC(6CW`!Fg%0`J!4>CcnWn2$Via!6B!s7K=?J( zx77>`44~oIFANL}pFxR@fq?H83{7#D+2=q$U2ZUAS=PfLY>J3Nj0_CYpp3}Kz#z)Vz#ziNz#t4wp`d)g z59*SF(mo>t11n=Xq<;zu)N}?01~!mFP)=uLVBlnAVBiAvSD|cfs2m?71A_n~0|SVb zU}RtrhbDC?Mg|5Gs2nI=fl3H1sH2poKg?qkmX%?Id`97V zZAJzLV@3uBBSr=WP=+psY#A9CY#13B>=_vt92glG!WkJD!WbDCLKzttLKqpQ zFV1K5^o(I-V2Ea9V2EO5V2A`2V8lfxJT5_LES`~pA#S>50i&@Sa;5}%8I-0#=?#>= zKxq$@20`f#l+HkD36xVo(VhrOKSdydfq`Yq_Duzh9~s#h<4pAo^$fPJDq@smmp0Qg zU|N=8XWv*`uhjB?w>su({CFq%zY*Ul(4U8x%^ zVbjeh2{B-|F?0$sr+Aoa*HjN7N{PG%IJzF-1l4daFBvJ)8< znWSx}J4|GhU^1|s9yO8ChtYfb{*8>1jM38%PGpp1Or3svBBL*3@pQ*cjAAUt3=H+t zW9KtUGWJh5T*xTSY-l)p`oVdOl2G0HtY!=h2DZ~TOlB0DerFP+nKW$9Z?@?6S5mEe zvY8m;4D^ikOc@x!PLY&>O%5h_CUYxwhTdXgj57vB3EUiJ6NZlI)sq<|A&v)IwP7;j zBo0$&1_liVhKA`16BwmH4glH8V#=WBGQD96qY~w2VEfZRv^Pgr)yU+N^d_imGJ>H z13Gto2FGh|?ZgrlUP(LpcBB%$ZTt+(%8Y<|ncxW{> zK_V0ujnjGNGs-}sS`rrjka$K*9a_`Z%x2^e#^ToL4`(wfGA^F}b3UUnG;vJ#o5QHb z_3TSf`=3vU^AkO+8iDe z=kuLsVvIA=GXO=*qv`J#GfJAlrcgDf^SwCmO+pH+zz~#vVUw&6pU!Q5cgUiTi80O) zqLnFVy4?~+2{Y)tY{QEDYr8KN@+yG!8t54zW^e;{O!y^b{QU?Mqk$f{@L{kFn%=X7 zQ9?QtI`{iXV3GIiRflWA`Nl}kn1P{s`u-)1t{e-4z?DtIberjnQcQxu(>0bd8Zq`x zk6y|sDGi%ZK2-1bF#rDUIIwOrkhj3;O~lH`RL__JHvhc7@aelBE^q&U-Dd$(g35ehHZn;>Oix(GD8Zx|F}-RTqY>ll>1&rUu4UXlJ$gB#B4g|H+U1Or(y-}aWu=Fy zj0P#I!69S_Dr2Wl-?*Gnl5yem(;#)QX=X`VE+#YfN-j`nfStjxeft09j5x{&15jW< z${LC3J}Vgg>S1%s49=M|rA!+&SQxiMqZu~)eD0BTd~?y!#|RnN{PadUrob1T%nJ}Q zuo>(f7o~iX8;jx*GO#&r+mou-o##(XhRU!oFf{C)F1wP^m&rPQdd^BlBgU5L^H(xT zO2a0x%@1~Oo96rwmdXqm7$B*PF=_f+kh+{iNLMAJc-{YB{HrrXK*a<&HI_|RT*Ww> zanJO}=bfrFq~2&Hxn5unF+RS!Jb_|Dt8V z5o~CzXTVTBy>~UEBxCFJ<*ONu8TW6$y_#_^6C(-va{J%)jFF6J#RI;|Ly{3vqCg7= zc+D|=#U@56mF2k*pMO7ph-cHc-8u+A1Z;s+*#cWZeJPRYzcw-EP1o4W7+_@{2w6J7 z^s8>0)MGiZGf@=Y7E_ zx&7%W#xNOB&H9}20z_;kquKQ3FBoH{E3z5ECpT zI6dze7^SCgf5|AtY_4ZC z{r`JLUuHu+gX#Vs7?T+-wr~ExD9*-gtY^H{T=?CvHDs7MX&UlZF&q%K%y(%R& zwIDaOC_Qz${Xa(Q>COKbji=YKFmX-i`^P9Wz2F}s*Y@TA87&y6|Gv&BJ%x#7`mTSB zYo^|3@?tdEuEogYt;pp8T@VzYGQD1jNl^^c6MfJ2`_9G3oUdm<is&ecuLD`U{KWnkcAU}%uHWnkc9U})fns=sf;z#z)N&`@o| zz#z%M(6G>ffkB*sp}`tLGd1{3{>heJALhcqAi}`VFwGTWZEA5rQEDm!!$b)P-`)kH zZH*hmn&jf*)Z%0Y1|1g$24Mz<21zJ=!<~VFlYyb3GBGy?LxHSFo-cQ zG&C_l%xU)o(`*f;3=9mslX*F$ITv|BjHsFXkzHI1=HEyL1_l`hh6W#yItGS@c3+69 z^ql;pqSOk8hrW}&IOH^E`$4>4=F7k!$iUE$>(tv#QEhc z5Dn`iAki>65aR3NNCpO3q*zUjgjf(A3DF-E2~p=cxsy{qF))UKL4kpx!6=4-L7su3 zK_rHOL5_i;;d?a1l-tn|ZoqSr7PqADY?IKMoPfuVVFBiDY$ zfXR;B?u^-+JGt4}HqQ{OV4Q3rEHPO?SYva5a0|=i5D$~h91>@ECyS_=Z01lqBLQMe z=CJ1h(;iT|14^HO(3?3Nd|1H>I$R+NPe5r7HwPwbo5@^$cATqi7#K_#7#dh73!0mA zX4x_@*fB6PFisW}H)mWi+0)&g>6Pu|E_XXl8#@LD4+e$?=E)Pa%{g1_7#JKNJaKcT zBX*O$JnT5X*)cGffpvqF=-4wbxG*p@uuPsPVa{4$&%j_axmU}Yam{2;PkYv{_6!Ve zlh2A1ofo!-0Xp3v3|BW~RxWUiPesjvzI?Qr3*iC!h4P=e+L7z@P^g&Y=8Ov`pY*Y3Ts)c6*PihPnB<+@>1)sEI{BopJ>#OuoPPF9k6b5v`Pp%b zxj_PeeR80OIcJy~149_ZE#el8Zj-q*?KnByAt4J6FjgCP1_r;$z1r5CT_6_NITzK< zIUl++Fjz4#G%$feiBWp8XMjDU&*aVkd&aqwPX^d?e)WJjo)awZIoUJNo^k5r&Om$C zYn}`Y){}kxtT_d}Ahxqiz9?bNdDshLFXQBi;uaj<3=Br#U=egN=M3?NSjIA0P}iKZ z&zpfE3+#}I+U88WK9jqG>^N;c8EoG&CGnI>QK zGG|;qxiiF`^|dbpgV|(WacfRRKL!RH28IR(kh?i!{UC7#4hznueh{6^VE5kjgV@Lf zN?447lR3leIsN=0sex(oL|=2x8U73meqc{blrZOf<_}3_tdj+`%sFKOAi5bQ2kMz~ z1_UrLSc7d1)H7%7p4=I3&nP_kWVk(NQ4j+|GDOD1obzK4149CsCm3(R5zN3401gL1 zO>?Fz!IMu#*l{X^FfcfQRRsE(GbT;;jI?LmG`Ta_MGcO zk^Oc*6k-_IJ&gL3Pe$2u#)UC3xPjvs6pBm2Ao+rA@OfQOIaK`DBbeWBFvxSbN6ZlRabY8963*#@cgE zh-6?02fO~FmpRk($jMxBcC4mR3=A%leI=|pE2AJ5a7-4AGH2Zy#lT=SxmUuP^F4?K zcIZSYb0*E`$z8s7jER#wy;P=hQ!GrmT4>lLp+!@ zC6<997R>q>%fJu~Vlnzm_Dr;Aoe&2yfLF_!^K2X>O)`UQXXKj9nPkrxG}$xBo^xS5 z1A`CPeo#!jjh}of$&S%#GH0?q=kx?fnqip?%KPUN;IZyz&dHp}z@W>((7-WyqP01v zMgx>0#Xt;!QrQYt8g4X>wPp9cM-| z14A0P-~r{7bIFsr((D+yCVQsYbNZ)1T*3s-Arn#{sRmqrGF?iU%$07(%9YB%;6Ir+ z-I_Hrm4U%`GH<303xttw&H5S6a!3P9rdzZ2rZF&hgEibpV_@(EvlP=|tSmTdGo1AY z&T`Fwsq2HYuESXhnG6i>VDr-9taWhKS2)Wii-Ey)^4Uxq7BB2uuTT>l5$`Ld!Vj4V2NfrKwBxJJ^Qd@|3Tvosfye8F+bxN)*)zC9z`=FWU=w#|D=D;O;q z85kHgfCx02g@J)#3nRE8!Ek^P+_GUf%gDe0QhJV&fq`RlZh1N}(2;gP-oqhl72rE}11M{WF7`GX87aWqYd{YSN=WUvu~32U3^PxSqd1 z`?d1*tPt@P4V>I1-?LjS@7Z>2o*e(1B`oo6uGXdBo4?LdP^$lJsrH4Xl<$0=ZgP2@ zms}iU=F%m0J6v;Xo>tww@NBbw0LQJRE~UMKCoN8{dhc@Uz3agXI_a-iZZEofV%cJQ zaVBs8{p0_~$iT1=5ycEF@9Jt-L?yK3>1A6T{kGaoLo9s$=FN`|_sl+CV483t`QG$t zxhvw=-IMH^H776N@vk=1DH~?jN2zW(=DO5dWWltDS&O&y%1mH6p>lppw&+hS@tYAz2^kV%lR9?3`)I)LXrtllG0E3; zZyA#779+c^{qzm1mtmFXz1!x7_dww)*_YJov+5i`0HL#{_kgLoXfvPLACt;V{2&?Z^I8Cnm>T)cwSx@Xa-7wT!@y zMpGGG^VuPyw+jAj`5tJs<+i5CripQp=Ity$r01pA?M=VI?z&3OUNf zb8_9L@87-a{tL;ID?}?b72oa&xNI^#{8p};{15ZE^a)zamrtI1Ou}LE*@?<`+S>LC z7#BQW{d|GYoWCpNrp$lZog}%!^z_qD(LRFDeZP()Ab;B>HK}_GnDxZZ$tp_9NF9>r^V=dJW%E2#;_5!{m(7LkEStWZx1Rj> zxWwe#6W)vmC+|EFK6%Fp-pR5jy%`Tr&O8}DIpZYnp`vC!Y6m!;GO*Rx;Nv;$%Z$= zCtKX)ojmo1H{<8Y4{wA|esPm`vg=K6zpu#Qz3cIOakh$MKkwU}n9ROxhkRsmuc^w0 zjIg;~JLA9Ep6{vrUEOozc+Ki>q7_B|-t#Xz#bB_&F}7h@O_HnL@X040@J`l!=*`GEx$ws^uj zdF~T$M&ZdXpM+0-@q~A>?^AC^(aAHPhEJaHly~yqr{0X>lRck>Pxg4mJ9+IhZ$`<< zKc9t9{_%`=a_n<&M(N2bpNCIg@tk)u?+b56*~yVF!Y4<(;GMkpg*T)8WX_l2lQ~}U zPR@Pl&8Rqe=gaWPJ6`fmmVM>Ts609IRXC%{2TX%lF}vE#C7^p8MXL(RlL9_u-RYyyuwB@W~OMc_;7v?9FIDne$8dWR5SqlXJg#GdfP*`6YbvjxW5EWxskeI#1608qVl4 z`QX=ZM%T%b-@+N)CKrASXLO%@@>@8g$7IFt;f$V>E5C;`dQHCgJ)F^dvgVI)MxV)z zKf)P(C*S-L&geJU@Mk!q|K!e};fw*3AN~wy44iEFE1WTC^2A@^jKPy%{t9Odne6yG zoH2Cr%-`XRVUs`p4rdIX?D;2rvd16Z$!q_3Ge%DS`6qnxk3YPVWB+B}x|A$ZB@t=3AETc64 zBypDM0sM>{tlBmV3I%~nI2fl)5@*?7Bg)9a$O{`k`U4tI0@(pFjk7$zC_A+%g<@-P64%YWc3=G^Lk#vw*6_ShwOq_7Lw{MhYEOOym5D#idGBA8em>!qFXg7U&0%L7` z9<*yLQ8TbgU8p)v1_p+Yj0_B*0aHCj@R%XU zqYPi5VlGgcn}LDB3~HVmR4)%`j1i;}G}7b_735`LV33=>Fp*K%Nf4^u6Dq~ez`!8H z2p-~M@Pdj7FfcH%Ld;TbwvS4tD0pJ$oY&644@+Q4FdziYX$~}mkbOH zwhRmmFBljYt}`$&Tw`Eh09A2U7#J8pje>m)3=GS*KTKy_&QgDxfq~%?0|UcF2Jomb z!+EHhWef}qrx+L*4l#fS0zh4UhLa2o3?~>E7>+YAFdSoGU^vRaz;J|tf#EO%1H(ZE z28IJj>XG%GWnf?c*>eUee-6q&#J~{802;Rb|NsC0%TPyx90*FPAOoH=Ffhb2FfcrW zjPWu&W?*1=#K6FCpMim4Cj$e+ZP1Y7|NsAQFfcHH^h{!4V3^Fnz;KI!fngd01H;Yf zskw~Rg7+9080IrDFx-V2b7%U;Tt<1phYSo151>L%85kIzOjpcf6t{f^^>H-=1H%Uf z1_sc$<$DGOhIde3zJ-PmC~<%s4wC=Ez`*bcl+dOZ<}sSrg8~K=K%l?^1YB zfdUc~XvhJK%PO$33=9m6pm=9wVE7LW{C`MJ`pv)qj<~-J3=BUR7=jqSF)%QIQUfS3 zLGJv)z`*dGfq~%<0|Ns{@h=7j22dIlVqjnZWwsbl24ZAj2xkP37Be_7GB8*%GB7AJ zGBB7hGB8L@Z_H;DuNPosVBiDw`#@=&k%55)+V=wmLpms(GlGY68Q4I5Kt=`zPEewS zvbmsgyo?MC{2+ad3=HC+{K&|_AOTI_#!$Ir1_lOgMg|5@UI#frk&%HxfsrAOL7tI; zL5>lUBcvG_7-Se37+|RiqzM!kN{kE)8jK7K>WmBwYK#mFs*DT_DvS)^Lc)lVfx(cG zfkB6nfkB^c>Mg|6h>4gQ1!j_;;uLUCm!$xR%Ui9$jHDD&B(wI#mK-A$;iME0m|~kM;$okK&dH? zk%1w0dSW4?u^VzK0eKRXdO#@)IU9mf7$`--vLPsv6Brp7ZWMs*W?;CpY5T20#*d7k zA_P=CZogE_D9O%fI{i%*qolN{o&f`cwm4*L|HPSducQLv^q3ee^bAe6D^xS`3o@Ec zH|SwBW;C7F%P7fcI=!w3Oes_|%1z(a!{~`30WmJvgn>bYfuUig?A;SrH@SX;7&jfP zC8w8hBU}q#Eu-A@us%jnM$_#%eT<4s5E)jmqo!ZzVU(JFYyzV`UQ-1of*d#9Wg??7 zUUeYb8LOvnoX9wtV~P!AB5Ha;AEU_hgh`BSO!sZ3H*8{*VESS+eZc}ot?7CT7&)e& z*~BQt$Ui-B0iz_N{B*|6jFOC+)1@~v`ZAhN51h;>$>=;i8$<<9kDtpZ!DJXeeg0%d zNw^v3+8H@OoOhEMeHg8$TTfw>gt$PQ*@R)?bjOv9BJ75s@c&{n{oQ0nF@zZApc;yMD-BekR5^Gd%;4KKtp;(-@5z!={%{ zW7L+;a)HbjrWWU9=9Mro>#aS4qO}{#eQJXPqI^%4{y^L$7 z@1M=+%XGtiI^P_|S&Z$|SI%Md6|eDP08fm0PTYF?-o@s(OpNJX3=E>v&-O4%v6wS3 zESk=~kkObC9C(t`Ll!dXFs`27xRBA9^}81XgEm;*^t*EzMOlA%gY@xlWE6#{P~5IJ zkFkvr7AKHkhs22(ixC3@*hq=#(hC@+ArU4Ci$zF;p~bcl*-lkt44Zy%J!3j!@^sA& zFu#aTFIdEA##lCeHAtv^`uz=z+KdyXb8lpnWSlZxaWSJJ(?j3sE{hqBgkdv{H4_g; zu^&*F%f#3_y>l_6FUP|G@X%Vrbca$#iRs@KGm0?13z*Kcgwco5XL{rk#&pK&=?9lE zDoVo|V-JopH2Ti8oWR7`9>@Tm44yOn?-E8y#%0rguVR#B+%Vm6DWfFg?&;o386{<4 zbBWw#>GfCd|I-F11Y=M_xDq(MVJV}8DQp%paL0sSQpVqpFfkhFnSm5Az~(D|oa54( z>9_3~NXA&tgn@xUa{5`29rn|oFJ*LPOr5T~j8T#4YS8q6WsFABuxZhNOQvd;+Hbs= z7~_l~X>aTFxyu+OrD2oR)3$jp<}g3=7#B}xUC!7j z1DoBvqx{zYg5~`E;G6>X!rSoai|3u84j z%3yP;=N?(dHy0g!jF5rNwr;dz3Vh+oyZ|8sn~&XbQOYN|u_zuP1Dmn6J*j%#dH%#? zs0<4OLqp?q*Hw(ZO#kDiPg%uiBn_LBePsXW`3}!zXTf1(pl4{r&_DelDD^-Rk+fO@ zWNQ1FVy0cY(n=R_m>cMs7%>=3*I&&j$!Im*b2Z~^Y1r(o3;%}YCA}BAm>BDf^uQ%u z-}L{h8I2iLrW>ze^kwXu-nfQQlF@Mb>@|#%(y-ax<_)RmwJiO2LQOYkVDOxNehs5B zWAk?AwTye2$jfuv-8M2>Frwvr;>vk&nF1*}Af*+&sGojeGout^_Vm}A86~+iHbW}h z6`QB?ZDDMheqjrvfYt8+2Jmb@)33U1Ql|xuaX}~F>%Va_x0YYeMVG$;H6&GOyVO?3 zQYL02J)`ZDwlgjiVKm)ta)vQqhS7BTk{65@*iH2e^h(mJrtg2jC_a7COU4>T)9L)L z7-Oby{LH8{J>dhR@bm?*7zM%H?U!FM9%KbG;W8}K&wgMOM-r3#2vt4Z=Od&1^yMEJ zJ=qQPEWwu4@iR$I7x={J#%R1f{1c-%8?%v~#q`1-jJb@)(=T!{DQ^48c#n Date: Tue, 26 Nov 2024 14:53:12 +0100 Subject: [PATCH 25/44] chore: remove unused import --- src/routes/game/+page.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/game/+page.svelte b/src/routes/game/+page.svelte index 6fc4d4f..646ec26 100644 --- a/src/routes/game/+page.svelte +++ b/src/routes/game/+page.svelte @@ -1,6 +1,5 @@ -

TCL-Guessr

+

tcl-guessr logo