From c573d8c2c60e9b4cbb70ed3d2543b96913408801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonardo=20Mur=C3=A7a?= Date: Mon, 2 Jun 2025 17:44:32 -0300 Subject: [PATCH] Setup header with i18n --- .svelte-kit/generated/client/app.js | 10 +- .svelte-kit/generated/client/nodes/0.js | 4 +- .svelte-kit/generated/client/nodes/3.js | 1 + .svelte-kit/generated/client/nodes/4.js | 1 + .svelte-kit/generated/client/nodes/5.js | 1 + .svelte-kit/generated/server/internal.js | 4 +- .svelte-kit/types/route_meta_data.json | 14 +- .svelte-kit/types/src/routes/$types.d.ts | 6 +- .../types/src/routes/about/$types.d.ts | 18 ++ .../types/src/routes/donate/$types.d.ts | 18 ++ .svelte-kit/types/src/routes/proxy+layout.js | 17 ++ .../types/src/routes/viewer/$types.d.ts | 18 ++ package-lock.json | 53 +++-- package.json | 3 + src/App.svelte | 1 - src/app.html | 76 +++++++ src/lib/assets/logo.webp | Bin 0 -> 17672 bytes src/lib/components/Header.svelte | 203 ++++++++++++++++++ src/lib/components/MediaQuery.svelte | 48 +++++ src/lib/translations/en/header.json | 7 + src/lib/translations/index.js | 41 ++++ src/lib/translations/lang.json | 4 + src/lib/translations/pt/header.json | 7 + src/routes/+layout.js | 16 ++ src/routes/+layout.svelte | 6 + src/routes/about/+page.svelte | 1 + src/routes/donate/+page.svelte | 1 + src/routes/viewer/+page.svelte | 1 + 28 files changed, 552 insertions(+), 28 deletions(-) create mode 100644 .svelte-kit/generated/client/nodes/3.js create mode 100644 .svelte-kit/generated/client/nodes/4.js create mode 100644 .svelte-kit/generated/client/nodes/5.js create mode 100644 .svelte-kit/types/src/routes/about/$types.d.ts create mode 100644 .svelte-kit/types/src/routes/donate/$types.d.ts create mode 100644 .svelte-kit/types/src/routes/proxy+layout.js create mode 100644 .svelte-kit/types/src/routes/viewer/$types.d.ts delete mode 100644 src/App.svelte create mode 100644 src/lib/assets/logo.webp create mode 100644 src/lib/components/Header.svelte create mode 100644 src/lib/components/MediaQuery.svelte create mode 100644 src/lib/translations/en/header.json create mode 100644 src/lib/translations/index.js create mode 100644 src/lib/translations/lang.json create mode 100644 src/lib/translations/pt/header.json create mode 100644 src/routes/+layout.js create mode 100644 src/routes/+layout.svelte create mode 100644 src/routes/about/+page.svelte create mode 100644 src/routes/donate/+page.svelte create mode 100644 src/routes/viewer/+page.svelte diff --git a/.svelte-kit/generated/client/app.js b/.svelte-kit/generated/client/app.js index b0d1237..744cd3a 100644 --- a/.svelte-kit/generated/client/app.js +++ b/.svelte-kit/generated/client/app.js @@ -3,13 +3,19 @@ export { matchers } from './matchers.js'; export const nodes = [ () => import('./nodes/0'), () => import('./nodes/1'), - () => import('./nodes/2') + () => import('./nodes/2'), + () => import('./nodes/3'), + () => import('./nodes/4'), + () => import('./nodes/5') ]; export const server_loads = []; export const dictionary = { - "/": [2] + "/": [2], + "/about": [3], + "/donate": [4], + "/viewer": [5] }; export const hooks = { diff --git a/.svelte-kit/generated/client/nodes/0.js b/.svelte-kit/generated/client/nodes/0.js index f02ab1d..45d0407 100644 --- a/.svelte-kit/generated/client/nodes/0.js +++ b/.svelte-kit/generated/client/nodes/0.js @@ -1 +1,3 @@ -export { default as component } from "../../../../node_modules/@sveltejs/kit/src/runtime/components/svelte-5/layout.svelte"; \ No newline at end of file +import * as universal from "../../../../src/routes/+layout.js"; +export { universal }; +export { default as component } from "../../../../src/routes/+layout.svelte"; \ No newline at end of file diff --git a/.svelte-kit/generated/client/nodes/3.js b/.svelte-kit/generated/client/nodes/3.js new file mode 100644 index 0000000..053ed5d --- /dev/null +++ b/.svelte-kit/generated/client/nodes/3.js @@ -0,0 +1 @@ +export { default as component } from "../../../../src/routes/about/+page.svelte"; \ No newline at end of file diff --git a/.svelte-kit/generated/client/nodes/4.js b/.svelte-kit/generated/client/nodes/4.js new file mode 100644 index 0000000..4fc32c1 --- /dev/null +++ b/.svelte-kit/generated/client/nodes/4.js @@ -0,0 +1 @@ +export { default as component } from "../../../../src/routes/donate/+page.svelte"; \ No newline at end of file diff --git a/.svelte-kit/generated/client/nodes/5.js b/.svelte-kit/generated/client/nodes/5.js new file mode 100644 index 0000000..07732a9 --- /dev/null +++ b/.svelte-kit/generated/client/nodes/5.js @@ -0,0 +1 @@ +export { default as component } from "../../../../src/routes/viewer/+page.svelte"; \ No newline at end of file diff --git a/.svelte-kit/generated/server/internal.js b/.svelte-kit/generated/server/internal.js index 9533fcb..8a81a08 100644 --- a/.svelte-kit/generated/server/internal.js +++ b/.svelte-kit/generated/server/internal.js @@ -18,10 +18,10 @@ export const options = { root, service_worker: false, templates: { - app: ({ head, body, assets, nonce, env }) => "\n\n\t\n\t\t\n\t\t\n\t\t\n\t\t" + head + "\n\t\n\t\n\t\t
" + body + "
\n\t\n\n", + app: ({ head, body, assets, nonce, env }) => "\n\n \n \n \n \n \n " + head + "\n \n \n
" + body + "
\n \n\n", error: ({ status, message }) => "\n\n\t\n\t\t\n\t\t" + message + "\n\n\t\t\n\t\n\t\n\t\t
\n\t\t\t" + status + "\n\t\t\t
\n\t\t\t\t

" + message + "

\n\t\t\t
\n\t\t
\n\t\n\n" }, - version_hash: "au0v7i" + version_hash: "lnkeyd" }; export async function get_hooks() { diff --git a/.svelte-kit/types/route_meta_data.json b/.svelte-kit/types/route_meta_data.json index a96ec02..2deec3b 100644 --- a/.svelte-kit/types/route_meta_data.json +++ b/.svelte-kit/types/route_meta_data.json @@ -1,3 +1,15 @@ { - "/": [] + "/": [ + "src/routes/+layout.js", + "src/routes/+layout.js" + ], + "/about": [ + "src/routes/+layout.js" + ], + "/donate": [ + "src/routes/+layout.js" + ], + "/viewer": [ + "src/routes/+layout.js" + ] } \ No newline at end of file diff --git a/.svelte-kit/types/src/routes/$types.d.ts b/.svelte-kit/types/src/routes/$types.d.ts index 9e82d29..0dd5022 100644 --- a/.svelte-kit/types/src/routes/$types.d.ts +++ b/.svelte-kit/types/src/routes/$types.d.ts @@ -12,7 +12,7 @@ type EnsureDefined = T extends null | undefined ? {} : T; type OptionalUnion, A extends keyof U = U extends U ? keyof U : never> = U extends unknown ? { [P in Exclude]?: never } & U : never; export type Snapshot = Kit.Snapshot; type PageParentData = EnsureDefined; -type LayoutRouteId = RouteId | "/" | null +type LayoutRouteId = RouteId | "/" | "/about" | "/donate" | "/viewer" | null type LayoutParams = RouteParams & { } type LayoutParentData = EnsureDefined<{}>; @@ -20,5 +20,7 @@ export type PageServerData = null; export type PageData = Expand; export type PageProps = { data: PageData } export type LayoutServerData = null; -export type LayoutData = Expand; +export type LayoutLoad = OutputDataShape> = Kit.Load; +export type LayoutLoadEvent = Parameters[0]; +export type LayoutData = Expand>>> & OptionalUnion>>>>>; export type LayoutProps = { data: LayoutData; children: import("svelte").Snippet } \ No newline at end of file diff --git a/.svelte-kit/types/src/routes/about/$types.d.ts b/.svelte-kit/types/src/routes/about/$types.d.ts new file mode 100644 index 0000000..462cbd7 --- /dev/null +++ b/.svelte-kit/types/src/routes/about/$types.d.ts @@ -0,0 +1,18 @@ +import type * as Kit from '@sveltejs/kit'; + +type Expand = T extends infer O ? { [K in keyof O]: O[K] } : never; +// @ts-ignore +type MatcherParam = M extends (param : string) => param is infer U ? U extends string ? U : string : string; +type RouteParams = { }; +type RouteId = '/about'; +type MaybeWithVoid = {} extends T ? T | void : T; +export type RequiredKeys = { [K in keyof T]-?: {} extends { [P in K]: T[K] } ? never : K; }[keyof T]; +type OutputDataShape = MaybeWithVoid> & Partial> & Record> +type EnsureDefined = T extends null | undefined ? {} : T; +type OptionalUnion, A extends keyof U = U extends U ? keyof U : never> = U extends unknown ? { [P in Exclude]?: never } & U : never; +export type Snapshot = Kit.Snapshot; +type PageParentData = EnsureDefined; + +export type PageServerData = null; +export type PageData = Expand; +export type PageProps = { data: PageData } \ No newline at end of file diff --git a/.svelte-kit/types/src/routes/donate/$types.d.ts b/.svelte-kit/types/src/routes/donate/$types.d.ts new file mode 100644 index 0000000..2434e6b --- /dev/null +++ b/.svelte-kit/types/src/routes/donate/$types.d.ts @@ -0,0 +1,18 @@ +import type * as Kit from '@sveltejs/kit'; + +type Expand = T extends infer O ? { [K in keyof O]: O[K] } : never; +// @ts-ignore +type MatcherParam = M extends (param : string) => param is infer U ? U extends string ? U : string : string; +type RouteParams = { }; +type RouteId = '/donate'; +type MaybeWithVoid = {} extends T ? T | void : T; +export type RequiredKeys = { [K in keyof T]-?: {} extends { [P in K]: T[K] } ? never : K; }[keyof T]; +type OutputDataShape = MaybeWithVoid> & Partial> & Record> +type EnsureDefined = T extends null | undefined ? {} : T; +type OptionalUnion, A extends keyof U = U extends U ? keyof U : never> = U extends unknown ? { [P in Exclude]?: never } & U : never; +export type Snapshot = Kit.Snapshot; +type PageParentData = EnsureDefined; + +export type PageServerData = null; +export type PageData = Expand; +export type PageProps = { data: PageData } \ No newline at end of file diff --git a/.svelte-kit/types/src/routes/proxy+layout.js b/.svelte-kit/types/src/routes/proxy+layout.js new file mode 100644 index 0000000..12a3ece --- /dev/null +++ b/.svelte-kit/types/src/routes/proxy+layout.js @@ -0,0 +1,17 @@ +// @ts-nocheck +import { loadTranslations } from '$lib/translations'; + +/** */ +export const load = async () => { + const initLocale = primaryLanguage(navigator.language) || 'en'; + + // TODO: Fix the undefined location issue + await loadTranslations(initLocale); + + return {}; +}; + +const primaryLanguage = (/** @type {string} */ locale) => { + if (!locale) return ''; + return locale.split('-')[0]; +}; diff --git a/.svelte-kit/types/src/routes/viewer/$types.d.ts b/.svelte-kit/types/src/routes/viewer/$types.d.ts new file mode 100644 index 0000000..23d2dd3 --- /dev/null +++ b/.svelte-kit/types/src/routes/viewer/$types.d.ts @@ -0,0 +1,18 @@ +import type * as Kit from '@sveltejs/kit'; + +type Expand = T extends infer O ? { [K in keyof O]: O[K] } : never; +// @ts-ignore +type MatcherParam = M extends (param : string) => param is infer U ? U extends string ? U : string : string; +type RouteParams = { }; +type RouteId = '/viewer'; +type MaybeWithVoid = {} extends T ? T | void : T; +export type RequiredKeys = { [K in keyof T]-?: {} extends { [P in K]: T[K] } ? never : K; }[keyof T]; +type OutputDataShape = MaybeWithVoid> & Partial> & Record> +type EnsureDefined = T extends null | undefined ? {} : T; +type OptionalUnion, A extends keyof U = U extends U ? keyof U : never> = U extends unknown ? { [P in Exclude]?: never } & U : never; +export type Snapshot = Kit.Snapshot; +type PageParentData = EnsureDefined; + +export type PageServerData = null; +export type PageData = Expand; +export type PageProps = { data: PageData } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e1784a8..a5b662f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,9 @@ "": { "name": "embroidery-viewer", "version": "0.0.1", + "dependencies": { + "sveltekit-i18n": "^2.4.2" + }, "devDependencies": { "@eslint/compat": "^1.2.5", "@eslint/js": "^9.18.0", @@ -29,7 +32,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -706,7 +708,6 @@ "version": "0.3.8", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", @@ -721,7 +722,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -731,7 +731,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -741,14 +740,12 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1046,7 +1043,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz", "integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==", - "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^8.9.0" @@ -1134,6 +1130,21 @@ "vite": "^6.0.0" } }, + "node_modules/@sveltekit-i18n/base": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@sveltekit-i18n/base/-/base-1.3.7.tgz", + "integrity": "sha512-kg1kql1/ro/lIudwFiWrv949Q07gmweln87tflUZR51MNdXXzK4fiJQv5Mw50K/CdQ5BOk/dJ0WOH2vOtBI6yw==", + "license": "MIT", + "peerDependencies": { + "svelte": ">=3.49.0" + } + }, + "node_modules/@sveltekit-i18n/parser-default": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@sveltekit-i18n/parser-default/-/parser-default-1.1.1.tgz", + "integrity": "sha512-/gtzLlqm/sox7EoPKD56BxGZktK/syGc79EbJAPWY5KVitQD9SM0TP8yJCqDxTVPk7Lk0WJhrBGUE2Nn0f5M1w==", + "license": "MIT" + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -1145,7 +1156,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", - "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { @@ -1159,7 +1169,6 @@ "version": "8.14.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -1222,7 +1231,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">= 0.4" @@ -1232,7 +1240,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">= 0.4" @@ -1303,7 +1310,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -1615,7 +1621,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", - "dev": true, "license": "MIT" }, "node_modules/espree": { @@ -1653,7 +1658,6 @@ "version": "1.4.6", "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.6.tgz", "integrity": "sha512-F/D2mADJ9SHY3IwksD4DAXjTt7qt7GWUf3/8RhCNWmC/67tyb55dpimHmy7EplakFaflV0R/PC+fdSPqrRHAQw==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" @@ -1894,7 +1898,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", - "dev": true, "license": "MIT", "dependencies": { "@types/estree": "^1.0.6" @@ -1996,7 +1999,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", - "dev": true, "license": "MIT" }, "node_modules/locate-path": { @@ -2026,7 +2028,6 @@ "version": "0.30.17", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" @@ -2560,7 +2561,6 @@ "version": "5.33.13", "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.33.13.tgz", "integrity": "sha512-uT3BAPpHGaJqpOgdwJwIK7P4JkBkSS0vylbaRXxQjt1gr+DZ9BiPkhmbZw3ql8LJofUyz5XyrzzQDgQQdfP86Q==", - "dev": true, "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.3.0", @@ -2635,6 +2635,22 @@ } } }, + "node_modules/sveltekit-i18n": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/sveltekit-i18n/-/sveltekit-i18n-2.4.2.tgz", + "integrity": "sha512-hjRWn4V4DBL8JQKJoJa3MRvn6d32Zo+rWkoSP5bsQ/XIAguPdQUZJ8LMe6Nc1rST8WEVdu9+vZI3aFdKYGR3+Q==", + "license": "MIT", + "workspaces": [ + "./examples/*/" + ], + "dependencies": { + "@sveltekit-i18n/base": "~1.3.0", + "@sveltekit-i18n/parser-default": "~1.1.0" + }, + "peerDependencies": { + "svelte": ">=3.49.0" + } + }, "node_modules/tinyglobby": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", @@ -2858,7 +2874,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", - "dev": true, "license": "MIT" } } diff --git a/package.json b/package.json index 172bc4d..738de6b 100644 --- a/package.json +++ b/package.json @@ -29,5 +29,8 @@ "svelte-check": "^4.0.0", "typescript": "^5.0.0", "vite": "^6.2.6" + }, + "dependencies": { + "sveltekit-i18n": "^2.4.2" } } diff --git a/src/App.svelte b/src/App.svelte deleted file mode 100644 index 597ecf5..0000000 --- a/src/App.svelte +++ /dev/null @@ -1 +0,0 @@ -

Hello world!

diff --git a/src/app.html b/src/app.html index 84ffad1..bcc5c50 100644 --- a/src/app.html +++ b/src/app.html @@ -1,6 +1,82 @@ + diff --git a/src/lib/assets/logo.webp b/src/lib/assets/logo.webp new file mode 100644 index 0000000000000000000000000000000000000000..a8d4df9f06b294ad3d49158019424ab87d69b9ac GIT binary patch literal 17672 zcmYhCbyS=^(CDAV-MY9HD6l}W0>$0k-J!S?S**Cj;w@I(T?-WVE>K)sS{#bIJ6zuH ze)pXFoIL*}lbPgXCi6?8Aul5XNCSYbw1k?D8lN5p004L|KQRJu0081jYI2vH004Ss zd?R=A?Cl^`bR?ee{OqA}*42KwbHs)Yl5LI(gN7~{o8iIo3TR<*A@Z=iC<_9Msn@R+ zyqssvLN}L=9tV%_Z~X$j7G2J3qn=cOn#9@w&$;{qx)JBN-e-(L=Ow9AvxetaSbtQV zWbU7_we)31Hmsf*C!gO|mp-t+b`~&Jio2&4`zg9(pV`+<*1mIu7#=XDI=wj+?*F@J z`cM}0HY2Ba-yh?;MnsaI(M+>ktybq9{J1uzH!;Yb9OHcCDF4>mlrK6(fSz5Ot{<+hBEi(bzUZ3Uzx*^0mg(xGtgoGqa z;@2K;*TW^1Xg{~_%9$7Sp3WT4gv2n5nRB+nEeKrltJ`-R-y}Zm>CVrwR)I|^&#hqh zN@@6&nytZJYWUBN4psKtPnwdoC8{}FgtBmbEfonGyRVTtx1^*qI-T$GKIb3#*iT^B z&g_n1F`J6z+m22aw>GLQJuS&<4lD{nZ6}<^^Swk**W2B@@7-0chhhgA0O==l2xB2f z2}y{k5e~i$?OoA|sGF zSkCyC+qiQQaqAtblF=56R@76*mcEG8-p(BK(oAxw>5FofR{H9F#@2Ob)cnWEIUcKg zC%0e!KB{}K-llJrQ%M~>iR%&#NUj`o1Pg9pU^C1Jp(nMEBe#+GjUz791RydJ5ebQ% zgQbpcoS>WzNJbQvZF*fUdB*W}HH;ztO2iYMVVOB_lrCL}8voaUV)dxS<|%lfeb3V8 zQmocF43Nd|sT&(1TCWW(;s9op=8s$_aEYL=+*HhQL&i|zLmSzCj|qE8H)!w*2N_qb zIFhN@{cmA3a|c9J;)@i1tF~A858?)>j5Li7SPhtWL{m2+wB9pHl|4&nryTuuAA6Va z$an{3>OP~|W&R<~j~CcAt3>F0SBj+{hu12+GX1^@Q9^X&L@sz4i!4_HDKO*vPi6cF zUUF;jKb|x4Uw5>6vfX3LWN3pJ;)8o39n`y{WsyV1M@Xz*I#S*_E^mleJxX1LXq!LM zvpzE=a6I-W>AP$%IP-ytdvi)Rf4xKdO^+i(Jda)KN0Q;S zRL!1E*@_XyTKhbnq1x{+;~j6L4qC=$YndWAp5RI0A$O+OrnGK>N{_kH_~WP)j2L@= zCrKTtT8|2z(xk%Nr-Cdc#g`EJaiivcf7lI>7t`}9KJQ0p)6kE&!ms=Xs(5}IauP6h zVg_2GgVsnCT|LQNQb(hGoDh-RM`){#0O32lo2!g@J^C?^3vS4fCS~IWEh59ys%DMg zxOU(nDAa&`w>m)#_dJfIh*7 z4jyyEbzyVIOZGl+_Z#EeziTp7pgEu}JeAl*Xj_W!I7_lKQ){T^?(3SCp0Ndw z{?2#D?(6WIJF(4D*}QtkF&Htm&wT`A%JZE)fetaxp4i_xGjzwL5>T7Ent5<3XUkI8 zT0z_shXY4?ciSxuT|OFXE3Kq`ylC|tbtz}U*a>{kji&x5H^gWSpX@=!Ml@gbojhA& z#rQBC`!8g?bHNnB;r>5?jPm2tSbt^DteRmnUzd@QFF5t%{n4tu=;XiiEV)Jx$SS=G zfp)RS$`zi=1JvrRl?cF_0EG>M@*`>}Lwoqe` z5PI#D@ezfp)J>HhX!%4uwt_)7Z7Xz~!Cvlb1zt>ew@6%Y8m~wXO4gHhHBH`-&cMB) zaE-AOF$N1G!2DA{dDrwXT(Sbuyqhl$$Pbv<%97A88+HJpml_rnIj9~S2@*TN1s_X= zo+smKfr8o}!3l5pU~Hv}O)eH`bW6mvD>h7-M}V3S?xsB8VybpS1QeudJPc^svv1PP zfmZp4pKt&*SC&muNOJ7Cpbo7N%W+}HFshkU&{lsj;BBqGsQ%8LesiM*PV39)0kqwl0U^49ERZ!KkKByBGIN^X z83RyH)1Tz#6coJfRJRil*x+erC=Mg^RO^WX8S8u|%N-Gb4j0|JIQ{ro;$1Hca4Qx* zc-aB!E1EbWVSOWU@rY>tD?;!#DYNuk>*v>it!wZW9Z#?in5!KSyL^@W%!Ju<&Y6;s zk9VGD>AtgPn)mRL>3`~S0Jb>_=kDJg^Rm%7P$>ItOpN>x(z)WrUhK6Hy1Nq==mYqHD6V=o_1(` zY(MZ_sHBkp0m|g4je*@)YLy zx+IEpq-3;ozCQ;+Y@QKgplz1KMxi-JqFbRK!_LiHt!vGvb_$MB)rLS4U{>h~fT0Y2*q;GHXx-AeOmnc0fApTYhryQ@615K(7;42SHcH-3Bb|C;lw zG<4&x>PwuG^7$eaH46i3)}ru#1Ay8c?&ndK+Z6}A&0XEMt`WZ_W|P)OZU1+;%6yWy zR#}0Z;v43y%Lz?C^zrl+2vr3l&~!bmcia7Y0Vb^bRvPPLN>oG1;__=e7na#K!%sYw}Bf1BW?3MC+;Q?BIR8Nrs zbwS&l{c!j9W4(iBe(CGK+yK1xh^>W_6^9JkTNs=e>PJ>UX7}$ZvlEE8vl}M`0K#iE zKVsmh==L7Mmx&b4XjYX<@5qF{{U+nL_fzPlrk_7N1UlG(m#>xf*9GTAy(MB`_^{|E zda!<~@jYn3%Z>{5T#)-CJEBeYTTM5Q2h^Cq>_~#ftrYHlq|B~mxm#7_K;Eb*So9hs zCXr*V>6(t4!O%~X-q-^_fHP|J7FP&cU`|YL%XCG+t<#+2hpM}b zE&%zSvtHrdvSf8+_*j_tHdTVEWeKr$+&m}XJgIF9%v+_+>8M~L_^?bv86#655Wz&l?4G<8;{$?AKC}y8Qds@5ux?lXnH0orEimkb>()&Xse4M%NL!|{Kfgg@7tP@2)V>t>5F+Yl+=t6U<0-&zgI#^} zsSdVEdgG92afG@lf%iD8&)i@=*B~HKj}yc^gEP}Ar+rz?rNyWUv2KpEpv(N_Q1+DX zYWotN3f~{X`7(FGvWSp#Pn2wZDx;>m`_^M2(Y>puY=zd7-e@JVnV{@=&3saYhCmKL z%3s>m(9XzQNa{RwI_f@t?;H`!saY-XTc^X^`|0UtgN_<0H4j~)F-^i#%?7({p*{wh zRgKwwpT<$DP1lKY7X~M<=4QQW`!7o8&OHrZ)-~E`Nx?J0suWcO7!y>Q%VWT*p_r>L zsZqI$2+{PrW0lwT_Eb(>f7`Y8(GHvE)I9R6!JDYXDD69YjP-3qP{sg$V*mr ze9=%lhkJ~N6dZ_h((W89qnyt)AOB0 z_cYu+#mKHb+nK7i&_`^BKCeZ5$2*6u_H991fA&u9u6>1~)%(f0RfsYxGmJ7{=#^Oc zTf3OwTZV9gyd-lS2o=`{EEHg35d6%F3Pk57eW)8wiKt|JKRs7m)6&^oW&tZ$e$Pyv zkzty*KVrfCWzi=zUx)BEhHd*&6FQ?*;zj|CCV96@M?1nvdVH5%xxsPlNk-bZfDpCX zqCOSC?3iEg+;#TbdjGnw|I%}<-v_1-^VdRog-wsk88*YiWz?Eu{_j4irgSdlNQ+`* zIu;65qfnh)Qn7LeMEUhZk;zefSNOJoL!e69B!31*KGcycUl$Wl8MBI zs|XRSxES^4m5L>4A9b-jhQA@Ir$ScQy}auzqFJN4A0)X}ebE>nP;e~1)ii3gBE~E< z7BPShJFxwBLDym0xPu<2&Gccsf{c6bDJ z+0vz+GIfFA7%nrP$=~e|n}p%+o#puIcG2#crj+EsGAzrn6|h5C?$XaQ66PCvoXJI5 zD>~Hg0`sq-nvkPPEPzu~Gb@ZGX_d(EujHVG}X1>=mHhB1(US8YV zp~Y$1piqx7u#NRaVl!LCHBcLfGEs7^zlQyzC)sG;yGjW;6(1AVz4{$y^dX!D>^j4{Zv&n2&M%55X{ZwvN)?PYNHHymbKt)kvS13Q;Tfk|;E)0S zkqX;HtBUxY(R{5QA@X6I^X$tuM?rFFl%3*T_MGt^Fp@q)fGVG$wtUQEo)9W2NpMaG zkNpL#W~#b=BsEGBLb+8POGrFct4qOT7hf@L7{ZhEaO1I!K?YansmLXrDP*1gSy|~a0<)cIzep6x;&26hmR40 zwk2UtPeYLwt6kQ`B~ccFjiyW{-+iYm@=LzcDR@v{;4olglldVYvKq!S=#vUv>res+l1QHI&%6{k|j$Tc1=r8I?a*d z93V05IXT^vlpp5tr!aEpZ*uQWK|;j7?oGgqY%|hz^Q_K31zKvKXpwJ>+U^ANj8KAO zzE=%jWsH`_D)$tXV>xtgY-7jLdnLxI?eF!8rOWMsH5)c<{?+_r7R!>|Q>hTpp>WH@ zml;^+BlD0lI95?xOjSVyllJsKeA0eHIu1cuh*fKBG@wK7jIi{KDQ5M&HdrFSkq0X5 z&nyXeKx7&L#HnLv6n;}FR3+3fP)|%UBZAoJM93TJmNSy_4E84NIUPT%>ty4$ zf{?YSf?#D|c$^N?G(E}nygzgHsh)EEUO9<>?S2ZNHJKGOqDdbQ9&*LMCv z&FEvEj0@zHJiG&D7nQetb*bpI+>0Hww85B%UG){>{FDRPFz-wSn3q$9n#y~pdS7u1 z#L7*bCPH4CqGIlaMf}uGDlIK zR8h6A*&ZvEi3-kC&MfBEJ5Iv!Wu?-n;;sJPu6!D%{L_(TLVtH+5j(sbbQaW%<)J=`8|`ZK61Q4{xsjN z)tCz|QVXYR>?0;<{|kj_NIRsqdUpTFG*Rbvq4A6i4wd8>Qgx*TW(B3sO>#sru&pZ5eKE(G5F zt6_FtEWb0d&tonj*+d~8P-ya0yX72pFIw{S7EkhO&7fDk1e4PR7bV>U6ZDbg}8ba%dTS=toq@_)G-PULP=pSETIj+8-k%IMr3a_`K7;hoW$BECsBQwv*J>{s;+?B7&i z#5PJtl(D4ggo<`SPe zpG!1E2O8Dt-y?M%6C zhuMI&7ki5E9*C;F`%->nn}=xxw(=5N1j0|%w1yj6c)`o;N|uR={Wkn}NpyGK>z$3?3mS^2fXY1(h@gLDkXA5G9OBcXhaw{_e1E|O&2 z_K<T5yz!#rm;Gxx1P-Az;x}_#p7YTXGT9&P-v2 zL7xNFRk|@e5;Ox4@fp+2F2CBRHOgOx7bMN)XU;6%v?DYoKxA4FCMwzdv(XNPkMi6j z$OZTO4{-`gkd5?B$=v+JhH-wR*WTQiEaYZkDB<=aGPLOxd5MY|x5t;iyt_>23Lppua0-OB0rT=T$< z;c8ICl!U?o^;X&nzQw%au4 zA7xE`gOIIlR@H;Z0if~6&s@&pJ7na!lWZLqGrn#n~6I@}?F|Bz)+Y+oqR zDk6+=pY{`f$``dyyqn1aEpH3INEps&y_c^kw9j}m$kHJ{4AK1Kywv99pi8v16JT1L z5g)KThq$02??b{HY1*>sqxJqd4~_%ov`L- z{iO(xbt>~CUt3x06^F0-<(y#xGDx=LJ4ma`ugA*Af+NfP219p~XAJV|P7$R&H%G(* zGS0jKI)s-D9(8qGD1*HbKtTc5`f{Y6g@1=QI({zqCQdt+6sO_C=!pWx{s@B>Gi2RA zk>~j{z*qHFxALIx(ShOaMo}-X5s47{dq^&e|Lr1G5&v<(e^R$EkU8FoofqSXRnLGC zy%3$gF_mzGf?me_EUhm%ptQ^n&3x(RP`j|$9F&3R1(4w9@t0Buw^^+p7in{5}>(9|wc=VoiJ!Zp`pg+7ld`McR&B_MJ1sk*C(0*LN*<84$?Ci0w} zEQxhr*Yp1ZCv0Qqn0F|F^{iqZ2FhWsU&o+0T+p!sew)`p_yHO2cc7gwlJ1`DFXUBd z3E{*~-1Q?5kS=%H7SgqCM@kXQQPUVY;2FPX^CB74gC;u0{|H=+mhd-I2bDso%3rV) zOpqC&=MXF^EBU7e>i4V08lfQ$In3_cA%2coB|3`=01Ll3gl>W z+kBS{4*aO?^0x2RGULBcm1{TLPTAukI`+pO1nrP=UuFed*vAYN5ycEMuC+rNSjL{Z zAU7Wi`FXL{gi^QMQvkDfalP#ztm_w^L@w42%{V^_a}Tw1u;Vl3q^v>NxG!1Fh9Fgy z>giFf3DMeO-~^vjOJ0rrM@`4~kn`q{GeWO>zb4w~>5>h6#9pZAe~6>mm-$ynpP|cA z2C*D|>_F~oGsGFwG#hn0utWb3%T`eVpT}n?{742YK%aY?EzEK@(sR*VD=d8p*al?| z?dii*TV;OJr?)+mzVW(vn|`vH^fPxw8+|Q1S>=2}WX64aqPC3}wL{Sze@N+0xNF^AU7WpG5}}!XmEY zUkK<>`^2EST6fr%F}=Cq;tP7>1>z>uC_Vdn|Mua^yXCkx=RbnIa(ytWL9>glQF>)a`>WIS{qR2^?BWW2saXP z<-N$9Mwfj?`lR8=ga>;}*}C{%M|o6wYrzOKC20DAZY}zxqlK3~!OoOOydWAFA%3RQ ze)Wisk#}}o^Y~(8bYN2nk=xdF-!!3i!X@PumMbt)r|NmJN*!goqWdRbU=Bw;E9Ai~ zh_?2-U^XN-=KWIbO%Y&AJ7$+{wm=uT)#wQ@AD7+;oQ<_`M}KVLl079IJ&g>{ia-`k znDQ$@cFZi9$y!DcgA0RKkb-VdQxCrq5}tC%x{6H25qyP-AQ%*peUmNdxgO8km7<#` z5*2gz)CD%ZH2ek;^9J!hAK=}7V)5=K$5mH}Nl|k+@?n^;k3v|<2a)0a3b{1Octivx zKSr)Yaf4iapeB^J78-=lpN!@!(i0H2$=z%h)k%LSDWMoy0yfhvtyl-dGbAnOV$ow@(JR0^e(O3B_iA#q&R5-)DL=2=N+7N>rXT(o z5fci4SHw=a*n=YN#;d5>4sZ!~b%$c1H6^96Kch)wZ;ZG1tC$&4Kl zey$}Uhfd6>gmnGIvy|t*ODS$`e$rjisr_6oG|j!eD(iyx7fWd$rzmBA;bw~qty~tb z6>7t6S|g?!3RqVI==EmyxOHqpv&Gq?z3G zR$=+!tnt3mfIFLZrBtEAMmfm(xwgNc>aS{&C1tgVVWz^?{4536R{q-IaJyEO&x-G0 z>@K2|u*bxzL#B>06n?)BZl&PxRzSNClbq}44#1C_WT+}==|Np>Q_5iHmVDY#RHtaX zHK+#Cso)Wuo&7Tb#qv!EG$Ii@1u% zIs(@Li66AB&LRMLlnjJ>8fL zhx|6?(?^O78=xnK;f%PQ6n2bX;44A=$QaikjONtJ3MQ6C+;K^=4ix>Dnawk?UsIZ8 zsL>!XWvIK&VT=|3&OFH?fq_Q(Xqxp)6%nwK3TdFiQGZB8C#d~6y)xpIC#EV|ay8Kuba_oi)jjR+GafAPt? ze$)rXG?}_W{F<`2?39g%gTGb4VeuL4yLYDqIF4#c$q{Ogu!~A4&A=r5m@3yzdZ{=3 zvkm?DyB8FOn=S|$Pt~F~(NL0&GQs-e0IiXevQ<1TNH@alnX_T)ihG!I*Q!@JZ?Pbp z#Uykh>@UN5Xb4cviC`yTU=B#u*}?gwRR48)+l5F_$!ROT+D2=aP*MwyEL4H^9a(L? zaa}Mfr<1@`eMxTfGT)x!o8+6&V=21EDF;Xi59;I&H~d-{u$vY_fApOZs7892OrP{b(zRwB_&R zHW_BxDoZZ*oCQ|{tGaY4-TFWbtuQGLHHO`J)}AonUM=Bn3Y^$mEM2;bs#Z3<0;u42|9s4mZQH9A zq`Y68FJ4D18k@Ujf}KNpjh)`FjKt|QxFGoC4Lp7_Re-4uW?8pxEScn(dEhOp)dubE z_mwi(pIK$H3l;26k%rXb$n~Z$5_(Bw7olmT2Ix|pw5S~+rFgxj4RC6kr4~yG1ry%{ zrLWjh<$g3OTy^H)lA1$V+e zDvd!thHR3<_DUQe%OCM`+5Gi;`6_z=ie=f+f`}*&bN^D`51vn`Et@%9E zoE$jjFRxzn`uS+(*_)9cBly9i97af`Hp;_Ybf(izq@TfMMH`WR!}y<~+3vO?MmTFb zmH(o#=F8KMA(V+v5r=Q2nKbQ(=7)m)r-=cBDGCUW!B8A>O^Nq_4IfDxoo6O~1YH$F zkH}h8vVPxb0j=;<#iBZM=p&x_hK`!iDqMEE%w+)Q(gICBXec~M^o$JgrJ#7 zUFwozW#ik|q82>FRfgdSec?)oJ!EVW_gx1)CBjKr9Tg(dcYrE&tJj+i+GK)|3Cra9%Ms|8c+3jJO?mHAV z6>VALKPCFL-`x7%n6K(Csz$X}^6EDZJ5q8zjI8Q9;5x|CBh+z4jf5%T1U0 zH^nzJd5;x0k#RJf$0Zz_qg`|}nRE7`eGp95e|cn8TtX#M_wjsd?juQ^)F<>D#gcRN z9;!9f+0qu2tz-^c^H)(gkGaP)&$&k87Eb()5BD*4VH<|$4@KCPC$2&ONo~q6T*|)&Ah~|Lxx3cv#K5g_u{R-glXFKUnk}A$vmep?9N&UhI7BEdD#O?GuUE6d{;v4-wM-b-n!E8Z>fU zZ7%O31Jg@xm%%i?2Ujwj6`?jzrwk>p6gr{4RwSFwY^9Bzw$g9*W~t*(T-nAnHE~f# z2GOP_Pv8%kbc;c|W!;zjlJ38g?xhCE5equtwK?VY9RxrXN_~83)u7m$sG#IO;;rm` z{A(dUa3RgEYeYHY5mYF@@A7U^kRtY%aLCMnNTP3s&2vVGi+0SZvA~x8r)3+@lQ`scCgO_FA|EZ@v{Vbn3$cAP!nHlZ+k`3xs*bSBH5kS87;wJo>ENSUt z_Zh+6@f!h_m*HX185{Dgy1Zr@B{#MI>jCHDf%{iuES(v+kmDGMexYdgR@c%c+Z_i~ zu-EJL8eR%}w7gz$*qS{%p&9 zwCkRgm#pdNmYh!9wJF2GQIDJM;CzaR!v zKviAjH&RbxUh)j(T5h`aC1~-0?J)HuZWx{{B`x0#f5qVVowT5LgPB)${;^!YM6dKF z>FgsFkTOjlu!Hbx-Ve!NsiF_AlV)0|O03*P24rLv+9@>fZ5zwO3kz=>|3Oy8)jp-Ave*0A<{^NUtsu$;=v>KF<0r= zGCL~#&FERGEDyS^90Mh-((E$aw|iV*n@^w>f??4gAnz25WnsX@A!zGB9BBKX*)dNl z7G9W~+hg@-amz88g|fIBS+FdRj2DGPQ;;*^h4QqdOB=y~r+qw=-miZPHQop^ zE42h^Et5Yiu-}@F5R>JW+|;1E`=DevuEoH889*YlmL?xp$&ma2(%cD)WIFk4*o8YGe^o!TPLEE3QOKhuA2 zI5(MGvTa}!ZD9^y=f(|^g#=O}t`fppB|)oOz!3S5w4v82h;Zl%v^%Dxa0vpQB5UhEFeK62P5x*`SU0%wYBuL zHnGK$9m8Y3WO-}NTcw~wsB&I1LJW7I*~(rJOQ2RT3o#FRWVo2&%!iEg5?M(@%fg-j z&yST1{og3)Ob<7}j3BYlb1<?f9{+T3t9%`PNgA?B8|-<2qHAsRvs)Gry%5M66}XU&Lh9{HXl@J@ z^*$Z*Tl`&X_@wqlccw)BU!_~vIv)UON?RAA4g$UKjWz@^4S}&zGEfgC7i%*D& zXeTVCm_yQCd4;KnY{_HW@;0GW^i8i&+QqTS1Jt8s$4=Ap=w;;F<~P+6FOG75gx;trRp_8o`ta_S*m{ z530*2RTiDMU)^LqS{6Cv*~$?K7O*?IYEX}S4TME}=dQ-c)4KdEt>)7dKX)?cc`r!~ zT~?;W%0OO?%vM-?v|G1mClw_!$b{fRL{PVpV7Z?_U_lx8Ee`UeZ4I`{8Vu}rk2rt*4r|D;g6N2I`i;4cEk1pH=0(fU_ zZE`|-Iz`L$q8>b>?Od@&WwEIT`);y#`O|-spE-y4l$d*Ir!%H^!Gh0uW=3tni#l1d zPVIi%Wpph7T@UHNq%U@)5BkPIi=$xTdK<5Awue^IiLaWo4RRM zvL)S?n$*7E2Arm!B_7kZR=y>KJp1D^G4l^Ze3 zd>CA4)5Q)us|Z%^R2x|2XrY>=he@n>inpsdVzR@nv^?< zdVfd0^{vm`K6TT>!}-Jl>ix4u;IB?e(ZNp!7ouC_ z;RD>SR;Y8afOAR}6EXS#JG~Wg7%3 zEaaK0>X0{^sjC0CkjKVygs$A{s)ZF=SY^{Rs^6z62%aVXe^tI;gdHmNsfiQIAuDUF zBC`D1R^IFp*W0Bfy{JX~|GLqSHq~}nNXGDsRphU=bYiofZSDvR{a2~-LTdhRXCej9 zD}5z95tMe^e@UqW5UK_EO};OF`mZc#2GqrfLA|sd?JWPKtEboa+v(d3yf0noO3as& zj11Qqx%e_stt0ox+xNFyK1b*k31&8NwmiYD9cCupV4?7gUyS|qyq8>~ zLL8~sGc%7((;U0$=}TWn?G*oFw-_-yohKc#puXfG&h_C&r=P*nhwd;0i?0GnD0ID) zrIs0r8M&!f6s1V(P*7kd+Kr}IXNI0=gqEy^kvTHh7Rf<`j4V9eV7Gd;%VYKjb$Um( zyB4e%-&6#$7kFpHj6-B$mxoW$8-@bj}CW%aA8&DIA)swSdnw)f(OXl(Ht#~ERwt`|^m8!ak?ydn)4{$Vz2 zek8So;nUu(tN!hZ1bOf@KGy3@VYYF%vA7Ye%st^vvUjz)L653t-?V&WtSVl=DhTyp z3|T7>mR^1@Ly29M-82!aC8)8bZvMu!SFr`ay%7RXFZX$$oD&98F@x0MGs*_lo@3}dnVVDfO3##sGNw5fgAKGJKlS_cY- z9-Wclu#A;;D0kyyk8Iz2`f~Fns<+g1hj7I_z_h{ZyKQ#Bt>d6Y3RMkBZHJ?nF%F+M z7|fEd3;&Ug07b$i@joK(E=3t+>>}@BDPW;o#Q{Oz#nMBxc4O8_kIEMd8%4>&BTCyl z@8XxHQsv`@kcFOsMQzY;QtO$wHt4BoE-(5ZOpSH+>T4^0EoCtx25&5a&q6Ced`Wd$ z-r-p4wPfj}**8Sc4Pzr#b1hrK;=VVmv&IX;KFT~{4LZk4gk=v3(fl9GHW?&%FP-Op z0P|~A7c2r;=--|>8zH%|!n{kB6YrpMy%SQXb~`~4)#UC@Lrx<&FE85wQuTO!C-csx z=a|6hC6`}rl<%#GgXyGWqTW9L8Wx!3Zz(s~lCB4USIa=gFNdB^-*Wd4W0T9!B565R zHxz1b`jx8%%`$5XTK068PED*o2+MaUJmGVNeX}@2bFM3|qJDqpCIu5jOuqDm%%EPn zT2ZTS64mPrizzv0{@`S|8+-{0w4xu&H@7}lrVbzL%Fh>XK-5-hIQ-(6cYl4CInbOF zDdrtQMx3w^k1O@cXIxI?q-Zz0Yno~F{Fj##^mi4vt<8!%UFIv=)1bIFX=3a_dJ{3$ znxonIod(m0xOdNsNh{CKppI7;uegUi3dNiy@Q~O*!u;zfd6_F1QnFl#_jJPiEd%hFeLVT2}**HMD! z6mMOQt)z1UssFu2CiJ{<*sH=KeF(tVxAB^!DZ|(y& zOAFdll*>1FXYUBSNj)4~KN&1q1x7_k<4Npe)-$C3bV>|-?g_b8WZhiI;PI@{o1oDj z-$Lym;4Yj&J&U~Lhy-xc>3~4&5Y+2KCx202lMy_FoIj^VRc^KdYgC8E`Q zjzHlX3Oda%kratof}h`Fo1ObGHs2&jg!%MwsLV@3F3a4CYdgfE)IM(x%730|5W49% z)E_5)p8sf^XoqZYEP40YUzg*H`96%kw3WIdXU)~v#PF#nUYv>TM?E?c_rytHS{{l- zS$tyn=SEo(*Q+Z@ly}rWZMy9!iw#$CCiibEgv!5TxYo^yw5jenI+@PW?&{r6oD3X} zzf$&qy_O0l&#l>>XLga_)-*m;K@!@fl((OW3txaTTQxYjYBD?KC#3O^SY#)1 zS&qi?Hf8UvKg*PPOuN0AsJ@igQAj(8wTeMTiuYSzzQDR75#~=*Dpv3iN1{EWwBa!> z(B_(kE*7h6WtHYnSZ+E3K{303#->zzQAFP)^tIN~DSpOI-DhWA-g>|~qQD^-Eeta; zQAYCsjLG^?g22JF1p+~|$O`Hk0_&+O8u{5y9gjU)T`)5FVvuuvtqqnd7QQuGrIusG zIDuR#OgzqCR5BNZ^D0>6DY}lF$}T{8&qQvz32c>ouO_X+Wg%8SpjG(8$v?d^43Myd z89Oy0kqBL&NzW4P$NsCS{)I^`_<%mIfp>B!OI|?Zv$MHNEcv~Dvf`=0>DFeALdpmH zT;&GC4ria;UksdYp;@Bz#fVd!jF#4l?c%wO2m-e7#Voagl1Q3Oe7p zPqq*71!|pj^@^`CBbl^d{z6L?o8Cojq7u*`w)lH56Q@3hnU!c9D)Ej)aS^wPAxf_Q z=Y+p3+=A-NwH{)zNYC8bp!VxCRn)h;4<@2+uMbib8WYO2`Dg5^B+-vU*RBx0z}ZWB z(J0@4QXa~)a}rO#VW69`QsN&D6&!o5I`sOHXmK z*1$x+wc8ghR~Szh7Ef6KSypOf3;X%{Kc3)5YgEXZ&II3-TTfp0 zP|w_opQU_ep5Gv^^E#CEX7k{+N0acRfZh6hJ+shf^f_Br{~i2R@<^T;`Nz+}xD*yh ztNv!~GR=oXqk{b~y+m1;OU{4p!(lRm$d8QgQN(`?3&zf)yGzIkzM&U@BnsmrnKH2s z+thizZ<;c1QVL?q2NlmhRPrf^mN@Jv+XaMHf9U3%b3V^<)w8!%$|pX}XR9-pW3uS#S@%7S>y>-4gAY=f%EyFZW&#NA8OqlW6$6 ztEBs%r+OFyx|~NS=?1x?6x$e?Xlt|ho2x}u3wYout6-HCU3X=q zrQf@Ho1W6u8gDDjMYl8iPUBhk81m6sY*cey#L4-4^8Lpl$V=B-Wni6+%p;`=7~16SMz<=gY@Vw%&e6fQ`V?+FBIZXy9qr zC1L)onw$L_ah?q6cSxLu)l_rCnFL(KExcQYq#E;Aa8+Icu-e+_&S}5*a@+z^=&tdUQEKa{e1 zSlQB0#`;5h%Yp(CzH8ya0B#)$jkPGF+0RKN9j&=r^}4#yGnSsvd-D1`--xAx<7tVt z3}YMgx&_i-i#I-38!W`LEtjwe1mK4AublTDzd7KQvf3jN5<&^v%2qym zZL=kQ5)VdD8Ia!wKK`EoKLo)0v|Krb6_;tYCO_vg+4q1aEBs17-GD`;HFyZ30nPMf z-s>1nMj4xf?`h7@9-HNW>xP(%Ng|EkDi~|U;yt*prXzvsdI_o=RdX% zN;LxE`yq1h6ASojP$b8V3d8K#2y>(C*^eahaXed8=NyjbYWCYB(Wz=C;Ff=Y-l|PM zbQ~#Ctkz^>Zf~D2$l7K4yD=g^8Zyu#M+?0l=`|3>#&Slgz=#7yHL5sxQOeZ?VJ4uW zAohxzl>j0G3(o30FUFlDxvwK7@nyJ|yTO0AzDI?LpU-SLL5g!h*$%bX#8k|DV z*@+yLVte4-02JotXHS}q_w2P+S~Rs42T4M*WDr2pL+}uw`>*l`QCA}rurQ%!yHDz~ zkOvl5a7{gj4JEnhWH|z0GK-vp{PBdaC5M){H-{69a9{PhrJ}`69gsWdZ#cd z@Px~Q-(Hb`@SkVnzXr6po-9h0Tny(Ka7Sae2qMhiL;VD(7H9s-dqhSh|5Eg3sHPJ? zmHBaE_joIta&JE?^Y`*>HnKrch_;?ml37phmj2L4XgOk9&Wo8!#jS0|KqBSCm_)_N z?tiIR;D$<>d7U0Im33v}3bx;9O5*Y#P5K^?__@`cZ!9>2G}m{ZNw>DR#@~FeH)`(O z$&9ZSCii+x>sX6%L3_!xAm2h(1D+pco}Z0L?g9X`>8`WS>U>uAvBoq=%2%Gy#8p+( zG@zu~%xgr2>aKUvJt*(?+cF$e|Nh9`eX}8jGy0@urDUK7nR)0msygC=FIhsS12xMC zs~^}|Kl)1W;RBWWfTz6zxvFu&YsD1RL*y~!ucrWN!`W+a3neT8O3*H)E#rNOwEfhY zJt=A)N=^tHXsqK(%3~2_#)>qn&=tt3VQobTP1S+S{ftk2_;1}>m|S1u;yV(z + import { t, locale, locales } from '$lib/translations'; + import logo from '$lib/assets/logo.webp'; + import MediaQuery from './MediaQuery.svelte'; + + const configsFor = (/** @type {boolean} */ matches) => { + return matches + ? { src: logo, width: 150, height: 70 } // mobile + : { src: logo, width: 150, height: 100 }; // desktop + }; + + const onSwitchToOppositeLang = () => { + $locale = $locale === 'en' ? 'pt' : 'en'; + }; + + let isMenuOpen = false; + + +
+ + + +
+ + diff --git a/src/lib/components/MediaQuery.svelte b/src/lib/components/MediaQuery.svelte new file mode 100644 index 0000000..7e64d7b --- /dev/null +++ b/src/lib/components/MediaQuery.svelte @@ -0,0 +1,48 @@ + + + diff --git a/src/lib/translations/en/header.json b/src/lib/translations/en/header.json new file mode 100644 index 0000000..9ad8c6c --- /dev/null +++ b/src/lib/translations/en/header.json @@ -0,0 +1,7 @@ +{ + "languageSwitch": "🇧🇷", + "homeNav": "🏠 Home", + "aboutNav": "ℹ About", + "viewerNav": "🧵 Viewer", + "donateNav": "💖 Donate" +} diff --git a/src/lib/translations/index.js b/src/lib/translations/index.js new file mode 100644 index 0000000..1218cc2 --- /dev/null +++ b/src/lib/translations/index.js @@ -0,0 +1,41 @@ +import i18n from 'sveltekit-i18n'; +import lang from './lang.json'; + +/** @type {import('sveltekit-i18n').Config} */ +const config = { + translations: { + en: { lang }, + pt: { lang }, + }, + loaders: [ + { + locale: 'en', + key: 'header', + loader: async () => (await import('./en/header.json')).default, + }, + { + locale: 'pt', + key: 'header', + loader: async () => (await import('./pt/header.json')).default, + }, + ], +}; + +export const { t, locale, locales, loading, loadTranslations } = new i18n( + config, +); + +// Save to localStorage on change +locale.subscribe(($locale) => { + if (typeof localStorage !== 'undefined') { + localStorage.setItem('locale', $locale); + } +}); + +// Load from localStorage on initialization +if (typeof localStorage !== 'undefined') { + const savedLocale = localStorage.getItem('locale'); + if (savedLocale && savedLocale !== 'null') { + locale.set(savedLocale); + } +} diff --git a/src/lib/translations/lang.json b/src/lib/translations/lang.json new file mode 100644 index 0000000..c51419e --- /dev/null +++ b/src/lib/translations/lang.json @@ -0,0 +1,4 @@ +{ + "en": "English", + "pt": "Português" +} diff --git a/src/lib/translations/pt/header.json b/src/lib/translations/pt/header.json new file mode 100644 index 0000000..b47bfff --- /dev/null +++ b/src/lib/translations/pt/header.json @@ -0,0 +1,7 @@ +{ + "languageSwitch": "🇺🇸", + "homeNav": "🏠 Página Inicial", + "aboutNav": "ℹ Sobre", + "viewerNav": "🧵 Visualizador", + "donateNav": "💖 Doe" +} diff --git a/src/routes/+layout.js b/src/routes/+layout.js new file mode 100644 index 0000000..f57e56a --- /dev/null +++ b/src/routes/+layout.js @@ -0,0 +1,16 @@ +import { loadTranslations } from '$lib/translations'; + +/** @type {import('@sveltejs/kit').Load} */ +export const load = async () => { + const initLocale = primaryLanguage(navigator.language) || 'en'; + + // TODO: Fix the undefined location issue + await loadTranslations(initLocale); + + return {}; +}; + +const primaryLanguage = (/** @type {string} */ locale) => { + if (!locale) return ''; + return locale.split('-')[0]; +}; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..76366d7 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,6 @@ + + +
+ diff --git a/src/routes/about/+page.svelte b/src/routes/about/+page.svelte new file mode 100644 index 0000000..ae068f6 --- /dev/null +++ b/src/routes/about/+page.svelte @@ -0,0 +1 @@ +

About

diff --git a/src/routes/donate/+page.svelte b/src/routes/donate/+page.svelte new file mode 100644 index 0000000..793dafb --- /dev/null +++ b/src/routes/donate/+page.svelte @@ -0,0 +1 @@ +

Donate

diff --git a/src/routes/viewer/+page.svelte b/src/routes/viewer/+page.svelte new file mode 100644 index 0000000..6ce7f01 --- /dev/null +++ b/src/routes/viewer/+page.svelte @@ -0,0 +1 @@ +

Viewer