academe-kit 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ declare const Button: React$1.ForwardRefExoticComponent<ButtonProps & React$1.Re
13
13
  type ProtectedAppProps = {
14
14
  children: React.ReactElement;
15
15
  requiredClientRoles?: string[];
16
- unauthorizedMessage?: string;
16
+ requiredRealmRoles?: string[];
17
17
  };
18
18
  declare const ProtectedApp: React.FC<ProtectedAppProps>;
19
19
 
@@ -33,32 +33,113 @@ declare const ProtectedRouter: React.FC<ProtectedRouterProps>;
33
33
 
34
34
  declare function Spinner({ className, ...props }: React.ComponentProps<"svg">): react_jsx_runtime.JSX.Element;
35
35
 
36
+ /**
37
+ * User Service - Fetches complete user data from MongoDB
38
+ * This service interacts with the new unified users collection
39
+ */
40
+ interface MongoDBUser {
41
+ id: string;
42
+ keycloak_user_id: string;
43
+ email: string;
44
+ full_name: string;
45
+ phone?: string;
46
+ school_id?: string;
47
+ active: boolean;
48
+ created_at: string;
49
+ updated_at: string;
50
+ last_login?: string;
51
+ registration_number?: string;
52
+ school_year?: string;
53
+ serie_ano?: string;
54
+ turma?: string;
55
+ turno?: string;
56
+ class_id?: string;
57
+ nome_responsavel?: string;
58
+ email_responsavel?: string;
59
+ telefone_responsavel?: string;
60
+ data_nascimento?: string;
61
+ cpf?: string;
62
+ sexo?: string;
63
+ completion_rate: number;
64
+ engagement_rate: number;
65
+ onboarding_completo: boolean;
66
+ acesso_liberado: boolean;
67
+ roles?: string[];
68
+ }
69
+ interface UserServiceConfig {
70
+ apiBaseUrl: string;
71
+ getAccessToken: () => string | null;
72
+ }
73
+ declare class UserService {
74
+ private client;
75
+ private getAccessToken;
76
+ private cachedUser;
77
+ private cacheExpiry;
78
+ constructor(config: UserServiceConfig);
79
+ /**
80
+ * Get current user data from MongoDB
81
+ * Includes caching to reduce API calls
82
+ */
83
+ getCurrentUser(forceRefresh?: boolean): Promise<MongoDBUser | null>;
84
+ /**
85
+ * Update current user data
86
+ */
87
+ updateCurrentUser(data: Partial<MongoDBUser>): Promise<MongoDBUser | null>;
88
+ /**
89
+ * Clear cached user data
90
+ */
91
+ clearCache(): void;
92
+ /**
93
+ * Check if user has a specific role
94
+ */
95
+ hasRole(user: MongoDBUser | null, role: string): boolean;
96
+ /**
97
+ * Check if user has access to a specific school
98
+ */
99
+ hasSchoolAccess(user: MongoDBUser | null, schoolId: string): boolean;
100
+ /**
101
+ * Check if user is a student (has student-specific data)
102
+ */
103
+ isStudent(user: MongoDBUser | null): boolean;
104
+ /**
105
+ * Check if user has completed onboarding
106
+ */
107
+ hasCompletedOnboarding(user: MongoDBUser | null): boolean;
108
+ /**
109
+ * Check if user has access enabled
110
+ */
111
+ hasAccessEnabled(user: MongoDBUser | null): boolean;
112
+ }
113
+ declare const createUserService: (config: UserServiceConfig) => UserService;
114
+
36
115
  type AcademeKeycloakContextProps = {
37
116
  realm: string;
38
117
  hubUrl: string;
39
118
  clientId: string;
40
119
  keycloakUrl: string;
120
+ apiBaseUrl?: string;
41
121
  children: React.ReactElement;
42
122
  };
43
123
  type SecurityProviderProps = {
44
124
  hubUrl: string;
125
+ apiBaseUrl?: string;
45
126
  children: React.ReactElement;
46
127
  };
47
128
  type KeycloakUser = {
48
129
  name: string;
49
130
  lastName: string;
50
131
  email: string;
51
- attributes: {
52
- school_ids: Array<string>;
53
- };
132
+ };
133
+ type AcademeUser = MongoDBUser & {
134
+ keycloakUser?: KeycloakUser;
54
135
  };
55
136
  type SecurityContextType = {
56
137
  isInitialized: boolean;
57
138
  isAuthenticated: () => boolean;
58
139
  signOut: () => void | null;
59
- redirectToHub: (errorMessage: string) => void | null;
60
140
  goToLogin: (options?: KeycloakLoginOptions | undefined) => KeycloakPromise<void, void> | null;
61
- getUser: () => KeycloakUser;
141
+ user: AcademeUser | null;
142
+ refreshUserData: () => Promise<void>;
62
143
  hasRealmRole: (role: string) => boolean;
63
144
  hasSchool: (schoolId: string) => boolean;
64
145
  hasClientRole: (role: string, resource?: string) => boolean;
@@ -74,5 +155,5 @@ declare const useAcademeAuth: () => SecurityContextType;
74
155
 
75
156
  declare function cn(...inputs: ClassValue[]): string;
76
157
 
77
- export { AcademeAuthProvider, Button, ProtectedApp, ProtectedComponent, ProtectedRouter, Spinner, cn, useAcademeAuth };
78
- export type { AcademeKeycloakContextProps, ButtonProps, KeycloakUser, SecurityContextType, SecurityProviderProps };
158
+ export { AcademeAuthProvider, Button, ProtectedApp, ProtectedComponent, ProtectedRouter, Spinner, cn, createUserService, useAcademeAuth };
159
+ export type { AcademeKeycloakContextProps, AcademeUser, ButtonProps, KeycloakUser, MongoDBUser, SecurityContextType, SecurityProviderProps, UserServiceConfig };
package/dist/index.esm.js CHANGED
@@ -1,6 +1,7 @@
1
- import { jsx, Fragment } from 'react/jsx-runtime';
1
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { createContext, useContext, useState, useEffect, forwardRef, createElement } from 'react';
3
+ import React__default, { createContext, useContext, useState, useEffect, useCallback, forwardRef, createElement } from 'react';
4
+ import axios from 'axios';
4
5
 
5
6
  function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
6
7
 
@@ -2230,66 +2231,250 @@ function isObject(input) {
2230
2231
  return typeof input === 'object' && input !== null;
2231
2232
  }
2232
2233
 
2233
- const AcademeAuthProvider = ({ realm, hubUrl, children, clientId, keycloakUrl, }) => {
2234
- return (jsx(ReactKeycloakProvider, { authClient: new Keycloak({ clientId, realm, url: keycloakUrl }), children: jsx(SecurityProvider, { hubUrl: hubUrl, children: children }) }));
2234
+ /**
2235
+ * User Service - Fetches complete user data from MongoDB
2236
+ * This service interacts with the new unified users collection
2237
+ */
2238
+ class UserService {
2239
+ constructor(config) {
2240
+ this.cachedUser = null;
2241
+ this.cacheExpiry = 0;
2242
+ this.getAccessToken = config.getAccessToken;
2243
+ this.client = axios.create({
2244
+ baseURL: config.apiBaseUrl,
2245
+ headers: {
2246
+ 'Content-Type': 'application/json'
2247
+ }
2248
+ });
2249
+ // Add auth interceptor
2250
+ this.client.interceptors.request.use((config) => {
2251
+ const token = this.getAccessToken();
2252
+ if (token) {
2253
+ config.headers.Authorization = `Bearer ${token}`;
2254
+ }
2255
+ return config;
2256
+ });
2257
+ // Add response interceptor for error handling
2258
+ this.client.interceptors.response.use((response) => response, (error) => {
2259
+ if (error.response?.status === 401) {
2260
+ // Clear cache on authentication error
2261
+ this.clearCache();
2262
+ }
2263
+ return Promise.reject(error);
2264
+ });
2265
+ }
2266
+ /**
2267
+ * Get current user data from MongoDB
2268
+ * Includes caching to reduce API calls
2269
+ */
2270
+ async getCurrentUser(forceRefresh = false) {
2271
+ try {
2272
+ // Check cache
2273
+ if (!forceRefresh && this.cachedUser && Date.now() < this.cacheExpiry) {
2274
+ return this.cachedUser;
2275
+ }
2276
+ const response = await this.client.get('/api/users/me');
2277
+ if (response.data) {
2278
+ // Cache for 5 minutes
2279
+ this.cachedUser = response.data;
2280
+ this.cacheExpiry = Date.now() + (5 * 60 * 1000);
2281
+ return response.data;
2282
+ }
2283
+ return null;
2284
+ }
2285
+ catch (error) {
2286
+ console.error('Error fetching current user:', error);
2287
+ // If it's a 404, user doesn't exist in MongoDB yet
2288
+ if (axios.isAxiosError(error) && error.response?.status === 404) {
2289
+ // User will be auto-created on next API call
2290
+ return null;
2291
+ }
2292
+ throw error;
2293
+ }
2294
+ }
2295
+ /**
2296
+ * Update current user data
2297
+ */
2298
+ async updateCurrentUser(data) {
2299
+ try {
2300
+ // First get current user to get the ID
2301
+ const currentUser = await this.getCurrentUser();
2302
+ if (!currentUser) {
2303
+ throw new Error('User not found');
2304
+ }
2305
+ const response = await this.client.put(`/api/users/${currentUser.id}`, data);
2306
+ if (response.data) {
2307
+ // Update cache
2308
+ this.cachedUser = response.data;
2309
+ this.cacheExpiry = Date.now() + (5 * 60 * 1000);
2310
+ return response.data;
2311
+ }
2312
+ return null;
2313
+ }
2314
+ catch (error) {
2315
+ console.error('Error updating user:', error);
2316
+ throw error;
2317
+ }
2318
+ }
2319
+ /**
2320
+ * Clear cached user data
2321
+ */
2322
+ clearCache() {
2323
+ this.cachedUser = null;
2324
+ this.cacheExpiry = 0;
2325
+ }
2326
+ /**
2327
+ * Check if user has a specific role
2328
+ */
2329
+ hasRole(user, role) {
2330
+ if (!user || !user.roles)
2331
+ return false;
2332
+ return user.roles.includes(role);
2333
+ }
2334
+ /**
2335
+ * Check if user has access to a specific school
2336
+ */
2337
+ hasSchoolAccess(user, schoolId) {
2338
+ if (!user)
2339
+ return false;
2340
+ // Admin has access to all schools
2341
+ if (this.hasRole(user, 'admin_academe'))
2342
+ return true;
2343
+ // Check if user's school matches
2344
+ return user.school_id === schoolId;
2345
+ }
2346
+ /**
2347
+ * Check if user is a student (has student-specific data)
2348
+ */
2349
+ isStudent(user) {
2350
+ if (!user)
2351
+ return false;
2352
+ return !!user.registration_number || this.hasRole(user, 'student');
2353
+ }
2354
+ /**
2355
+ * Check if user has completed onboarding
2356
+ */
2357
+ hasCompletedOnboarding(user) {
2358
+ if (!user)
2359
+ return false;
2360
+ return user.onboarding_completo;
2361
+ }
2362
+ /**
2363
+ * Check if user has access enabled
2364
+ */
2365
+ hasAccessEnabled(user) {
2366
+ if (!user)
2367
+ return false;
2368
+ return user.acesso_liberado && user.active;
2369
+ }
2370
+ }
2371
+ // Export singleton instance creator
2372
+ const createUserService = (config) => {
2373
+ return new UserService(config);
2374
+ };
2375
+
2376
+ const AcademeAuthProvider = ({ realm, hubUrl, children, clientId, keycloakUrl, apiBaseUrl, }) => {
2377
+ return (jsx(ReactKeycloakProvider, { authClient: new Keycloak({ clientId, realm, url: keycloakUrl }), children: jsx(SecurityProvider, { hubUrl: hubUrl, apiBaseUrl: apiBaseUrl, children: children }) }));
2235
2378
  };
2236
2379
  const SecurityContext = createContext({
2237
2380
  isInitialized: false,
2238
- getUser: () => ({
2239
- email: "",
2240
- name: "",
2241
- lastName: "",
2242
- attributes: {
2243
- school_ids: [],
2244
- },
2245
- }),
2381
+ user: null,
2382
+ refreshUserData: async () => { },
2246
2383
  signOut: () => null,
2247
2384
  goToLogin: () => null,
2248
2385
  hasSchool: () => false,
2249
2386
  hasRealmRole: () => false,
2250
- redirectToHub: () => null,
2251
2387
  hasClientRole: () => false,
2252
2388
  isAuthenticated: () => false,
2253
2389
  });
2254
- const SecurityProvider = ({ hubUrl, children, }) => {
2390
+ const SecurityProvider = ({ apiBaseUrl = "https://api.academe.com.br", children, }) => {
2255
2391
  const [isInitialized, setIsInitialized] = useState(false);
2392
+ const [currentUser, setCurrentUser] = useState(null);
2256
2393
  const { initialized, keycloak } = useKeycloak();
2394
+ const userService = createUserService({
2395
+ apiBaseUrl,
2396
+ getAccessToken: () => keycloak?.token || null,
2397
+ });
2257
2398
  useEffect(() => {
2258
2399
  setIsInitialized(initialized);
2259
2400
  }, [initialized]);
2260
2401
  useEffect(() => {
2261
2402
  window.accessToken = keycloak.token;
2262
2403
  }, [keycloak.token]);
2263
- const getUser = () => {
2404
+ // Fetch user data from MongoDB when authenticated
2405
+ useEffect(() => {
2406
+ const fetchUserData = async () => {
2407
+ if (initialized && keycloak?.authenticated && keycloak?.token) {
2408
+ try {
2409
+ const mongoUser = await userService.getCurrentUser();
2410
+ if (mongoUser) {
2411
+ const academeUser = {
2412
+ ...mongoUser,
2413
+ keycloakUser: getKeycloakUser(),
2414
+ };
2415
+ setCurrentUser(academeUser);
2416
+ }
2417
+ }
2418
+ catch (error) {
2419
+ console.error("Error fetching user data:", error);
2420
+ }
2421
+ }
2422
+ else if (!keycloak?.authenticated) {
2423
+ // Clear user data when not authenticated
2424
+ setCurrentUser(null);
2425
+ userService.clearCache();
2426
+ }
2427
+ };
2428
+ fetchUserData();
2429
+ }, [initialized, keycloak?.authenticated, keycloak?.token]);
2430
+ const getKeycloakUser = () => {
2264
2431
  const idTokenParsed = keycloak?.idTokenParsed || {};
2265
2432
  return {
2266
- email: keycloak?.idTokenParsed?.email || "",
2267
- name: keycloak?.idTokenParsed?.given_name || "",
2268
- lastName: keycloak?.idTokenParsed?.family_name || "",
2269
- attributes: {
2270
- school_ids: (idTokenParsed.school_ids || []),
2271
- },
2433
+ email: idTokenParsed?.email || "",
2434
+ name: idTokenParsed?.given_name || "",
2435
+ lastName: idTokenParsed?.family_name || "",
2272
2436
  };
2273
2437
  };
2274
- const redirectToHub = (errorMessage) => {
2275
- window.location.replace(`${hubUrl}?errorMessage=${errorMessage}`);
2276
- };
2438
+ const refreshUserData = useCallback(async () => {
2439
+ if (keycloak?.authenticated) {
2440
+ try {
2441
+ const mongoUser = await userService.getCurrentUser(true); // Force refresh
2442
+ if (mongoUser) {
2443
+ const academeUser = {
2444
+ ...mongoUser,
2445
+ keycloakUser: getKeycloakUser(),
2446
+ };
2447
+ setCurrentUser(academeUser);
2448
+ }
2449
+ }
2450
+ catch (error) {
2451
+ console.error("Error refreshing user data:", error);
2452
+ }
2453
+ }
2454
+ }, [keycloak?.authenticated]);
2277
2455
  const signOut = () => {
2456
+ userService.clearCache();
2457
+ setCurrentUser(null);
2278
2458
  keycloak?.logout();
2279
2459
  };
2280
2460
  const isAuthenticated = () => {
2281
2461
  return (!!keycloak?.idTokenParsed?.email?.length && !!keycloak?.authenticated);
2282
2462
  };
2283
2463
  const hasSchool = (schoolId) => {
2284
- return getUser().attributes.school_ids.includes(schoolId);
2464
+ if (currentUser?.school_id) {
2465
+ return (currentUser.school_id === schoolId ||
2466
+ userService.hasRole(currentUser, "admin_academe"));
2467
+ }
2468
+ // Fallback to Keycloak data
2469
+ return false; // No school_id in Keycloak data
2285
2470
  };
2286
2471
  return (jsx(SecurityContext.Provider, { value: {
2287
2472
  isInitialized,
2288
- getUser,
2473
+ user: currentUser,
2474
+ refreshUserData,
2289
2475
  signOut,
2290
- redirectToHub,
2291
2476
  isAuthenticated,
2292
- hasSchool: hasSchool,
2477
+ hasSchool,
2293
2478
  goToLogin: keycloak.login,
2294
2479
  hasRealmRole: keycloak?.hasRealmRole,
2295
2480
  hasClientRole: keycloak.hasResourceRole,
@@ -5380,8 +5565,8 @@ function Spinner({ className, ...props }) {
5380
5565
  return (jsx(LoaderCircle, { role: "status", "aria-label": "Loading", className: cn("size-10 animate-spin text-violet-500", className), ...props }));
5381
5566
  }
5382
5567
 
5383
- const ProtectedApp = ({ children, unauthorizedMessage, requiredClientRoles, }) => {
5384
- const { isInitialized, goToLogin, hasClientRole, redirectToHub, isAuthenticated, } = useAcademeAuth();
5568
+ const ProtectedApp = ({ children, requiredClientRoles, requiredRealmRoles, }) => {
5569
+ const { isInitialized, goToLogin, hasClientRole, hasRealmRole, isAuthenticated, } = useAcademeAuth();
5385
5570
  if (!isInitialized) {
5386
5571
  return (jsx("div", { className: "flex w-screen h-screen items-center justify-center", children: jsx(Spinner, { className: "size-10 text-violet-500" }) }));
5387
5572
  }
@@ -5391,9 +5576,12 @@ const ProtectedApp = ({ children, unauthorizedMessage, requiredClientRoles, }) =
5391
5576
  }
5392
5577
  if (requiredClientRoles &&
5393
5578
  !requiredClientRoles?.some((role) => hasClientRole(role))) {
5394
- redirectToHub(unauthorizedMessage || "Unauthorized");
5395
5579
  return jsx(Fragment, {});
5396
5580
  }
5581
+ if (requiredRealmRoles &&
5582
+ !requiredRealmRoles?.some((role) => hasRealmRole(role))) {
5583
+ return (jsxs("div", { className: "flex w-screen h-screen items-center justify-center", children: [jsx("h1", { className: "text-2xl font-bold", children: "Voc\u00EA n\u00E3o tem permiss\u00E3o para acessar esta p\u00E1gina" }), jsx("span", { children: "Se voc\u00EA acredita que isso \u00E9 um erro, entre em contato com o suporte." })] }));
5584
+ }
5397
5585
  return children;
5398
5586
  };
5399
5587
 
@@ -5446,11 +5634,11 @@ function styleInject(css, ref) {
5446
5634
  }
5447
5635
  }
5448
5636
 
5449
- var css_248z$1 = "*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--primary:222.2 47.4% 11.2%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--ring:222.2 84% 4.9%;--radius:0.5rem}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.flex{display:flex}.size-10{height:2.5rem;width:2.5rem}.h-screen{height:100vh}.w-screen{width:100vw}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.items-center{align-items:center}.justify-center{justify-content:center}.rounded-lg{border-radius:var(--radius)}.border-2{border-width:2px}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-violet-500{--tw-text-opacity:1;color:rgb(139 92 246/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.outline{outline-style:solid}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.duration-200{animation-duration:.2s}.hover\\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.hover\\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\\:ring-gray-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(107 114 128/var(--tw-ring-opacity,1))}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px}";
5637
+ var css_248z$1 = "*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background:0 0% 100%;--foreground:222.2 84% 4.9%;--card:0 0% 100%;--card-foreground:222.2 84% 4.9%;--popover:0 0% 100%;--popover-foreground:222.2 84% 4.9%;--primary:222.2 47.4% 11.2%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 84.2% 60.2%;--destructive-foreground:210 40% 98%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--ring:222.2 84% 4.9%;--radius:0.5rem}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.flex{display:flex}.size-10{height:2.5rem;width:2.5rem}.h-screen{height:100vh}.w-screen{width:100vw}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.items-center{align-items:center}.justify-center{justify-content:center}.rounded-lg{border-radius:var(--radius)}.border-2{border-width:2px}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-violet-500{--tw-text-opacity:1;color:rgb(139 92 246/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.outline{outline-style:solid}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.duration-200{animation-duration:.2s}.hover\\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.hover\\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\\:ring-gray-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(107 114 128/var(--tw-ring-opacity,1))}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px}";
5450
5638
  styleInject(css_248z$1,{"insertAt":"top"});
5451
5639
 
5452
- var css_248z = "*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}.flex{display:flex}.size-10{height:2.5rem;width:2.5rem}.h-screen{height:100vh}.w-screen{width:100vw}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.items-center{align-items:center}.justify-center{justify-content:center}.rounded-lg{border-radius:var(--radius)}.border-2{border-width:2px}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-violet-500{--tw-text-opacity:1;color:rgb(139 92 246/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.outline{outline-style:solid}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.duration-200{animation-duration:.2s}.hover\\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.hover\\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\\:ring-gray-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(107 114 128/var(--tw-ring-opacity,1))}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px}";
5640
+ var css_248z = "*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.18 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{-webkit-text-size-adjust:100%;font-feature-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-variation-settings:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-feature-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{font-feature-settings:inherit;color:inherit;font-family:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}.flex{display:flex}.size-10{height:2.5rem;width:2.5rem}.h-screen{height:100vh}.w-screen{width:100vw}@keyframes spin{to{transform:rotate(1turn)}}.animate-spin{animation:spin 1s linear infinite}.items-center{align-items:center}.justify-center{justify-content:center}.rounded-lg{border-radius:var(--radius)}.border-2{border-width:2px}.border-blue-600{--tw-border-opacity:1;border-color:rgb(37 99 235/var(--tw-border-opacity,1))}.bg-blue-600{--tw-bg-opacity:1;background-color:rgb(37 99 235/var(--tw-bg-opacity,1))}.bg-gray-600{--tw-bg-opacity:1;background-color:rgb(75 85 99/var(--tw-bg-opacity,1))}.bg-transparent{background-color:transparent}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1\\.5{padding-bottom:.375rem;padding-top:.375rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.text-blue-600{--tw-text-opacity:1;color:rgb(37 99 235/var(--tw-text-opacity,1))}.text-violet-500{--tw-text-opacity:1;color:rgb(139 92 246/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.outline{outline-style:solid}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.duration-200{animation-duration:.2s}.hover\\:bg-blue-50:hover{--tw-bg-opacity:1;background-color:rgb(239 246 255/var(--tw-bg-opacity,1))}.hover\\:bg-blue-700:hover{--tw-bg-opacity:1;background-color:rgb(29 78 216/var(--tw-bg-opacity,1))}.hover\\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity,1))}.focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\\:ring-blue-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(59 130 246/var(--tw-ring-opacity,1))}.focus\\:ring-gray-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(107 114 128/var(--tw-ring-opacity,1))}.focus\\:ring-offset-2:focus{--tw-ring-offset-width:2px}";
5453
5641
  styleInject(css_248z,{"insertAt":"top"});
5454
5642
 
5455
- export { AcademeAuthProvider, Button, ProtectedApp, ProtectedComponent, ProtectedRouter, Spinner, cn, useAcademeAuth };
5643
+ export { AcademeAuthProvider, Button, ProtectedApp, ProtectedComponent, ProtectedRouter, Spinner, cn, createUserService, useAcademeAuth };
5456
5644
  //# sourceMappingURL=index.esm.js.map