diff --git a/examples/svelte-multi-providers/.env.local.sample b/examples/svelte-multi-providers/.env.local.sample
new file mode 100644
index 00000000..1d19998f
--- /dev/null
+++ b/examples/svelte-multi-providers/.env.local.sample
@@ -0,0 +1,23 @@
+# Pick one of the following configurations, those are not mock credentials, you can use them for testing purposes.
+
+# ======= Keycloak =================
+# VITE_OIDC_ISSUER_URI=https://cloud-iam.oidc-spa.dev/realms/oidc-spa
+# VITE_OIDC_CLIENT_ID=example-react-router
+
+# ======= Microsoft Entra ID =======
+VITE_OIDC_ISSUER_URI_MICROSOFT=https://login.microsoftonline.com/71a0a621-363a-4182-8209-86364aa6de03/v2.0
+VITE_OIDC_CLIENT_ID_MICROSOFT=3c8f72b4-4dd9-4aa2-a01d-43349ba90394
+VITE_OIDC_SCOPE_MICROSOFT="profile api://example-multi-providers/access_as_user"
+
+# ======= Google OAuth =============
+VITE_OIDC_ISSUER_URI_GOOGLE=https://accounts.google.com
+VITE_OIDC_CLIENT_ID_GOOGLE=928024164279-ifjvmsffi64slkk81h3gmoh7p03ev68k.apps.googleusercontent.com
+VITE_OIDC_CLIENT_SECRET_GOOGLE=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
+VITE_OIDC_SCOPE_GOOGLE="profile email"
+
+# ======= Auth0 ====================
+#VITE_OIDC_ISSUER_URI=https://auth0.oidc-spa.dev
+#VITE_OIDC_CLIENT_ID=DkoDtyQkYj4UPk3gKk4MjtnD9nskUhpt
+#VITE_OIDC_AUDIENCE=https://oidc-spa-example
+#VITE_OIDC_SSO_SESSION_IDLE_SECONDS=120
+
diff --git a/examples/svelte-multi-providers/.gitignore b/examples/svelte-multi-providers/.gitignore
new file mode 100644
index 00000000..a547bf36
--- /dev/null
+++ b/examples/svelte-multi-providers/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/examples/svelte-multi-providers/README.md b/examples/svelte-multi-providers/README.md
new file mode 100644
index 00000000..4b6673d6
--- /dev/null
+++ b/examples/svelte-multi-providers/README.md
@@ -0,0 +1,47 @@
+# Svelte + TS + Vite
+
+This template should help get you started developing with Svelte and TypeScript in Vite.
+
+## Recommended IDE Setup
+
+[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
+
+## Need an official Svelte framework?
+
+Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more.
+
+## Technical considerations
+
+**Why use this over SvelteKit?**
+
+- It brings its own routing solution which might not be preferable for some users.
+- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
+
+This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project.
+
+Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate.
+
+**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
+
+Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information.
+
+**Why include `.vscode/extensions.json`?**
+
+Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project.
+
+**Why enable `allowJs` in the TS template?**
+
+While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant.
+
+**Why is HMR not preserving my local component state?**
+
+HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior.
+
+If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. You can read the details in the [svelte-hmr documentation](https://github.com/rixo/svelte-hmr#svelte-hmr).
+
+```ts
+// store.ts
+// An extremely simple external store
+import { writable } from "svelte/store";
+export default writable(0);
+```
diff --git a/examples/svelte-multi-providers/index.html b/examples/svelte-multi-providers/index.html
new file mode 100644
index 00000000..28d46da7
--- /dev/null
+++ b/examples/svelte-multi-providers/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite + Svelte + TS
+
+
+
+
+
+
diff --git a/examples/svelte-multi-providers/package.json b/examples/svelte-multi-providers/package.json
new file mode 100644
index 00000000..a27d1d06
--- /dev/null
+++ b/examples/svelte-multi-providers/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "svelte-multi-providers",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "prepare": "[ ! -f .env.local ] && cp .env.local.sample .env.local || true",
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json"
+ },
+ "dependencies": {
+ "oidc-spa": "file:../../dist"
+ },
+ "devDependencies": {
+ "@mateothegreat/svelte5-router": "^2.16.19",
+ "@sveltejs/vite-plugin-svelte": "^6.2.1",
+ "@tsconfig/svelte": "^5.0.5",
+ "@types/node": "^24.6.0",
+ "evt": "2.5.9",
+ "svelte": "^5.39.6",
+ "svelte-check": "^4.3.2",
+ "typescript": "~5.9.3",
+ "vite": "^7.1.7",
+ "zod": "^4.1.11"
+ }
+}
diff --git a/examples/svelte-multi-providers/src/App.svelte b/examples/svelte-multi-providers/src/App.svelte
new file mode 100644
index 00000000..10e2fdc0
--- /dev/null
+++ b/examples/svelte-multi-providers/src/App.svelte
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
diff --git a/examples/svelte-multi-providers/src/app.css b/examples/svelte-multi-providers/src/app.css
new file mode 100644
index 00000000..6a9b32cb
--- /dev/null
+++ b/examples/svelte-multi-providers/src/app.css
@@ -0,0 +1,96 @@
+:root {
+ font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+.card {
+ padding: 2em;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
+ transition: filter 300ms;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.svelte:hover {
+ filter: drop-shadow(0 0 2em #ff3e00aa);
+}
+
+.read-the-docs {
+ color: #888;
+}
diff --git a/examples/svelte-multi-providers/src/assets/svelte.svg b/examples/svelte-multi-providers/src/assets/svelte.svg
new file mode 100644
index 00000000..c5e08481
--- /dev/null
+++ b/examples/svelte-multi-providers/src/assets/svelte.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/examples/svelte-multi-providers/src/assets/vite.svg b/examples/svelte-multi-providers/src/assets/vite.svg
new file mode 100644
index 00000000..e7b8dfb1
--- /dev/null
+++ b/examples/svelte-multi-providers/src/assets/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/examples/svelte-multi-providers/src/components/AutoLogoutWarningOverlay.svelte b/examples/svelte-multi-providers/src/components/AutoLogoutWarningOverlay.svelte
new file mode 100644
index 00000000..25c10240
--- /dev/null
+++ b/examples/svelte-multi-providers/src/components/AutoLogoutWarningOverlay.svelte
@@ -0,0 +1,17 @@
+
+
+{#if $secondsLeft}
+
+
+
Are you still there?
+
You will be logged out in {$secondsLeft}
+
+
+{/if}
diff --git a/examples/svelte-multi-providers/src/components/Google.svelte b/examples/svelte-multi-providers/src/components/Google.svelte
new file mode 100644
index 00000000..8688ee1b
--- /dev/null
+++ b/examples/svelte-multi-providers/src/components/Google.svelte
@@ -0,0 +1,33 @@
+
+
+{#if oidcOrInitializationError === undefined}
+ Loading...
+{:else if isOidcInitializationError(oidcOrInitializationError)}
+ {@const initializationError = oidcOrInitializationError}
+
+ An error occurred while initializing the OIDC client:
+ {initializationError.message}
+
+{:else}
+ {@const oidc = oidcOrInitializationError}
+
+ {@render children()}
+
+{/if}
diff --git a/examples/svelte-multi-providers/src/components/Header.svelte b/examples/svelte-multi-providers/src/components/Header.svelte
new file mode 100644
index 00000000..957bbc04
--- /dev/null
+++ b/examples/svelte-multi-providers/src/components/Header.svelte
@@ -0,0 +1,25 @@
+
+
+
+
OIDC-SPA + Svelte5: Login with Google or Microsoft example
+
+
+ {#if isUserLoggedIn}
+
+ {:else}
+
+ {/if}
+
diff --git a/examples/svelte-multi-providers/src/components/LoggedInAuthButton.svelte b/examples/svelte-multi-providers/src/components/LoggedInAuthButton.svelte
new file mode 100644
index 00000000..a66257e8
--- /dev/null
+++ b/examples/svelte-multi-providers/src/components/LoggedInAuthButton.svelte
@@ -0,0 +1,11 @@
+
+
+
+ Hello {decodedIdToken.name}
+
+ logout({ redirectTo: "home" })}>Logout
+
diff --git a/examples/svelte-multi-providers/src/components/Microsoft.svelte b/examples/svelte-multi-providers/src/components/Microsoft.svelte
new file mode 100644
index 00000000..0d8297fd
--- /dev/null
+++ b/examples/svelte-multi-providers/src/components/Microsoft.svelte
@@ -0,0 +1,33 @@
+
+
+{#if oidcOrInitializationError === undefined}
+ Loading...
+{:else if isOidcInitializationError(oidcOrInitializationError)}
+ {@const initializationError = oidcOrInitializationError}
+
+ An error occurred while initializing the OIDC client:
+ {initializationError.message}
+
+{:else}
+ {@const oidc = oidcOrInitializationError}
+
+ {@render children()}
+
+{/if}
diff --git a/examples/svelte-multi-providers/src/components/NotLoggedInAuthButton.svelte b/examples/svelte-multi-providers/src/components/NotLoggedInAuthButton.svelte
new file mode 100644
index 00000000..5aeb1d46
--- /dev/null
+++ b/examples/svelte-multi-providers/src/components/NotLoggedInAuthButton.svelte
@@ -0,0 +1,19 @@
+
+
+
+ login()}>Login with Google or Microsoft
+
diff --git a/examples/svelte-multi-providers/src/components/SelectProviderDialog.svelte b/examples/svelte-multi-providers/src/components/SelectProviderDialog.svelte
new file mode 100644
index 00000000..0f5b632b
--- /dev/null
+++ b/examples/svelte-multi-providers/src/components/SelectProviderDialog.svelte
@@ -0,0 +1,39 @@
+
+
+ selectProvider(undefined)}>
+
+
Login with
+
+ {
+ selectProvider("google");
+ }}>Google
+
+ {
+ selectProvider("microsoft");
+ }}>Microsoft
+
+
diff --git a/examples/svelte-multi-providers/src/env.d.ts b/examples/svelte-multi-providers/src/env.d.ts
new file mode 100644
index 00000000..d8d2aae8
--- /dev/null
+++ b/examples/svelte-multi-providers/src/env.d.ts
@@ -0,0 +1,10 @@
+///
+
+interface ImportMetaEnv {
+ readonly VITE_OIDC_ISSUER_URI: string;
+ readonly VITE_OIDC_CLIENT_ID: string;
+}
+
+interface ImportMeta {
+ readonly env: ImportMetaEnv;
+}
diff --git a/examples/svelte-multi-providers/src/main.lazy.ts b/examples/svelte-multi-providers/src/main.lazy.ts
new file mode 100644
index 00000000..bd2a980a
--- /dev/null
+++ b/examples/svelte-multi-providers/src/main.lazy.ts
@@ -0,0 +1,12 @@
+import { mount } from "svelte";
+import "./app.css";
+import App from "./App.svelte";
+
+const appElement = document.getElementById("app");
+if (!appElement) {
+ throw new Error("Could not find #app element");
+}
+
+const app = mount(App, { target: appElement });
+
+export default app;
diff --git a/examples/svelte-multi-providers/src/main.ts b/examples/svelte-multi-providers/src/main.ts
new file mode 100644
index 00000000..dcd26f56
--- /dev/null
+++ b/examples/svelte-multi-providers/src/main.ts
@@ -0,0 +1,11 @@
+import { oidcEarlyInit } from "oidc-spa/entrypoint";
+
+const { shouldLoadApp } = oidcEarlyInit({
+ freezeFetch: true,
+ freezeXMLHttpRequest: true,
+ freezeWebSocket: true
+});
+
+if (shouldLoadApp) {
+ import("./main.lazy");
+}
diff --git a/examples/svelte-multi-providers/src/oidc.ts b/examples/svelte-multi-providers/src/oidc.ts
new file mode 100644
index 00000000..3c30d953
--- /dev/null
+++ b/examples/svelte-multi-providers/src/oidc.ts
@@ -0,0 +1,158 @@
+import { Evt } from "evt";
+import type { Oidc } from "oidc-spa";
+import { createSvelteOidc, type OidcSvelte } from "oidc-spa/svelte";
+import { z } from "zod";
+
+const decodedIdTokenSchema = z.object({
+ sub: z.string(),
+ name: z.string()
+});
+
+type DecodedIdToken = z.infer;
+
+const autoLogin = false;
+const homeUrl = import.meta.env.BASE_URL;
+
+const google = createSvelteOidc({
+ issuerUri: import.meta.env.VITE_OIDC_ISSUER_URI_GOOGLE,
+ clientId: import.meta.env.VITE_OIDC_CLIENT_ID_GOOGLE,
+ __unsafe_clientSecret: import.meta.env.VITE_OIDC_CLIENT_SECRET_GOOGLE,
+ __unsafe_useIdTokenAsAccessToken: true,
+ scopes: import.meta.env.VITE_OIDC_SCOPE_GOOGLE.split(" "),
+ homeUrl,
+ decodedIdTokenSchema,
+ debugLogs: true,
+ autoLogin
+});
+
+const microsoft = createSvelteOidc({
+ issuerUri: import.meta.env.VITE_OIDC_ISSUER_URI_MICROSOFT,
+ clientId: import.meta.env.VITE_OIDC_CLIENT_ID_MICROSOFT,
+ scopes: import.meta.env.VITE_OIDC_SCOPE_MICROSOFT.split(" "),
+ homeUrl,
+ decodedIdTokenSchema,
+ debugLogs: true,
+ autoLogin
+});
+
+export async function getOidc(): Promise<
+ | Oidc.LoggedIn
+ | { isUserLoggedIn: false; google: Oidc.NotLoggedIn; microsoft: Oidc.NotLoggedIn }
+> {
+ const oidc_google = await google.getOidc();
+
+ if (oidc_google.isUserLoggedIn) {
+ return oidc_google;
+ }
+
+ const oidc_microsoft = await microsoft.getOidc();
+
+ if (oidc_microsoft.isUserLoggedIn) {
+ return oidc_microsoft;
+ }
+
+ return {
+ isUserLoggedIn: false,
+ google: oidc_google,
+ microsoft: oidc_microsoft
+ };
+}
+
+export function initializeOidc() {
+ const googleInitializer = google.initializeOidc();
+ const microsoftInitializer = microsoft.initializeOidc();
+ return {
+ google: {
+ ...googleInitializer,
+ OidcContextProvider: google.OidcContextProvider
+ },
+ microsoft: {
+ ...microsoftInitializer,
+ OidcContextProvider: microsoft.OidcContextProvider
+ }
+ };
+}
+
+export function useIsUserLoggedIn(): boolean {
+ const { isUserLoggedIn: isUserLoggedIn_google } = google.useOidc();
+ const { isUserLoggedIn: isUserLoggedIn_microsoft } = microsoft.useOidc();
+
+ return isUserLoggedIn_google || isUserLoggedIn_microsoft;
+}
+
+export function useOidc_assertUserLoggedIn(): OidcSvelte.LoggedIn & {
+ provider: "google" | "microsoft";
+} {
+ const oidcSvelte_google = google.useOidc();
+ const oidcSvelte_microsoft = microsoft.useOidc();
+
+ if (oidcSvelte_google.isUserLoggedIn) {
+ return { ...oidcSvelte_google, provider: "google" };
+ }
+
+ if (oidcSvelte_microsoft.isUserLoggedIn) {
+ return { ...oidcSvelte_microsoft, provider: "microsoft" };
+ }
+
+ throw new Error("Assertion error, user is not logged in");
+}
+
+export function useOidc_assertUserNotLoggedIn(): {
+ microsoft: OidcSvelte.NotLoggedIn;
+ google: OidcSvelte.NotLoggedIn;
+} {
+ const oidcSvelte_google = google.useOidc({ assert: "user not logged in" });
+ const oidcSvelte_microsoft = microsoft.useOidc({ assert: "user not logged in" });
+
+ return {
+ google: oidcSvelte_google,
+ microsoft: oidcSvelte_microsoft
+ };
+}
+
+export type Provider = "google" | "microsoft";
+
+export const evtProviderSelected = Evt.create();
+
+export const evtIsModalOpen = Evt.create(false);
+
+export function askUserToSelectProvider(): Promise {
+ evtIsModalOpen.state = true;
+
+ return evtProviderSelected.waitFor();
+}
+
+evtProviderSelected.attach(provider => {
+ if (provider === undefined) {
+ evtIsModalOpen.state = false;
+ }
+});
+
+export async function beforeLoad_protectedRoute(params: {
+ cause: "preload" | string;
+}): Promise {
+ const { cause } = params;
+
+ const oidc = await getOidc();
+
+ if (oidc.isUserLoggedIn) {
+ return true;
+ }
+
+ if (cause === "preload") {
+ throw new Error(
+ "oidc-spa: User is not yet logged in. This is an expected error, nothing to be addressed."
+ );
+ }
+
+ const provider = await askUserToSelectProvider();
+
+ if (provider === undefined) {
+ history.back();
+ return false;
+ }
+ await oidc[provider].login({
+ doesCurrentHrefRequiresAuth: true
+ });
+ return true;
+}
diff --git a/examples/svelte-multi-providers/src/pages/ProtectedPage.svelte b/examples/svelte-multi-providers/src/pages/ProtectedPage.svelte
new file mode 100644
index 00000000..63eccd50
--- /dev/null
+++ b/examples/svelte-multi-providers/src/pages/ProtectedPage.svelte
@@ -0,0 +1,108 @@
+
+
+{#if $decodedAccessToken !== undefined}
+
+ Hello {decodedIdToken.name}
+
+
+ {#if $decodedAccessToken !== null}
+ Decoded Access Token:
+ {JSON.stringify(
+ $decodedAccessToken,
+ null,
+ 2
+ )}
+ {:else}
+ The Access Token issued by the IDP is opaque (Not a JWT).
+ {/if}
+
+ renewTokens()}>Renew tokens
+
+{/if}
diff --git a/examples/svelte-multi-providers/src/pages/PublicPage.svelte b/examples/svelte-multi-providers/src/pages/PublicPage.svelte
new file mode 100644
index 00000000..8a2625e0
--- /dev/null
+++ b/examples/svelte-multi-providers/src/pages/PublicPage.svelte
@@ -0,0 +1,14 @@
+
+
+
+This is a page that do not requires the user to be authenticated
diff --git a/examples/svelte-multi-providers/src/routes.ts b/examples/svelte-multi-providers/src/routes.ts
new file mode 100644
index 00000000..6ff7b78c
--- /dev/null
+++ b/examples/svelte-multi-providers/src/routes.ts
@@ -0,0 +1,19 @@
+import { type RouteConfig } from "@mateothegreat/svelte5-router";
+import { beforeLoad_protectedRoute } from "./oidc";
+import ProtectedPage from "./pages/ProtectedPage.svelte";
+import PublicPage from "./pages/PublicPage.svelte";
+
+export const routes: RouteConfig[] = [
+ {
+ component: PublicPage
+ },
+ {
+ path: "protected",
+ component: ProtectedPage,
+ hooks: {
+ pre: async route => {
+ return beforeLoad_protectedRoute({ cause: "" });
+ }
+ }
+ }
+];
diff --git a/examples/svelte-multi-providers/src/vite-env.d.ts b/examples/svelte-multi-providers/src/vite-env.d.ts
new file mode 100644
index 00000000..11f02fe2
--- /dev/null
+++ b/examples/svelte-multi-providers/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/examples/svelte-multi-providers/svelte.config.js b/examples/svelte-multi-providers/svelte.config.js
new file mode 100644
index 00000000..96b34554
--- /dev/null
+++ b/examples/svelte-multi-providers/svelte.config.js
@@ -0,0 +1,8 @@
+import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
+
+/** @type {import("@sveltejs/vite-plugin-svelte").SvelteConfig} */
+export default {
+ // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
+ // for more information about preprocessors
+ preprocess: vitePreprocess(),
+}
diff --git a/examples/svelte-multi-providers/tsconfig.app.json b/examples/svelte-multi-providers/tsconfig.app.json
new file mode 100644
index 00000000..4b70ad5d
--- /dev/null
+++ b/examples/svelte-multi-providers/tsconfig.app.json
@@ -0,0 +1,25 @@
+{
+ "extends": "@tsconfig/svelte/tsconfig.json",
+ "compilerOptions": {
+ "tsBuildInfoFile": "../svelte-multi-providers/node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "types": ["svelte", "vite/client"],
+ "noEmit": true,
+ /**
+ * Typecheck JS in `.svelte` and `.js` files by default.
+ * Disable checkJs if you'd like to use dynamic types in JS.
+ * Note that setting allowJs false does not prevent the use
+ * of JS in `.svelte` files.
+ */
+ "allowJs": true,
+ "checkJs": true,
+ "moduleDetection": "force"
+ },
+ "include": [
+ "../svelte-multi-providers/src/**/*.ts",
+ "../svelte-multi-providers/src/**/*.js",
+ "../svelte-multi-providers/src/**/*.svelte"
+ ]
+}
diff --git a/examples/svelte-multi-providers/tsconfig.json b/examples/svelte-multi-providers/tsconfig.json
new file mode 100644
index 00000000..eb69b0d0
--- /dev/null
+++ b/examples/svelte-multi-providers/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "files": [],
+ "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
+}
diff --git a/examples/svelte-multi-providers/tsconfig.node.json b/examples/svelte-multi-providers/tsconfig.node.json
new file mode 100644
index 00000000..0cc4c356
--- /dev/null
+++ b/examples/svelte-multi-providers/tsconfig.node.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ "target": "ES2023",
+ "lib": ["ES2023"],
+ "module": "ESNext",
+ "types": ["node"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/examples/svelte-multi-providers/vite.config.ts b/examples/svelte-multi-providers/vite.config.ts
new file mode 100644
index 00000000..2a2348f3
--- /dev/null
+++ b/examples/svelte-multi-providers/vite.config.ts
@@ -0,0 +1,7 @@
+import { defineConfig } from "vite";
+import { svelte } from "@sveltejs/vite-plugin-svelte";
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [svelte()]
+});
diff --git a/examples/svelte-multi-providers/yarn.lock b/examples/svelte-multi-providers/yarn.lock
new file mode 100644
index 00000000..f98615e2
--- /dev/null
+++ b/examples/svelte-multi-providers/yarn.lock
@@ -0,0 +1,623 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@esbuild/aix-ppc64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz#ee6b7163a13528e099ecf562b972f2bcebe0aa97"
+ integrity sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==
+
+"@esbuild/android-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz#115fc76631e82dd06811bfaf2db0d4979c16e2cb"
+ integrity sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==
+
+"@esbuild/android-arm@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.10.tgz#8d5811912da77f615398611e5bbc1333fe321aa9"
+ integrity sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==
+
+"@esbuild/android-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.10.tgz#e3e96516b2d50d74105bb92594c473e30ddc16b1"
+ integrity sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==
+
+"@esbuild/darwin-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz#6af6bb1d05887dac515de1b162b59dc71212ed76"
+ integrity sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==
+
+"@esbuild/darwin-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz#99ae82347fbd336fc2d28ffd4f05694e6e5b723d"
+ integrity sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==
+
+"@esbuild/freebsd-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz#0c6d5558a6322b0bdb17f7025c19bd7d2359437d"
+ integrity sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==
+
+"@esbuild/freebsd-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz#8c35873fab8c0857a75300a3dcce4324ca0b9844"
+ integrity sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==
+
+"@esbuild/linux-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz#3edc2f87b889a15b4cedaf65f498c2bed7b16b90"
+ integrity sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==
+
+"@esbuild/linux-arm@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz#86501cfdfb3d110176d80c41b27ed4611471cde7"
+ integrity sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==
+
+"@esbuild/linux-ia32@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz#e6589877876142537c6864680cd5d26a622b9d97"
+ integrity sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==
+
+"@esbuild/linux-loong64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz#11119e18781f136d8083ea10eb6be73db7532de8"
+ integrity sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==
+
+"@esbuild/linux-mips64el@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz#3052f5436b0c0c67a25658d5fc87f045e7def9e6"
+ integrity sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==
+
+"@esbuild/linux-ppc64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz#2f098920ee5be2ce799f35e367b28709925a8744"
+ integrity sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==
+
+"@esbuild/linux-riscv64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz#fa51d7fd0a22a62b51b4b94b405a3198cf7405dd"
+ integrity sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==
+
+"@esbuild/linux-s390x@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz#a27642e36fc282748fdb38954bd3ef4f85791e8a"
+ integrity sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==
+
+"@esbuild/linux-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz#9d9b09c0033d17529570ced6d813f98315dfe4e9"
+ integrity sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==
+
+"@esbuild/netbsd-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz#25c09a659c97e8af19e3f2afd1c9190435802151"
+ integrity sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==
+
+"@esbuild/netbsd-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz#7fa5f6ffc19be3a0f6f5fd32c90df3dc2506937a"
+ integrity sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==
+
+"@esbuild/openbsd-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz#8faa6aa1afca0c6d024398321d6cb1c18e72a1c3"
+ integrity sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==
+
+"@esbuild/openbsd-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz#a42979b016f29559a8453d32440d3c8cd420af5e"
+ integrity sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==
+
+"@esbuild/openharmony-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz#fd87bfeadd7eeb3aa384bbba907459ffa3197cb1"
+ integrity sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==
+
+"@esbuild/sunos-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz#3a18f590e36cb78ae7397976b760b2b8c74407f4"
+ integrity sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==
+
+"@esbuild/win32-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz#e71741a251e3fd971408827a529d2325551f530c"
+ integrity sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==
+
+"@esbuild/win32-ia32@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz#c6f010b5d3b943d8901a0c87ea55f93b8b54bf94"
+ integrity sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==
+
+"@esbuild/win32-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz#e4b3e255a1b4aea84f6e1d2ae0b73f826c3785bd"
+ integrity sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==
+
+"@jridgewell/gen-mapping@^0.3.5":
+ version "0.3.13"
+ resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f"
+ integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.0"
+ "@jridgewell/trace-mapping" "^0.3.24"
+
+"@jridgewell/remapping@^2.3.4":
+ version "2.3.5"
+ resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1"
+ integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.3.5"
+ "@jridgewell/trace-mapping" "^0.3.24"
+
+"@jridgewell/resolve-uri@^3.1.0":
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
+ integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
+
+"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5":
+ version "1.5.5"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
+ integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
+
+"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
+ version "0.3.31"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0"
+ integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.1.0"
+ "@jridgewell/sourcemap-codec" "^1.4.14"
+
+"@mateothegreat/svelte5-router@^2.16.19":
+ version "2.16.19"
+ resolved "https://registry.yarnpkg.com/@mateothegreat/svelte5-router/-/svelte5-router-2.16.19.tgz#f14b4b3206e3b70fbbbdd3e9e05c6c5a1bd17d3d"
+ integrity sha512-SNkR15x3b0HLNM33BORKF9U6elHHWZxg42yikNUKW1YNjkYRBLBgDkVSJTqRIC6aE8Wt4vqmKKmHzQTK2EKiqA==
+
+"@rollup/rollup-android-arm-eabi@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz#59e7478d310f7e6a7c72453978f562483828112f"
+ integrity sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==
+
+"@rollup/rollup-android-arm64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz#a825192a0b1b2f27a5c950c439e7e37a33c5d056"
+ integrity sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==
+
+"@rollup/rollup-darwin-arm64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz#4ee37078bccd725ae3c5f30ef92efc8e1bf886f3"
+ integrity sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==
+
+"@rollup/rollup-darwin-x64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz#43cc08bd05bf9f388f125e7210a544e62d368d90"
+ integrity sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==
+
+"@rollup/rollup-freebsd-arm64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz#bc8e640e28abe52450baf3fc80d9b26d9bb6587d"
+ integrity sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==
+
+"@rollup/rollup-freebsd-x64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz#e981a22e057cc8c65bb523019d344d3a66b15bbc"
+ integrity sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==
+
+"@rollup/rollup-linux-arm-gnueabihf@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz#4036b68904f392a20f3499d63b33e055b67eb274"
+ integrity sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==
+
+"@rollup/rollup-linux-arm-musleabihf@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz#d3b1b9589606e0ff916801c855b1ace9e733427a"
+ integrity sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==
+
+"@rollup/rollup-linux-arm64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz#cbf0943c477e3b96340136dd3448eaf144378cf2"
+ integrity sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==
+
+"@rollup/rollup-linux-arm64-musl@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz#837f5a428020d5dce1c3b4cc049876075402cf78"
+ integrity sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==
+
+"@rollup/rollup-linux-loong64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz#532c214ababb32ab4bc21b4054278b9a8979e516"
+ integrity sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==
+
+"@rollup/rollup-linux-ppc64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz#93900163b61b49cee666d10ee38257a8b1dd161a"
+ integrity sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==
+
+"@rollup/rollup-linux-riscv64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz#f0ffdcc7066ca04bc972370c74289f35c7a7dc42"
+ integrity sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==
+
+"@rollup/rollup-linux-riscv64-musl@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz#361695c39dbe96773509745d77a870a32a9f8e48"
+ integrity sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==
+
+"@rollup/rollup-linux-s390x-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz#09fc6cc2e266a2324e366486ae5d1bca48c43a6a"
+ integrity sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==
+
+"@rollup/rollup-linux-x64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz#aa9d5b307c08f05d3454225bb0a2b4cc87eeb2e1"
+ integrity sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==
+
+"@rollup/rollup-linux-x64-musl@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz#26949e5b4645502a61daba2f7a8416bd17cb5382"
+ integrity sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==
+
+"@rollup/rollup-openharmony-arm64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz#ef493c072f9dac7e0edb6c72d63366846b6ffcd9"
+ integrity sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==
+
+"@rollup/rollup-win32-arm64-msvc@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz#56e1aaa6a630d2202ee7ec0adddd05cf384ffd44"
+ integrity sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==
+
+"@rollup/rollup-win32-ia32-msvc@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz#0a44bbf933a9651c7da2b8569fa448dec0de7480"
+ integrity sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==
+
+"@rollup/rollup-win32-x64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz#730e12f0b60b234a7c02d5d3179ca3ec7972033d"
+ integrity sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==
+
+"@rollup/rollup-win32-x64-msvc@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz#5b2dd648a960b8fa00d76f2cc4eea2f03daa80f4"
+ integrity sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==
+
+"@sveltejs/acorn-typescript@^1.0.5":
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.6.tgz#ca236a97d895869138091c6fba100114951daa97"
+ integrity sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==
+
+"@sveltejs/vite-plugin-svelte-inspector@^5.0.0":
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.1.tgz#3d35254b76e07551ea8921029a96d99b94ffbc5c"
+ integrity sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==
+ dependencies:
+ debug "^4.4.1"
+
+"@sveltejs/vite-plugin-svelte@^6.2.1":
+ version "6.2.1"
+ resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.1.tgz#3414c10aaacce8f23a8db2a37926da00ab7a78cb"
+ integrity sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==
+ dependencies:
+ "@sveltejs/vite-plugin-svelte-inspector" "^5.0.0"
+ debug "^4.4.1"
+ deepmerge "^4.3.1"
+ magic-string "^0.30.17"
+ vitefu "^1.1.1"
+
+"@tsconfig/svelte@^5.0.5":
+ version "5.0.5"
+ resolved "https://registry.yarnpkg.com/@tsconfig/svelte/-/svelte-5.0.5.tgz#781df887c6a41b574e6972f9e002cea7edf4f450"
+ integrity sha512-48fAnUjKye38FvMiNOj0J9I/4XlQQiZlpe9xaNPfe8vy2Y1hFBt8g1yqf2EGjVvHavo4jf2lC+TQyENCr4BJBQ==
+
+"@types/estree@1.0.8", "@types/estree@^1.0.5", "@types/estree@^1.0.6":
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
+ integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
+
+"@types/node@^24.6.0":
+ version "24.7.0"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-24.7.0.tgz#a34c9f0d3401db396782e440317dd5d8373c286f"
+ integrity sha512-IbKooQVqUBrlzWTi79E8Fw78l8k1RNtlDDNWsFZs7XonuQSJ8oNYfEeclhprUldXISRMLzBpILuKgPlIxm+/Yw==
+ dependencies:
+ undici-types "~7.14.0"
+
+acorn@^8.12.1:
+ version "8.15.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816"
+ integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
+
+aria-query@^5.3.1:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59"
+ integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==
+
+axobject-query@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee"
+ integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==
+
+chokidar@^4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30"
+ integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==
+ dependencies:
+ readdirp "^4.0.1"
+
+clsx@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
+ integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
+
+debug@^4.4.1:
+ version "4.4.3"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
+ integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
+ dependencies:
+ ms "^2.1.3"
+
+deepmerge@^4.3.1:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
+ integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
+
+esbuild@^0.25.0:
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.10.tgz#37f5aa5cd14500f141be121c01b096ca83ac34a9"
+ integrity sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==
+ optionalDependencies:
+ "@esbuild/aix-ppc64" "0.25.10"
+ "@esbuild/android-arm" "0.25.10"
+ "@esbuild/android-arm64" "0.25.10"
+ "@esbuild/android-x64" "0.25.10"
+ "@esbuild/darwin-arm64" "0.25.10"
+ "@esbuild/darwin-x64" "0.25.10"
+ "@esbuild/freebsd-arm64" "0.25.10"
+ "@esbuild/freebsd-x64" "0.25.10"
+ "@esbuild/linux-arm" "0.25.10"
+ "@esbuild/linux-arm64" "0.25.10"
+ "@esbuild/linux-ia32" "0.25.10"
+ "@esbuild/linux-loong64" "0.25.10"
+ "@esbuild/linux-mips64el" "0.25.10"
+ "@esbuild/linux-ppc64" "0.25.10"
+ "@esbuild/linux-riscv64" "0.25.10"
+ "@esbuild/linux-s390x" "0.25.10"
+ "@esbuild/linux-x64" "0.25.10"
+ "@esbuild/netbsd-arm64" "0.25.10"
+ "@esbuild/netbsd-x64" "0.25.10"
+ "@esbuild/openbsd-arm64" "0.25.10"
+ "@esbuild/openbsd-x64" "0.25.10"
+ "@esbuild/openharmony-arm64" "0.25.10"
+ "@esbuild/sunos-x64" "0.25.10"
+ "@esbuild/win32-arm64" "0.25.10"
+ "@esbuild/win32-ia32" "0.25.10"
+ "@esbuild/win32-x64" "0.25.10"
+
+esm-env@^1.2.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.2.2.tgz#263c9455c55861f41618df31b20cb571fc20b75e"
+ integrity sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==
+
+esrap@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/esrap/-/esrap-2.1.0.tgz#70df8f20129df3ad82f20e306dc4000dd5947813"
+ integrity sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.4.15"
+
+evt@2.5.9:
+ version "2.5.9"
+ resolved "https://registry.yarnpkg.com/evt/-/evt-2.5.9.tgz#cd270e50ce1e7c586bf86242c054dd958d06a5c4"
+ integrity sha512-GpjX476FSlttEGWHT8BdVMoI8wGXQGbEOtKcP4E+kggg+yJzXBZN2n4x7TS/zPBJ1DZqWI+rguZZApjjzQ0HpA==
+ dependencies:
+ minimal-polyfills "^2.2.3"
+ run-exclusive "^2.2.19"
+ tsafe "^1.8.5"
+
+fdir@^6.2.0, fdir@^6.5.0:
+ version "6.5.0"
+ resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350"
+ integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==
+
+fsevents@~2.3.2, fsevents@~2.3.3:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
+ integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
+
+is-reference@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.3.tgz#9ef7bf9029c70a67b2152da4adf57c23d718910f"
+ integrity sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==
+ dependencies:
+ "@types/estree" "^1.0.6"
+
+locate-character@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/locate-character/-/locate-character-3.0.0.tgz#0305c5b8744f61028ef5d01f444009e00779f974"
+ integrity sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==
+
+magic-string@^0.30.11, magic-string@^0.30.17:
+ version "0.30.19"
+ resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.19.tgz#cebe9f104e565602e5d2098c5f2e79a77cc86da9"
+ integrity sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.5"
+
+minimal-polyfills@^2.2.3:
+ version "2.2.3"
+ resolved "https://registry.yarnpkg.com/minimal-polyfills/-/minimal-polyfills-2.2.3.tgz#22af58de16807b325f29b83ca38ffb83e75ec3f4"
+ integrity sha512-oxdmJ9cL+xV72h0xYxp4tP2d5/fTBpP45H8DIOn9pASuF8a3IYTf+25fMGDYGiWW+MFsuog6KD6nfmhZJQ+uUw==
+
+mri@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
+ integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
+
+ms@^2.1.3:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+nanoid@^3.3.11:
+ version "3.3.11"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
+ integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
+
+"oidc-spa@file:../../dist":
+ version "8.1.6"
+
+picocolors@^1.0.0, picocolors@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
+ integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
+
+picomatch@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042"
+ integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==
+
+postcss@^8.5.6:
+ version "8.5.6"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c"
+ integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==
+ dependencies:
+ nanoid "^3.3.11"
+ picocolors "^1.1.1"
+ source-map-js "^1.2.1"
+
+readdirp@^4.0.1:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d"
+ integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==
+
+rollup@^4.43.0:
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.52.4.tgz#71e64cce96a865fcbaa6bb62c6e82807f4e378a1"
+ integrity sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==
+ dependencies:
+ "@types/estree" "1.0.8"
+ optionalDependencies:
+ "@rollup/rollup-android-arm-eabi" "4.52.4"
+ "@rollup/rollup-android-arm64" "4.52.4"
+ "@rollup/rollup-darwin-arm64" "4.52.4"
+ "@rollup/rollup-darwin-x64" "4.52.4"
+ "@rollup/rollup-freebsd-arm64" "4.52.4"
+ "@rollup/rollup-freebsd-x64" "4.52.4"
+ "@rollup/rollup-linux-arm-gnueabihf" "4.52.4"
+ "@rollup/rollup-linux-arm-musleabihf" "4.52.4"
+ "@rollup/rollup-linux-arm64-gnu" "4.52.4"
+ "@rollup/rollup-linux-arm64-musl" "4.52.4"
+ "@rollup/rollup-linux-loong64-gnu" "4.52.4"
+ "@rollup/rollup-linux-ppc64-gnu" "4.52.4"
+ "@rollup/rollup-linux-riscv64-gnu" "4.52.4"
+ "@rollup/rollup-linux-riscv64-musl" "4.52.4"
+ "@rollup/rollup-linux-s390x-gnu" "4.52.4"
+ "@rollup/rollup-linux-x64-gnu" "4.52.4"
+ "@rollup/rollup-linux-x64-musl" "4.52.4"
+ "@rollup/rollup-openharmony-arm64" "4.52.4"
+ "@rollup/rollup-win32-arm64-msvc" "4.52.4"
+ "@rollup/rollup-win32-ia32-msvc" "4.52.4"
+ "@rollup/rollup-win32-x64-gnu" "4.52.4"
+ "@rollup/rollup-win32-x64-msvc" "4.52.4"
+ fsevents "~2.3.2"
+
+run-exclusive@^2.2.19:
+ version "2.2.19"
+ resolved "https://registry.yarnpkg.com/run-exclusive/-/run-exclusive-2.2.19.tgz#37a2fb6e3671f8ae0d63521ebd1865fc796cf307"
+ integrity sha512-K3mdoAi7tjJ/qT7Flj90L7QyPozwUaAG+CVhkdDje4HLKXUYC3N/Jzkau3flHVDLQVhiHBtcimVodMjN9egYbA==
+ dependencies:
+ minimal-polyfills "^2.2.3"
+
+sade@^1.7.4:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
+ integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
+ dependencies:
+ mri "^1.1.0"
+
+source-map-js@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
+ integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
+
+svelte-check@^4.3.2:
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-4.3.2.tgz#cef142a3c76911cf56b975ab0c0dbf360061f49c"
+ integrity sha512-71udP5w2kaSTcX8iV0hn3o2FWlabQHhJTJLIQrCqMsrcOeDUO2VhCQKKCA8AMVHSPwdxLEWkUWh9OKxns5PD9w==
+ dependencies:
+ "@jridgewell/trace-mapping" "^0.3.25"
+ chokidar "^4.0.1"
+ fdir "^6.2.0"
+ picocolors "^1.0.0"
+ sade "^1.7.4"
+
+svelte@^5.39.6:
+ version "5.39.9"
+ resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.39.9.tgz#b1e2406592be78d2db3d2e54026c85362297790d"
+ integrity sha512-sVOie0sbU9F/Lh0IoUfaq9hLzujRKxiL7xTMbG0y8ROx/qErtbfmm6sLSlJUbUMW4NcIgqHQPFiHX4LakA8fzA==
+ dependencies:
+ "@jridgewell/remapping" "^2.3.4"
+ "@jridgewell/sourcemap-codec" "^1.5.0"
+ "@sveltejs/acorn-typescript" "^1.0.5"
+ "@types/estree" "^1.0.5"
+ acorn "^8.12.1"
+ aria-query "^5.3.1"
+ axobject-query "^4.1.0"
+ clsx "^2.1.1"
+ esm-env "^1.2.1"
+ esrap "^2.1.0"
+ is-reference "^3.0.3"
+ locate-character "^3.0.0"
+ magic-string "^0.30.11"
+ zimmerframe "^1.1.2"
+
+tinyglobby@^0.2.15:
+ version "0.2.15"
+ resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2"
+ integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==
+ dependencies:
+ fdir "^6.5.0"
+ picomatch "^4.0.3"
+
+tsafe@^1.8.5:
+ version "1.8.12"
+ resolved "https://registry.yarnpkg.com/tsafe/-/tsafe-1.8.12.tgz#68a410b4b7687ef497b1c85904b1215532335c3e"
+ integrity sha512-nFRqW0ttu/2o6XTXsHiVZWJBCOaxhVqZLg7dgs3coZNsCMPXPfwz+zPHAQA+70fNnVJLAPg1EgGIqK9Q84tvAw==
+
+typescript@~5.9.3:
+ version "5.9.3"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f"
+ integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
+
+undici-types@~7.14.0:
+ version "7.14.0"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.14.0.tgz#4c037b32ca4d7d62fae042174604341588bc0840"
+ integrity sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==
+
+vite@^7.1.7:
+ version "7.1.9"
+ resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.9.tgz#ba844410e5d0c0f2a4eaf17a52af60ebea322cbf"
+ integrity sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==
+ dependencies:
+ esbuild "^0.25.0"
+ fdir "^6.5.0"
+ picomatch "^4.0.3"
+ postcss "^8.5.6"
+ rollup "^4.43.0"
+ tinyglobby "^0.2.15"
+ optionalDependencies:
+ fsevents "~2.3.3"
+
+vitefu@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/vitefu/-/vitefu-1.1.1.tgz#c39b7e4c91bf2f6c590fb96e0758f394dff5795b"
+ integrity sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==
+
+zimmerframe@^1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/zimmerframe/-/zimmerframe-1.1.4.tgz#0352b5cafad3ad4526b0a526a9a52d9c040d865b"
+ integrity sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==
+
+zod@^4.1.11:
+ version "4.1.11"
+ resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.11.tgz#4aab62f76cfd45e6c6166519ba31b2ea019f75f5"
+ integrity sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==
diff --git a/examples/svelte/.env.local.sample b/examples/svelte/.env.local.sample
new file mode 100644
index 00000000..8ac51cc1
--- /dev/null
+++ b/examples/svelte/.env.local.sample
@@ -0,0 +1,24 @@
+# Pick one of the following configurations, those are not mock credentials, you can use them for testing purposes.
+
+# ======= Keycloak =================
+VITE_OIDC_ISSUER_URI=https://cloud-iam.oidc-spa.dev/realms/oidc-spa
+VITE_OIDC_CLIENT_ID=example-react-router
+
+# ======= Microsoft Entra ID =======
+#VITE_OIDC_ISSUER_URI=https://login.microsoftonline.com/71a0a621-363a-4182-8209-86364aa6de03/v2.0
+#VITE_OIDC_CLIENT_ID=3c8f72b4-4dd9-4aa2-a01d-43349ba90394
+#VITE_OIDC_SCOPE="profile api://example-multi-providers/access_as_user"
+
+# ======= Google OAuth =============
+#VITE_OIDC_ISSUER_URI=https://accounts.google.com
+#VITE_OIDC_CLIENT_ID=928024164279-ifjvmsffi64slkk81h3gmoh7p03ev68k.apps.googleusercontent.com
+#VITE_OIDC_CLIENT_SECRET=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
+#VITE_OIDC_USE_ID_TOKEN_AS_ACCESS_TOKEN=true
+#VITE_OIDC_SCOPE="profile email"
+
+# ======= Auth0 ====================
+#VITE_OIDC_ISSUER_URI=https://auth0.oidc-spa.dev
+#VITE_OIDC_CLIENT_ID=DkoDtyQkYj4UPk3gKk4MjtnD9nskUhpt
+#VITE_OIDC_AUDIENCE=https://oidc-spa-example
+#VITE_OIDC_SSO_SESSION_IDLE_SECONDS=120
+
diff --git a/examples/svelte/.gitignore b/examples/svelte/.gitignore
new file mode 100644
index 00000000..a547bf36
--- /dev/null
+++ b/examples/svelte/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/examples/svelte/README.md b/examples/svelte/README.md
new file mode 100644
index 00000000..4b6673d6
--- /dev/null
+++ b/examples/svelte/README.md
@@ -0,0 +1,47 @@
+# Svelte + TS + Vite
+
+This template should help get you started developing with Svelte and TypeScript in Vite.
+
+## Recommended IDE Setup
+
+[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
+
+## Need an official Svelte framework?
+
+Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more.
+
+## Technical considerations
+
+**Why use this over SvelteKit?**
+
+- It brings its own routing solution which might not be preferable for some users.
+- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
+
+This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project.
+
+Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate.
+
+**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
+
+Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information.
+
+**Why include `.vscode/extensions.json`?**
+
+Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project.
+
+**Why enable `allowJs` in the TS template?**
+
+While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant.
+
+**Why is HMR not preserving my local component state?**
+
+HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior.
+
+If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. You can read the details in the [svelte-hmr documentation](https://github.com/rixo/svelte-hmr#svelte-hmr).
+
+```ts
+// store.ts
+// An extremely simple external store
+import { writable } from "svelte/store";
+export default writable(0);
+```
diff --git a/examples/svelte/index.html b/examples/svelte/index.html
new file mode 100644
index 00000000..7f606e0d
--- /dev/null
+++ b/examples/svelte/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite + Svelte + TS
+
+
+
+
+
+
diff --git a/examples/svelte/package.json b/examples/svelte/package.json
new file mode 100644
index 00000000..364efbcd
--- /dev/null
+++ b/examples/svelte/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "svelte",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "prepare": "[ ! -f .env.local ] && cp .env.local.sample .env.local || true",
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json"
+ },
+ "dependencies": {
+ "oidc-spa": "file:../../dist"
+ },
+ "devDependencies": {
+ "@mateothegreat/svelte5-router": "^2.16.19",
+ "@sveltejs/vite-plugin-svelte": "^6.2.1",
+ "@tsconfig/svelte": "^5.0.5",
+ "@types/node": "^24.6.0",
+ "svelte": "^5.39.6",
+ "svelte-check": "^4.3.2",
+ "typescript": "~5.9.3",
+ "vite": "^7.1.7",
+ "zod": "^4.1.11"
+ }
+}
diff --git a/examples/svelte/src/App.svelte b/examples/svelte/src/App.svelte
new file mode 100644
index 00000000..293450d3
--- /dev/null
+++ b/examples/svelte/src/App.svelte
@@ -0,0 +1,34 @@
+
+
+{#if oidcOrInitializationError === undefined}
+ Loading...
+{:else if isOidcInitializationError(oidcOrInitializationError)}
+ {@const initializationError = oidcOrInitializationError}
+
+ An error occurred while initializing the OIDC client:
+ {initializationError.message}
+
+{:else}
+ {@const oidc = oidcOrInitializationError}
+
+
+
+
+
+{/if}
diff --git a/examples/svelte/src/app.css b/examples/svelte/src/app.css
new file mode 100644
index 00000000..6a9b32cb
--- /dev/null
+++ b/examples/svelte/src/app.css
@@ -0,0 +1,96 @@
+:root {
+ font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+.card {
+ padding: 2em;
+}
+
+#app {
+ max-width: 1280px;
+ margin: 0 auto;
+ padding: 2rem;
+ text-align: center;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ }
+}
+
+.logo {
+ height: 6em;
+ padding: 1.5em;
+ will-change: filter;
+ transition: filter 300ms;
+}
+.logo:hover {
+ filter: drop-shadow(0 0 2em #646cffaa);
+}
+.logo.svelte:hover {
+ filter: drop-shadow(0 0 2em #ff3e00aa);
+}
+
+.read-the-docs {
+ color: #888;
+}
diff --git a/examples/svelte/src/assets/svelte.svg b/examples/svelte/src/assets/svelte.svg
new file mode 100644
index 00000000..c5e08481
--- /dev/null
+++ b/examples/svelte/src/assets/svelte.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/examples/svelte/src/assets/vite.svg b/examples/svelte/src/assets/vite.svg
new file mode 100644
index 00000000..e7b8dfb1
--- /dev/null
+++ b/examples/svelte/src/assets/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/examples/svelte/src/components/AutoLogoutWarningOverlay.svelte b/examples/svelte/src/components/AutoLogoutWarningOverlay.svelte
new file mode 100644
index 00000000..f860bf73
--- /dev/null
+++ b/examples/svelte/src/components/AutoLogoutWarningOverlay.svelte
@@ -0,0 +1,17 @@
+
+
+{#if $secondsLeft}
+
+
+
Are you still there?
+
You will be logged out in {$secondsLeft}
+
+
+{/if}
diff --git a/examples/svelte/src/components/Header.svelte b/examples/svelte/src/components/Header.svelte
new file mode 100644
index 00000000..42bd51b0
--- /dev/null
+++ b/examples/svelte/src/components/Header.svelte
@@ -0,0 +1,35 @@
+
+
+
+
OIDC-SPA + Svelte5 Router
+
+ {#if initializationError !== undefined}
+
+ {initializationError.isAuthServerLikelyDown
+ ? "Sorry our Auth server is down"
+ : `Initialization error: ${initializationError.message}`}
+
+ {/if}
+
+
+ {#if isUserLoggedIn}
+
+ {:else}
+
+ {/if}
+
diff --git a/examples/svelte/src/components/LoggedInAuthButton.svelte b/examples/svelte/src/components/LoggedInAuthButton.svelte
new file mode 100644
index 00000000..d669a0c2
--- /dev/null
+++ b/examples/svelte/src/components/LoggedInAuthButton.svelte
@@ -0,0 +1,11 @@
+
+
+
+ Hello {decodedIdToken.name}
+
+ logout({ redirectTo: "home" })}>Logout
+
diff --git a/examples/svelte/src/components/NotLoggedInAuthButton.svelte b/examples/svelte/src/components/NotLoggedInAuthButton.svelte
new file mode 100644
index 00000000..9dfe9b0b
--- /dev/null
+++ b/examples/svelte/src/components/NotLoggedInAuthButton.svelte
@@ -0,0 +1,39 @@
+
+
+
+ login()}>Login
+ {#if keycloakUtils !== undefined}
+
+ login({
+ transformUrlBeforeRedirect: keycloakUtils.transformUrlBeforeRedirectForRegister
+ })}
+ >
+ Register
+
+ {/if}
+ {#if isAuth0}
+
+ login({
+ extraQueryParams: {
+ screen_hint: "signup"
+ }
+ })}
+ >
+ Register
+
+ {/if}
+
diff --git a/examples/svelte/src/env.d.ts b/examples/svelte/src/env.d.ts
new file mode 100644
index 00000000..d8d2aae8
--- /dev/null
+++ b/examples/svelte/src/env.d.ts
@@ -0,0 +1,10 @@
+///
+
+interface ImportMetaEnv {
+ readonly VITE_OIDC_ISSUER_URI: string;
+ readonly VITE_OIDC_CLIENT_ID: string;
+}
+
+interface ImportMeta {
+ readonly env: ImportMetaEnv;
+}
diff --git a/examples/svelte/src/main.lazy.ts b/examples/svelte/src/main.lazy.ts
new file mode 100644
index 00000000..bd2a980a
--- /dev/null
+++ b/examples/svelte/src/main.lazy.ts
@@ -0,0 +1,12 @@
+import { mount } from "svelte";
+import "./app.css";
+import App from "./App.svelte";
+
+const appElement = document.getElementById("app");
+if (!appElement) {
+ throw new Error("Could not find #app element");
+}
+
+const app = mount(App, { target: appElement });
+
+export default app;
diff --git a/examples/svelte/src/main.ts b/examples/svelte/src/main.ts
new file mode 100644
index 00000000..dcd26f56
--- /dev/null
+++ b/examples/svelte/src/main.ts
@@ -0,0 +1,11 @@
+import { oidcEarlyInit } from "oidc-spa/entrypoint";
+
+const { shouldLoadApp } = oidcEarlyInit({
+ freezeFetch: true,
+ freezeXMLHttpRequest: true,
+ freezeWebSocket: true
+});
+
+if (shouldLoadApp) {
+ import("./main.lazy");
+}
diff --git a/examples/svelte/src/oidc.ts b/examples/svelte/src/oidc.ts
new file mode 100644
index 00000000..ed78c060
--- /dev/null
+++ b/examples/svelte/src/oidc.ts
@@ -0,0 +1,32 @@
+import { createSvelteOidc } from "oidc-spa/svelte";
+import { createMockSvelteOidc } from "oidc-spa/mock/svelte";
+import { z } from "zod";
+
+const decodedIdTokenSchema = z.object({
+ sub: z.string(),
+ name: z.string()
+});
+
+const autoLogin = false;
+
+export const { initializeOidc, OidcContextProvider, useOidc, getOidc, enforceLogin } = !import.meta.env
+ .VITE_OIDC_ISSUER_URI
+ ? createMockSvelteOidc({
+ homeUrl: import.meta.env.BASE_URL,
+ mockedTokens: {
+ decodedIdToken: {
+ sub: "123",
+ name: "John"
+ } satisfies z.infer
+ },
+ // NOTE: If autoLogin is set to true this option must be removed
+ isUserInitiallyLoggedIn: true,
+ autoLogin
+ })
+ : createSvelteOidc({
+ issuerUri: import.meta.env.VITE_OIDC_ISSUER_URI,
+ clientId: import.meta.env.VITE_OIDC_CLIENT_ID,
+ homeUrl: import.meta.env.BASE_URL,
+ decodedIdTokenSchema,
+ autoLogin
+ });
diff --git a/examples/svelte/src/pages/ProtectedPage.svelte b/examples/svelte/src/pages/ProtectedPage.svelte
new file mode 100644
index 00000000..688c830f
--- /dev/null
+++ b/examples/svelte/src/pages/ProtectedPage.svelte
@@ -0,0 +1,157 @@
+
+
+{#if $decodedAccessToken !== undefined}
+
+ Hello {decodedIdToken.name}
+
+
+ {#if $decodedAccessToken !== null}
+ Decoded Access Token:
+ {JSON.stringify(
+ $decodedAccessToken,
+ null,
+ 2
+ )}
+ {:else}
+ The Access Token issued by the IDP is opaque (Not a JWT).
+ {/if}
+
+ renewTokens()}>Renew tokens
+
+ {#if keycloakUtils !== undefined}
+
+
+ goToAuthServer({
+ extraQueryParams: { kc_action: "UPDATE_PASSWORD" }
+ })}
+ >
+ Change Password
+
+ {#if backFromAuthServer?.extraQueryParams.kc_action === "UPDATE_PASSWORD"}
+ Result: {backFromAuthServer.result.kc_action_status}
+ {/if}
+
+
+ goToAuthServer({
+ extraQueryParams: { kc_action: "UPDATE_PROFILE" }
+ })}
+ >
+ Update profile
+
+ {#if backFromAuthServer?.extraQueryParams.kc_action === "UPDATE_PROFILE"}
+ Result: {backFromAuthServer.result.kc_action_status}
+ {/if}
+
+
+ goToAuthServer({
+ extraQueryParams: { kc_action: "delete_account" }
+ })}
+ >
+ Delete account
+
+
+
+ Go to Keycloak Account Management Console
+
+ {/if}
+
+{/if}
diff --git a/examples/svelte/src/pages/PublicPage.svelte b/examples/svelte/src/pages/PublicPage.svelte
new file mode 100644
index 00000000..8a2625e0
--- /dev/null
+++ b/examples/svelte/src/pages/PublicPage.svelte
@@ -0,0 +1,14 @@
+
+
+
+This is a page that do not requires the user to be authenticated
diff --git a/examples/svelte/src/routes.ts b/examples/svelte/src/routes.ts
new file mode 100644
index 00000000..96bb11fd
--- /dev/null
+++ b/examples/svelte/src/routes.ts
@@ -0,0 +1,21 @@
+import { type RouteConfig } from "@mateothegreat/svelte5-router";
+import { enforceLogin, getOidc } from "./oidc";
+import ProtectedPage from "./pages/ProtectedPage.svelte";
+import PublicPage from "./pages/PublicPage.svelte";
+
+export const routes: RouteConfig[] = [
+ {
+ component: PublicPage
+ },
+ {
+ path: "protected",
+ component: ProtectedPage,
+ hooks: {
+ pre: async route => {
+ return enforceLogin({
+ location: { href: `${window.origin}/${route.result.path.original}` }
+ });
+ }
+ }
+ }
+];
diff --git a/examples/svelte/src/vite-env.d.ts b/examples/svelte/src/vite-env.d.ts
new file mode 100644
index 00000000..11f02fe2
--- /dev/null
+++ b/examples/svelte/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/examples/svelte/svelte.config.js b/examples/svelte/svelte.config.js
new file mode 100644
index 00000000..96b34554
--- /dev/null
+++ b/examples/svelte/svelte.config.js
@@ -0,0 +1,8 @@
+import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
+
+/** @type {import("@sveltejs/vite-plugin-svelte").SvelteConfig} */
+export default {
+ // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
+ // for more information about preprocessors
+ preprocess: vitePreprocess(),
+}
diff --git a/examples/svelte/tsconfig.app.json b/examples/svelte/tsconfig.app.json
new file mode 100644
index 00000000..f3e467e1
--- /dev/null
+++ b/examples/svelte/tsconfig.app.json
@@ -0,0 +1,21 @@
+{
+ "extends": "@tsconfig/svelte/tsconfig.json",
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "module": "ESNext",
+ "types": ["svelte", "vite/client"],
+ "noEmit": true,
+ /**
+ * Typecheck JS in `.svelte` and `.js` files by default.
+ * Disable checkJs if you'd like to use dynamic types in JS.
+ * Note that setting allowJs false does not prevent the use
+ * of JS in `.svelte` files.
+ */
+ "allowJs": true,
+ "checkJs": true,
+ "moduleDetection": "force"
+ },
+ "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"]
+}
diff --git a/examples/svelte/tsconfig.json b/examples/svelte/tsconfig.json
new file mode 100644
index 00000000..eb69b0d0
--- /dev/null
+++ b/examples/svelte/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "files": [],
+ "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
+}
diff --git a/examples/svelte/tsconfig.node.json b/examples/svelte/tsconfig.node.json
new file mode 100644
index 00000000..0cc4c356
--- /dev/null
+++ b/examples/svelte/tsconfig.node.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ "target": "ES2023",
+ "lib": ["ES2023"],
+ "module": "ESNext",
+ "types": ["node"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/examples/svelte/vite.config.ts b/examples/svelte/vite.config.ts
new file mode 100644
index 00000000..efd89994
--- /dev/null
+++ b/examples/svelte/vite.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig } from "vite";
+import { svelte } from "@sveltejs/vite-plugin-svelte";
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [svelte()],
+ build: {
+ sourcemap: true // If you want to use a debugger, add this!
+ },
+ define: {
+ // Tell the router to log when we're in debug mode.
+ // Otherwise, this statement is removed by the compiler (known as tree-shaking)
+ // and all subsequent log statements are removed at build time:
+ "import.meta.env.SPA_ROUTER": {
+ logLevel: "debug"
+ }
+ }
+});
diff --git a/examples/svelte/yarn.lock b/examples/svelte/yarn.lock
new file mode 100644
index 00000000..b24e2a79
--- /dev/null
+++ b/examples/svelte/yarn.lock
@@ -0,0 +1,597 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@esbuild/aix-ppc64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz#ee6b7163a13528e099ecf562b972f2bcebe0aa97"
+ integrity sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==
+
+"@esbuild/android-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz#115fc76631e82dd06811bfaf2db0d4979c16e2cb"
+ integrity sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==
+
+"@esbuild/android-arm@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.10.tgz#8d5811912da77f615398611e5bbc1333fe321aa9"
+ integrity sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==
+
+"@esbuild/android-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.10.tgz#e3e96516b2d50d74105bb92594c473e30ddc16b1"
+ integrity sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==
+
+"@esbuild/darwin-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz#6af6bb1d05887dac515de1b162b59dc71212ed76"
+ integrity sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==
+
+"@esbuild/darwin-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz#99ae82347fbd336fc2d28ffd4f05694e6e5b723d"
+ integrity sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==
+
+"@esbuild/freebsd-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz#0c6d5558a6322b0bdb17f7025c19bd7d2359437d"
+ integrity sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==
+
+"@esbuild/freebsd-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz#8c35873fab8c0857a75300a3dcce4324ca0b9844"
+ integrity sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==
+
+"@esbuild/linux-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz#3edc2f87b889a15b4cedaf65f498c2bed7b16b90"
+ integrity sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==
+
+"@esbuild/linux-arm@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz#86501cfdfb3d110176d80c41b27ed4611471cde7"
+ integrity sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==
+
+"@esbuild/linux-ia32@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz#e6589877876142537c6864680cd5d26a622b9d97"
+ integrity sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==
+
+"@esbuild/linux-loong64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz#11119e18781f136d8083ea10eb6be73db7532de8"
+ integrity sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==
+
+"@esbuild/linux-mips64el@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz#3052f5436b0c0c67a25658d5fc87f045e7def9e6"
+ integrity sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==
+
+"@esbuild/linux-ppc64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz#2f098920ee5be2ce799f35e367b28709925a8744"
+ integrity sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==
+
+"@esbuild/linux-riscv64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz#fa51d7fd0a22a62b51b4b94b405a3198cf7405dd"
+ integrity sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==
+
+"@esbuild/linux-s390x@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz#a27642e36fc282748fdb38954bd3ef4f85791e8a"
+ integrity sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==
+
+"@esbuild/linux-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz#9d9b09c0033d17529570ced6d813f98315dfe4e9"
+ integrity sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==
+
+"@esbuild/netbsd-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz#25c09a659c97e8af19e3f2afd1c9190435802151"
+ integrity sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==
+
+"@esbuild/netbsd-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz#7fa5f6ffc19be3a0f6f5fd32c90df3dc2506937a"
+ integrity sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==
+
+"@esbuild/openbsd-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz#8faa6aa1afca0c6d024398321d6cb1c18e72a1c3"
+ integrity sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==
+
+"@esbuild/openbsd-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz#a42979b016f29559a8453d32440d3c8cd420af5e"
+ integrity sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==
+
+"@esbuild/openharmony-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz#fd87bfeadd7eeb3aa384bbba907459ffa3197cb1"
+ integrity sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==
+
+"@esbuild/sunos-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz#3a18f590e36cb78ae7397976b760b2b8c74407f4"
+ integrity sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==
+
+"@esbuild/win32-arm64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz#e71741a251e3fd971408827a529d2325551f530c"
+ integrity sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==
+
+"@esbuild/win32-ia32@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz#c6f010b5d3b943d8901a0c87ea55f93b8b54bf94"
+ integrity sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==
+
+"@esbuild/win32-x64@0.25.10":
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz#e4b3e255a1b4aea84f6e1d2ae0b73f826c3785bd"
+ integrity sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==
+
+"@jridgewell/gen-mapping@^0.3.5":
+ version "0.3.13"
+ resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f"
+ integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.0"
+ "@jridgewell/trace-mapping" "^0.3.24"
+
+"@jridgewell/remapping@^2.3.4":
+ version "2.3.5"
+ resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1"
+ integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.3.5"
+ "@jridgewell/trace-mapping" "^0.3.24"
+
+"@jridgewell/resolve-uri@^3.1.0":
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
+ integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
+
+"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5":
+ version "1.5.5"
+ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
+ integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
+
+"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
+ version "0.3.31"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0"
+ integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.1.0"
+ "@jridgewell/sourcemap-codec" "^1.4.14"
+
+"@mateothegreat/svelte5-router@^2.16.19":
+ version "2.16.19"
+ resolved "https://registry.yarnpkg.com/@mateothegreat/svelte5-router/-/svelte5-router-2.16.19.tgz#f14b4b3206e3b70fbbbdd3e9e05c6c5a1bd17d3d"
+ integrity sha512-SNkR15x3b0HLNM33BORKF9U6elHHWZxg42yikNUKW1YNjkYRBLBgDkVSJTqRIC6aE8Wt4vqmKKmHzQTK2EKiqA==
+
+"@rollup/rollup-android-arm-eabi@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz#59e7478d310f7e6a7c72453978f562483828112f"
+ integrity sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==
+
+"@rollup/rollup-android-arm64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz#a825192a0b1b2f27a5c950c439e7e37a33c5d056"
+ integrity sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==
+
+"@rollup/rollup-darwin-arm64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz#4ee37078bccd725ae3c5f30ef92efc8e1bf886f3"
+ integrity sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==
+
+"@rollup/rollup-darwin-x64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz#43cc08bd05bf9f388f125e7210a544e62d368d90"
+ integrity sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==
+
+"@rollup/rollup-freebsd-arm64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz#bc8e640e28abe52450baf3fc80d9b26d9bb6587d"
+ integrity sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==
+
+"@rollup/rollup-freebsd-x64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz#e981a22e057cc8c65bb523019d344d3a66b15bbc"
+ integrity sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==
+
+"@rollup/rollup-linux-arm-gnueabihf@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz#4036b68904f392a20f3499d63b33e055b67eb274"
+ integrity sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==
+
+"@rollup/rollup-linux-arm-musleabihf@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz#d3b1b9589606e0ff916801c855b1ace9e733427a"
+ integrity sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==
+
+"@rollup/rollup-linux-arm64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz#cbf0943c477e3b96340136dd3448eaf144378cf2"
+ integrity sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==
+
+"@rollup/rollup-linux-arm64-musl@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz#837f5a428020d5dce1c3b4cc049876075402cf78"
+ integrity sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==
+
+"@rollup/rollup-linux-loong64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz#532c214ababb32ab4bc21b4054278b9a8979e516"
+ integrity sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==
+
+"@rollup/rollup-linux-ppc64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz#93900163b61b49cee666d10ee38257a8b1dd161a"
+ integrity sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==
+
+"@rollup/rollup-linux-riscv64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz#f0ffdcc7066ca04bc972370c74289f35c7a7dc42"
+ integrity sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==
+
+"@rollup/rollup-linux-riscv64-musl@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz#361695c39dbe96773509745d77a870a32a9f8e48"
+ integrity sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==
+
+"@rollup/rollup-linux-s390x-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz#09fc6cc2e266a2324e366486ae5d1bca48c43a6a"
+ integrity sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==
+
+"@rollup/rollup-linux-x64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz#aa9d5b307c08f05d3454225bb0a2b4cc87eeb2e1"
+ integrity sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==
+
+"@rollup/rollup-linux-x64-musl@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz#26949e5b4645502a61daba2f7a8416bd17cb5382"
+ integrity sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==
+
+"@rollup/rollup-openharmony-arm64@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz#ef493c072f9dac7e0edb6c72d63366846b6ffcd9"
+ integrity sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==
+
+"@rollup/rollup-win32-arm64-msvc@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz#56e1aaa6a630d2202ee7ec0adddd05cf384ffd44"
+ integrity sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==
+
+"@rollup/rollup-win32-ia32-msvc@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz#0a44bbf933a9651c7da2b8569fa448dec0de7480"
+ integrity sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==
+
+"@rollup/rollup-win32-x64-gnu@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz#730e12f0b60b234a7c02d5d3179ca3ec7972033d"
+ integrity sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==
+
+"@rollup/rollup-win32-x64-msvc@4.52.4":
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz#5b2dd648a960b8fa00d76f2cc4eea2f03daa80f4"
+ integrity sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==
+
+"@sveltejs/acorn-typescript@^1.0.5":
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.6.tgz#ca236a97d895869138091c6fba100114951daa97"
+ integrity sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==
+
+"@sveltejs/vite-plugin-svelte-inspector@^5.0.0":
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.1.tgz#3d35254b76e07551ea8921029a96d99b94ffbc5c"
+ integrity sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==
+ dependencies:
+ debug "^4.4.1"
+
+"@sveltejs/vite-plugin-svelte@^6.2.1":
+ version "6.2.1"
+ resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.1.tgz#3414c10aaacce8f23a8db2a37926da00ab7a78cb"
+ integrity sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==
+ dependencies:
+ "@sveltejs/vite-plugin-svelte-inspector" "^5.0.0"
+ debug "^4.4.1"
+ deepmerge "^4.3.1"
+ magic-string "^0.30.17"
+ vitefu "^1.1.1"
+
+"@tsconfig/svelte@^5.0.5":
+ version "5.0.5"
+ resolved "https://registry.yarnpkg.com/@tsconfig/svelte/-/svelte-5.0.5.tgz#781df887c6a41b574e6972f9e002cea7edf4f450"
+ integrity sha512-48fAnUjKye38FvMiNOj0J9I/4XlQQiZlpe9xaNPfe8vy2Y1hFBt8g1yqf2EGjVvHavo4jf2lC+TQyENCr4BJBQ==
+
+"@types/estree@1.0.8", "@types/estree@^1.0.5", "@types/estree@^1.0.6":
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
+ integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
+
+"@types/node@^24.6.0":
+ version "24.7.0"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-24.7.0.tgz#a34c9f0d3401db396782e440317dd5d8373c286f"
+ integrity sha512-IbKooQVqUBrlzWTi79E8Fw78l8k1RNtlDDNWsFZs7XonuQSJ8oNYfEeclhprUldXISRMLzBpILuKgPlIxm+/Yw==
+ dependencies:
+ undici-types "~7.14.0"
+
+acorn@^8.12.1:
+ version "8.15.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816"
+ integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
+
+aria-query@^5.3.1:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59"
+ integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==
+
+axobject-query@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee"
+ integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==
+
+chokidar@^4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30"
+ integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==
+ dependencies:
+ readdirp "^4.0.1"
+
+clsx@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
+ integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
+
+debug@^4.4.1:
+ version "4.4.3"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
+ integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
+ dependencies:
+ ms "^2.1.3"
+
+deepmerge@^4.3.1:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
+ integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
+
+esbuild@^0.25.0:
+ version "0.25.10"
+ resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.10.tgz#37f5aa5cd14500f141be121c01b096ca83ac34a9"
+ integrity sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==
+ optionalDependencies:
+ "@esbuild/aix-ppc64" "0.25.10"
+ "@esbuild/android-arm" "0.25.10"
+ "@esbuild/android-arm64" "0.25.10"
+ "@esbuild/android-x64" "0.25.10"
+ "@esbuild/darwin-arm64" "0.25.10"
+ "@esbuild/darwin-x64" "0.25.10"
+ "@esbuild/freebsd-arm64" "0.25.10"
+ "@esbuild/freebsd-x64" "0.25.10"
+ "@esbuild/linux-arm" "0.25.10"
+ "@esbuild/linux-arm64" "0.25.10"
+ "@esbuild/linux-ia32" "0.25.10"
+ "@esbuild/linux-loong64" "0.25.10"
+ "@esbuild/linux-mips64el" "0.25.10"
+ "@esbuild/linux-ppc64" "0.25.10"
+ "@esbuild/linux-riscv64" "0.25.10"
+ "@esbuild/linux-s390x" "0.25.10"
+ "@esbuild/linux-x64" "0.25.10"
+ "@esbuild/netbsd-arm64" "0.25.10"
+ "@esbuild/netbsd-x64" "0.25.10"
+ "@esbuild/openbsd-arm64" "0.25.10"
+ "@esbuild/openbsd-x64" "0.25.10"
+ "@esbuild/openharmony-arm64" "0.25.10"
+ "@esbuild/sunos-x64" "0.25.10"
+ "@esbuild/win32-arm64" "0.25.10"
+ "@esbuild/win32-ia32" "0.25.10"
+ "@esbuild/win32-x64" "0.25.10"
+
+esm-env@^1.2.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.2.2.tgz#263c9455c55861f41618df31b20cb571fc20b75e"
+ integrity sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==
+
+esrap@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/esrap/-/esrap-2.1.0.tgz#70df8f20129df3ad82f20e306dc4000dd5947813"
+ integrity sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.4.15"
+
+fdir@^6.2.0, fdir@^6.5.0:
+ version "6.5.0"
+ resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350"
+ integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==
+
+fsevents@~2.3.2, fsevents@~2.3.3:
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
+ integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
+
+is-reference@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.3.tgz#9ef7bf9029c70a67b2152da4adf57c23d718910f"
+ integrity sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==
+ dependencies:
+ "@types/estree" "^1.0.6"
+
+locate-character@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/locate-character/-/locate-character-3.0.0.tgz#0305c5b8744f61028ef5d01f444009e00779f974"
+ integrity sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==
+
+magic-string@^0.30.11, magic-string@^0.30.17:
+ version "0.30.19"
+ resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.19.tgz#cebe9f104e565602e5d2098c5f2e79a77cc86da9"
+ integrity sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.5"
+
+mri@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
+ integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
+
+ms@^2.1.3:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+nanoid@^3.3.11:
+ version "3.3.11"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
+ integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
+
+"oidc-spa@file:../../dist":
+ version "8.1.6"
+
+picocolors@^1.0.0, picocolors@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
+ integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
+
+picomatch@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042"
+ integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==
+
+postcss@^8.5.6:
+ version "8.5.6"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c"
+ integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==
+ dependencies:
+ nanoid "^3.3.11"
+ picocolors "^1.1.1"
+ source-map-js "^1.2.1"
+
+readdirp@^4.0.1:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d"
+ integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==
+
+rollup@^4.43.0:
+ version "4.52.4"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.52.4.tgz#71e64cce96a865fcbaa6bb62c6e82807f4e378a1"
+ integrity sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==
+ dependencies:
+ "@types/estree" "1.0.8"
+ optionalDependencies:
+ "@rollup/rollup-android-arm-eabi" "4.52.4"
+ "@rollup/rollup-android-arm64" "4.52.4"
+ "@rollup/rollup-darwin-arm64" "4.52.4"
+ "@rollup/rollup-darwin-x64" "4.52.4"
+ "@rollup/rollup-freebsd-arm64" "4.52.4"
+ "@rollup/rollup-freebsd-x64" "4.52.4"
+ "@rollup/rollup-linux-arm-gnueabihf" "4.52.4"
+ "@rollup/rollup-linux-arm-musleabihf" "4.52.4"
+ "@rollup/rollup-linux-arm64-gnu" "4.52.4"
+ "@rollup/rollup-linux-arm64-musl" "4.52.4"
+ "@rollup/rollup-linux-loong64-gnu" "4.52.4"
+ "@rollup/rollup-linux-ppc64-gnu" "4.52.4"
+ "@rollup/rollup-linux-riscv64-gnu" "4.52.4"
+ "@rollup/rollup-linux-riscv64-musl" "4.52.4"
+ "@rollup/rollup-linux-s390x-gnu" "4.52.4"
+ "@rollup/rollup-linux-x64-gnu" "4.52.4"
+ "@rollup/rollup-linux-x64-musl" "4.52.4"
+ "@rollup/rollup-openharmony-arm64" "4.52.4"
+ "@rollup/rollup-win32-arm64-msvc" "4.52.4"
+ "@rollup/rollup-win32-ia32-msvc" "4.52.4"
+ "@rollup/rollup-win32-x64-gnu" "4.52.4"
+ "@rollup/rollup-win32-x64-msvc" "4.52.4"
+ fsevents "~2.3.2"
+
+sade@^1.7.4:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
+ integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
+ dependencies:
+ mri "^1.1.0"
+
+source-map-js@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
+ integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
+
+svelte-check@^4.3.2:
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-4.3.2.tgz#cef142a3c76911cf56b975ab0c0dbf360061f49c"
+ integrity sha512-71udP5w2kaSTcX8iV0hn3o2FWlabQHhJTJLIQrCqMsrcOeDUO2VhCQKKCA8AMVHSPwdxLEWkUWh9OKxns5PD9w==
+ dependencies:
+ "@jridgewell/trace-mapping" "^0.3.25"
+ chokidar "^4.0.1"
+ fdir "^6.2.0"
+ picocolors "^1.0.0"
+ sade "^1.7.4"
+
+svelte@^5.39.6:
+ version "5.39.9"
+ resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.39.9.tgz#b1e2406592be78d2db3d2e54026c85362297790d"
+ integrity sha512-sVOie0sbU9F/Lh0IoUfaq9hLzujRKxiL7xTMbG0y8ROx/qErtbfmm6sLSlJUbUMW4NcIgqHQPFiHX4LakA8fzA==
+ dependencies:
+ "@jridgewell/remapping" "^2.3.4"
+ "@jridgewell/sourcemap-codec" "^1.5.0"
+ "@sveltejs/acorn-typescript" "^1.0.5"
+ "@types/estree" "^1.0.5"
+ acorn "^8.12.1"
+ aria-query "^5.3.1"
+ axobject-query "^4.1.0"
+ clsx "^2.1.1"
+ esm-env "^1.2.1"
+ esrap "^2.1.0"
+ is-reference "^3.0.3"
+ locate-character "^3.0.0"
+ magic-string "^0.30.11"
+ zimmerframe "^1.1.2"
+
+tinyglobby@^0.2.15:
+ version "0.2.15"
+ resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2"
+ integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==
+ dependencies:
+ fdir "^6.5.0"
+ picomatch "^4.0.3"
+
+typescript@~5.9.3:
+ version "5.9.3"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f"
+ integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
+
+undici-types@~7.14.0:
+ version "7.14.0"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.14.0.tgz#4c037b32ca4d7d62fae042174604341588bc0840"
+ integrity sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==
+
+vite@^7.1.7:
+ version "7.1.9"
+ resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.9.tgz#ba844410e5d0c0f2a4eaf17a52af60ebea322cbf"
+ integrity sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==
+ dependencies:
+ esbuild "^0.25.0"
+ fdir "^6.5.0"
+ picomatch "^4.0.3"
+ postcss "^8.5.6"
+ rollup "^4.43.0"
+ tinyglobby "^0.2.15"
+ optionalDependencies:
+ fsevents "~2.3.3"
+
+vitefu@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/vitefu/-/vitefu-1.1.1.tgz#c39b7e4c91bf2f6c590fb96e0758f394dff5795b"
+ integrity sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==
+
+zimmerframe@^1.1.2:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/zimmerframe/-/zimmerframe-1.1.4.tgz#0352b5cafad3ad4526b0a526a9a52d9c040d865b"
+ integrity sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==
+
+zod@^4.1.11:
+ version "4.1.11"
+ resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.11.tgz#4aab62f76cfd45e6c6166519ba31b2ea019f75f5"
+ integrity sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==
diff --git a/package.json b/package.json
index b6752590..fc05a988 100755
--- a/package.json
+++ b/package.json
@@ -48,11 +48,12 @@
"homepage": "https://docs.oidc-spa.dev/",
"dependencies": {},
"peerDependencies": {
+ "@angular/core": "*",
+ "@angular/router": "*",
"@types/react": "*",
"react": "*",
"rxjs": "*",
- "@angular/core": "*",
- "@angular/router": "*"
+ "svelte": "*"
},
"peerDependenciesMeta": {
"react": {
@@ -69,9 +70,16 @@
},
"@angular/router": {
"optional": true
+ },
+ "svelte": {
+ "optional": true
}
},
"devDependencies": {
+ "@angular/common": "^20.3.1",
+ "@angular/core": "^20.3.1",
+ "@angular/platform-browser": "^20.3.1",
+ "@angular/router": "^20.3.1",
"@babel/core": "7.24.9",
"@babel/preset-env": "7.24.8",
"@types/jsonwebtoken": "9.0.6",
@@ -91,6 +99,9 @@
"prettier": "^2.8.8",
"punycode": "^2.3.1",
"react": "19.1.1",
+ "rxjs": "^7.8.2",
+ "svelte": "^5.39.8",
+ "svelte-loader": "^3.2.4",
"ts-node": "^10.9.1",
"tsafe": "^1.8.12",
"tsx": "^4.15.5",
@@ -98,12 +109,7 @@
"webpack": "5.93.0",
"webpack-cli": "5.1.4",
"worker-timers": "7.1.7",
- "zod": "^3.23.8",
- "rxjs": "^7.8.2",
- "@angular/core": "^20.3.1",
- "@angular/router": "^20.3.1",
- "@angular/common": "^20.3.1",
- "@angular/platform-browser": "^20.3.1"
+ "zod": "^3.23.8"
},
"publishConfig": {
"access": "public"
@@ -130,10 +136,19 @@
"types": "./dist/esm/angular.d.ts",
"default": "./dist/esm/angular.js"
},
+ "./svelte": {
+ "module": "./dist/esm/svelte/index.svelte.js",
+ "types": "./dist/esm/svelte/index.svelte.d.ts",
+ "default": "./dist/esm/svelte/index.svelte.js"
+ },
"./mock/react": {
"module": "./dist/esm/mock/react.js",
"default": "./dist/mock/react.js"
},
+ "./mock/svelte": {
+ "module": "./dist/esm/mock/svelte.js",
+ "default": "./dist/mock/svelte.js"
+ },
"./entrypoint": {
"module": "./dist/esm/entrypoint.js",
"default": "./dist/entrypoint.js"
diff --git a/scripts/build.ts b/scripts/build.ts
index 64449ed0..82c92bcd 100644
--- a/scripts/build.ts
+++ b/scripts/build.ts
@@ -69,6 +69,24 @@ for (const targetFormat of ["cjs", "esm"] as const) {
break;
case "esm":
run(`npx tsc --module es2020 --outDir ${distDirPath}`);
+ {
+ const srcSvelteDirPath = pathJoin(projectDirPath, "src", "svelte");
+ if (fs.existsSync(srcSvelteDirPath)) {
+ const svelteFiles = fs
+ .readdirSync(srcSvelteDirPath, { withFileTypes: true })
+ .filter(
+ f =>
+ f.isFile() &&
+ (f.name.endsWith(".svelte") || f.name.endsWith(".svelte.d.ts"))
+ );
+ for (let file of svelteFiles) {
+ fs.copyFileSync(
+ pathJoin(srcSvelteDirPath, file.name),
+ pathJoin(distDirPath, "svelte", `${file.name}`)
+ );
+ }
+ }
+ }
break;
}
@@ -201,7 +219,7 @@ for (const targetFormat of ["cjs", "esm"] as const) {
` module: {`,
` rules: [`,
` {`,
- ` test: /\.js$/,`,
+ ` test: ${/\.js$/},`,
` use: {`,
` loader: 'babel-loader',`,
` options: {`,
@@ -308,6 +326,7 @@ transformCodebase({
for (const ext of ["js", "d.ts", "js.map"]) {
fs.rmSync(pathJoin(distDirPath_root, `angular.${ext}`));
}
+fs.rmSync(pathJoin(distDirPath_root, "svelte"), { force: true, recursive: true });
transformCodebase({
srcDirPath: distDirPath_root,
diff --git a/src/mock/svelte.ts b/src/mock/svelte.ts
new file mode 100644
index 00000000..fc809c0f
--- /dev/null
+++ b/src/mock/svelte.ts
@@ -0,0 +1,10 @@
+import { createMockOidc, type ParamsOfCreateMockOidc } from "../mock/oidc";
+import { createSvelteOidc_dependencyInjection } from "../svelte/index.svelte";
+import type { ValueOrAsyncGetter } from "../tools/ValueOrAsyncGetter";
+
+export function createMockSvelteOidc<
+ DecodedIdToken extends Record = Record,
+ AutoLogin extends boolean = false
+>(params: ValueOrAsyncGetter>) {
+ return createSvelteOidc_dependencyInjection(params, createMockOidc);
+}
diff --git a/src/svelte/OidcContextProvider.svelte b/src/svelte/OidcContextProvider.svelte
new file mode 100644
index 00000000..b5b56675
--- /dev/null
+++ b/src/svelte/OidcContextProvider.svelte
@@ -0,0 +1,15 @@
+
+
+{@render children()}
diff --git a/src/svelte/OidcProvider.svelte b/src/svelte/OidcProvider.svelte
new file mode 100644
index 00000000..0b8f5d96
--- /dev/null
+++ b/src/svelte/OidcProvider.svelte
@@ -0,0 +1,39 @@
+
+
+{#if oidcOrInitializationError === undefined}
+ {#if Fallback}
+
+ {/if}
+{:else if oidcOrInitializationError instanceof OidcInitializationError}
+ {@const initializationError = oidcOrInitializationError}
+ {#if ErrorFallback}
+
+ {:else}
+
+ An error occurred while initializing the OIDC client:
+ {initializationError.message}
+
+ {/if}
+{:else}
+ setOidcContext(oidcContextKey, context)}
+ >
+
+
+{/if}
diff --git a/src/svelte/OidcProviderProps.ts b/src/svelte/OidcProviderProps.ts
new file mode 100644
index 00000000..dc9e0b1b
--- /dev/null
+++ b/src/svelte/OidcProviderProps.ts
@@ -0,0 +1,21 @@
+import type { Component, mount } from "svelte";
+import type { Oidc, OidcInitializationError } from "..";
+
+export type OidcProviderOidcProps = AutoLogin extends true
+ ? {
+ Fallback?: Component;
+ ErrorFallback?: Component<{ initializationError: OidcInitializationError }>;
+ }
+ : { Fallback?: Component; ErrorFallback?: never };
+
+// Assumes Svelte mount signature: mount(component: Component, options: { target: Element, props?: Record })
+export type OidcProviderProps<
+ DecodedIdToken extends Record,
+ AutoLogin extends boolean
+> = {
+ App: Parameters[0];
+ appProps: Parameters[1]["props"];
+ oidcOrInitializationError: OidcInitializationError | Oidc | undefined;
+ oidcProps?: OidcProviderOidcProps;
+ oidcContextKey: symbol;
+};
diff --git a/src/svelte/index.svelte.ts b/src/svelte/index.svelte.ts
new file mode 100644
index 00000000..2e904fc7
--- /dev/null
+++ b/src/svelte/index.svelte.ts
@@ -0,0 +1,467 @@
+import { mount, onMount } from "svelte";
+import { derived, readonly, Writable, writable, type Readable } from "svelte/store";
+import { createOidc, OidcInitializationError, ParamsOfCreateOidc, type Oidc } from "../core";
+import { Deferred } from "../tools/Deferred";
+import type { ValueOrAsyncGetter } from "../tools/ValueOrAsyncGetter";
+import { toFullyQualifiedUrl } from "../tools/toFullyQualifiedUrl";
+import type { Param0 } from "../tools/tsafe/Param0";
+import { assert, type Equals } from "../tools/tsafe/assert";
+import { id } from "../tools/tsafe/id";
+import OidcProvider from "./OidcProvider.svelte";
+import type { OidcProviderOidcProps, OidcProviderProps } from "./OidcProviderProps";
+import { getOidcContext, setOidcContext } from "./oidc.context";
+import OidcContextProvider from "./OidcContextProvider.svelte";
+
+const useState = (initialState: T): [Readable, (newState: T) => void] => {
+ const state = writable(initialState);
+ const dispatch = (newState: T) => state.set(newState);
+ const readableState = derived(state, $state => $state);
+ return [readableState, dispatch];
+};
+
+export type OidcSvelte> =
+ | OidcSvelte.NotLoggedIn
+ | OidcSvelte.LoggedIn;
+
+export namespace OidcSvelte {
+ export type Common = Oidc.Common & {
+ useAutoLogoutWarningCountdown: (params: { warningDurationSeconds: number }) => {
+ secondsLeft: Readable;
+ };
+ };
+ export type NotLoggedIn = Common & {
+ isUserLoggedIn: false;
+ login: (params?: {
+ extraQueryParams?: Record;
+ redirectUrl?: string;
+ transformUrlBeforeRedirect?: (url: string) => string;
+ doesCurrentHrefRequiresAuth?: boolean;
+ }) => Promise;
+ initializationError: OidcInitializationError | undefined;
+
+ decodedIdToken?: never;
+ logout?: never;
+ renewTokens?: never;
+ goToAuthServer?: never;
+ backFromAuthServer?: never;
+ isNewBrowserSession?: never;
+ };
+
+ export type LoggedIn> = Common & {
+ isUserLoggedIn: true;
+ decodedIdToken: DecodedIdToken;
+ logout: Oidc.LoggedIn["logout"];
+ renewTokens: Oidc.LoggedIn["renewTokens"];
+ login?: never;
+ initializationError?: never;
+ goToAuthServer: (params: {
+ extraQueryParams?: Record;
+ redirectUrl?: string;
+ transformUrlBeforeRedirect?: (url: string) => string;
+ }) => Promise;
+
+ backFromAuthServer:
+ | {
+ extraQueryParams: Record;
+ result: Record;
+ }
+ | undefined;
+
+ isNewBrowserSession: boolean;
+ };
+}
+
+{
+ type Actual = Param0;
+ type Expected = Omit, "doesCurrentHrefRequiresAuth"> & {
+ doesCurrentHrefRequiresAuth?: boolean;
+ };
+
+ assert>();
+}
+
+type OidcSvelteApi, AutoLogin extends boolean> = {
+ /**
+ * Generic initialization function that covers multi-provider and svelte-kit implementations.
+ *
+ * NB: If only one provider is required and the project doesn't use svelte-kit,
+ * it is possible to use `mountOidc`.
+ *
+ */
+ initializeOidc: () => {
+ props: Readable<{
+ oidcOrInitializationError: OidcInitializationError | Oidc | undefined;
+ }>;
+ setOidcContext: (context: { oidc: Oidc }) => void;
+ };
+ /**
+ * Default Svelte component responsible to provide oidc context for its children.
+ *
+ * NB: it is mandatory to retrieve and to set oidcContext from `initializeOidc`.
+ * It is possible to use also a custom component, see documentation.
+ */
+ OidcContextProvider: typeof OidcContextProvider;
+ /**
+ * A special version of Svelte's `mount` function that should be used to mount the root component of the application.
+ * It takes the same parameters as `mount` plus an extra one for OIDC configuration.
+ *
+ * NB: this can be used only when having a single OIDC provider and when usign Svelte without svelte-kit.
+ * For a generic initialization referes to `initializeOidc`
+ *
+ * @param {...Parameters} params - The same parameters as Svelte's `mount` function.
+ * @param {OidcProviderOidcProps} oidcProps - The OIDC configuration.
+ * @returns {ReturnType} The mounted component.
+ */
+ mountOidc: (
+ ...params: [...Parameters, OidcProviderOidcProps]
+ ) => ReturnType;
+ useOidc: AutoLogin extends true
+ ? {
+ (params?: { assert: "user logged in" }): OidcSvelte.LoggedIn;
+ }
+ : {
+ (params?: { assert?: undefined }): OidcSvelte;
+ (params: { assert: "user logged in" }): OidcSvelte.LoggedIn;
+ (params: { assert: "user not logged in" }): OidcSvelte.NotLoggedIn;
+ };
+ getOidc: () => Promise<
+ AutoLogin extends true ? Oidc.LoggedIn : Oidc
+ >;
+} & (AutoLogin extends true
+ ? // eslint-disable-next-line @typescript-eslint/no-empty-object-type
+ {}
+ : {
+ enforceLogin: (loaderParams: {
+ request?: { url?: string };
+ cause?: "preload" | string;
+ location?: {
+ href?: string;
+ };
+ }) => Promise;
+ });
+
+export function createSvelteOidc_dependencyInjection<
+ DecodedIdToken extends Record,
+ ParamsOfCreateOidc extends {
+ autoLogin?: boolean;
+ } & (
+ | {
+ decodedIdTokenSchema: { parse: (data: unknown) => DecodedIdToken } | undefined;
+ }
+ | {}
+ )
+>(
+ paramsOrGetParams: ValueOrAsyncGetter,
+ createOidc: (params: ParamsOfCreateOidc) => Promise>
+): OidcSvelteApi<
+ DecodedIdToken,
+ ParamsOfCreateOidc extends { autoLogin?: true | undefined } ? true : false
+> {
+ const dReadyToCreate = new Deferred();
+
+ // NOTE: It can be InitializationError only if autoLogin is true
+ const prOidcOrInitializationError = (async () => {
+ const params = await (async () => {
+ await dReadyToCreate.pr;
+
+ if (typeof paramsOrGetParams === "function") {
+ const getParams = paramsOrGetParams;
+
+ const params = await getParams();
+
+ return params;
+ }
+
+ const params = paramsOrGetParams;
+
+ return params;
+ })();
+
+ let oidc: Oidc;
+
+ try {
+ oidc = await createOidc(params);
+ } catch (error) {
+ if (!(error instanceof OidcInitializationError)) {
+ throw error;
+ }
+
+ return error;
+ }
+
+ return oidc;
+ })();
+
+ let prOidcOrInitializationError_resolvedValue:
+ | Oidc
+ | OidcInitializationError
+ | undefined = undefined;
+ prOidcOrInitializationError.then(value => (prOidcOrInitializationError_resolvedValue = value));
+
+ let oidcContextKey: symbol;
+
+ const initializeOidc: () => {
+ props: Readable<{
+ oidcOrInitializationError: OidcInitializationError | Oidc | undefined;
+ }>;
+ setOidcContext: (context: { oidc: Oidc }) => void;
+ } = () => {
+ assert(
+ oidcContextKey === undefined,
+ "You must call initializeOidc only once per provider to initialize"
+ );
+ oidcContextKey = Symbol("oidc");
+ const props: Writable<{
+ oidcOrInitializationError: Oidc | OidcInitializationError | undefined;
+ }> = writable({ oidcOrInitializationError: prOidcOrInitializationError_resolvedValue });
+ dReadyToCreate.resolve();
+ prOidcOrInitializationError.then(value => {
+ props.set({ oidcOrInitializationError: value });
+ });
+ return {
+ props: readonly(props),
+ setOidcContext: (context: { oidc: Oidc }) =>
+ setOidcContext(oidcContextKey, context)
+ };
+ };
+
+ const mountOidc = (
+ ...params: [
+ ...Parameters,
+ OidcProviderOidcProps<
+ ParamsOfCreateOidc extends { autoLogin?: true | undefined } ? true : false
+ >
+ ]
+ ) => {
+ const [App, options, oidcProps] = params;
+
+ assert(oidcContextKey === undefined, "You can call mountOidc only once");
+ oidcContextKey = Symbol("oidc");
+ const props: OidcProviderProps<
+ DecodedIdToken,
+ ParamsOfCreateOidc extends { autoLogin?: true | undefined } ? true : false
+ > = $state({
+ App,
+ oidcOrInitializationError: prOidcOrInitializationError_resolvedValue,
+ oidcProps,
+ appProps: options.props,
+ oidcContextKey
+ });
+ const mounted = mount(OidcProvider, {
+ ...options,
+ props
+ });
+ dReadyToCreate.resolve();
+ prOidcOrInitializationError.then(value => {
+ props.oidcOrInitializationError = value;
+ });
+ return mounted;
+ };
+
+ const useAutoLogoutWarningCountdown: OidcSvelte.LoggedIn["useAutoLogoutWarningCountdown"] =
+ ({ warningDurationSeconds }) => {
+ assert(
+ oidcContextKey !== undefined,
+ "Oidc not inizitialized, you must call initializeOidc or mountOidc"
+ );
+ const contextValue = getOidcContext(oidcContextKey);
+
+ assert(contextValue !== undefined);
+
+ const { oidc } = contextValue;
+
+ const [secondsLeft, setSecondsLeft] = useState(undefined);
+
+ onMount(() => {
+ if (!oidc.isUserLoggedIn) {
+ return;
+ }
+
+ const { unsubscribeFromAutoLogoutCountdown } = oidc.subscribeToAutoLogoutCountdown(
+ ({ secondsLeft }) =>
+ setSecondsLeft(
+ secondsLeft === undefined || secondsLeft > warningDurationSeconds
+ ? undefined
+ : secondsLeft
+ )
+ );
+
+ return () => {
+ unsubscribeFromAutoLogoutCountdown();
+ };
+ });
+
+ return { secondsLeft };
+ };
+
+ function useOidc(params?: {
+ assert?: "user logged in" | "user not logged in";
+ }): OidcSvelte {
+ const { assert: assert_params } = params ?? {};
+
+ assert(
+ oidcContextKey !== undefined,
+ "Oidc not initialized, you must call initializeOidc or mountOidc"
+ );
+ const contextValue = getOidcContext(oidcContextKey);
+
+ assert(contextValue !== undefined, "You must use useOidc inside the corresponding OidcProvider");
+
+ const { oidc } = contextValue;
+
+ check_assertion: {
+ if (assert_params === undefined) {
+ break check_assertion;
+ }
+
+ const getMessage = (v: string) =>
+ [
+ "There is a logic error in the application.",
+ `If this component is mounted the user is supposed ${v}.`,
+ "An explicit assertion was made in this sense."
+ ].join(" ");
+
+ switch (assert_params) {
+ case "user logged in":
+ if (!oidc.isUserLoggedIn) {
+ throw new Error(getMessage("to be logged in but currently they aren't"));
+ }
+ break;
+ case "user not logged in":
+ if (oidc.isUserLoggedIn) {
+ throw new Error(getMessage("not to be logged in but currently they are"));
+ }
+ break;
+ default:
+ assert>(false);
+ }
+ }
+
+ const [, reRenderIfDecodedIdTokenChanged] = useState(
+ !oidc.isUserLoggedIn ? undefined : oidc.getDecodedIdToken()
+ );
+
+ onMount(() => {
+ if (!oidc.isUserLoggedIn) {
+ return;
+ }
+
+ const { unsubscribe } = oidc.subscribeToTokensChange(() =>
+ reRenderIfDecodedIdTokenChanged(oidc.getDecodedIdToken())
+ );
+
+ reRenderIfDecodedIdTokenChanged(oidc.getDecodedIdToken());
+
+ return () => unsubscribe();
+ });
+
+ const common: OidcSvelte.Common = {
+ params: oidc.params,
+ useAutoLogoutWarningCountdown
+ };
+
+ if (!oidc.isUserLoggedIn) {
+ return id({
+ ...common,
+ isUserLoggedIn: false,
+ login: ({ doesCurrentHrefRequiresAuth = false, ...rest } = {}) =>
+ oidc.login({ doesCurrentHrefRequiresAuth, ...rest }),
+ initializationError: oidc.initializationError
+ });
+ }
+
+ const oidcSvelte: OidcSvelte.LoggedIn = {
+ ...common,
+ isUserLoggedIn: true,
+ decodedIdToken: oidc.getDecodedIdToken(),
+ logout: oidc.logout,
+ renewTokens: oidc.renewTokens,
+ goToAuthServer: oidc.goToAuthServer,
+ isNewBrowserSession: oidc.isNewBrowserSession,
+ backFromAuthServer: oidc.backFromAuthServer
+ };
+
+ return oidcSvelte;
+ }
+ async function getOidc(): Promise> {
+ dReadyToCreate.resolve();
+
+ const oidcOrInitializationError = await prOidcOrInitializationError;
+
+ if (oidcOrInitializationError instanceof OidcInitializationError) {
+ const error = oidcOrInitializationError;
+ throw error;
+ }
+
+ const oidc = oidcOrInitializationError;
+
+ return oidc;
+ }
+
+ async function enforceLogin(loaderParams: {
+ request?: { url?: string };
+ cause?: "preload" | string;
+ location?: { href?: string };
+ }): Promise {
+ try {
+ const { cause } = loaderParams;
+
+ const redirectUrl = (() => {
+ if (loaderParams.request?.url !== undefined) {
+ return toFullyQualifiedUrl({
+ urlish: loaderParams.request.url,
+ doAssertNoQueryParams: false
+ });
+ }
+
+ if (loaderParams.location?.href !== undefined) {
+ return toFullyQualifiedUrl({
+ urlish: loaderParams.location.href,
+ doAssertNoQueryParams: false
+ });
+ }
+
+ return location.href;
+ })();
+
+ const oidc = await getOidc();
+
+ if (!oidc.isUserLoggedIn) {
+ if (cause === "preload") {
+ throw new Error(
+ "oidc-spa: User is not yet logged in. This is an expected error, nothing to be addressed."
+ );
+ }
+ const doesCurrentHrefRequiresAuth =
+ location.href.replace(/\/$/, "") === redirectUrl.replace(/\/$/, "");
+
+ await oidc.login({
+ redirectUrl,
+ doesCurrentHrefRequiresAuth
+ });
+ }
+ return true;
+ } catch (error) {
+ return false;
+ }
+ }
+
+ const oidcSvelteApi: OidcSvelteApi = {
+ initializeOidc,
+ OidcContextProvider,
+ mountOidc,
+ useOidc: useOidc as any,
+ getOidc,
+ enforceLogin
+ };
+
+ // @ts-expect-error: We know what we are doing
+ return oidcSvelteApi;
+}
+
+export function createSvelteOidc<
+ DecodedIdToken extends Record = Oidc.Tokens.DecodedIdToken_base,
+ AutoLogin extends boolean = false
+>(params: ValueOrAsyncGetter>) {
+ return createSvelteOidc_dependencyInjection(params, createOidc);
+}
diff --git a/src/svelte/oidc.context.ts b/src/svelte/oidc.context.ts
new file mode 100644
index 00000000..7f843e29
--- /dev/null
+++ b/src/svelte/oidc.context.ts
@@ -0,0 +1,17 @@
+import { getContext, setContext } from "svelte";
+import type { Oidc } from "../core";
+
+export const setOidcContext = >(
+ oidcContextKey: symbol,
+ context: {
+ oidc: Oidc;
+ }
+) => {
+ setContext(oidcContextKey, context);
+};
+
+export const getOidcContext = >(
+ oidcContextKey: symbol
+) => {
+ return getContext<{ oidc: Oidc }>(oidcContextKey);
+};
diff --git a/yarn.lock b/yarn.lock
index 0bddf607..fed70738 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1086,6 +1086,14 @@
"@jridgewell/sourcemap-codec" "^1.4.10"
"@jridgewell/trace-mapping" "^0.3.24"
+"@jridgewell/remapping@^2.3.4":
+ version "2.3.5"
+ resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1"
+ integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==
+ dependencies:
+ "@jridgewell/gen-mapping" "^0.3.5"
+ "@jridgewell/trace-mapping" "^0.3.24"
+
"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
@@ -1104,7 +1112,7 @@
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.25"
-"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14":
+"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
@@ -1125,6 +1133,11 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
+"@sveltejs/acorn-typescript@^1.0.5":
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz#f518101d1b2e12ce80854f1cd850d3b9fb91d710"
+ integrity sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==
+
"@tsconfig/node10@^1.0.7":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2"
@@ -1166,6 +1179,11 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
+"@types/estree@^1.0.6":
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
+ integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
+
"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
@@ -1387,6 +1405,11 @@ acorn@^8.11.0, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248"
integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==
+acorn@^8.12.1:
+ version "8.14.1"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb"
+ integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
+
aggregate-error@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a"
@@ -1470,6 +1493,11 @@ arg@^4.1.0:
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
+aria-query@^5.3.1:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59"
+ integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==
+
astral-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
@@ -1485,6 +1513,11 @@ at-least-node@^1.0.0:
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
+axobject-query@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee"
+ integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==
+
babel-loader@9.1.3:
version "9.1.3"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.1.3.tgz#3d0e01b4e69760cc694ee306fe16d358aa1c6f9a"
@@ -1532,6 +1565,11 @@ base64url@^3.0.1:
resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==
+big.js@^5.2.2:
+ version "5.2.2"
+ resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
+ integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
+
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -1657,6 +1695,11 @@ clone-deep@^4.0.1:
kind-of "^6.0.2"
shallow-clone "^3.0.0"
+clsx@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
+ integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
+
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -1813,6 +1856,11 @@ emoji-regex@^8.0.0:
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+emojis-list@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
+ integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
+
enhanced-resolve@^5.17.0:
version "5.17.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15"
@@ -1910,6 +1958,18 @@ eslint-scope@5.1.1:
esrecurse "^4.3.0"
estraverse "^4.1.1"
+esm-env@^1.2.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.2.2.tgz#263c9455c55861f41618df31b20cb571fc20b75e"
+ integrity sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==
+
+esrap@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/esrap/-/esrap-2.1.0.tgz#70df8f20129df3ad82f20e306dc4000dd5947813"
+ integrity sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.4.15"
+
esrecurse@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
@@ -2286,6 +2346,13 @@ is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
+is-reference@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.3.tgz#9ef7bf9029c70a67b2152da4adf57c23d718910f"
+ integrity sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==
+ dependencies:
+ "@types/estree" "^1.0.6"
+
is-regexp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
@@ -2367,7 +2434,7 @@ json-stable-stringify@^1.0.2:
jsonify "^0.0.1"
object-keys "^1.1.1"
-json5@^2.2.3:
+json5@^2.1.2, json5@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
@@ -2480,6 +2547,20 @@ loader-runner@^4.2.0:
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1"
integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==
+loader-utils@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
+ integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
+ dependencies:
+ big.js "^5.2.2"
+ emojis-list "^3.0.0"
+ json5 "^2.1.2"
+
+locate-character@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/locate-character/-/locate-character-3.0.0.tgz#0305c5b8744f61028ef5d01f444009e00779f974"
+ integrity sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==
+
locate-path@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
@@ -2568,6 +2649,13 @@ lru-cache@^5.1.1:
dependencies:
yallist "^3.0.2"
+magic-string@^0.30.11:
+ version "0.30.17"
+ resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453"
+ integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.0"
+
make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
@@ -3231,6 +3319,45 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+svelte-dev-helper@^1.1.9:
+ version "1.1.9"
+ resolved "https://registry.yarnpkg.com/svelte-dev-helper/-/svelte-dev-helper-1.1.9.tgz#7d187db5c6cdbbd64d75a32f91b8998bde3273c3"
+ integrity sha512-oU+Xv7Dl4kRU2kdFjsoPLfJfnt5hUhsFUZtuzI3Ku/f2iAFZqBoEuXOqK3N9ngD4dxQOmN4OKWPHVi3NeAeAfQ==
+
+svelte-hmr@^0.14.2:
+ version "0.14.12"
+ resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.12.tgz#a127aec02f1896500b10148b2d4d21ddde39973f"
+ integrity sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w==
+
+svelte-loader@^3.2.4:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/svelte-loader/-/svelte-loader-3.2.4.tgz#0d05ae1f95aec6d480ee86e80e9f756ac419e694"
+ integrity sha512-e0HdDnkYH/MDx4/IfTSka5AOFg9yYJcPuoZJB5x0l60fkHjVjNvrrxr+rJegDG9J7ZymmdHt00/hdLw+QF299w==
+ dependencies:
+ loader-utils "^2.0.4"
+ svelte-dev-helper "^1.1.9"
+ svelte-hmr "^0.14.2"
+
+svelte@^5.39.8:
+ version "5.39.8"
+ resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.39.8.tgz#db34b2436d036c34fc77b1249437b71675e2fcdc"
+ integrity sha512-KfZ3hCITdxIXTOvrea4nFZX2o+47HPTChKeocgj9BwJQYqWrviVCcPj4boXHF5yf8+eBKqhHY8xii//XaakKXA==
+ dependencies:
+ "@jridgewell/remapping" "^2.3.4"
+ "@jridgewell/sourcemap-codec" "^1.5.0"
+ "@sveltejs/acorn-typescript" "^1.0.5"
+ "@types/estree" "^1.0.5"
+ acorn "^8.12.1"
+ aria-query "^5.3.1"
+ axobject-query "^4.1.0"
+ clsx "^2.1.1"
+ esm-env "^1.2.1"
+ esrap "^2.1.0"
+ is-reference "^3.0.3"
+ locate-character "^3.0.0"
+ magic-string "^0.30.11"
+ zimmerframe "^1.1.2"
+
tapable@^2.1.1, tapable@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
@@ -3590,6 +3717,11 @@ yocto-queue@^1.0.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.1.1.tgz#fef65ce3ac9f8a32ceac5a634f74e17e5b232110"
integrity sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==
+zimmerframe@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/zimmerframe/-/zimmerframe-1.1.2.tgz#5b75f1fa83b07ae2a428d51e50f58e2ae6855e5e"
+ integrity sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==
+
zod@^3.23.8:
version "3.23.8"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"