From dfe324cf8fda2782495362d8da1c4aae3d731ced Mon Sep 17 00:00:00 2001 From: Luka Dekanozishvili Date: Mon, 5 Jan 2026 17:39:59 +0100 Subject: [PATCH] init commit --- .gitignore | 23 + .npmrc | 1 + .vscode/settings.json | 10 + README.md | 41 + deno.lock | 1663 +++++++++++++++++ eslint.config.js | 41 + package.json | 40 + src/app.d.ts | 13 + src/app.html | 11 + src/lib/CollapsibleSubmenu.svelte | 0 src/lib/ErrorPopup.svelte | 33 + src/lib/MainNavbar.svelte | 87 + src/lib/Record.svelte | 261 +++ src/lib/RecordExplanation.svelte | 108 ++ src/lib/SideMenu.svelte | 35 + src/lib/api.ts | 21 + src/lib/assets/favicon.svg | 14 + src/lib/auth.svelte.ts | 40 + src/lib/domains.svelte.ts | 82 + src/lib/index.ts | 1 + src/lib/records.svelte.ts | 175 ++ src/routes/+layout.svelte | 39 + src/routes/+page.svelte | 272 +++ src/routes/about/+page.svelte | 44 + src/routes/dashboard/+page.svelte | 11 + src/routes/dashboard/[id]/+page.svelte | 352 ++++ src/routes/dashboard/[id]/delete/+page.svelte | 72 + .../dashboard/register-domain/+page.svelte | 139 ++ src/routes/delete-account/+page.svelte | 54 + src/routes/faq/+page.svelte | 150 ++ src/routes/forgot-password/+page.svelte | 52 + src/routes/layout.css | 64 + src/routes/login/+page.svelte | 64 + src/routes/logout/+page.svelte | 27 + src/routes/redirect/[url]/+layout.ts | 1 + src/routes/redirect/[url]/+page.svelte | 15 + src/routes/register/+page.svelte | 79 + src/routes/verify-email/[token]/+page.svelte | 48 + start_backend.sh | 12 + static/robots.txt | 3 + svelte.config.js | 12 + tsconfig.json | 20 + vite.config.ts | 7 + 43 files changed, 4237 insertions(+) create mode 100644 .gitignore create mode 100644 .npmrc create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 deno.lock create mode 100644 eslint.config.js create mode 100644 package.json create mode 100644 src/app.d.ts create mode 100644 src/app.html create mode 100644 src/lib/CollapsibleSubmenu.svelte create mode 100644 src/lib/ErrorPopup.svelte create mode 100644 src/lib/MainNavbar.svelte create mode 100644 src/lib/Record.svelte create mode 100644 src/lib/RecordExplanation.svelte create mode 100644 src/lib/SideMenu.svelte create mode 100644 src/lib/api.ts create mode 100644 src/lib/assets/favicon.svg create mode 100644 src/lib/auth.svelte.ts create mode 100644 src/lib/domains.svelte.ts create mode 100644 src/lib/index.ts create mode 100644 src/lib/records.svelte.ts create mode 100644 src/routes/+layout.svelte create mode 100644 src/routes/+page.svelte create mode 100644 src/routes/about/+page.svelte create mode 100644 src/routes/dashboard/+page.svelte create mode 100644 src/routes/dashboard/[id]/+page.svelte create mode 100644 src/routes/dashboard/[id]/delete/+page.svelte create mode 100644 src/routes/dashboard/register-domain/+page.svelte create mode 100644 src/routes/delete-account/+page.svelte create mode 100644 src/routes/faq/+page.svelte create mode 100644 src/routes/forgot-password/+page.svelte create mode 100644 src/routes/layout.css create mode 100644 src/routes/login/+page.svelte create mode 100644 src/routes/logout/+page.svelte create mode 100644 src/routes/redirect/[url]/+layout.ts create mode 100644 src/routes/redirect/[url]/+page.svelte create mode 100644 src/routes/register/+page.svelte create mode 100644 src/routes/verify-email/[token]/+page.svelte create mode 100755 start_backend.sh create mode 100644 static/robots.txt create mode 100644 svelte.config.js create mode 100644 tsconfig.json create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3b462cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +node_modules + +# Output +.output +.vercel +.netlify +.wrangler +/.svelte-kit +/build + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..b6f27f1 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b1108d1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "files.associations": { + "*.css": "tailwindcss" + }, + "piny.project_settings": { + "open-pages": [ + "pinyfakepage.html" + ] + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..d2f9f29 --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# sv + +Everything you need to build a Svelte project, powered by +[`sv`](https://github.com/sveltejs/cli). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```sh +# create a new project in the current directory +npx sv create + +# create a new project in my-app +npx sv create my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or +`pnpm install` or `yarn`), start a development server: + +```sh +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```sh +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an +> [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..1d4c547 --- /dev/null +++ b/deno.lock @@ -0,0 +1,1663 @@ +{ + "version": "5", + "specifiers": { + "npm:@eslint/compat@^1.4.0": "1.4.1_eslint@9.39.1", + "npm:@eslint/js@^9.39.1": "9.39.1", + "npm:@sveltejs/adapter-node@^5.4.0": "5.4.0_@sveltejs+kit@2.49.0__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.44.1____acorn@8.15.0___vite@7.2.4____@types+node@22.19.1____picomatch@4.0.3___@types+node@22.19.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__acorn@8.15.0__@types+node@22.19.1_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__@types+node@22.19.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1", + "npm:@sveltejs/kit@^2.48.5": "2.49.0_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__@types+node@22.19.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_acorn@8.15.0_@types+node@22.19.1", + "npm:@sveltejs/vite-plugin-svelte@^6.2.1": "6.2.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1", + "npm:@tailwindcss/forms@~0.5.10": "0.5.10_tailwindcss@4.1.17", + "npm:@tailwindcss/typography@~0.5.19": "0.5.19_tailwindcss@4.1.17", + "npm:@tailwindcss/vite@^4.1.17": "4.1.17_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1", + "npm:@types/node@22": "22.19.1", + "npm:daisyui@^5.5.5": "5.5.5", + "npm:eslint-plugin-svelte@^3.13.0": "3.13.0_eslint@9.39.1_svelte@5.44.1__acorn@8.15.0_postcss@8.5.6", + "npm:eslint@^9.39.1": "9.39.1", + "npm:globals@^16.5.0": "16.5.0", + "npm:prettier-plugin-svelte@^3.4.0": "3.4.0_prettier@3.7.4_svelte@5.44.1__acorn@8.15.0", + "npm:prettier@^3.7.4": "3.7.4", + "npm:svelte-check@^4.3.4": "4.3.4_svelte@5.44.1__acorn@8.15.0_typescript@5.9.3", + "npm:svelte@^5.43.8": "5.44.1_acorn@8.15.0", + "npm:tailwindcss@^4.1.17": "4.1.17", + "npm:typescript-eslint@^8.47.0": "8.48.0_eslint@9.39.1_typescript@5.9.3_@typescript-eslint+parser@8.48.0__eslint@9.39.1__typescript@5.9.3", + "npm:typescript@^5.9.3": "5.9.3", + "npm:vite@^7.2.2": "7.2.4_@types+node@22.19.1_picomatch@4.0.3" + }, + "npm": { + "@esbuild/aix-ppc64@0.25.12": { + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "os": ["aix"], + "cpu": ["ppc64"] + }, + "@esbuild/android-arm64@0.25.12": { + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "os": ["android"], + "cpu": ["arm64"] + }, + "@esbuild/android-arm@0.25.12": { + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "os": ["android"], + "cpu": ["arm"] + }, + "@esbuild/android-x64@0.25.12": { + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "os": ["android"], + "cpu": ["x64"] + }, + "@esbuild/darwin-arm64@0.25.12": { + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "os": ["darwin"], + "cpu": ["arm64"] + }, + "@esbuild/darwin-x64@0.25.12": { + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "os": ["darwin"], + "cpu": ["x64"] + }, + "@esbuild/freebsd-arm64@0.25.12": { + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "os": ["freebsd"], + "cpu": ["arm64"] + }, + "@esbuild/freebsd-x64@0.25.12": { + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "os": ["freebsd"], + "cpu": ["x64"] + }, + "@esbuild/linux-arm64@0.25.12": { + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "os": ["linux"], + "cpu": ["arm64"] + }, + "@esbuild/linux-arm@0.25.12": { + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "os": ["linux"], + "cpu": ["arm"] + }, + "@esbuild/linux-ia32@0.25.12": { + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "os": ["linux"], + "cpu": ["ia32"] + }, + "@esbuild/linux-loong64@0.25.12": { + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "os": ["linux"], + "cpu": ["loong64"] + }, + "@esbuild/linux-mips64el@0.25.12": { + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "os": ["linux"], + "cpu": ["mips64el"] + }, + "@esbuild/linux-ppc64@0.25.12": { + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "os": ["linux"], + "cpu": ["ppc64"] + }, + "@esbuild/linux-riscv64@0.25.12": { + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "os": ["linux"], + "cpu": ["riscv64"] + }, + "@esbuild/linux-s390x@0.25.12": { + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "os": ["linux"], + "cpu": ["s390x"] + }, + "@esbuild/linux-x64@0.25.12": { + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "os": ["linux"], + "cpu": ["x64"] + }, + "@esbuild/netbsd-arm64@0.25.12": { + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "os": ["netbsd"], + "cpu": ["arm64"] + }, + "@esbuild/netbsd-x64@0.25.12": { + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "os": ["netbsd"], + "cpu": ["x64"] + }, + "@esbuild/openbsd-arm64@0.25.12": { + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "os": ["openbsd"], + "cpu": ["arm64"] + }, + "@esbuild/openbsd-x64@0.25.12": { + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "os": ["openbsd"], + "cpu": ["x64"] + }, + "@esbuild/openharmony-arm64@0.25.12": { + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "os": ["openharmony"], + "cpu": ["arm64"] + }, + "@esbuild/sunos-x64@0.25.12": { + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "os": ["sunos"], + "cpu": ["x64"] + }, + "@esbuild/win32-arm64@0.25.12": { + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "os": ["win32"], + "cpu": ["arm64"] + }, + "@esbuild/win32-ia32@0.25.12": { + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "os": ["win32"], + "cpu": ["ia32"] + }, + "@esbuild/win32-x64@0.25.12": { + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "os": ["win32"], + "cpu": ["x64"] + }, + "@eslint-community/eslint-utils@4.9.0_eslint@9.39.1": { + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dependencies": [ + "eslint", + "eslint-visitor-keys@3.4.3" + ] + }, + "@eslint-community/regexpp@4.12.2": { + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==" + }, + "@eslint/compat@1.4.1_eslint@9.39.1": { + "integrity": "sha512-cfO82V9zxxGBxcQDr1lfaYB7wykTa0b00mGa36FrJl7iTFd0Z2cHfEYuxcBRP/iNijCsWsEkA+jzT8hGYmv33w==", + "dependencies": [ + "@eslint/core", + "eslint" + ], + "optionalPeers": [ + "eslint" + ] + }, + "@eslint/config-array@0.21.1": { + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dependencies": [ + "@eslint/object-schema", + "debug", + "minimatch@3.1.2" + ] + }, + "@eslint/config-helpers@0.4.2": { + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dependencies": [ + "@eslint/core" + ] + }, + "@eslint/core@0.17.0": { + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dependencies": [ + "@types/json-schema" + ] + }, + "@eslint/eslintrc@3.3.1": { + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dependencies": [ + "ajv", + "debug", + "espree", + "globals@14.0.0", + "ignore@5.3.2", + "import-fresh", + "js-yaml", + "minimatch@3.1.2", + "strip-json-comments" + ] + }, + "@eslint/js@9.39.1": { + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==" + }, + "@eslint/object-schema@2.1.7": { + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==" + }, + "@eslint/plugin-kit@0.4.1": { + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dependencies": [ + "@eslint/core", + "levn" + ] + }, + "@humanfs/core@0.19.1": { + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==" + }, + "@humanfs/node@0.16.7": { + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dependencies": [ + "@humanfs/core", + "@humanwhocodes/retry" + ] + }, + "@humanwhocodes/module-importer@1.0.1": { + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" + }, + "@humanwhocodes/retry@0.4.3": { + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==" + }, + "@jridgewell/gen-mapping@0.3.13": { + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dependencies": [ + "@jridgewell/sourcemap-codec", + "@jridgewell/trace-mapping" + ] + }, + "@jridgewell/remapping@2.3.5": { + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dependencies": [ + "@jridgewell/gen-mapping", + "@jridgewell/trace-mapping" + ] + }, + "@jridgewell/resolve-uri@3.1.2": { + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" + }, + "@jridgewell/sourcemap-codec@1.5.5": { + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" + }, + "@jridgewell/trace-mapping@0.3.31": { + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dependencies": [ + "@jridgewell/resolve-uri", + "@jridgewell/sourcemap-codec" + ] + }, + "@polka/url@1.0.0-next.29": { + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==" + }, + "@rollup/plugin-commonjs@28.0.9_rollup@4.53.3_picomatch@4.0.3": { + "integrity": "sha512-PIR4/OHZ79romx0BVVll/PkwWpJ7e5lsqFa3gFfcrFPWwLXLV39JVUzQV9RKjWerE7B845Hqjj9VYlQeieZ2dA==", + "dependencies": [ + "@rollup/pluginutils", + "commondir", + "estree-walker", + "fdir", + "is-reference@1.2.1", + "magic-string", + "picomatch", + "rollup" + ], + "optionalPeers": [ + "rollup" + ] + }, + "@rollup/plugin-json@6.1.0_rollup@4.53.3": { + "integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==", + "dependencies": [ + "@rollup/pluginutils", + "rollup" + ], + "optionalPeers": [ + "rollup" + ] + }, + "@rollup/plugin-node-resolve@16.0.3_rollup@4.53.3": { + "integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==", + "dependencies": [ + "@rollup/pluginutils", + "@types/resolve", + "deepmerge", + "is-module", + "resolve", + "rollup" + ], + "optionalPeers": [ + "rollup" + ] + }, + "@rollup/pluginutils@5.3.0_rollup@4.53.3": { + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "dependencies": [ + "@types/estree", + "estree-walker", + "picomatch", + "rollup" + ], + "optionalPeers": [ + "rollup" + ] + }, + "@rollup/rollup-android-arm-eabi@4.53.3": { + "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", + "os": ["android"], + "cpu": ["arm"] + }, + "@rollup/rollup-android-arm64@4.53.3": { + "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", + "os": ["android"], + "cpu": ["arm64"] + }, + "@rollup/rollup-darwin-arm64@4.53.3": { + "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", + "os": ["darwin"], + "cpu": ["arm64"] + }, + "@rollup/rollup-darwin-x64@4.53.3": { + "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", + "os": ["darwin"], + "cpu": ["x64"] + }, + "@rollup/rollup-freebsd-arm64@4.53.3": { + "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", + "os": ["freebsd"], + "cpu": ["arm64"] + }, + "@rollup/rollup-freebsd-x64@4.53.3": { + "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", + "os": ["freebsd"], + "cpu": ["x64"] + }, + "@rollup/rollup-linux-arm-gnueabihf@4.53.3": { + "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", + "os": ["linux"], + "cpu": ["arm"] + }, + "@rollup/rollup-linux-arm-musleabihf@4.53.3": { + "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", + "os": ["linux"], + "cpu": ["arm"] + }, + "@rollup/rollup-linux-arm64-gnu@4.53.3": { + "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", + "os": ["linux"], + "cpu": ["arm64"] + }, + "@rollup/rollup-linux-arm64-musl@4.53.3": { + "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", + "os": ["linux"], + "cpu": ["arm64"] + }, + "@rollup/rollup-linux-loong64-gnu@4.53.3": { + "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", + "os": ["linux"], + "cpu": ["loong64"] + }, + "@rollup/rollup-linux-ppc64-gnu@4.53.3": { + "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", + "os": ["linux"], + "cpu": ["ppc64"] + }, + "@rollup/rollup-linux-riscv64-gnu@4.53.3": { + "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", + "os": ["linux"], + "cpu": ["riscv64"] + }, + "@rollup/rollup-linux-riscv64-musl@4.53.3": { + "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", + "os": ["linux"], + "cpu": ["riscv64"] + }, + "@rollup/rollup-linux-s390x-gnu@4.53.3": { + "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", + "os": ["linux"], + "cpu": ["s390x"] + }, + "@rollup/rollup-linux-x64-gnu@4.53.3": { + "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", + "os": ["linux"], + "cpu": ["x64"] + }, + "@rollup/rollup-linux-x64-musl@4.53.3": { + "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", + "os": ["linux"], + "cpu": ["x64"] + }, + "@rollup/rollup-openharmony-arm64@4.53.3": { + "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", + "os": ["openharmony"], + "cpu": ["arm64"] + }, + "@rollup/rollup-win32-arm64-msvc@4.53.3": { + "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "os": ["win32"], + "cpu": ["arm64"] + }, + "@rollup/rollup-win32-ia32-msvc@4.53.3": { + "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", + "os": ["win32"], + "cpu": ["ia32"] + }, + "@rollup/rollup-win32-x64-gnu@4.53.3": { + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "os": ["win32"], + "cpu": ["x64"] + }, + "@rollup/rollup-win32-x64-msvc@4.53.3": { + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "os": ["win32"], + "cpu": ["x64"] + }, + "@standard-schema/spec@1.0.0": { + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==" + }, + "@sveltejs/acorn-typescript@1.0.7_acorn@8.15.0": { + "integrity": "sha512-znp1A/Y1Jj4l/Zy7PX5DZKBE0ZNY+5QBngiE21NJkfSTyzzC5iKNWOtwFXKtIrn7MXEFBck4jD95iBNkGjK92Q==", + "dependencies": [ + "acorn" + ] + }, + "@sveltejs/adapter-node@5.4.0_@sveltejs+kit@2.49.0__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.44.1____acorn@8.15.0___vite@7.2.4____@types+node@22.19.1____picomatch@4.0.3___@types+node@22.19.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__acorn@8.15.0__@types+node@22.19.1_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__@types+node@22.19.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1": { + "integrity": "sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==", + "dependencies": [ + "@rollup/plugin-commonjs", + "@rollup/plugin-json", + "@rollup/plugin-node-resolve", + "@sveltejs/kit", + "rollup" + ] + }, + "@sveltejs/kit@2.49.0_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__@types+node@22.19.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_acorn@8.15.0_@types+node@22.19.1": { + "integrity": "sha512-oH8tXw7EZnie8FdOWYrF7Yn4IKrqTFHhXvl8YxXxbKwTMcD/5NNCryUSEXRk2ZR4ojnub0P8rNrsVGHXWqIDtA==", + "dependencies": [ + "@standard-schema/spec", + "@sveltejs/acorn-typescript", + "@sveltejs/vite-plugin-svelte", + "@types/cookie", + "acorn", + "cookie", + "devalue", + "esm-env", + "kleur", + "magic-string", + "mrmime", + "sade", + "set-cookie-parser", + "sirv", + "svelte", + "vite" + ], + "bin": true + }, + "@sveltejs/vite-plugin-svelte-inspector@5.0.1_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.44.1___acorn@8.15.0__vite@7.2.4___@types+node@22.19.1___picomatch@4.0.3__@types+node@22.19.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1": { + "integrity": "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==", + "dependencies": [ + "@sveltejs/vite-plugin-svelte", + "debug", + "svelte", + "vite" + ] + }, + "@sveltejs/vite-plugin-svelte@6.2.1_svelte@5.44.1__acorn@8.15.0_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1": { + "integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==", + "dependencies": [ + "@sveltejs/vite-plugin-svelte-inspector", + "debug", + "deepmerge", + "magic-string", + "svelte", + "vite", + "vitefu" + ] + }, + "@tailwindcss/forms@0.5.10_tailwindcss@4.1.17": { + "integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==", + "dependencies": [ + "mini-svg-data-uri", + "tailwindcss" + ] + }, + "@tailwindcss/node@4.1.17": { + "integrity": "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg==", + "dependencies": [ + "@jridgewell/remapping", + "enhanced-resolve", + "jiti", + "lightningcss", + "magic-string", + "source-map-js", + "tailwindcss" + ] + }, + "@tailwindcss/oxide-android-arm64@4.1.17": { + "integrity": "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==", + "os": ["android"], + "cpu": ["arm64"] + }, + "@tailwindcss/oxide-darwin-arm64@4.1.17": { + "integrity": "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg==", + "os": ["darwin"], + "cpu": ["arm64"] + }, + "@tailwindcss/oxide-darwin-x64@4.1.17": { + "integrity": "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==", + "os": ["darwin"], + "cpu": ["x64"] + }, + "@tailwindcss/oxide-freebsd-x64@4.1.17": { + "integrity": "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==", + "os": ["freebsd"], + "cpu": ["x64"] + }, + "@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17": { + "integrity": "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==", + "os": ["linux"], + "cpu": ["arm"] + }, + "@tailwindcss/oxide-linux-arm64-gnu@4.1.17": { + "integrity": "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==", + "os": ["linux"], + "cpu": ["arm64"] + }, + "@tailwindcss/oxide-linux-arm64-musl@4.1.17": { + "integrity": "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==", + "os": ["linux"], + "cpu": ["arm64"] + }, + "@tailwindcss/oxide-linux-x64-gnu@4.1.17": { + "integrity": "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==", + "os": ["linux"], + "cpu": ["x64"] + }, + "@tailwindcss/oxide-linux-x64-musl@4.1.17": { + "integrity": "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==", + "os": ["linux"], + "cpu": ["x64"] + }, + "@tailwindcss/oxide-wasm32-wasi@4.1.17": { + "integrity": "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==", + "cpu": ["wasm32"] + }, + "@tailwindcss/oxide-win32-arm64-msvc@4.1.17": { + "integrity": "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==", + "os": ["win32"], + "cpu": ["arm64"] + }, + "@tailwindcss/oxide-win32-x64-msvc@4.1.17": { + "integrity": "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw==", + "os": ["win32"], + "cpu": ["x64"] + }, + "@tailwindcss/oxide@4.1.17": { + "integrity": "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA==", + "optionalDependencies": [ + "@tailwindcss/oxide-android-arm64", + "@tailwindcss/oxide-darwin-arm64", + "@tailwindcss/oxide-darwin-x64", + "@tailwindcss/oxide-freebsd-x64", + "@tailwindcss/oxide-linux-arm-gnueabihf", + "@tailwindcss/oxide-linux-arm64-gnu", + "@tailwindcss/oxide-linux-arm64-musl", + "@tailwindcss/oxide-linux-x64-gnu", + "@tailwindcss/oxide-linux-x64-musl", + "@tailwindcss/oxide-wasm32-wasi", + "@tailwindcss/oxide-win32-arm64-msvc", + "@tailwindcss/oxide-win32-x64-msvc" + ] + }, + "@tailwindcss/typography@0.5.19_tailwindcss@4.1.17": { + "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==", + "dependencies": [ + "postcss-selector-parser@6.0.10", + "tailwindcss" + ] + }, + "@tailwindcss/vite@4.1.17_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1": { + "integrity": "sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA==", + "dependencies": [ + "@tailwindcss/node", + "@tailwindcss/oxide", + "tailwindcss", + "vite" + ] + }, + "@types/cookie@0.6.0": { + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, + "@types/estree@1.0.8": { + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" + }, + "@types/json-schema@7.0.15": { + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "@types/node@22.19.1": { + "integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==", + "dependencies": [ + "undici-types" + ] + }, + "@types/resolve@1.20.2": { + "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" + }, + "@typescript-eslint/eslint-plugin@8.48.0_@typescript-eslint+parser@8.48.0__eslint@9.39.1__typescript@5.9.3_eslint@9.39.1_typescript@5.9.3": { + "integrity": "sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==", + "dependencies": [ + "@eslint-community/regexpp", + "@typescript-eslint/parser", + "@typescript-eslint/scope-manager", + "@typescript-eslint/type-utils", + "@typescript-eslint/utils", + "@typescript-eslint/visitor-keys", + "eslint", + "graphemer", + "ignore@7.0.5", + "natural-compare", + "ts-api-utils", + "typescript" + ] + }, + "@typescript-eslint/parser@8.48.0_eslint@9.39.1_typescript@5.9.3": { + "integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==", + "dependencies": [ + "@typescript-eslint/scope-manager", + "@typescript-eslint/types", + "@typescript-eslint/typescript-estree", + "@typescript-eslint/visitor-keys", + "debug", + "eslint", + "typescript" + ] + }, + "@typescript-eslint/project-service@8.48.0_typescript@5.9.3": { + "integrity": "sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==", + "dependencies": [ + "@typescript-eslint/tsconfig-utils", + "@typescript-eslint/types", + "debug", + "typescript" + ] + }, + "@typescript-eslint/scope-manager@8.48.0": { + "integrity": "sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==", + "dependencies": [ + "@typescript-eslint/types", + "@typescript-eslint/visitor-keys" + ] + }, + "@typescript-eslint/tsconfig-utils@8.48.0_typescript@5.9.3": { + "integrity": "sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==", + "dependencies": [ + "typescript" + ] + }, + "@typescript-eslint/type-utils@8.48.0_eslint@9.39.1_typescript@5.9.3": { + "integrity": "sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==", + "dependencies": [ + "@typescript-eslint/types", + "@typescript-eslint/typescript-estree", + "@typescript-eslint/utils", + "debug", + "eslint", + "ts-api-utils", + "typescript" + ] + }, + "@typescript-eslint/types@8.48.0": { + "integrity": "sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==" + }, + "@typescript-eslint/typescript-estree@8.48.0_typescript@5.9.3": { + "integrity": "sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==", + "dependencies": [ + "@typescript-eslint/project-service", + "@typescript-eslint/tsconfig-utils", + "@typescript-eslint/types", + "@typescript-eslint/visitor-keys", + "debug", + "minimatch@9.0.5", + "semver", + "tinyglobby", + "ts-api-utils", + "typescript" + ] + }, + "@typescript-eslint/utils@8.48.0_eslint@9.39.1_typescript@5.9.3": { + "integrity": "sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==", + "dependencies": [ + "@eslint-community/eslint-utils", + "@typescript-eslint/scope-manager", + "@typescript-eslint/types", + "@typescript-eslint/typescript-estree", + "eslint", + "typescript" + ] + }, + "@typescript-eslint/visitor-keys@8.48.0": { + "integrity": "sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==", + "dependencies": [ + "@typescript-eslint/types", + "eslint-visitor-keys@4.2.1" + ] + }, + "acorn-jsx@5.3.2_acorn@8.15.0": { + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dependencies": [ + "acorn" + ] + }, + "acorn@8.15.0": { + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "bin": true + }, + "ajv@6.12.6": { + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": [ + "fast-deep-equal", + "fast-json-stable-stringify", + "json-schema-traverse", + "uri-js" + ] + }, + "ansi-styles@4.3.0": { + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": [ + "color-convert" + ] + }, + "argparse@2.0.1": { + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "aria-query@5.3.2": { + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==" + }, + "axobject-query@4.1.0": { + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==" + }, + "balanced-match@1.0.2": { + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion@1.1.12": { + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dependencies": [ + "balanced-match", + "concat-map" + ] + }, + "brace-expansion@2.0.2": { + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dependencies": [ + "balanced-match" + ] + }, + "callsites@3.1.0": { + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "chalk@4.1.2": { + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": [ + "ansi-styles", + "supports-color" + ] + }, + "chokidar@4.0.3": { + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dependencies": [ + "readdirp" + ] + }, + "clsx@2.1.1": { + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" + }, + "color-convert@2.0.1": { + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": [ + "color-name" + ] + }, + "color-name@1.1.4": { + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "commondir@1.0.1": { + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "concat-map@0.0.1": { + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "cookie@0.6.0": { + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" + }, + "cross-spawn@7.0.6": { + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dependencies": [ + "path-key", + "shebang-command", + "which" + ] + }, + "cssesc@3.0.0": { + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": true + }, + "daisyui@5.5.5": { + "integrity": "sha512-ekvI93ZkWIJoCOtDl0D2QMxnWvTejk9V5nWBqRv+7t0xjiBXqAK5U6o6JE2RPvlIC3EqwNyUoIZSdHX9MZK3nw==" + }, + "debug@4.4.3": { + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dependencies": [ + "ms" + ] + }, + "deep-is@0.1.4": { + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "deepmerge@4.3.1": { + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" + }, + "detect-libc@2.1.2": { + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==" + }, + "devalue@5.5.0": { + "integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==" + }, + "enhanced-resolve@5.18.3": { + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "dependencies": [ + "graceful-fs", + "tapable" + ] + }, + "esbuild@0.25.12": { + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "optionalDependencies": [ + "@esbuild/aix-ppc64", + "@esbuild/android-arm", + "@esbuild/android-arm64", + "@esbuild/android-x64", + "@esbuild/darwin-arm64", + "@esbuild/darwin-x64", + "@esbuild/freebsd-arm64", + "@esbuild/freebsd-x64", + "@esbuild/linux-arm", + "@esbuild/linux-arm64", + "@esbuild/linux-ia32", + "@esbuild/linux-loong64", + "@esbuild/linux-mips64el", + "@esbuild/linux-ppc64", + "@esbuild/linux-riscv64", + "@esbuild/linux-s390x", + "@esbuild/linux-x64", + "@esbuild/netbsd-arm64", + "@esbuild/netbsd-x64", + "@esbuild/openbsd-arm64", + "@esbuild/openbsd-x64", + "@esbuild/openharmony-arm64", + "@esbuild/sunos-x64", + "@esbuild/win32-arm64", + "@esbuild/win32-ia32", + "@esbuild/win32-x64" + ], + "scripts": true, + "bin": true + }, + "escape-string-regexp@4.0.0": { + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "eslint-plugin-svelte@3.13.0_eslint@9.39.1_svelte@5.44.1__acorn@8.15.0_postcss@8.5.6": { + "integrity": "sha512-2ohCCQJJTNbIpQCSDSTWj+FN0OVfPmSO03lmSNT7ytqMaWF6kpT86LdzDqtm4sh7TVPl/OEWJ/d7R87bXP2Vjg==", + "dependencies": [ + "@eslint-community/eslint-utils", + "@jridgewell/sourcemap-codec", + "eslint", + "esutils", + "globals@16.5.0", + "known-css-properties", + "postcss", + "postcss-load-config", + "postcss-safe-parser", + "semver", + "svelte", + "svelte-eslint-parser" + ], + "optionalPeers": [ + "svelte" + ] + }, + "eslint-scope@8.4.0": { + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dependencies": [ + "esrecurse", + "estraverse" + ] + }, + "eslint-visitor-keys@3.4.3": { + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==" + }, + "eslint-visitor-keys@4.2.1": { + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==" + }, + "eslint@9.39.1": { + "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", + "dependencies": [ + "@eslint-community/eslint-utils", + "@eslint-community/regexpp", + "@eslint/config-array", + "@eslint/config-helpers", + "@eslint/core", + "@eslint/eslintrc", + "@eslint/js", + "@eslint/plugin-kit", + "@humanfs/node", + "@humanwhocodes/module-importer", + "@humanwhocodes/retry", + "@types/estree", + "ajv", + "chalk", + "cross-spawn", + "debug", + "escape-string-regexp", + "eslint-scope", + "eslint-visitor-keys@4.2.1", + "espree", + "esquery", + "esutils", + "fast-deep-equal", + "file-entry-cache", + "find-up", + "glob-parent", + "ignore@5.3.2", + "imurmurhash", + "is-glob", + "json-stable-stringify-without-jsonify", + "lodash.merge", + "minimatch@3.1.2", + "natural-compare", + "optionator" + ], + "bin": true + }, + "esm-env@1.2.2": { + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==" + }, + "espree@10.4.0_acorn@8.15.0": { + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dependencies": [ + "acorn", + "acorn-jsx", + "eslint-visitor-keys@4.2.1" + ] + }, + "esquery@1.6.0": { + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dependencies": [ + "estraverse" + ] + }, + "esrap@2.2.0": { + "integrity": "sha512-WBmtxe7R9C5mvL4n2le8nMUe4mD5V9oiK2vJpQ9I3y20ENPUomPcphBXE8D1x/Bm84oN1V+lOfgXxtqmxTp3Xg==", + "dependencies": [ + "@jridgewell/sourcemap-codec" + ] + }, + "esrecurse@4.3.0": { + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dependencies": [ + "estraverse" + ] + }, + "estraverse@5.3.0": { + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" + }, + "estree-walker@2.0.2": { + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "esutils@2.0.3": { + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "fast-deep-equal@3.1.3": { + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify@2.1.0": { + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "fast-levenshtein@2.0.6": { + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + }, + "fdir@6.5.0_picomatch@4.0.3": { + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dependencies": [ + "picomatch" + ], + "optionalPeers": [ + "picomatch" + ] + }, + "file-entry-cache@8.0.0": { + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dependencies": [ + "flat-cache" + ] + }, + "find-up@5.0.0": { + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dependencies": [ + "locate-path", + "path-exists" + ] + }, + "flat-cache@4.0.1": { + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dependencies": [ + "flatted", + "keyv" + ] + }, + "flatted@3.3.3": { + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==" + }, + "fsevents@2.3.3": { + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "os": ["darwin"], + "scripts": true + }, + "function-bind@1.1.2": { + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "glob-parent@6.0.2": { + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": [ + "is-glob" + ] + }, + "globals@14.0.0": { + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==" + }, + "globals@16.5.0": { + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==" + }, + "graceful-fs@4.2.11": { + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "graphemer@1.4.0": { + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" + }, + "has-flag@4.0.0": { + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "hasown@2.0.2": { + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": [ + "function-bind" + ] + }, + "ignore@5.3.2": { + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==" + }, + "ignore@7.0.5": { + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==" + }, + "import-fresh@3.3.1": { + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dependencies": [ + "parent-module", + "resolve-from" + ] + }, + "imurmurhash@0.1.4": { + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" + }, + "is-core-module@2.16.1": { + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dependencies": [ + "hasown" + ] + }, + "is-extglob@2.1.1": { + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob@4.0.3": { + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": [ + "is-extglob" + ] + }, + "is-module@1.0.0": { + "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" + }, + "is-reference@1.2.1": { + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", + "dependencies": [ + "@types/estree" + ] + }, + "is-reference@3.0.3": { + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "dependencies": [ + "@types/estree" + ] + }, + "isexe@2.0.0": { + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "jiti@2.6.1": { + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "bin": true + }, + "js-yaml@4.1.1": { + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dependencies": [ + "argparse" + ], + "bin": true + }, + "json-buffer@3.0.1": { + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "json-schema-traverse@0.4.1": { + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify-without-jsonify@1.0.1": { + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + }, + "keyv@4.5.4": { + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dependencies": [ + "json-buffer" + ] + }, + "kleur@4.1.5": { + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==" + }, + "known-css-properties@0.37.0": { + "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==" + }, + "levn@0.4.1": { + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dependencies": [ + "prelude-ls", + "type-check" + ] + }, + "lightningcss-android-arm64@1.30.2": { + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "os": ["android"], + "cpu": ["arm64"] + }, + "lightningcss-darwin-arm64@1.30.2": { + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "os": ["darwin"], + "cpu": ["arm64"] + }, + "lightningcss-darwin-x64@1.30.2": { + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "os": ["darwin"], + "cpu": ["x64"] + }, + "lightningcss-freebsd-x64@1.30.2": { + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "os": ["freebsd"], + "cpu": ["x64"] + }, + "lightningcss-linux-arm-gnueabihf@1.30.2": { + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "os": ["linux"], + "cpu": ["arm"] + }, + "lightningcss-linux-arm64-gnu@1.30.2": { + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "os": ["linux"], + "cpu": ["arm64"] + }, + "lightningcss-linux-arm64-musl@1.30.2": { + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "os": ["linux"], + "cpu": ["arm64"] + }, + "lightningcss-linux-x64-gnu@1.30.2": { + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "os": ["linux"], + "cpu": ["x64"] + }, + "lightningcss-linux-x64-musl@1.30.2": { + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "os": ["linux"], + "cpu": ["x64"] + }, + "lightningcss-win32-arm64-msvc@1.30.2": { + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "os": ["win32"], + "cpu": ["arm64"] + }, + "lightningcss-win32-x64-msvc@1.30.2": { + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "os": ["win32"], + "cpu": ["x64"] + }, + "lightningcss@1.30.2": { + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "dependencies": [ + "detect-libc" + ], + "optionalDependencies": [ + "lightningcss-android-arm64", + "lightningcss-darwin-arm64", + "lightningcss-darwin-x64", + "lightningcss-freebsd-x64", + "lightningcss-linux-arm-gnueabihf", + "lightningcss-linux-arm64-gnu", + "lightningcss-linux-arm64-musl", + "lightningcss-linux-x64-gnu", + "lightningcss-linux-x64-musl", + "lightningcss-win32-arm64-msvc", + "lightningcss-win32-x64-msvc" + ] + }, + "lilconfig@2.1.0": { + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==" + }, + "locate-character@3.0.0": { + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" + }, + "locate-path@6.0.0": { + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dependencies": [ + "p-locate" + ] + }, + "lodash.merge@4.6.2": { + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "magic-string@0.30.21": { + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dependencies": [ + "@jridgewell/sourcemap-codec" + ] + }, + "mini-svg-data-uri@1.4.4": { + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "bin": true + }, + "minimatch@3.1.2": { + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": [ + "brace-expansion@1.1.12" + ] + }, + "minimatch@9.0.5": { + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": [ + "brace-expansion@2.0.2" + ] + }, + "mri@1.2.0": { + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" + }, + "mrmime@2.0.1": { + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==" + }, + "ms@2.1.3": { + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "nanoid@3.3.11": { + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "bin": true + }, + "natural-compare@1.4.0": { + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" + }, + "optionator@0.9.4": { + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dependencies": [ + "deep-is", + "fast-levenshtein", + "levn", + "prelude-ls", + "type-check", + "word-wrap" + ] + }, + "p-limit@3.1.0": { + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dependencies": [ + "yocto-queue" + ] + }, + "p-locate@5.0.0": { + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dependencies": [ + "p-limit" + ] + }, + "parent-module@1.0.1": { + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": [ + "callsites" + ] + }, + "path-exists@4.0.0": { + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-key@3.1.1": { + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "path-parse@1.0.7": { + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "picocolors@1.1.1": { + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "picomatch@4.0.3": { + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==" + }, + "postcss-load-config@3.1.4_postcss@8.5.6": { + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dependencies": [ + "lilconfig", + "postcss", + "yaml" + ], + "optionalPeers": [ + "postcss" + ] + }, + "postcss-safe-parser@7.0.1_postcss@8.5.6": { + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", + "dependencies": [ + "postcss" + ] + }, + "postcss-scss@4.0.9_postcss@8.5.6": { + "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", + "dependencies": [ + "postcss" + ] + }, + "postcss-selector-parser@6.0.10": { + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dependencies": [ + "cssesc", + "util-deprecate" + ] + }, + "postcss-selector-parser@7.1.0": { + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "dependencies": [ + "cssesc", + "util-deprecate" + ] + }, + "postcss@8.5.6": { + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dependencies": [ + "nanoid", + "picocolors", + "source-map-js" + ] + }, + "prelude-ls@1.2.1": { + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, + "prettier-plugin-svelte@3.4.0_prettier@3.7.4_svelte@5.44.1__acorn@8.15.0": { + "integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==", + "dependencies": [ + "prettier", + "svelte" + ] + }, + "prettier@3.7.4": { + "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", + "bin": true + }, + "punycode@2.3.1": { + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" + }, + "readdirp@4.1.2": { + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==" + }, + "resolve-from@4.0.0": { + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "resolve@1.22.11": { + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dependencies": [ + "is-core-module", + "path-parse", + "supports-preserve-symlinks-flag" + ], + "bin": true + }, + "rollup@4.53.3": { + "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", + "dependencies": [ + "@types/estree" + ], + "optionalDependencies": [ + "@rollup/rollup-android-arm-eabi", + "@rollup/rollup-android-arm64", + "@rollup/rollup-darwin-arm64", + "@rollup/rollup-darwin-x64", + "@rollup/rollup-freebsd-arm64", + "@rollup/rollup-freebsd-x64", + "@rollup/rollup-linux-arm-gnueabihf", + "@rollup/rollup-linux-arm-musleabihf", + "@rollup/rollup-linux-arm64-gnu", + "@rollup/rollup-linux-arm64-musl", + "@rollup/rollup-linux-loong64-gnu", + "@rollup/rollup-linux-ppc64-gnu", + "@rollup/rollup-linux-riscv64-gnu", + "@rollup/rollup-linux-riscv64-musl", + "@rollup/rollup-linux-s390x-gnu", + "@rollup/rollup-linux-x64-gnu", + "@rollup/rollup-linux-x64-musl", + "@rollup/rollup-openharmony-arm64", + "@rollup/rollup-win32-arm64-msvc", + "@rollup/rollup-win32-ia32-msvc", + "@rollup/rollup-win32-x64-gnu", + "@rollup/rollup-win32-x64-msvc", + "fsevents" + ], + "bin": true + }, + "sade@1.8.1": { + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": [ + "mri" + ] + }, + "semver@7.7.3": { + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "bin": true + }, + "set-cookie-parser@2.7.2": { + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==" + }, + "shebang-command@2.0.0": { + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": [ + "shebang-regex" + ] + }, + "shebang-regex@3.0.0": { + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "sirv@3.0.2": { + "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", + "dependencies": [ + "@polka/url", + "mrmime", + "totalist" + ] + }, + "source-map-js@1.2.1": { + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" + }, + "strip-json-comments@3.1.1": { + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "supports-color@7.2.0": { + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": [ + "has-flag" + ] + }, + "supports-preserve-symlinks-flag@1.0.0": { + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "svelte-check@4.3.4_svelte@5.44.1__acorn@8.15.0_typescript@5.9.3": { + "integrity": "sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw==", + "dependencies": [ + "@jridgewell/trace-mapping", + "chokidar", + "fdir", + "picocolors", + "sade", + "svelte", + "typescript" + ], + "bin": true + }, + "svelte-eslint-parser@1.4.0_svelte@5.44.1__acorn@8.15.0_postcss@8.5.6": { + "integrity": "sha512-fjPzOfipR5S7gQ/JvI9r2H8y9gMGXO3JtmrylHLLyahEMquXI0lrebcjT+9/hNgDej0H7abTyox5HpHmW1PSWA==", + "dependencies": [ + "eslint-scope", + "eslint-visitor-keys@4.2.1", + "espree", + "postcss", + "postcss-scss", + "postcss-selector-parser@7.1.0", + "svelte" + ], + "optionalPeers": [ + "svelte" + ] + }, + "svelte@5.44.1_acorn@8.15.0": { + "integrity": "sha512-8VnkRXpa6tJ9IqiwKvzZBNnBy9tZg0N63duDz0EJqiozsmBEAZfHiZzWWWAneIN+cAWkK1JkafW1xIbC4YrdBA==", + "dependencies": [ + "@jridgewell/remapping", + "@jridgewell/sourcemap-codec", + "@sveltejs/acorn-typescript", + "@types/estree", + "acorn", + "aria-query", + "axobject-query", + "clsx", + "devalue", + "esm-env", + "esrap", + "is-reference@3.0.3", + "locate-character", + "magic-string", + "zimmerframe" + ] + }, + "tailwindcss@4.1.17": { + "integrity": "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q==" + }, + "tapable@2.3.0": { + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==" + }, + "tinyglobby@0.2.15_picomatch@4.0.3": { + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dependencies": [ + "fdir", + "picomatch" + ] + }, + "totalist@3.0.1": { + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" + }, + "ts-api-utils@2.1.0_typescript@5.9.3": { + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dependencies": [ + "typescript" + ] + }, + "type-check@0.4.0": { + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dependencies": [ + "prelude-ls" + ] + }, + "typescript-eslint@8.48.0_eslint@9.39.1_typescript@5.9.3_@typescript-eslint+parser@8.48.0__eslint@9.39.1__typescript@5.9.3": { + "integrity": "sha512-fcKOvQD9GUn3Xw63EgiDqhvWJ5jsyZUaekl3KVpGsDJnN46WJTe3jWxtQP9lMZm1LJNkFLlTaWAxK2vUQR+cqw==", + "dependencies": [ + "@typescript-eslint/eslint-plugin", + "@typescript-eslint/parser", + "@typescript-eslint/typescript-estree", + "@typescript-eslint/utils", + "eslint", + "typescript" + ] + }, + "typescript@5.9.3": { + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "bin": true + }, + "undici-types@6.21.0": { + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" + }, + "uri-js@4.4.1": { + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": [ + "punycode" + ] + }, + "util-deprecate@1.0.2": { + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "vite@7.2.4_@types+node@22.19.1_picomatch@4.0.3": { + "integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==", + "dependencies": [ + "@types/node", + "esbuild", + "fdir", + "picomatch", + "postcss", + "rollup", + "tinyglobby" + ], + "optionalDependencies": [ + "fsevents" + ], + "optionalPeers": [ + "@types/node" + ], + "bin": true + }, + "vitefu@1.1.1_vite@7.2.4__@types+node@22.19.1__picomatch@4.0.3_@types+node@22.19.1": { + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", + "dependencies": [ + "vite" + ], + "optionalPeers": [ + "vite" + ] + }, + "which@2.0.2": { + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": [ + "isexe" + ], + "bin": true + }, + "word-wrap@1.2.5": { + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==" + }, + "yaml@1.10.2": { + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yocto-queue@0.1.0": { + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + }, + "zimmerframe@1.1.4": { + "integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==" + } + }, + "workspace": { + "packageJson": { + "dependencies": [ + "npm:@eslint/compat@^1.4.0", + "npm:@eslint/js@^9.39.1", + "npm:@sveltejs/adapter-node@^5.4.0", + "npm:@sveltejs/kit@^2.48.5", + "npm:@sveltejs/vite-plugin-svelte@^6.2.1", + "npm:@tailwindcss/forms@~0.5.10", + "npm:@tailwindcss/typography@~0.5.19", + "npm:@tailwindcss/vite@^4.1.17", + "npm:@types/node@22", + "npm:daisyui@^5.5.5", + "npm:eslint-plugin-svelte@^3.13.0", + "npm:eslint@^9.39.1", + "npm:globals@^16.5.0", + "npm:prettier-plugin-svelte@^3.4.0", + "npm:prettier@^3.7.4", + "npm:svelte-check@^4.3.4", + "npm:svelte@^5.43.8", + "npm:tailwindcss@^4.1.17", + "npm:typescript-eslint@^8.47.0", + "npm:typescript@^5.9.3", + "npm:vite@^7.2.2" + ] + } + } +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..5521184 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,41 @@ +import { fileURLToPath } from "node:url"; +import { includeIgnoreFile } from "@eslint/compat"; +import js from "@eslint/js"; +import svelte from "eslint-plugin-svelte"; +import { defineConfig } from "eslint/config"; +import globals from "globals"; +import ts from "typescript-eslint"; +import svelteConfig from "./svelte.config.js"; + +const gitignorePath = fileURLToPath(new URL("./.gitignore", import.meta.url)); + +export default defineConfig( + includeIgnoreFile(gitignorePath), + js.configs.recommended, + ...ts.configs.recommended, + ...svelte.configs.recommended, + { + languageOptions: { + globals: { ...globals.browser, ...globals.node }, + }, + rules: { // typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects. + // see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors + "no-undef": "off", + }, + }, + { + files: [ + "**/*.svelte", + "**/*.svelte.ts", + "**/*.svelte.js", + ], + languageOptions: { + parserOptions: { + projectService: true, + extraFileExtensions: [".svelte"], + parser: ts.parser, + svelteConfig, + }, + }, + }, +); diff --git a/package.json b/package.json new file mode 100644 index 0000000..870b3f9 --- /dev/null +++ b/package.json @@ -0,0 +1,40 @@ +{ + "name": "dns-frontend", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "prepare": "svelte-kit sync || echo ''", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "lint": "eslint ." + }, + "dependencies": { + "daisyui": "^5.5.5" + }, + "devDependencies": { + "@eslint/compat": "^1.4.0", + "@eslint/js": "^9.39.1", + "@sveltejs/adapter-node": "^5.4.0", + "@sveltejs/kit": "^2.48.5", + "@sveltejs/vite-plugin-svelte": "^6.2.1", + "@tailwindcss/forms": "^0.5.10", + "@tailwindcss/typography": "^0.5.19", + "@tailwindcss/vite": "^4.1.17", + "@types/node": "^22", + "eslint": "^9.39.1", + "eslint-plugin-svelte": "^3.13.0", + "globals": "^16.5.0", + "prettier": "^3.7.4", + "prettier-plugin-svelte": "^3.4.0", + "svelte": "^5.43.8", + "svelte-check": "^4.3.4", + "tailwindcss": "^4.1.17", + "typescript": "^5.9.3", + "typescript-eslint": "^8.47.0", + "vite": "^7.2.2" + } +} diff --git a/src/app.d.ts b/src/app.d.ts new file mode 100644 index 0000000..520c421 --- /dev/null +++ b/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://svelte.dev/docs/kit/types#app.d.ts +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/src/app.html b/src/app.html new file mode 100644 index 0000000..179941a --- /dev/null +++ b/src/app.html @@ -0,0 +1,11 @@ + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/src/lib/CollapsibleSubmenu.svelte b/src/lib/CollapsibleSubmenu.svelte new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/ErrorPopup.svelte b/src/lib/ErrorPopup.svelte new file mode 100644 index 0000000..fa3ce86 --- /dev/null +++ b/src/lib/ErrorPopup.svelte @@ -0,0 +1,33 @@ + + +{#if visible} + +{/if} diff --git a/src/lib/MainNavbar.svelte b/src/lib/MainNavbar.svelte new file mode 100644 index 0000000..0a9d3ea --- /dev/null +++ b/src/lib/MainNavbar.svelte @@ -0,0 +1,87 @@ + + + diff --git a/src/lib/Record.svelte b/src/lib/Record.svelte new file mode 100644 index 0000000..42449f9 --- /dev/null +++ b/src/lib/Record.svelte @@ -0,0 +1,261 @@ + + +td]:bg-base-100' : '[&>td]:bg-base-200' + }` + } +> + + {record.record_type} + + {record.name || '@'} + {record.value} + {record.ttl} + {record.comment || '-'} + + {#if record.is_active} + Active + {:else} + Inactive + {/if} + + + {#if isEdit} + + {:else} + + {/if} + + +{#if isEdit} + + +
+
+
+ +
{error}
+
+ + {#if record.record_type === 'MX'} +
+ +
{error}
+
+ {/if} + + {#if record.record_type === 'SRV'} +
+ +
{error}
+
+
+ +
{error}
+
+
+ +
{error}
+
+ {/if} + +
+ +
{error}
+
+
+
+ +
+ +
{error}
+
+
+ +
+ + + +
+
+ + {#if errorMessage} +
+ +
+ {/if} + + + +{/if} diff --git a/src/lib/RecordExplanation.svelte b/src/lib/RecordExplanation.svelte new file mode 100644 index 0000000..4f17dd2 --- /dev/null +++ b/src/lib/RecordExplanation.svelte @@ -0,0 +1,108 @@ + + +
+ {#if recordType === 'A' || recordType === 'AAAA'} + + {#if name} + {displayName} + {:else} + {displayName} + {/if}{fqdn} + points to + + {#if value} + {displayValue} + {:else} + {displayValue} + {/if} + {:else if recordType === 'CNAME'} + + {#if name} + {displayName} + {:else} + {displayName} + {/if}{fqdn} + redirects to + + {#if value} + {displayValue} + {:else} + {displayValue} + {/if} + {:else if recordType === 'NS'} + + {#if name} + {displayName} + {:else} + {displayName} + {/if}{fqdn} + has the nameserver + + {#if value} + {displayValue} + {:else} + {displayValue} + {/if} + {:else if recordType === 'CNAME'} + + {#if name} + {displayName} + {:else} + {displayName} + {/if}{fqdn} + redirects to + + {#if value} + {displayValue} + {:else} + {displayValue} + {/if} + {:else if recordType === 'MX'} + + {#if name} + {displayName} + {:else} + {displayName} + {/if}{fqdn} + has the mailserver + + {#if value} + {displayValue} + {:else} + {displayValue} + {/if} + {:else if recordType === 'SRV'} + A service of + + {#if name} + {displayName} + {:else} + {displayName} + {/if}{fqdn} + is hosted at + + {#if value} + {displayValue} + {:else} + {displayValue} + {/if} + {:else if recordType === 'TXT'} + + {#if name} + {displayName} + {:else} + {displayName} + {/if}{fqdn} + has the content + + {#if value} + {displayValue} + {:else} + {displayValue} + {/if} + {:else} + Unknown record type + {/if} +
\ No newline at end of file diff --git a/src/lib/SideMenu.svelte b/src/lib/SideMenu.svelte new file mode 100644 index 0000000..2512d05 --- /dev/null +++ b/src/lib/SideMenu.svelte @@ -0,0 +1,35 @@ + + + \ No newline at end of file diff --git a/src/lib/api.ts b/src/lib/api.ts new file mode 100644 index 0000000..8edde53 --- /dev/null +++ b/src/lib/api.ts @@ -0,0 +1,21 @@ +import { goto } from "$app/navigation"; +import { setUserLoggedOut } from "./auth.svelte.ts"; + +export async function get_request(url: string): Promise { + try { + let res: Response = await fetch(url, { + credentials: "include", + }); + + if (res.status === 401) { + throw new Error("Unauthorized"); + } + + return res.json() as Promise; + } catch (err) { + console.log(err); + setUserLoggedOut(); + goto("/login"); + throw err; + } +} diff --git a/src/lib/assets/favicon.svg b/src/lib/assets/favicon.svg new file mode 100644 index 0000000..75846c2 --- /dev/null +++ b/src/lib/assets/favicon.svg @@ -0,0 +1,14 @@ + + svelte-logo + diff --git a/src/lib/auth.svelte.ts b/src/lib/auth.svelte.ts new file mode 100644 index 0000000..9705226 --- /dev/null +++ b/src/lib/auth.svelte.ts @@ -0,0 +1,40 @@ +import { PUBLIC_BACKEND_API_HOST } from "$env/static/public"; + +interface Auth { + isAuthenticated: boolean; + isMfaEnabled?: boolean; + userEmail?: string; +} + +export let auth = $state({ + isAuthenticated: false, +}); + +// Call upon app startup. Makes a GET request to /user/me to check if the session token is present/valid +export async function initUserAuthStatus() { + try { + const res = await fetch(PUBLIC_BACKEND_API_HOST + "/api/v1/user/me", { + method: "GET", + }); + + if (res.status === 401) { + setUserLoggedOut(); + } else if (res.status === 200) { + const data = await res.json(); + + auth.isAuthenticated = true; + auth.isMfaEnabled = data.mfa_enabled ?? false; + auth.userEmail = data.email ?? "error-email@example.com"; + } else { + console.log(`Unexpected response from server: ${res.status}`); + } + } catch (error) { + console.log("unexpected error: ", error); + } +} + +export function setUserLoggedOut() { + auth.isAuthenticated = false; + auth.isMfaEnabled = undefined; + auth.userEmail = undefined; +} diff --git a/src/lib/domains.svelte.ts b/src/lib/domains.svelte.ts new file mode 100644 index 0000000..36454ef --- /dev/null +++ b/src/lib/domains.svelte.ts @@ -0,0 +1,82 @@ +import { PUBLIC_BACKEND_API_HOST } from "$env/static/public"; + +export type Subdomain = { + id: string; + domain: string; + name: string; +}; + +export type BaseDomain = { + id: string; + domain: string; +}; + +interface Domains { + loadingBaseDomains: boolean; + loadingSubdomains: boolean; + subdomains: Subdomain[]; + subdomainsFromId: Record, + baseDomains: BaseDomain[]; + loadingFailed: boolean; +} + +export let domains = $state({ + loadingBaseDomains: true, + loadingSubdomains: true, + subdomains: [], + subdomainsFromId: {}, + baseDomains: [], + loadingFailed: false, +}); + +export async function clearSubdomains() { + domains.subdomains = []; + domains.loadingFailed = false; + domains.loadingSubdomains = true; +} + + +export async function getSubdomains() { + try { + const res = await fetch( + `${PUBLIC_BACKEND_API_HOST}/api/v1/subdomain` + ); + const data = await res.json(); + if (!res.ok) { + throw new Error(data?.msg || "Failed to load subdomains"); + } + domains.subdomains = data + .slice() + .sort((a: { id: string; }, b: { id: any; }) => a.id.localeCompare(b.id)); + + for (const sub of domains.subdomains) { + domains.subdomainsFromId[sub.id] = sub; + } + + } catch (err) { + console.error(err); + domains.loadingFailed = true; + } finally { + domains.loadingSubdomains = false; + } +}; + +export async function getBaseDomains() { + try { + const res = await fetch( + `${PUBLIC_BACKEND_API_HOST}/api/v1/subdomain/domains` + ); + const data = await res.json(); + if (!res.ok) { + throw new Error(data?.msg || "Failed to load base domains"); + } + domains.baseDomains = data + .slice() + .sort((a: { id: string; }, b: { id: any; }) => a.id.localeCompare(b.id)); + } catch (err) { + console.error(err); + domains.loadingFailed = true; + } finally { + domains.loadingBaseDomains = false; + } +}; diff --git a/src/lib/index.ts b/src/lib/index.ts new file mode 100644 index 0000000..856f2b6 --- /dev/null +++ b/src/lib/index.ts @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/src/lib/records.svelte.ts b/src/lib/records.svelte.ts new file mode 100644 index 0000000..178a35b --- /dev/null +++ b/src/lib/records.svelte.ts @@ -0,0 +1,175 @@ +import { PUBLIC_BACKEND_API_HOST } from '$env/static/public'; + +export interface DnsRecord { + id: string; + name: string; + record_type: string; + value: string; + ttl: number; + comment: string; + is_active: boolean; + priority?: number; + weight?: number; + port?: number; +} + +export interface RecordsResponse { + msg: string; + records: DnsRecord[]; +} + +export async function fetchRecords( + subdomainId: string +): Promise { + const res = await fetch( + `${PUBLIC_BACKEND_API_HOST}/api/v1/record/${subdomainId}` + ); + + if (!res.ok) { + throw new Error('Failed to fetch records'); + } + + return res.json(); +} + +export function getValueTitleText(type: string) { + switch (type) { + case 'A': return 'IPv4 address' + case 'AAAA': return 'IPv6 address' + case 'CNAME': return 'Target' + case 'NS': return 'Nameserver' + case 'MX': return 'Mailserver' + case 'SRV': return 'Target' + case 'TXT': return 'Content' + } +} + +export function getNamePlaceholderText(type: string) { + switch (type) { + case 'A': return 'example' + case 'AAAA': return 'example' + case 'CNAME': return 'www' + case 'NS': return 'example' + case 'MX': return 'example' + case 'SRV': return '_service._proto' + case 'TXT': return 'example' + } +} + +export function getValuePlaceholderText(type: string) { + switch (type) { + case 'A': return '198.51.100.51' + case 'AAAA': return 'fd40:7d1d:b637::' + case 'CNAME': return 'example.com' + case 'NS': return 'ns.example.com' + case 'MX': return 'mx.example.com' + case 'SRV': return 'example.com' + case 'TXT': return 'v=spf1 mx -all' + } +} + +export function getDisplayName(type: string, name: string) { + if (!name) { + return `${getNamePlaceholderText(type)}.`; + } + + if (name === "@") { + return ''; + } else { + return `${name}.` + } +} + +export function getDisplayValue(type: string, value: string, fqdn: string) { + if (!value) { + return `${getValuePlaceholderText(type)}`; + } + + if (value === "@" && (type === 'MX' || type === 'CNAME' || type === 'NS')) { + return fqdn; + } + + return value; +} + +export function isRecordValid( + recordType: string, + name: string, + value: string, + priority: number, + weight: number, + port: number, + comment: string, + ttl: number +): string { + if (comment.length >= 255) { + return 'The comment length must not exceed 255 characters' + } + + if (ttl < 30 || ttl > 2147483647) { + return 'The TTL must not be below 30 and above 2147483647' + } + + if (!name.match(/^[a-zA-Z0-9-_.]+$/) && name !== '@') { + return 'Invalid record name'; + } + + switch (recordType) { + case 'A': + if (!value.match(/^(?:\d{1,3}\.){3}\d{1,3}$/)) { + return 'Invalid IPv4 address'; + } + break; + case 'AAAA': + if (!value.match(/^[0-9a-fA-F:]+$/)) { + return 'Invalid IPv6 address'; + } + break; + case 'CNAME': + case 'NS': + if (!value.match(/^[a-zA-Z0-9.-]+$/) && name === '@') { + return 'Target must be a fully qualified domain name'; + } + break; + case 'MX': + if (priority < 0) { + return 'MX records require a non-negative priority'; + } + break; + case 'SRV': + if (priority < 0 || weight < 0 || port < 0 || + priority > 65535 || weight > 65535 || port > 65535 + ) { + return 'Priority, weight, and port must be in the range of 0-65535'; + } + break; + case 'TXT': + if (value.length === 0 || value.length > 255) { + return 'The content of the TXT record must not exceed 255 characters'; + } + break; + } + return ''; +} + +// Makes sure to update/replace records which have been implicitly updated by either a TTL change or have been created +// Find all records with the same name and type, delete them, insert the records from the API response +export function handleUiRecordUpdates(oldRecords: DnsRecord[], data: any): DnsRecord[] { + let records = oldRecords.filter((rec) => rec.record_type !== data.type || rec.name !== data.name); + for (let rec of data.records) { + let newRecord: DnsRecord = { + id: rec.id, + name: data.name, + record_type: data.type, + value: rec.value, + ttl: data.ttl, + comment: rec.comment, + is_active: rec.is_active, + priority: rec.priority, + weight: rec.weight, + port: rec.port, + }; + records.push(newRecord); + } + return records.sort((a, b) => (a.id > b.id ? -1 : 1)); +} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..7f793a6 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,39 @@ + + + + + + +
+ +
+ {#if auth.isAuthenticated} + + + {/if} +
+ {@render children()} +
+
+
\ No newline at end of file diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte new file mode 100644 index 0000000..9977a25 --- /dev/null +++ b/src/routes/+page.svelte @@ -0,0 +1,272 @@ + + + + + + + + + + + + +
+ +
+ Start using today! +
+

Let's manage the backbone of every website - DNS

+

Our platform helps you manage DNS and DynDNS - so you can focus on what really matters.

+
+ + + +
+
+ +
+
dig example.hexname.com
+ + + + +
;; QUESTION SECTION:
+
;example.hexname.com.            IN      A
+

+
;; ANSWER SECTION:
+
example.hexname.com.     300     IN      A       198.51.100.51
+
;; Query time: 57 msec
+
;; SERVER: 9.9.9.9#53(9.9.9.9) (UDP)
+ + +
+
+
+
+
+

+ Our DNS services +

+

Register our premium subdomains and manage + A, + AAAA, + TXT, + CNAME, + MX, + NS, + SRV + records.

+
+
+
+ Prompt engineers +
+

Prompt engineers

+

Bridging the gap between human intent and machine understanding through expert prompt design.

+
+
+
+ Data scientists +
+

Data scientists

+

Turning data into actionable insights that drive intelligent innovation and growth.

+
+
+
+ Software engineers +
+

Software engineers

+

Building scalable and efficient systems that bring ideas to life through code.

+
+
+
+
+
+
+

+ About our apps +

+

A visual collection of our most recent works - each piece crafted with intention, emotion, and style.

+
+
+
+
+
+

Lightning-Fast Performance

+

Built with speed — minimal load times and optimized.

+
+
+
+
+
+

Beautifully Designed Components

+

Modern, pixel-perfect UI components ready for any project.

+
+
+
+
+
+

Plug-and-Play Integration

+

Simple setup with support for React, Next.js and Tailwind css.

+
+
+
+
+
+
+

+ Our testimonials +

+

A visual collection of our most recent works - each piece crafted with intention, emotion, and style.

+
+
+
+

Super clean and easy to use. These Tailwind + React components saved me hours of dev time!

+
+ user image +
+

Richard Nelson

+

AI Content Marketer

+
+
+
+
+

The design quality is top-notch. Perfect balance between simplicity and style. Highly recommend!

+
+ user image +
+

Sophia Martinez

+

UI/UX Designer

+
+
+
+
+

Absolutely love the reusability of these components. My workflow feels 10x faster now.

+
+ user image +
+

Ethan Roberts

+

Frontend Developer

+
+
+
+
+

Clean, elegant, and efficient. These components are a dream for any modern web developer.

+
+ user image +
+

Isabella Kim

+

Product Designer

+
+
+
+
+

I've tried dozens of UI kits, but this one just feels right. Everything works seamlessly.

+
+ user image +
+

Liam Johnson

+

Software Engineer

+
+
+
+
+

Brilliantly structured components with clean, modern styling. Makes development a joy!

+
+ user image +
+

Ava Patel

+

Full Stack Developer

+
+
+
+
+
+
+
+

+ Trusted companies +

+

A visual collection of our most recent works - each piece crafted with intention, emotion, and style.

+
+
+
+
+
+ + NEW +

+ Try 30 days free trial option + + + +

+
+

Trusted by leading companies.

+

Built to integrate effortlessly with your existing tools, frameworks and workflows — so you can move faster.

+ +
+
+
+
+
+
+

+ Get in touch +

+

A visual collection of our most recent works - each piece crafted with intention, emotion, and style.

+
+
+
+
+
+ +
+
+
+
+

+ Subscribe newsletter +

+

A visual collection of our most recent works - each piece crafted with intention, emotion, and style.

+
+
+
+ + + diff --git a/src/routes/about/+page.svelte b/src/routes/about/+page.svelte new file mode 100644 index 0000000..9225e59 --- /dev/null +++ b/src/routes/about/+page.svelte @@ -0,0 +1,44 @@ +
+
+ +
+
+
+
Question?
+
Answering...
+
Done!
+
+
+

Our mission

+
+ We saw that the available solutions for free DNS management as well as DDNS were lackluster. + We thought that this was unacceptable, and decided to create the simplest solution for managing your DNS records, with more freedom than anyone on the market. +
+ Get started +
+
+
+ +
+

About the team

+ HexName was developed by a team of passionate tech-enthusiasts with years of experience in the field. + +
+
+ +
+

Head of Marketing

+

Luka Dekanozishvili

+

+ Mr. Dekanozishvili is our Head of Marketing as well as our Senior Marketing Manager. He excells in Search Engine Optimization, and helped build up the reputation of HexName from the ground up. +

+ +
+
+
+ +
+
diff --git a/src/routes/dashboard/+page.svelte b/src/routes/dashboard/+page.svelte new file mode 100644 index 0000000..dbbda0a --- /dev/null +++ b/src/routes/dashboard/+page.svelte @@ -0,0 +1,11 @@ + + +
+ +
diff --git a/src/routes/dashboard/[id]/+page.svelte b/src/routes/dashboard/[id]/+page.svelte new file mode 100644 index 0000000..138d320 --- /dev/null +++ b/src/routes/dashboard/[id]/+page.svelte @@ -0,0 +1,352 @@ + + +
+
+
+ Create a new Record + +
+ +
+
+
+ +
{error}
+
+
+ +
+ +
{error}
+
+ + {#if recordType === 'MX'} +
+ +
{error}
+
+ {/if} + + {#if recordType === 'SRV'} +
+ +
{error}
+
+
+ +
{error}
+
+
+ +
{error}
+
+ {/if} + +
+ +
{error}
+
+
+ +
+ +
+ +
{error}
+
+
+ +
+ + +
+ + {#if error} +
{error}
+ {/if} +
+ +
+ +
+ +

Manage your records

+
+ + + + + + + + + + + + + + {#if loadingRecords} + + + + {:else if recordsError} + + + + {:else if records.length === 0} + + + + {:else} + {#each records as record, i} + + {/each} + {/if} + +
TypeNameValue
+ Loading records… +
+ An error occured while loading your records: {error} +
+ No records found. Why not create one! +
+
+ + Delete subdomain + + +
diff --git a/src/routes/dashboard/[id]/delete/+page.svelte b/src/routes/dashboard/[id]/delete/+page.svelte new file mode 100644 index 0000000..509305e --- /dev/null +++ b/src/routes/dashboard/[id]/delete/+page.svelte @@ -0,0 +1,72 @@ + + +
+
+ Are you sure you want to delete your following subdomain? + {#if domains.loadingSubdomains} + + {:else} + {fqdn} + {/if} + + +
+ + +
+
+
+ +
+
\ No newline at end of file diff --git a/src/routes/dashboard/register-domain/+page.svelte b/src/routes/dashboard/register-domain/+page.svelte new file mode 100644 index 0000000..d80cd79 --- /dev/null +++ b/src/routes/dashboard/register-domain/+page.svelte @@ -0,0 +1,139 @@ + + +
+
+ Register a new domain +
+ +
+ + {#if !domains.loadingBaseDomains} + + {/if} +
+ +

+ {#if available !== null && !loadingCheck} + {subdomain}.{selectedDomainName} + {available ? " is available" : " is unavailable"} + {:else} +   + {/if} +

+
+ + +
+ +
+ +
+
diff --git a/src/routes/delete-account/+page.svelte b/src/routes/delete-account/+page.svelte new file mode 100644 index 0000000..c1b15e9 --- /dev/null +++ b/src/routes/delete-account/+page.svelte @@ -0,0 +1,54 @@ + + +
+
+ Are you sure you want to delete your account? + + + + +
+
+ +
+
\ No newline at end of file diff --git a/src/routes/faq/+page.svelte b/src/routes/faq/+page.svelte new file mode 100644 index 0000000..420837a --- /dev/null +++ b/src/routes/faq/+page.svelte @@ -0,0 +1,150 @@ +
+
+ +
+
+
+
Question?
+
Answering...
+
Done!
+
+
+

Frequently asked questions

+
+ Find some of HexName's most frequently asked questions and answers about our services, security, getting started, and support. +
+ Get started +
+
+
+ +
+

Questions about our services

+ +
+ +
What is HexName?
+
HexName is a free DNS service that allows you to register and manage subdomains under domains we own, such as example.hexname.com, example.loves-beer.com and others.
+
+ +
+ +
Where can I learn more about using HexName?
+
+
+ The easiest way to learn how to use HexName is to sign up, which takes less than 1 minute. +
+
+
+ +
+ +
Do you offer Dynamic DNS services?
+
+
+ Yes! We provide a DDNS service for A and AAAA records, allowing you to update your DNS records automatically whenever your IP address changes. +
+
+
+ +
+ +
Are there going to be any costs in the future?
+
+
+ Never. We promise to never put the basic features provided behind a paywall, and to keep the necessary features always 100% free. +
+
+
+ + +
+ +
Is this service really free?
+
+
+ Yes. The DNS and DDNS services are provided free of charge, with no usage fees. +
+
+
+ +
+ +
What DNS record types do you support?
+
+
+ You can create and manage A, AAAA, TXT, CNAME, MX, NS, and SRV records for your registered subdomains. +
+
+
+ +
+ +
What domains does HexName provide for registration?
+
+
+ As of now, we own the following domains: hexname.com, loves-beer.com, dickdns.org, and they can be used to register available subdomains. +
+
+
+ +
+ +
What does DDNS mean?
+
+
+ DDNS stands for Dynamic DNS and is a service that lets you update a DNS record (usually an A/AAAA record) to point to your desired IP address. +
+
+ This is mostly useful for individuals who would like to expose services run at their home to the internet and have a memorable domain instead of having to use the IP address. +
+
+
+ +
+

Questions about your account

+ +
+ +
I forgot my password. What should I do?
+
+
+ Click here or on "Forgot password" on the login page and follow the instructions sent to your email. +
+
+
+ +
+ +
How do I delete my account?
+
+
+ Click here or the profile icon in the top right corner, then "Delete account", and you'll be prompted to the confirmation page. +
+
+
+ +
+ +
Can I register multiple domains?
+
+
+ Yes. You may register up to 20 domains and manage any subdomain under them, such as mail.example.hexname.com and email.example.hexname.com. +
+
+
+ +
+

Miscellaneous questions

+ +
+ +
How does HexName make money?
+
+
+ I don't make a cent lol +
+
+
+
+
diff --git a/src/routes/forgot-password/+page.svelte b/src/routes/forgot-password/+page.svelte new file mode 100644 index 0000000..2b19752 --- /dev/null +++ b/src/routes/forgot-password/+page.svelte @@ -0,0 +1,52 @@ + + +
+
+ Forgot your password? +
+ + +
Enter valid email address
+
+ + +
+
+ +
+
diff --git a/src/routes/layout.css b/src/routes/layout.css new file mode 100644 index 0000000..a16d265 --- /dev/null +++ b/src/routes/layout.css @@ -0,0 +1,64 @@ +@import "tailwindcss"; +@plugin "@tailwindcss/typography"; +@plugin "daisyui"; + +@plugin "daisyui/theme" { + name: "dark"; + default: true; + prefersdark: true; + color-scheme: "dark"; + --color-base-100: oklch(25.33% 0.016 252.42); + --color-base-200: oklch(23.26% 0.014 253.1); + --color-base-300: oklch(21.15% 0.012 254.09); + --color-base-content: oklch(92% 0.013 255.508); + --color-primary: oklch(48% 0.243 264.376); + --color-primary-content: oklch(93% 0.032 255.585); + --color-secondary: oklch(65% 0.241 354.308); + --color-secondary-content: oklch(94% 0.028 342.258); + --color-accent: oklch(77% 0.152 181.912); + --color-accent-content: oklch(38% 0.063 188.416); + --color-neutral: oklch(14% 0.005 285.823); + --color-neutral-content: oklch(92% 0.004 286.32); + --color-info: oklch(74% 0.16 232.661); + --color-info-content: oklch(29% 0.066 243.157); + --color-success: oklch(79% 0.209 151.711); + --color-success-content: oklch(39% 0.095 152.535); + --color-warning: oklch(90% 0.182 98.111); + --color-warning-content: oklch(42% 0.095 57.708); + --color-error: oklch(64% 0.246 16.439); + --color-error-content: oklch(27% 0.105 12.094); + --radius-selector: 0.5rem; + --radius-field: 0.25rem; + --radius-box: 0.5rem; + --size-selector: 0.25rem; + --size-field: 0.25rem; + --border: 1px; + --depth: 0; + --noise: 0; +} + +@theme { + --animate-fadeInDown: fadeInDown 1s ease-in; + @keyframes fadeInDown { + from { + opacity: 0; + transform: translateY(-20px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + --animate-fadeOutDown: fadeOutDown 1s ease-out; + @keyframes fadeOutDown { + from { + opacity: 1; + transform: translateY(-20px); + } + to { + opacity: 0; + transform: translateY(0); + } + } +} diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte new file mode 100644 index 0000000..b9b07e6 --- /dev/null +++ b/src/routes/login/+page.svelte @@ -0,0 +1,64 @@ + + +
+
+ Log in to your account +
+ + +
Enter valid email address
+
+
+ + +

The password must be at least 12 characters long

+
+
+ + Forgot password +
+
+
+ +
+
diff --git a/src/routes/logout/+page.svelte b/src/routes/logout/+page.svelte new file mode 100644 index 0000000..9f6cf8c --- /dev/null +++ b/src/routes/logout/+page.svelte @@ -0,0 +1,27 @@ + diff --git a/src/routes/redirect/[url]/+layout.ts b/src/routes/redirect/[url]/+layout.ts new file mode 100644 index 0000000..a3d1578 --- /dev/null +++ b/src/routes/redirect/[url]/+layout.ts @@ -0,0 +1 @@ +export const ssr = false; diff --git a/src/routes/redirect/[url]/+page.svelte b/src/routes/redirect/[url]/+page.svelte new file mode 100644 index 0000000..5b4eb9d --- /dev/null +++ b/src/routes/redirect/[url]/+page.svelte @@ -0,0 +1,15 @@ + + +
+

Redirecting you to the {target} page

+ +
diff --git a/src/routes/register/+page.svelte b/src/routes/register/+page.svelte new file mode 100644 index 0000000..cdedf38 --- /dev/null +++ b/src/routes/register/+page.svelte @@ -0,0 +1,79 @@ + + + + + + + +
+
+ Create your account +
+ + +
Enter valid email address
+
+
+ + +

The password must be at least 12 characters long

+
+ +
+
+ +
+
diff --git a/src/routes/verify-email/[token]/+page.svelte b/src/routes/verify-email/[token]/+page.svelte new file mode 100644 index 0000000..2ca5474 --- /dev/null +++ b/src/routes/verify-email/[token]/+page.svelte @@ -0,0 +1,48 @@ + + +{#if success === undefined} +
+

Verifying your email

+ +
+{:else if success} +
+

Email successfully verified!

+

You may log in now.

+
+{:else} +
+

Failed to verify your email:

+

{errorMessage}

+
+{/if} diff --git a/start_backend.sh b/start_backend.sh new file mode 100755 index 0000000..06b4639 --- /dev/null +++ b/start_backend.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -euo pipefail + +cd ~/Documents/Prog/dns +sudo caddy run & + +cd ~/Documents/Prog/dns/dns-server +sudo systemctl start docker +sudo docker-compose up -d & + +cd ~/Documents/Prog/dns/dns-backend +cargo run diff --git a/static/robots.txt b/static/robots.txt new file mode 100644 index 0000000..b6dd667 --- /dev/null +++ b/static/robots.txt @@ -0,0 +1,3 @@ +# allow crawling everything by default +User-agent: * +Disallow: diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 0000000..10153b5 --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,12 @@ +import adapter from "@sveltejs/adapter-node"; +import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + // Consult https://svelte.dev/docs/kit/integrations + // for more information about preprocessors + preprocess: vitePreprocess(), + kit: { adapter: adapter() }, +}; + +export default config; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..c7b9df5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "rewriteRelativeImportExtensions": true, + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias + // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files + // + // To make changes to top-level options such as include and exclude, we recommend extending + // the generated config; see https://svelte.dev/docs/kit/configuration#typescript +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..8668317 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,7 @@ +import tailwindcss from "@tailwindcss/vite"; +import { sveltekit } from "@sveltejs/kit/vite"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [tailwindcss(), sveltekit()], +});