shared-lib-angular 1.0.30 → 1.0.32
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.
|
@@ -20,14 +20,14 @@ import { CommonModule } from '@angular/common';
|
|
|
20
20
|
* Versión actual de la librería @dinafi/frmk
|
|
21
21
|
* Sincronizada con package.json
|
|
22
22
|
*/
|
|
23
|
-
const VERSION = '1.0.
|
|
23
|
+
const VERSION = '1.0.32';
|
|
24
24
|
/**
|
|
25
25
|
* Información completa de la versión
|
|
26
26
|
*/
|
|
27
27
|
const VERSION_INFO = {
|
|
28
|
-
version: '1.0.
|
|
28
|
+
version: '1.0.32',
|
|
29
29
|
name: 'shared-lib-angular',
|
|
30
|
-
buildDate: '2026-02-05T17:
|
|
30
|
+
buildDate: '2026-02-05T17:56:18.182Z',
|
|
31
31
|
angular: '^20.0.0'
|
|
32
32
|
};
|
|
33
33
|
|
|
@@ -673,6 +673,25 @@ class AuthService {
|
|
|
673
673
|
this.oauthService.responseType = authConfig.responseType;
|
|
674
674
|
}
|
|
675
675
|
initializeAuth(authConfig) {
|
|
676
|
+
// CRÍTICO: Limpiar tokens expirados ANTES de configurar OAuthService
|
|
677
|
+
// angular-oauth2-oidc valida tokens existentes en configure() y lanza "Token has expired"
|
|
678
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
679
|
+
const hasCode = urlParams.has('code');
|
|
680
|
+
const expiresAt = localStorage.getItem('expires_at');
|
|
681
|
+
const isExpired = expiresAt && parseInt(expiresAt, 10) < Date.now();
|
|
682
|
+
if (isExpired) {
|
|
683
|
+
if (hasCode) {
|
|
684
|
+
// Callback OAuth: limpiar tokens pero mantener state/nonce/PKCE para validar el callback
|
|
685
|
+
console.log('[AuthService] Clearing expired tokens before configure (keeping state for callback)');
|
|
686
|
+
this.clearOldTokensKeepState();
|
|
687
|
+
}
|
|
688
|
+
else {
|
|
689
|
+
// No hay callback: limpiar todo
|
|
690
|
+
console.log('[AuthService] Clearing all expired tokens before configure');
|
|
691
|
+
this.clearAllTokens();
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
// Ahora es seguro configurar OAuthService (no hay tokens expirados que validar)
|
|
676
695
|
this.oauthService.configure(authConfig);
|
|
677
696
|
// NO usar silent refresh - si expira, redirigir al login
|
|
678
697
|
this.setupManualConfiguration();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-lib-angular.mjs","sources":["../../src/lib/version.ts","../../src/lib/models/login-config.interface.ts","../../src/lib/models/dashboard-config.interface.ts","../../src/lib/models/library-config.interface.ts","../../src/lib/config/app.config.ts","../../src/lib/config/authentication.config.ts","../../src/lib/services/authentication.service.ts","../../src/lib/services/config.service.ts","../../src/lib/services/authorization.service.ts","../../src/lib/guards/authorization.guard.ts","../../src/lib/components/login/login.component.ts","../../src/lib/components/login/login.component.html","../../src/lib/components/dashboard/dashboard.component.ts","../../src/lib/components/dashboard/dashboard.component.html","../../src/public-api.ts","../../src/shared-lib-angular.ts"],"sourcesContent":["// ========================================\n// VERSION - Auto-generado por sync-version.js\n// ========================================\n// Ejecutar 'npm run sync-version' para actualizar manualmente\n// Se sincroniza automáticamente en prebuild\n\n/**\n * Versión actual de la librería @dinafi/frmk\n * Sincronizada con package.json\n */\nexport const VERSION = '1.0.30';\n\n/**\n * Información completa de la versión\n */\nexport const VERSION_INFO = {\n version: '1.0.30',\n name: 'shared-lib-angular',\n buildDate: '2026-02-05T17:48:24.121Z',\n angular: '^20.0.0'\n} as const;\n","/**\r\n * Interface for configuring the LoginComponent appearance and behavior\r\n */\r\nexport interface LoginConfig {\r\n // === IDENTITY ===\r\n /** URL of the logo image. Defaults to the Ministerio de Hacienda logo */\r\n logoUrl: string;\r\n /** Alt text for the logo image */\r\n logoAlt: string;\r\n /** Width of the logo (CSS value, e.g., '120px') */\r\n logoWidth: string;\r\n /** Height of the logo (CSS value, e.g., '120px') */\r\n logoHeight: string;\r\n\r\n // === TEXTS ===\r\n /** Main title displayed on the login page */\r\n title: string;\r\n /** Optional subtitle displayed below the title */\r\n subtitle?: string;\r\n /** Institution name displayed in the footer */\r\n institutionName: string;\r\n /** Text for the login button */\r\n loginButtonText: string;\r\n /** Text for the logout button */\r\n logoutButtonText: string;\r\n /** Text for the \"go to dashboard\" button when already authenticated */\r\n dashboardButtonText: string;\r\n\r\n // === VERSION ===\r\n /** Whether to show the version number */\r\n showVersion: boolean;\r\n /** Version string to display */\r\n version: string;\r\n\r\n // === COLORS (CSS custom properties override) ===\r\n /** Primary color (overrides --color-primary) */\r\n primaryColor?: string;\r\n /** Background color of the container */\r\n backgroundColor?: string;\r\n /** Text color */\r\n textColor?: string;\r\n\r\n // === BEHAVIOR ===\r\n /** URL to redirect after successful login */\r\n redirectUrl: string;\r\n /** Whether to show the logout button when authenticated */\r\n showLogoutButton: boolean;\r\n\r\n // === FOOTER ===\r\n /** Custom footer text */\r\n footerText?: string;\r\n /** Whether to show the footer */\r\n showFooter: boolean;\r\n}\r\n\r\n/**\r\n * Default configuration for the LoginComponent\r\n */\r\nexport const DEFAULT_LOGIN_CONFIG: LoginConfig = {\r\n logoUrl: 'assets/@dinafi/frmk/logo-mh.png',\r\n logoAlt: 'Logo',\r\n logoWidth: '120px',\r\n logoHeight: '120px',\r\n title: 'Sistema de Autenticación',\r\n institutionName: 'Ministerio de Hacienda de El Salvador',\r\n loginButtonText: 'Iniciar Sesión con OIDC',\r\n logoutButtonText: 'Cerrar Sesión',\r\n dashboardButtonText: 'Ir al Dashboard',\r\n showVersion: true,\r\n version: '1.0.0',\r\n redirectUrl: '/home',\r\n showLogoutButton: true,\r\n showFooter: true\r\n};\r\n","/**\r\n * Interface for configuring the DashboardComponent appearance and behavior\r\n */\r\nexport interface DashboardConfig {\r\n /** Application title displayed in the header */\r\n title: string;\r\n /** Optional subtitle */\r\n subtitle?: string;\r\n /** Logo URL */\r\n logoUrl: string;\r\n /** Logo alt text */\r\n logoAlt: string;\r\n /** Footer text */\r\n footerText: string;\r\n /** Whether to show the version in the footer */\r\n showVersion: boolean;\r\n /** Version string */\r\n version: string;\r\n /** Whether to show static menu items (Inicio, Página Ejemplo, Componentes UI) */\r\n showStaticMenu: boolean;\r\n}\r\n\r\n/**\r\n * Default configuration for the DashboardComponent\r\n */\r\nexport const DEFAULT_DASHBOARD_CONFIG: DashboardConfig = {\r\n title: 'Sistema',\r\n logoUrl: 'assets/@dinafi/frmk/logo-mh.png',\r\n logoAlt: 'Logo',\r\n footerText: 'Ministerio de Hacienda, El Salvador',\r\n showVersion: true,\r\n version: '1.0.0',\r\n showStaticMenu: true\r\n};\r\n","import { InjectionToken } from '@angular/core';\r\nimport { LoginConfig } from './login-config.interface';\r\nimport { DashboardConfig } from './dashboard-config.interface';\r\n\r\n/**\r\n * Configuración de la librería que debe ser proporcionada por la aplicación consumidora\r\n * Estos valores son críticos y deben ser configurados al inicializar la librería\r\n */\r\nexport interface FrmkLibraryConfig {\r\n /**\r\n * URL del servidor de configuración (Config Server)\r\n * Ejemplo: 'config-server.example.com' o 'localhost:8080'\r\n */\r\n configServerHost: string;\r\n\r\n /**\r\n * Identificador del frontend en el Config Server\r\n * Este valor identifica la aplicación para obtener su configuración específica\r\n * Ejemplo: 'mi-aplicacion-frontend'\r\n */\r\n frontendId: string;\r\n\r\n /**\r\n * Ruta del servicio de configuración (opcional)\r\n * Por defecto: '/api/v1/config/service'\r\n */\r\n configServicePath?: string;\r\n\r\n /**\r\n * Realm de autenticación (opcional)\r\n * Por defecto se obtiene del Config Server\r\n */\r\n realm?: string;\r\n\r\n /**\r\n * Si es ambiente de producción (opcional)\r\n * Por defecto: false\r\n */\r\n production?: boolean;\r\n\r\n /**\r\n * Si requiere HTTPS (opcional)\r\n * Por defecto: true\r\n */\r\n requireHttps?: boolean;\r\n\r\n /**\r\n * Mostrar información de debug (opcional)\r\n * Por defecto: false\r\n */\r\n showDebugInformation?: boolean;\r\n\r\n /**\r\n * Configuración del componente de Login (opcional)\r\n * Permite personalizar textos, logos y comportamiento del login\r\n */\r\n loginConfig?: Partial<LoginConfig>;\r\n\r\n /**\r\n * Configuración del componente Dashboard (opcional)\r\n * Permite personalizar el layout principal de la aplicación\r\n */\r\n dashboardConfig?: Partial<DashboardConfig>;\r\n}\r\n\r\n/**\r\n * Configuración por defecto de la librería\r\n */\r\nexport const DEFAULT_LIBRARY_CONFIG: Partial<FrmkLibraryConfig> = {\r\n configServicePath: '/api/v1/config/service',\r\n production: false,\r\n requireHttps: true,\r\n showDebugInformation: false\r\n};\r\n\r\n/**\r\n * Token de inyección para la configuración de la librería\r\n * \r\n * @example\r\n * // En el app.config.ts o app.module.ts de la aplicación consumidora:\r\n * providers: [\r\n * {\r\n * provide: FRMK_LIBRARY_CONFIG,\r\n * useValue: {\r\n * configServerHost: 'config-server.miempresa.com',\r\n * frontendId: 'mi-aplicacion-frontend',\r\n * production: environment.production\r\n * }\r\n * }\r\n * ]\r\n */\r\nexport const FRMK_LIBRARY_CONFIG = new InjectionToken<FrmkLibraryConfig>('FrmkLibraryConfig');\r\n\r\n/**\r\n * Función helper para crear la configuración de la librería\r\n * \r\n * @example\r\n * // En el app.config.ts:\r\n * import { provideFrmkConfig } from '@mh-dinafi-frmk/shared-lib-angular';\r\n * \r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideFrmkConfig({\r\n * configServerHost: environment.configServerHost,\r\n * frontendId: 'mi-aplicacion'\r\n * })\r\n * ]\r\n * };\r\n */\r\nexport function provideFrmkConfig(config: FrmkLibraryConfig) {\r\n return {\r\n provide: FRMK_LIBRARY_CONFIG,\r\n useValue: {\r\n ...DEFAULT_LIBRARY_CONFIG,\r\n ...config\r\n }\r\n };\r\n}\r\n","import { AppConfiguration, ConfigServerResponse } from '../models/app-config.interface';\r\nimport { FrmkLibraryConfig, DEFAULT_LIBRARY_CONFIG } from '../models/library-config.interface';\r\nimport { LoginConfig, DEFAULT_LOGIN_CONFIG } from '../models/login-config.interface';\r\nimport { DashboardConfig, DEFAULT_DASHBOARD_CONFIG } from '../models/dashboard-config.interface';\r\n\r\n// Variable global para almacenar la configuración actual\r\nlet currentAppConfig: AppConfiguration | null = null;\r\n\r\n// Variable global para almacenar la configuración de la librería\r\nlet libraryConfig: FrmkLibraryConfig | null = null;\r\n\r\n/**\r\n * Inicializa la configuración de la librería con los valores proporcionados por la aplicación\r\n * Esta función debe ser llamada antes de usar cualquier servicio de la librería\r\n * \r\n * @param config Configuración proporcionada por la aplicación consumidora\r\n */\r\nexport function initializeLibraryConfig(config: FrmkLibraryConfig): void {\r\n libraryConfig = {\r\n ...DEFAULT_LIBRARY_CONFIG,\r\n ...config\r\n } as FrmkLibraryConfig;\r\n \r\n // Resetear la configuración actual para que se reconstruya con los nuevos valores\r\n currentAppConfig = null;\r\n}\r\n\r\n/**\r\n * Obtiene la configuración de la librería\r\n * Lanza error si no ha sido inicializada\r\n */\r\nexport function getLibraryConfig(): FrmkLibraryConfig {\r\n if (!libraryConfig) {\r\n throw new Error(\r\n '[FRMK] La librería no ha sido configurada. ' +\r\n 'Debe proporcionar FRMK_LIBRARY_CONFIG en los providers de su aplicación. ' +\r\n 'Ejemplo: provideFrmkConfig({ configServerHost: \"...\", frontendId: \"...\" })'\r\n );\r\n }\r\n return libraryConfig;\r\n}\r\n\r\n/**\r\n * Verifica si la librería ha sido configurada\r\n */\r\nexport function isLibraryConfigured(): boolean {\r\n return libraryConfig !== null;\r\n}\r\n\r\n/**\r\n * Obtiene la configuración del componente Login\r\n * Combina los valores por defecto con los configurados en la librería\r\n */\r\nexport function getLoginConfig(): LoginConfig {\r\n const libConfig = isLibraryConfigured() ? getLibraryConfig() : null;\r\n return {\r\n ...DEFAULT_LOGIN_CONFIG,\r\n ...(libConfig?.loginConfig || {})\r\n };\r\n}\r\n\r\n/**\r\n * Obtiene la configuración del componente Dashboard\r\n * Combina los valores por defecto con los configurados en la librería\r\n */\r\nexport function getDashboardConfig(): DashboardConfig {\r\n const libConfig = isLibraryConfigured() ? getLibraryConfig() : null;\r\n return {\r\n ...DEFAULT_DASHBOARD_CONFIG,\r\n ...(libConfig?.dashboardConfig || {})\r\n };\r\n}\r\n\r\n// Función para crear la configuración por defecto usando los valores de la librería\r\nfunction createDefaultAppConfig(): AppConfiguration {\r\n const libConfig = getLibraryConfig();\r\n \r\n return {\r\n hosts: { \r\n configServer: libConfig.configServerHost,\r\n authServer: '', // Leído desde Config Server\r\n keycloak: '', // Leído desde Config Server\r\n localApp: '' // Leído desde Config Server\r\n },\r\n paths: {\r\n configService: libConfig.configServicePath || '/api/v1/config/service',\r\n realm: libConfig.realm || 'realm-to-create'\r\n },\r\n configServer: {\r\n url: '', // Se construirá dinámicamente\r\n frontend: libConfig.frontendId\r\n },\r\n auth: {\r\n issuer: '', // Se construirá dinámicamente\r\n loginUrl: '', // Se construirá dinámicamente\r\n tokenEndpoint: '', // Se construirá dinámicamente\r\n userinfoEndpoint: '', // Se construirá dinámicamente\r\n logoutUrl: '', // Se construirá dinámicamente\r\n clientId: '',\r\n redirectUri: '', // Se construirá dinámicamente\r\n postLogoutRedirectUri: '', // Se construirá dinámicamente\r\n silentRefreshRedirectUri: '', // Se construirá dinámicamente\r\n scope: 'openid email profile'\r\n },\r\n authorization: {\r\n baseUrl: '',\r\n verifyEndpoint: '/api/v1/authz/verify-groups',\r\n hierarchyEndpoint: '/api/v1/authz/hierarchy-by-component-and-groups',\r\n },\r\n environment: {\r\n production: libConfig.production ?? false,\r\n requireHttps: libConfig.requireHttps ?? true,\r\n showDebugInformation: libConfig.showDebugInformation ?? false\r\n }\r\n };\r\n}\r\n\r\n// Getter para obtener la configuración por defecto (lazy initialization)\r\nexport function getDefaultAppConfig(): AppConfiguration {\r\n return createDefaultAppConfig();\r\n}\r\n\r\n// Función para mapear la configuración del config server a la configuración de la aplicación\r\nexport function mapConfigServerResponse(configServerData: ConfigServerResponse): Partial<AppConfiguration> {\r\n const mappedConfig: Partial<AppConfiguration> = {};\r\n const defaultConfig = getDefaultAppConfig();\r\n \r\n // Mapear Auth URL\r\n configureAuthServer();\r\n\r\n // Mapear client ID\r\n initializeClientId();\r\n\r\n // Mapear realm\r\n initializeRealmMapping();\r\n\r\n // Mapear URL de autorización (authServer)\r\n initializeAuthorizationConfig();\r\n\r\n // Mapear scope de autorización\r\n initializeAuthScope();\r\n\r\n // Mapear keycloak URL\r\n initializeKeycloakHost();\r\n\r\n // Mapear callback URL (local app host)\r\n configureLocalAppCallback(); \r\n\r\n // Mapear callback URL (local app host)\r\n initializeHttpsSettings(); \r\n\r\n return mappedConfig;\r\n\r\n function initializeHttpsSettings() {\r\n if (configServerData[\"security.url.https\"]) {\r\n mappedConfig.environment = {\r\n ...defaultConfig.environment,\r\n ...(mappedConfig.environment || {}),\r\n requireHttps: configServerData[\"security.url.https\"]\r\n };\r\n }\r\n }\r\n\r\n function configureLocalAppCallback() {\r\n if (configServerData[\"security.url.callback\"]) {\r\n mappedConfig.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mappedConfig.hosts || {}),\r\n localApp: configServerData[\"security.url.callback\"]\r\n };\r\n }\r\n }\r\n\r\n function initializeKeycloakHost() {\r\n if (configServerData[\"security.url.keycloak\"]) {\r\n mappedConfig.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mappedConfig.hosts || {}),\r\n keycloak: configServerData[\"security.url.keycloak\"]\r\n };\r\n }\r\n }\r\n\r\n function initializeAuthScope() {\r\n if (configServerData[\"security.scope\"]) {\r\n mappedConfig.auth = {\r\n ...defaultConfig.auth,\r\n ...(mappedConfig.auth || {}),\r\n scope: configServerData[\"security.scope\"]\r\n };\r\n }\r\n }\r\n\r\n function initializeAuthorizationConfig() {\r\n if (configServerData[\"security.url.authz\"]) {\r\n mappedConfig.authorization = {\r\n ...defaultConfig.authorization,\r\n ...(mappedConfig.authorization || {}),\r\n baseUrl: configServerData[\"security.url.authz\"]\r\n };\r\n }\r\n }\r\n\r\n function initializeRealmMapping() {\r\n if (configServerData[\"security.realm\"]) {\r\n mappedConfig.paths = {\r\n ...defaultConfig.paths,\r\n ...(mappedConfig.paths || {}),\r\n realm: configServerData[\"security.realm\"]\r\n };\r\n }\r\n }\r\n\r\n function initializeClientId() {\r\n if (configServerData[\"quarkus.oidc.client-id\"]) {\r\n mappedConfig.auth = {\r\n ...defaultConfig.auth,\r\n ...(mappedConfig.auth || {}),\r\n clientId: configServerData[\"quarkus.oidc.client-id\"]\r\n };\r\n }\r\n }\r\n\r\n function configureAuthServer() {\r\n if (configServerData[\"security.url.auth\"]) {\r\n mappedConfig.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mappedConfig.hosts || {}),\r\n authServer: configServerData[\"security.url.auth\"]\r\n };\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Función para establecer la configuración actual con datos del config server\r\n * Esta función debe ser llamada desde el ConfigService después de cargar la configuración\r\n */\r\nexport function setCurrentAppConfig(configServerData?: ConfigServerResponse): void {\r\n currentAppConfig = getAppConfigWithServerData(configServerData);\r\n}\r\n\r\n/**\r\n * Función para obtener la configuración actual\r\n * Si no se ha establecido una configuración, devuelve la configuración por defecto\r\n */\r\nexport function getCurrentAppConfig(): AppConfiguration {\r\n return currentAppConfig || getAppConfig();\r\n}\r\n\r\n// Función para obtener la configuración con posibles sobrescrituras de variables de entorno\r\nexport function getAppConfig(): AppConfiguration {\r\n const config = { ...getDefaultAppConfig() };\r\n\r\n // Construir URLs dinámicamente\r\n const localProtocol = config.environment.requireHttps ? 'https' : 'http';\r\n \r\n // Config Server URL\r\n config.configServer.url = `${localProtocol}://${config.hosts.configServer}${config.paths.configService}`;\r\n \r\n // Auth URLs\r\n config.auth.issuer = `${localProtocol}://${config.hosts.keycloak}/realms/${config.paths.realm}`;\r\n config.auth.loginUrl = `${localProtocol}://${config.hosts.keycloak}/realms/${config.paths.realm}/protocol/openid-connect/auth`;\r\n config.auth.tokenEndpoint = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/token`;\r\n config.auth.userinfoEndpoint = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/userinfo`;\r\n config.auth.logoutUrl = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/logout`;\r\n \r\n // Redirect URLs (locales)\r\n const currentOrigin = globalThis.window?.location?.origin ?? config.hosts.localApp;\r\n config.auth.redirectUri = `${currentOrigin}/login`;\r\n config.auth.postLogoutRedirectUri = `${currentOrigin}/login`;\r\n \r\n // Authorization URL\r\n config.authorization.baseUrl = `${localProtocol}://${config.authorization.baseUrl}`;\r\n \r\n return config;\r\n}\r\n\r\n// Función para obtener la configuración aplicando primero la del config server y luego variables de entorno\r\nexport function getAppConfigWithServerData(configServerData?: ConfigServerResponse): AppConfiguration {\r\n let config = { ...getDefaultAppConfig() };\r\n \r\n // Aplicar configuración del config server si está disponible\r\n if (configServerData) {\r\n const serverMappedConfig = mapConfigServerResponse(configServerData);\r\n config = mergeConfigurations(config, serverMappedConfig);\r\n }\r\n \r\n // Construir URLs dinámicamente\r\n config = buildDynamicUrls(config);\r\n \r\n return config;\r\n}\r\n\r\n// Función auxiliar para fusionar configuraciones\r\nfunction mergeConfigurations(base: AppConfiguration, override: Partial<AppConfiguration>): AppConfiguration {\r\n const merged = { ...base };\r\n \r\n if (override.hosts) {\r\n merged.hosts = { ...merged.hosts, ...override.hosts };\r\n }\r\n if (override.paths) {\r\n merged.paths = { ...merged.paths, ...override.paths };\r\n }\r\n if (override.configServer) {\r\n merged.configServer = { ...merged.configServer, ...override.configServer };\r\n }\r\n if (override.auth) {\r\n merged.auth = { ...merged.auth, ...override.auth };\r\n }\r\n if (override.authorization) {\r\n merged.authorization = { ...merged.authorization, ...override.authorization };\r\n }\r\n if (override.environment) {\r\n merged.environment = { ...merged.environment, ...override.environment };\r\n }\r\n \r\n return merged;\r\n}\r\n\r\n// Función para construir URLs dinámicamente\r\nfunction buildDynamicUrls(config: AppConfiguration): AppConfiguration {\r\n const localProtocol = config.environment.requireHttps ? 'https' : 'http';\r\n \r\n // Config Server URL\r\n config.configServer.url = `${localProtocol}://${config.hosts.configServer}${config.paths.configService}`;\r\n \r\n // Auth URLs\r\n config.auth.issuer = `${localProtocol}://${config.hosts.keycloak}/realms/${config.paths.realm}`;\r\n config.auth.loginUrl = `${localProtocol}://${config.hosts.keycloak}/realms/${config.paths.realm}/protocol/openid-connect/auth`;\r\n config.auth.tokenEndpoint = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/token`;\r\n config.auth.userinfoEndpoint = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/userinfo`;\r\n config.auth.logoutUrl = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/logout`;\r\n \r\n // Redirect URLs (locales)\r\n const currentOrigin = globalThis.window?.location?.origin ?? config.hosts.localApp;\r\n config.auth.redirectUri = `${currentOrigin}/login`;\r\n config.auth.postLogoutRedirectUri = `${currentOrigin}/login`;\r\n\r\n // Authorization URL\r\n config.authorization.baseUrl = `${localProtocol}://${config.authorization.baseUrl}`;\r\n \r\n return config;\r\n}\r\n","import { AuthConfig } from 'angular-oauth2-oidc';\r\nimport { getCurrentAppConfig } from './app.config';\r\n\r\n/**\r\n * Función para obtener la configuración de autenticación actual\r\n * Esta función se evalúa cada vez que se llama, por lo que siempre tendrá la configuración más reciente\r\n */\r\nexport function getAuthConfig(): AuthConfig {\r\n const appConfig = getCurrentAppConfig();\r\n\r\n return {\r\n // URL base del servidor de identidad\r\n issuer: appConfig.auth.issuer,\r\n \r\n // URLs específicas para evitar discovery document\r\n loginUrl: appConfig.auth.loginUrl,\r\n tokenEndpoint: appConfig.auth.tokenEndpoint,\r\n userinfoEndpoint: appConfig.auth.userinfoEndpoint,\r\n logoutUrl: appConfig.auth.logoutUrl,\r\n \r\n // IMPORTANTE: URLs de redirección completas\r\n redirectUri: appConfig.auth.redirectUri,\r\n postLogoutRedirectUri: appConfig.auth.postLogoutRedirectUri,\r\n\r\n // Configuración del cliente\r\n clientId: appConfig.auth.clientId,\r\n\r\n // Configuración OAuth\r\n responseType: 'code',\r\n scope: appConfig.auth.scope,\r\n \r\n // Configuraciones para desarrollo\r\n disableAtHashCheck: true,\r\n requireHttps: appConfig.environment.requireHttps,\r\n showDebugInformation: appConfig.environment.showDebugInformation,\r\n strictDiscoveryDocumentValidation: false,\r\n skipIssuerCheck: true,\r\n\r\n // IMPORTANTE: Configuraciones para manejar state y session_state\r\n requestAccessToken: true,\r\n customQueryParams: {},\r\n\r\n // Timeouts\r\n silentRefreshTimeout: 5000,\r\n timeoutFactor: 0.25,\r\n \r\n // Session checks\r\n sessionChecksEnabled: false,\r\n clearHashAfterLogin: true,\r\n\r\n // Configuración OIDC\r\n oidc: true\r\n };\r\n}\r\n\r\n// Mantener la exportación original para compatibilidad\r\nexport function getAuthConfigEnv(): AuthConfig {\r\n return getAuthConfig();\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { AuthConfig, OAuthService, OAuthEvent } from 'angular-oauth2-oidc';\r\nimport { BehaviorSubject } from 'rxjs';\r\nimport { getAuthConfigEnv } from '../config/authentication.config';\r\n\r\n@Injectable({ \r\n providedIn: 'root'\r\n})\r\nexport class AuthService {\r\n private readonly isAuthenticatedSubject$ = new BehaviorSubject<boolean>(false);\r\n public isAuthenticated$ = this.isAuthenticatedSubject$.asObservable();\r\n\r\n private readonly isDoneLoadingSubject$ = new BehaviorSubject<boolean>(false);\r\n public isDoneLoading$ = this.isDoneLoadingSubject$.asObservable();\r\n\r\n private isInitialLogin = true;\r\n\r\n constructor(private readonly oauthService: OAuthService, private readonly router: Router) {\r\n // IMPORTANTE: Limpiar tokens expirados ANTES de cualquier otra operación\r\n this.clearExpiredTokensOnStartup();\r\n \r\n this.oauthService.events \r\n .subscribe((event) => {\r\n if (event instanceof OAuthEvent) {\r\n if (event.type === 'token_received') {\r\n this.handleSuccessfulAuthentication();\r\n }\r\n if (event.type === 'logout') {\r\n this.handleLogout();\r\n }\r\n if (event.type === 'token_error') {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n if (event.type === 'silently_refreshed') {\r\n this.handleSilentRefresh();\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Limpia tokens expirados al iniciar la aplicación\r\n * Solo limpia si NO estamos en un callback OAuth\r\n */\r\n private clearExpiredTokensOnStartup(): void {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n \r\n // Detectar TODOS los parámetros que indican un callback OAuth\r\n // Keycloak puede enviar: code, state, session_state, iss (RFC 9207)\r\n const isOAuthCallback = urlParams.has('code') || \r\n urlParams.has('iss') || \r\n urlParams.has('session_state') ||\r\n urlParams.has('state') ||\r\n window.location.hash.includes('access_token') ||\r\n window.location.hash.includes('code');\r\n \r\n if (isOAuthCallback) {\r\n console.log('[AuthService] OAuth callback detected, skipping token cleanup');\r\n return;\r\n }\r\n\r\n // Verificar si hay un token y si está expirado\r\n const expiresAt = localStorage.getItem('expires_at') || sessionStorage.getItem('expires_at');\r\n if (expiresAt) {\r\n const expirationTime = parseInt(expiresAt, 10);\r\n const now = Date.now();\r\n \r\n if (expirationTime < now) {\r\n console.log('[AuthService] Expired token detected, clearing storage');\r\n this.clearAllTokens();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Limpia todos los tokens del storage\r\n */\r\n private clearAllTokens(): void {\r\n const keysToRemove = [\r\n 'access_token', 'refresh_token', 'id_token', 'token_type',\r\n 'expires_at', 'nonce', 'PKCE_verifier', 'session_state',\r\n 'id_token_claims_obj', 'id_token_expires_at', 'id_token_stored_at',\r\n 'access_token_stored_at'\r\n ];\r\n \r\n keysToRemove.forEach(key => {\r\n localStorage.removeItem(key);\r\n sessionStorage.removeItem(key);\r\n });\r\n }\r\n\r\n /**\r\n * Limpia tokens antiguos pero MANTIENE state, nonce y PKCE_verifier\r\n * que son necesarios para validar el callback OAuth\r\n */\r\n private clearOldTokensKeepState(): void {\r\n // Solo limpiar tokens, NO state/nonce/PKCE_verifier\r\n const keysToRemove = [\r\n 'access_token', 'refresh_token', 'id_token', 'token_type',\r\n 'expires_at', 'id_token_claims_obj', 'id_token_expires_at', \r\n 'id_token_stored_at', 'access_token_stored_at'\r\n ];\r\n \r\n keysToRemove.forEach(key => {\r\n localStorage.removeItem(key);\r\n sessionStorage.removeItem(key);\r\n });\r\n \r\n console.log('[AuthService] Cleared old tokens, kept state/nonce/PKCE for callback validation');\r\n }\r\n\r\n private handleSuccessfulAuthentication(): void {\r\n if (this.oauthService.hasValidAccessToken()) {\r\n this.isAuthenticatedSubject$.next(true);\r\n this.isDoneLoadingSubject$.next(true);\r\n \r\n // Limpiar parámetros OAuth de la URL para evitar problemas al refrescar\r\n this.cleanupOAuthParams();\r\n \r\n if (this.isInitialLogin) {\r\n this.isInitialLogin = false;\r\n }\r\n } else {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n }\r\n\r\n /**\r\n * Limpia los parámetros OAuth de la URL después del login exitoso\r\n * Esto evita problemas cuando el usuario refresca la página\r\n */\r\n private cleanupOAuthParams(): void {\r\n try {\r\n const url = new URL(window.location.href);\r\n const paramsToRemove = ['code', 'state', 'session_state', 'iss'];\r\n let hasOAuthParams = false;\r\n \r\n paramsToRemove.forEach(param => {\r\n if (url.searchParams.has(param)) {\r\n url.searchParams.delete(param);\r\n hasOAuthParams = true;\r\n }\r\n });\r\n \r\n if (hasOAuthParams) {\r\n // Reemplazar URL sin recargar la página\r\n window.history.replaceState({}, document.title, url.toString());\r\n console.log('[AuthService] OAuth params cleaned from URL');\r\n }\r\n } catch (error) {\r\n console.warn('[AuthService] Error cleaning OAuth params:', error);\r\n }\r\n }\r\n\r\n private handleSilentRefresh(): void {\r\n if (this.oauthService.hasValidAccessToken()) {\r\n this.isAuthenticatedSubject$.next(true);\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n }\r\n\r\n private handleLogout(): void {\r\n this.isAuthenticatedSubject$.next(false);\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n\r\n /**\r\n * Limpia todos los tokens del storage\r\n */\r\n private clearTokenStorage(): void {\r\n this.oauthService.logOut(true); // true = no redirect, solo limpiar\r\n localStorage.removeItem('access_token');\r\n localStorage.removeItem('refresh_token');\r\n localStorage.removeItem('id_token');\r\n localStorage.removeItem('nonce');\r\n localStorage.removeItem('expires_at');\r\n sessionStorage.removeItem('access_token');\r\n sessionStorage.removeItem('refresh_token');\r\n sessionStorage.removeItem('id_token');\r\n }\r\n\r\n /**\r\n * Verifica si el token actual está expirado\r\n */\r\n private isTokenExpired(): boolean {\r\n const expiresAt = this.oauthService.getAccessTokenExpiration();\r\n if (!expiresAt) {\r\n return false; // Si no hay token, no está \"expirado\", simplemente no existe\r\n }\r\n return expiresAt < Date.now();\r\n }\r\n\r\n private async runInitialLoginSequence(): Promise<void> {\r\n try {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hasCode = urlParams.has('code');\r\n const hasState = urlParams.has('state');\r\n const hasIss = urlParams.has('iss');\r\n const hasSessionState = urlParams.has('session_state');\r\n const hasFragment = window.location.hash.includes('access_token') || window.location.hash.includes('code');\r\n \r\n // Detectar si estamos en un callback OAuth (Keycloak envía code, state, session_state, iss)\r\n const isOAuthCallback = hasCode || hasFragment || (hasState && (hasIss || hasSessionState));\r\n\r\n // Si NO estamos en callback OAuth y hay tokens expirados, limpiar y terminar\r\n if (!isOAuthCallback && this.isTokenExpired()) {\r\n console.log('[AuthService] No OAuth callback detected and token expired, clearing storage');\r\n this.clearTokenStorage();\r\n this.isDoneLoadingSubject$.next(true);\r\n return;\r\n }\r\n\r\n // Si estamos en callback OAuth, SIEMPRE limpiar tokens anteriores para evitar conflictos\r\n // Esto es crítico: angular-oauth2-oidc valida tokens existentes antes de procesar el código nuevo\r\n if (isOAuthCallback) {\r\n console.log('[AuthService] OAuth callback detected, clearing old tokens before processing');\r\n // Limpiar solo tokens, NO el state/nonce que necesitamos para validar el callback\r\n this.clearOldTokensKeepState();\r\n \r\n this.isInitialLogin = true;\r\n await this.oauthService.tryLoginCodeFlow();\r\n } \r\n\r\n const hasValidToken = this.oauthService.hasValidAccessToken();\r\n \r\n if (hasValidToken) {\r\n if (!hasCode && !hasFragment) {\r\n this.isInitialLogin = false;\r\n }\r\n this.handleSuccessfulAuthentication();\r\n } else {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n \r\n } catch (error: any) {\r\n console.error('[AuthService] Error during authentication initialization:', error);\r\n \r\n // Si el error es por token expirado, limpiar y permitir nuevo login\r\n if (error?.message?.includes('expired') || error?.reason?.includes('expired')) {\r\n this.clearTokenStorage();\r\n }\r\n \r\n this.isDoneLoadingSubject$.next(true);\r\n } \r\n }\r\n\r\n private setupManualConfiguration(): void {\r\n const authConfig = getAuthConfigEnv();\r\n this.oauthService.tokenEndpoint = authConfig.tokenEndpoint!;\r\n this.oauthService.userinfoEndpoint = authConfig.userinfoEndpoint!;\r\n this.oauthService.loginUrl = authConfig.loginUrl!;\r\n this.oauthService.logoutUrl = authConfig.logoutUrl!;\r\n this.oauthService.clientId = authConfig.clientId!;\r\n this.oauthService.redirectUri = authConfig.redirectUri!;\r\n this.oauthService.scope = authConfig.scope!;\r\n this.oauthService.responseType = authConfig.responseType!;\r\n }\r\n\r\n public initializeAuth(authConfig: AuthConfig): void {\r\n this.oauthService.configure(authConfig);\r\n // NO usar silent refresh - si expira, redirigir al login\r\n this.setupManualConfiguration();\r\n this.runInitialLoginSequence();\r\n }\r\n\r\n public getAuthConfig(): AuthConfig {\r\n return getAuthConfigEnv();\r\n }\r\n\r\n public login(targetUrl?: string): void {\r\n this.isInitialLogin = true;\r\n \r\n if (!this.oauthService.clientId) {\r\n return;\r\n }\r\n if (!this.oauthService.redirectUri) {\r\n return;\r\n }\r\n\r\n this.oauthService.initLoginFlow(targetUrl || undefined);\r\n }\r\n\r\n public async logout(): Promise<void> {\r\n try {\r\n await this.callKeycloakLogoutEndpoint().catch(err => {\r\n console.warn('Keycloak logout endpoint failed, but will continue with local cleanup:', err);\r\n });\r\n \r\n this.performLocalLogout();\r\n \r\n } catch (error) {\r\n console.error('Error during logout:', error);\r\n this.performLocalLogout();\r\n }\r\n }\r\n\r\n private async callKeycloakLogoutEndpoint(): Promise<void> {\r\n const authConfig = getAuthConfigEnv();\r\n const logoutUrl = authConfig.logoutUrl;\r\n \r\n let refreshToken: string | null = this.oauthService.getRefreshToken();\r\n \r\n if (!refreshToken) {\r\n refreshToken = localStorage.getItem('refresh_token') \r\n || localStorage.getItem('refresh_token_' + authConfig.clientId)\r\n || sessionStorage.getItem('refresh_token');\r\n }\r\n \r\n if (!logoutUrl) {\r\n console.warn('Logout URL not configured, skipping Keycloak logout');\r\n return;\r\n }\r\n\r\n if (!refreshToken) {\r\n console.warn('No refresh token found, logout endpoint may fail');\r\n }\r\n\r\n const body = new URLSearchParams();\r\n body.set('client_id', authConfig.clientId!);\r\n \r\n if (refreshToken) {\r\n body.set('refresh_token', refreshToken);\r\n }\r\n\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/x-www-form-urlencoded'\r\n };\r\n\r\n try {\r\n const response = await fetch(logoutUrl, {\r\n method: 'POST',\r\n headers,\r\n body: body.toString()\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n console.warn('Keycloak logout returned error, but local cleanup completed:', errorText);\r\n }\r\n } catch (error) {\r\n console.warn('Failed to call Keycloak logout endpoint:', error);\r\n }\r\n }\r\n\r\n private performLocalLogout(): void {\r\n this.oauthService.logOut(true);\r\n \r\n // Limpiar tokens del localStorage\r\n localStorage.removeItem('access_token');\r\n localStorage.removeItem('id_token');\r\n localStorage.removeItem('refresh_token');\r\n localStorage.removeItem('code_verifier');\r\n localStorage.removeItem('nonce');\r\n localStorage.removeItem('PKCE_verifier');\r\n \r\n // Limpiar tokens del sessionStorage\r\n sessionStorage.removeItem('access_token');\r\n sessionStorage.removeItem('id_token');\r\n sessionStorage.removeItem('refresh_token');\r\n sessionStorage.removeItem('nonce');\r\n sessionStorage.removeItem('PKCE_verifier');\r\n \r\n this.isAuthenticatedSubject$.next(false);\r\n this.isDoneLoadingSubject$.next(true);\r\n \r\n const currentUrl = this.router.url;\r\n if (currentUrl !== '/login' && !currentUrl.includes('/login')) {\r\n this.router.navigate(['/login']);\r\n }\r\n }\r\n\r\n public logoutAndRedirect(targetUrl: string = '/login'): void {\r\n this.logout();\r\n this.router.navigate([targetUrl]);\r\n }\r\n\r\n public hasValidToken(): boolean {\r\n return this.oauthService.hasValidAccessToken();\r\n }\r\n\r\n public get identityClaims(): any {\r\n return this.oauthService.getIdentityClaims();\r\n }\r\n\r\n public get accessToken(): string {\r\n return this.oauthService.getAccessToken();\r\n }\r\n\r\n public getUserRoles(): string[] {\r\n const claims = this.identityClaims;\r\n if (claims?.roles) {\r\n return Array.isArray(claims.roles) ? claims.roles : [claims.roles];\r\n }\r\n \r\n if (claims) {\r\n const roles: string[] = [];\r\n \r\n if (claims.realm_access?.roles) {\r\n roles.push(...claims.realm_access.roles);\r\n }\r\n \r\n const authConfig = getAuthConfigEnv();\r\n if (claims.resource_access?.[authConfig.clientId!]?.roles) {\r\n roles.push(...claims.resource_access[authConfig.clientId!].roles);\r\n }\r\n \r\n return roles;\r\n }\r\n return [];\r\n }\r\n\r\n public hasRole(role: string): boolean {\r\n return this.getUserRoles().includes(role);\r\n }\r\n\r\n public hasAnyRole(roles: string[]): boolean {\r\n const userRoles = this.getUserRoles();\r\n return roles.some(role => userRoles.includes(role));\r\n }\r\n\r\n public getUserGroups(): string[] {\r\n const claims = this.identityClaims;\r\n const groups: string[] = [];\r\n\r\n // First, try to get groups from identity claims (ID token)\r\n if (claims) {\r\n if (claims.groups) {\r\n if (Array.isArray(claims.groups)) {\r\n groups.push(...claims.groups);\r\n } else {\r\n groups.push(claims.groups);\r\n }\r\n }\r\n\r\n if (claims.accessTokenGroups) {\r\n if (Array.isArray(claims.accessTokenGroups)) {\r\n groups.push(...claims.accessTokenGroups);\r\n } else {\r\n groups.push(claims.accessTokenGroups);\r\n }\r\n }\r\n\r\n if (claims.realm_access?.groups) {\r\n groups.push(...claims.realm_access.groups);\r\n }\r\n }\r\n\r\n // If no groups found in ID token, try to decode access token\r\n if (groups.length === 0) {\r\n const accessToken = this.accessToken;\r\n if (accessToken) {\r\n try {\r\n const payload = this.decodeJwtPayload(accessToken);\r\n console.log('[AuthService] Access token payload:', payload);\r\n\r\n // Extract groups from access token\r\n if (payload.groups) {\r\n if (Array.isArray(payload.groups)) {\r\n groups.push(...payload.groups);\r\n } else {\r\n groups.push(payload.groups);\r\n }\r\n }\r\n\r\n // Also check realm_access.roles as groups (Keycloak pattern)\r\n if (payload.realm_access?.roles) {\r\n groups.push(...payload.realm_access.roles);\r\n }\r\n\r\n // Check resource_access for client-specific roles\r\n if (payload.resource_access) {\r\n Object.values(payload.resource_access).forEach((resource: any) => {\r\n if (resource.roles && Array.isArray(resource.roles)) {\r\n groups.push(...resource.roles);\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n console.error('[AuthService] Error decoding access token:', error);\r\n }\r\n }\r\n }\r\n\r\n const uniqueGroups = [...new Set(groups)];\r\n console.log('[AuthService] getUserGroups result:', uniqueGroups);\r\n return uniqueGroups;\r\n }\r\n\r\n private decodeJwtPayload(token: string): any {\r\n try {\r\n const parts = token.split('.');\r\n if (parts.length !== 3) {\r\n throw new Error('Invalid JWT format');\r\n }\r\n const payload = parts[1];\r\n const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));\r\n return JSON.parse(decoded);\r\n } catch (error) {\r\n console.error('[AuthService] Failed to decode JWT:', error);\r\n return {};\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { firstValueFrom } from 'rxjs';\r\nimport { AppConfiguration, ConfigServerResponse } from '../models/app-config.interface';\r\nimport { getAppConfig, getAppConfigWithServerData, setCurrentAppConfig } from '../config/app.config';\r\n\r\n@Injectable({ \r\n providedIn: 'root' \r\n})\r\nexport class ConfigService {\r\n private configServerData: ConfigServerResponse | null = null;\r\n private finalAppConfig: AppConfiguration | null = null;\r\n private isLoaded = false;\r\n private readonly initialAppConfig = getAppConfig();\r\n\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /**\r\n * Carga la configuración desde el config-server\r\n */\r\n async loadConfig(): Promise<void> {\r\n try {\r\n const url = `${this.initialAppConfig.configServer.url}/${this.initialAppConfig.configServer.frontend}`;\r\n \r\n this.configServerData = await firstValueFrom(\r\n this.http.get<ConfigServerResponse>(url)\r\n );\r\n \r\n this.finalAppConfig = getAppConfigWithServerData(this.configServerData);\r\n \r\n // IMPORTANTE: Establecer la configuración actual para que esté disponible globalmente\r\n setCurrentAppConfig(this.configServerData);\r\n \r\n this.isLoaded = true;\r\n } catch (error) {\r\n console.log(`Exception while loading config: ${error}`);\r\n this.finalAppConfig = this.initialAppConfig;\r\n setCurrentAppConfig();\r\n this.isLoaded = true;\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene un valor de configuración por clave del config server\r\n */\r\n get(key: string): string | boolean | undefined {\r\n return this.configServerData?.[key as keyof ConfigServerResponse];\r\n }\r\n\r\n /**\r\n * Obtiene toda la configuración del config server\r\n */\r\n getAll(): ConfigServerResponse | null {\r\n return this.configServerData ? { ...this.configServerData } : null;\r\n }\r\n\r\n /**\r\n * Verifica si la configuración ha sido cargada\r\n */\r\n isConfigLoaded(): boolean {\r\n return this.isLoaded;\r\n }\r\n\r\n /**\r\n * Obtiene la configuración final de la aplicación (con valores del config server aplicados)\r\n */\r\n getAppConfig(): AppConfiguration {\r\n return this.finalAppConfig || this.initialAppConfig;\r\n }\r\n\r\n /**\r\n * Obtiene los datos raw del config server\r\n */\r\n getConfigServerData(): ConfigServerResponse | null {\r\n return this.configServerData;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';\r\nimport { Observable, of } from 'rxjs';\r\nimport { catchError, map } from 'rxjs/operators';\r\nimport { AuthService } from './authentication.service';\r\nimport { ConfigService } from './config.service';\r\nimport { AuthorizationRequest, AuthorizationResponse, MenuHierarchyItem } from '../models/authorization.interface';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class AuthorizationService {\r\n\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly authService: AuthService,\r\n private readonly configService: ConfigService\r\n ) {}\r\n\r\n /**\r\n * Verifica si el usuario tiene permisos para acceder a un recurso específico\r\n */\r\n verifyPermission(resourcePath: string, operationName: string = 'VIEW'): Observable<boolean> {\r\n const groups = this.getUserGroups();\r\n const config = this.configService.getAppConfig();\r\n \r\n if (groups.length === 0) {\r\n return of(false);\r\n }\r\n\r\n const request: AuthorizationRequest = {\r\n groupIds: groups,\r\n componentId: config.configServer.frontend,\r\n resourcePath: resourcePath,\r\n operationName: operationName\r\n };\r\n\r\n return this.checkAuthorization(request);\r\n }\r\n\r\n /**\r\n * Realiza la llamada HTTP al servicio de autorización\r\n */\r\n private checkAuthorization(request: AuthorizationRequest): Observable<boolean> {\r\n let params = new HttpParams();\r\n \r\n const cleanGroups = request.groupIds.map(group => group.replace(/\\//g, ''));\r\n const groupIdsString = cleanGroups.join(',');\r\n \r\n params = params.set('groupIds', groupIdsString);\r\n params = params.set('componentId', request.componentId);\r\n params = params.set('resourcePath', request.resourcePath);\r\n params = params.set('operationName', request.operationName);\r\n\r\n let headers = new HttpHeaders();\r\n\r\n const url = `${this.configService.getAppConfig().authorization.baseUrl}${this.configService.getAppConfig().authorization.verifyEndpoint}`;\r\n\r\n return this.http.get<AuthorizationResponse>(url, { \r\n params,\r\n headers\r\n }).pipe(\r\n map(response => {\r\n return response.hasPermission;\r\n }),\r\n catchError(() => {\r\n return of(false);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene los grupos del usuario desde el access token\r\n */\r\n private getUserGroups(): string[] {\r\n return this.authService.getUserGroups();\r\n }\r\n\r\n /** \r\n * Método público para obtener los grupos del usuario (útil para debugging)\r\n */\r\n public getUserGroupsDebug(): string[] {\r\n return this.authService.getUserGroups();\r\n }\r\n\r\n /**\r\n * Obtiene la jerarquía de menús basada en el componente y los grupos del usuario\r\n */\r\n getMenuHierarchy(): Observable<MenuHierarchyItem[]> {\r\n const groups = this.getUserGroups();\r\n const config = this.configService.getAppConfig();\r\n \r\n if (groups.length === 0) {\r\n return of([]);\r\n }\r\n\r\n const cleanGroups = groups.map(group => group.replace(/\\//g, ''));\r\n const groupIdsString = cleanGroups.join(',');\r\n\r\n let params = new HttpParams();\r\n params = params.set('componentId', config.configServer.frontend);\r\n params = params.set('groupIds', groupIdsString);\r\n\r\n let headers = new HttpHeaders();\r\n\r\n const url = `${config.authorization.baseUrl}${config.authorization.hierarchyEndpoint}`;\r\n\r\n return this.http.get<MenuHierarchyItem[]>(url, { \r\n params,\r\n headers\r\n }).pipe(\r\n catchError(error => {\r\n console.error('Error obteniendo jerarquía de menús:', error);\r\n return of([]);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene elementos de menú de nivel raíz (level 1)\r\n */\r\n getRootMenuItems(menuHierarchy: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n return menuHierarchy.filter(item => item.level === 1);\r\n }\r\n\r\n /**\r\n * Obtiene elementos hijos de un elemento padre específico por path\r\n */\r\n getChildMenuItems(menuHierarchy: MenuHierarchyItem[], parentPath: string, level: number): MenuHierarchyItem[] {\r\n return menuHierarchy.filter(item => \r\n item.level === level && \r\n item.hasParent && \r\n item.path.startsWith(parentPath) &&\r\n item.path !== parentPath &&\r\n this.isDirectChild(item.path, parentPath, level)\r\n );\r\n }\r\n\r\n /**\r\n * Verifica si un elemento tiene hijos\r\n */\r\n hasChildren(menuHierarchy: MenuHierarchyItem[], item: MenuHierarchyItem): boolean {\r\n return this.getChildMenuItems(menuHierarchy, item.path, item.level + 1).length > 0;\r\n }\r\n\r\n /**\r\n * Verifica si un path es hijo directo de otro path\r\n */\r\n private isDirectChild(childPath: string, parentPath: string, expectedLevel: number): boolean {\r\n const relativePath = childPath.substring(parentPath.length);\r\n const slashCount = (relativePath.match(/\\//g) || []).length;\r\n return slashCount === 1;\r\n }\r\n\r\n /**\r\n * Verifica múltiples permisos a la vez\r\n */\r\n verifyMultiplePermissions(permissions: { resourcePath: string, operationName?: string }[]): Observable<{ [key: string]: boolean }> {\r\n const results: { [key: string]: boolean } = {};\r\n const observables = permissions.map(permission => \r\n this.verifyPermission(permission.resourcePath, permission.operationName).pipe(\r\n map(authorized => ({ \r\n key: `${permission.resourcePath}_${permission.operationName || 'VIEW'}`, \r\n authorized \r\n }))\r\n )\r\n );\r\n\r\n return new Observable(observer => {\r\n let completed = 0;\r\n observables.forEach(obs => {\r\n obs.subscribe(result => {\r\n results[result.key] = result.authorized;\r\n completed++;\r\n if (completed === observables.length) {\r\n observer.next(results);\r\n observer.complete();\r\n }\r\n });\r\n });\r\n });\r\n }\r\n}\r\n","import { inject } from '@angular/core';\r\nimport { CanActivateFn, Router } from '@angular/router';\r\nimport { AuthService } from '../services/authentication.service';\r\nimport { map, take } from 'rxjs/operators';\r\n\r\nexport const authGuard: CanActivateFn = (route, state) => {\r\n const authService = inject(AuthService);\r\n const router = inject(Router);\r\n\r\n const handleAuthenticated = (): boolean => {\r\n return true;\r\n };\r\n\r\n const handleUnauthenticated = (currentUrl: string): boolean => {\r\n if (currentUrl !== '/login' && !currentUrl.includes('/login')) {\r\n router.navigate(['/login'], { \r\n queryParams: { returnUrl: currentUrl } \r\n });\r\n }\r\n return false;\r\n }; \r\n\r\n return authService.isAuthenticated$.pipe(\r\n take(1),\r\n map(isAuthenticated => {\r\n return isAuthenticated \r\n ? handleAuthenticated() \r\n : handleUnauthenticated(state.url);\r\n })\r\n );\r\n};\r\n","import { Component, OnInit, OnDestroy, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Subscription } from 'rxjs';\r\nimport { AuthService } from '../../services/authentication.service';\r\nimport { LoginConfig, DEFAULT_LOGIN_CONFIG } from '../../models/login-config.interface';\r\nimport { getLoginConfig } from '../../config/app.config';\r\nimport { VERSION } from '../../version';\r\n\r\n@Component({\r\n selector: 'lib-login',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './login.component.html',\r\n styleUrls: ['./login.component.scss']\r\n})\r\nexport class LoginComponent implements OnInit, OnDestroy {\r\n /**\r\n * Configuration object to customize the login component appearance and behavior\r\n */\r\n @Input() config: Partial<LoginConfig> = {};\r\n\r\n isLoggingIn = false;\r\n statusMessage = '';\r\n private authSubscription?: Subscription;\r\n private isProcessingCallback = false;\r\n\r\n // Merged configuration with defaults - initialize with defaults immediately\r\n private _mergedConfig: LoginConfig;\r\n\r\n constructor(public authService: AuthService) {\r\n // Initialize with global config in constructor to avoid template errors\r\n try {\r\n this._mergedConfig = getLoginConfig();\r\n } catch {\r\n this._mergedConfig = { ...DEFAULT_LOGIN_CONFIG };\r\n }\r\n }\r\n\r\n ngOnInit() {\r\n // Get global config from library, then merge with component input\r\n try {\r\n const globalConfig = getLoginConfig();\r\n this._mergedConfig = {\r\n ...globalConfig,\r\n ...this.config,\r\n version: this.config?.version || globalConfig.version || VERSION\r\n };\r\n } catch {\r\n this._mergedConfig = {\r\n ...DEFAULT_LOGIN_CONFIG,\r\n ...this.config,\r\n version: this.config?.version || VERSION\r\n };\r\n }\r\n\r\n // Check if processing OAuth callback\r\n // Also check for 'iss' and 'session_state' which indicate we came from OAuth even if 'code' was already processed\r\n const urlParams = new URLSearchParams(globalThis.location?.search || '');\r\n const hasCode = urlParams.has('code');\r\n const hasIss = urlParams.has('iss');\r\n const hasSessionState = urlParams.has('session_state');\r\n const hasFragment = (globalThis.location?.hash || '').includes('access_token') || \r\n (globalThis.location?.hash || '').includes('code');\r\n \r\n if (hasCode || hasFragment || hasIss || hasSessionState) {\r\n this.isProcessingCallback = true;\r\n this.statusMessage = 'Procesando autenticación...';\r\n }\r\n\r\n // Subscribe to authentication state changes\r\n this.authSubscription = this.authService.isAuthenticated$.subscribe(isAuthenticated => {\r\n if (isAuthenticated) {\r\n this.statusMessage = '¡Autenticación exitosa! Redirigiendo...';\r\n // Small delay to show success message, then redirect\r\n setTimeout(() => {\r\n this.navigateToRedirect();\r\n }, 500);\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n if (this.authSubscription) {\r\n this.authSubscription.unsubscribe();\r\n }\r\n }\r\n\r\n /**\r\n * Get merged configuration value\r\n */\r\n getConfig<K extends keyof LoginConfig>(key: K): LoginConfig[K] {\r\n return this._mergedConfig[key];\r\n }\r\n\r\n /**\r\n * Get custom CSS styles for theming\r\n */\r\n getCustomStyles(): { [key: string]: string } {\r\n const styles: { [key: string]: string } = {};\r\n \r\n if (this._mergedConfig.primaryColor) {\r\n styles['--color-primary'] = this._mergedConfig.primaryColor;\r\n }\r\n if (this._mergedConfig.backgroundColor) {\r\n styles['--login-bg-color'] = this._mergedConfig.backgroundColor;\r\n }\r\n if (this._mergedConfig.textColor) {\r\n styles['--login-text-color'] = this._mergedConfig.textColor;\r\n }\r\n \r\n return styles;\r\n }\r\n\r\n login(): void {\r\n this.isLoggingIn = true;\r\n this.statusMessage = 'Redirigiendo al proveedor de autenticación...';\r\n \r\n setTimeout(() => {\r\n this.authService.login();\r\n }, 500);\r\n }\r\n\r\n logout(): void {\r\n this.authService.logout();\r\n this.isLoggingIn = false;\r\n this.statusMessage = '';\r\n this.isProcessingCallback = false;\r\n }\r\n\r\n goToDashboard(): void {\r\n this.navigateToRedirect();\r\n }\r\n\r\n private navigateToRedirect(): void {\r\n const redirectUrl = this._mergedConfig.redirectUrl;\r\n if (typeof globalThis.location !== 'undefined') {\r\n const baseUrl = `${globalThis.location.protocol}//${globalThis.location.host}`;\r\n globalThis.location.href = `${baseUrl}${redirectUrl}`;\r\n }\r\n }\r\n}\r\n","<div class=\"login-page\" [ngStyle]=\"getCustomStyles()\">\r\n <div class=\"login-page__container\">\r\n <!-- Logo -->\r\n <div class=\"login-page__logo\">\r\n <img \r\n [src]=\"getConfig('logoUrl')\" \r\n [alt]=\"getConfig('logoAlt')\" \r\n class=\"login-page__logo-img\"\r\n [style.width]=\"getConfig('logoWidth')\"\r\n [style.height]=\"getConfig('logoHeight')\" />\r\n </div>\r\n\r\n <!-- Header -->\r\n <div class=\"login-page__header\">\r\n <h1>{{ getConfig('title') }}</h1>\r\n <p *ngIf=\"getConfig('subtitle')\" class=\"subtitle\">{{ getConfig('subtitle') }}</p>\r\n </div>\r\n \r\n <!-- Login Form -->\r\n <div *ngIf=\"(authService.isDoneLoading$ | async)\" class=\"login-page__form\">\r\n <div *ngIf=\"!(authService.isAuthenticated$ | async)\">\r\n <!-- Status Message -->\r\n <div *ngIf=\"statusMessage\" class=\"auth-alert auth-alert--info\">\r\n <div class=\"auth-alert__content\">\r\n <p>{{ statusMessage }}</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Login Button -->\r\n <button \r\n class=\"btn btn--primary btn--lg\" \r\n (click)=\"login()\" \r\n [disabled]=\"isLoggingIn\"\r\n [class.loading]=\"isLoggingIn\">\r\n {{ isLoggingIn ? 'Redirigiendo...' : getConfig('loginButtonText') }}\r\n </button>\r\n\r\n <!-- Footer -->\r\n <div class=\"login-page__footer\" *ngIf=\"getConfig('showFooter')\">\r\n <p *ngIf=\"getConfig('footerText'); else defaultFooter\">\r\n {{ getConfig('footerText') }}\r\n </p>\r\n <ng-template #defaultFooter>\r\n <p>\r\n Acceso seguro para usuarios de \r\n <strong>{{ getConfig('institutionName') }}</strong>\r\n </p>\r\n </ng-template>\r\n </div>\r\n </div>\r\n \r\n <!-- Already Authenticated -->\r\n <div *ngIf=\"authService.isAuthenticated$ | async\" class=\"auth-alert auth-alert--success\">\r\n <div class=\"auth-alert__content\">\r\n <h4>¡Sesión activa!</h4>\r\n <p>Ya tienes una sesión iniciada en el sistema.</p>\r\n </div>\r\n \r\n <div class=\"login-page__actions\">\r\n <button class=\"btn btn--primary btn--lg\" (click)=\"goToDashboard()\">\r\n {{ getConfig('dashboardButtonText') }}\r\n </button>\r\n \r\n <button \r\n *ngIf=\"getConfig('showLogoutButton')\"\r\n class=\"btn btn--secondary btn--lg\" \r\n (click)=\"logout()\">\r\n {{ getConfig('logoutButtonText') }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Loading State -->\r\n <div *ngIf=\"!(authService.isDoneLoading$ | async)\" class=\"auth-loading\">\r\n <div class=\"auth-loading__spinner\"></div>\r\n <p class=\"auth-loading__text\">Procesando autenticación...</p>\r\n </div>\r\n\r\n <!-- Version -->\r\n <div *ngIf=\"getConfig('showVersion')\" class=\"login-page__version\">\r\n <span>v{{ getConfig('version') }}</span>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, OnInit, HostListener, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { RouterModule } from '@angular/router';\r\nimport { AuthService } from '../../services/authentication.service';\r\nimport { AuthorizationService } from '../../services/authorization.service';\r\nimport { MenuHierarchyItem } from '../../models/authorization.interface';\r\nimport { DashboardConfig, DEFAULT_DASHBOARD_CONFIG } from '../../models/dashboard-config.interface';\r\nimport { getDashboardConfig } from '../../config/app.config';\r\nimport { VERSION } from '../../version';\r\n\r\n// Re-export for backwards compatibility\r\nexport { DashboardConfig } from '../../models/dashboard-config.interface';\r\n\r\n@Component({\r\n selector: 'lib-dashboard',\r\n standalone: true,\r\n imports: [CommonModule, RouterModule],\r\n templateUrl: './dashboard.component.html',\r\n styleUrls: ['./dashboard.component.scss']\r\n})\r\nexport class DashboardComponent implements OnInit {\r\n @Input() config: Partial<DashboardConfig> = {};\r\n\r\n userInfo: any = null;\r\n userRoles: string[] = [];\r\n menuHierarchy: MenuHierarchyItem[] = [];\r\n isMenuOpen = false;\r\n isLoadingMenu = false;\r\n openMenuItems: Set<string> = new Set();\r\n isUserPanelOpen = false;\r\n isMobileMenuOpen = false;\r\n\r\n private _mergedConfig: DashboardConfig;\r\n\r\n constructor(\r\n public authService: AuthService,\r\n private readonly authorizationService: AuthorizationService\r\n ) {\r\n // Initialize with global config in constructor to avoid template errors\r\n try {\r\n this._mergedConfig = getDashboardConfig();\r\n } catch {\r\n this._mergedConfig = { ...DEFAULT_DASHBOARD_CONFIG };\r\n }\r\n }\r\n\r\n ngOnInit(): void {\r\n // Get global config from library, then merge with component input\r\n try {\r\n const globalConfig = getDashboardConfig();\r\n this._mergedConfig = {\r\n ...globalConfig,\r\n ...this.config,\r\n version: this.config?.version || globalConfig.version || VERSION\r\n };\r\n } catch {\r\n this._mergedConfig = {\r\n ...DEFAULT_DASHBOARD_CONFIG,\r\n ...this.config,\r\n version: this.config?.version || VERSION\r\n };\r\n }\r\n this.loadUserInfo();\r\n this.loadMenuHierarchy();\r\n }\r\n\r\n getConfig<K extends keyof DashboardConfig>(key: K): DashboardConfig[K] {\r\n return this._mergedConfig[key];\r\n }\r\n\r\n get appVersion(): string {\r\n return this._mergedConfig.version;\r\n }\r\n\r\n private loadUserInfo(): void {\r\n this.userInfo = this.authService.identityClaims;\r\n this.userRoles = this.authService.getUserRoles();\r\n }\r\n\r\n private loadMenuHierarchy(): void {\r\n this.isLoadingMenu = true;\r\n this.authorizationService.getMenuHierarchy().subscribe({\r\n next: (menuItems) => {\r\n this.menuHierarchy = this.buildHierarchicalMenu(menuItems);\r\n this.isLoadingMenu = false;\r\n },\r\n error: (error) => {\r\n console.error('Error loading menu hierarchy:', error);\r\n this.menuHierarchy = [];\r\n this.isLoadingMenu = false;\r\n }\r\n });\r\n }\r\n\r\n private buildHierarchicalMenu(flatItems: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n const itemMap = new Map<string, MenuHierarchyItem>();\r\n \r\n flatItems.forEach(item => {\r\n itemMap.set(item.path, { ...item, children: [] });\r\n });\r\n\r\n const rootItems: MenuHierarchyItem[] = [];\r\n \r\n flatItems.forEach(item => {\r\n const currentItem = itemMap.get(item.path)!;\r\n \r\n if (item.level === 1) {\r\n rootItems.push(currentItem);\r\n } else {\r\n const parent = this.findParent(item, flatItems);\r\n if (parent) {\r\n const parentItem = itemMap.get(parent.path);\r\n if (parentItem?.children) {\r\n parentItem.children.push(currentItem);\r\n }\r\n }\r\n }\r\n });\r\n\r\n return rootItems;\r\n }\r\n\r\n private findParent(item: MenuHierarchyItem, allItems: MenuHierarchyItem[]): MenuHierarchyItem | null {\r\n for (const potentialParent of allItems) {\r\n if (potentialParent.level === item.level - 1 && \r\n item.path.startsWith(potentialParent.path) &&\r\n item.path !== potentialParent.path) {\r\n return potentialParent;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n toggleMenuItem(itemId: string, item: MenuHierarchyItem): void {\r\n const isCurrentlyOpen = this.openMenuItems.has(itemId);\r\n \r\n if (isCurrentlyOpen) {\r\n this.closeMenuAndChildren(itemId);\r\n } else {\r\n this.closeSiblingMenus(item);\r\n this.openMenuItems.add(itemId);\r\n }\r\n }\r\n\r\n private closeMenuAndChildren(itemId: string): void {\r\n this.openMenuItems.delete(itemId);\r\n const itemsToClose = Array.from(this.openMenuItems).filter(id => id.startsWith(itemId + '-'));\r\n itemsToClose.forEach(id => this.openMenuItems.delete(id));\r\n }\r\n\r\n private closeSiblingMenus(currentItem: MenuHierarchyItem): void {\r\n if (currentItem.level === 1) {\r\n const rootItems = this.getRootMenuItems();\r\n rootItems.forEach(rootItem => {\r\n if (rootItem.code !== currentItem.code) {\r\n this.closeMenuAndChildren(rootItem.code);\r\n }\r\n });\r\n } else {\r\n const allItems = this.flattenMenuItems(this.menuHierarchy);\r\n const parent = this.findParent(currentItem, allItems);\r\n if (parent?.children) {\r\n parent.children.forEach(sibling => {\r\n if (sibling.code !== currentItem.code) {\r\n this.closeMenuAndChildren(sibling.code);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n private flattenMenuItems(items: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n const flattened: MenuHierarchyItem[] = [];\r\n \r\n const flatten = (itemList: MenuHierarchyItem[]) => {\r\n itemList.forEach(item => {\r\n flattened.push(item);\r\n if (item.children) {\r\n flatten(item.children);\r\n }\r\n });\r\n };\r\n \r\n flatten(items);\r\n return flattened;\r\n }\r\n\r\n onMenuItemClick(event: Event, item: MenuHierarchyItem): void {\r\n if (this.hasChildren(item)) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.toggleMenuItem(item.code, item);\r\n } else {\r\n // Close mobile menu when navigating to a page\r\n this.closeMobileMenu();\r\n }\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onDocumentClick(event: Event): void {\r\n const target = event.target as HTMLElement;\r\n const navElement = target.closest('.dashboard-nav');\r\n const userPanel = target.closest('.user-profile');\r\n \r\n if (!navElement) {\r\n this.openMenuItems.clear();\r\n }\r\n \r\n if (!userPanel) {\r\n this.isUserPanelOpen = false;\r\n }\r\n }\r\n\r\n toggleUserPanel(event: Event): void {\r\n event.stopPropagation();\r\n this.isUserPanelOpen = !this.isUserPanelOpen;\r\n }\r\n\r\n getUsername(): string {\r\n if (!this.userInfo?.preferred_username) return 'usuario';\r\n const username = this.userInfo.preferred_username;\r\n const atIndex = username.indexOf('@');\r\n return atIndex > 0 ? username.substring(0, atIndex) : username;\r\n }\r\n\r\n getUserFullName(): string {\r\n return this.userInfo?.name || 'Usuario';\r\n }\r\n\r\n getDocument(): string {\r\n return this.userInfo?.dui || 'N/A';\r\n }\r\n\r\n getInstitution(): string {\r\n return this.userInfo?.direccion || 'N/A';\r\n }\r\n\r\n getDependency(): string {\r\n return this.userInfo?.dependencia || 'N/A';\r\n }\r\n\r\n getRole(): string {\r\n return this.userInfo?.cargo || 'N/A';\r\n }\r\n\r\n isMenuItemOpen(itemId: string): boolean {\r\n return this.openMenuItems.has(itemId);\r\n }\r\n\r\n hasChildren(item: MenuHierarchyItem): boolean {\r\n return !!(item.children && item.children.length > 0);\r\n }\r\n\r\n getRootMenuItems(): MenuHierarchyItem[] {\r\n return this.menuHierarchy.filter(item => item.level === 1);\r\n }\r\n\r\n /**\r\n * Obtiene el icono para un item del menú.\r\n * Si el item tiene un icono definido, lo usa; de lo contrario, usa un icono por defecto según el nivel.\r\n */\r\n getMenuIcon(item: MenuHierarchyItem): string {\r\n // Si tiene icono definido, usarlo\r\n if (item.icono && item.icono.trim() !== '') {\r\n return item.icono;\r\n }\r\n \r\n // Iconos por defecto según el nivel\r\n if (item.level === 1) {\r\n return 'folder';\r\n } else if (item.level === 2) {\r\n return 'article';\r\n } else {\r\n return 'radio_button_unchecked';\r\n }\r\n }\r\n\r\n logoutAndRedirect(): void {\r\n this.authService.logoutAndRedirect();\r\n }\r\n\r\n getUserInitials(): string {\r\n if (!this.userInfo) return 'U';\r\n \r\n const name = this.userInfo.name || this.userInfo.preferred_username || 'Usuario';\r\n const words = name.split(' ');\r\n \r\n if (words.length >= 2) {\r\n return (words[0][0] + words[1][0]).toUpperCase();\r\n } else {\r\n return name.substring(0, 2).toUpperCase();\r\n }\r\n }\r\n\r\n toggleMobileMenu(): void {\r\n this.isMobileMenuOpen = !this.isMobileMenuOpen;\r\n }\r\n\r\n closeMobileMenu(): void {\r\n this.isMobileMenuOpen = false;\r\n document.body.style.overflow = '';\r\n }\r\n}\r\n","<div class=\"dashboard\">\r\n <!-- Header -->\r\n <header class=\"dashboard-header\">\r\n <!-- Mobile Header Top -->\r\n <div class=\"header-mobile-top\">\r\n <div class=\"ministry-logo-mobile\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n </div>\r\n <h1 class=\"mobile-title\">{{ getConfig('title') }}</h1>\r\n </div>\r\n\r\n <!-- Mobile Header Bottom -->\r\n <div class=\"header-mobile-bottom\">\r\n <button class=\"hamburger-btn\" \r\n (click)=\"toggleMobileMenu()\"\r\n [class.active]=\"isMobileMenuOpen\"\r\n aria-label=\"Toggle menu\">\r\n <span class=\"hamburger-line\"></span>\r\n <span class=\"hamburger-line\"></span>\r\n <span class=\"hamburger-line\"></span>\r\n </button>\r\n\r\n <div class=\"user-profile mobile-user\" *ngIf=\"userInfo\">\r\n <button class=\"user-info-trigger\" \r\n (click)=\"toggleUserPanel($event)\"\r\n [attr.aria-expanded]=\"isUserPanelOpen\"\r\n aria-label=\"Abrir menú de usuario\">\r\n <div class=\"user-avatar\">\r\n <span>{{ getUserInitials() }}</span>\r\n </div>\r\n <div class=\"user-details\">\r\n <span class=\"user-name\">{{ getUsername() }}</span>\r\n </div>\r\n <span class=\"material-symbols-outlined dropdown-icon\">\r\n {{ isUserPanelOpen ? 'expand_less' : 'expand_more' }}\r\n </span>\r\n </button>\r\n \r\n <!-- User Panel -->\r\n <ng-container *ngTemplateOutlet=\"userPanelTemplate\"></ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Desktop Header -->\r\n <div class=\"header-desktop-layout\">\r\n <div class=\"header-left\">\r\n <div class=\"ministry-logo\">\r\n <div class=\"logo-icon\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n </div>\r\n <div class=\"ministry-info\">\r\n <h1>{{ getConfig('title') }}</h1>\r\n <span class=\"subtitle\" *ngIf=\"getConfig('subtitle')\">{{ getConfig('subtitle') }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <div class=\"header-right\">\r\n <div class=\"user-profile desktop-user\" *ngIf=\"userInfo\">\r\n <button class=\"user-info-trigger\" \r\n (click)=\"toggleUserPanel($event)\"\r\n [attr.aria-expanded]=\"isUserPanelOpen\"\r\n aria-label=\"Abrir menú de usuario\">\r\n <div class=\"user-avatar\">\r\n <span>{{ getUserInitials() }}</span>\r\n </div>\r\n <div class=\"user-details\">\r\n <span class=\"user-name\">{{ getUsername() }}</span>\r\n </div>\r\n <span class=\"material-symbols-outlined dropdown-icon\">\r\n {{ isUserPanelOpen ? 'expand_less' : 'expand_more' }}\r\n </span>\r\n </button>\r\n \r\n <!-- User Panel -->\r\n <ng-container *ngTemplateOutlet=\"userPanelTemplate\"></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </header>\r\n\r\n <!-- User Panel Template -->\r\n <ng-template #userPanelTemplate>\r\n <div class=\"user-panel\" *ngIf=\"isUserPanelOpen\">\r\n <div class=\"user-panel-header\">\r\n <span class=\"panel-title\">Perfil de Usuario</span>\r\n </div>\r\n <div class=\"user-panel-content\">\r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">person</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Código de Usuario:</span>\r\n <span class=\"info-value\">{{ getUsername() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">badge</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Nombre de Usuario:</span>\r\n <span class=\"info-value\">{{ getUserFullName() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">credit_card</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Documento:</span>\r\n <span class=\"info-value\">{{ getDocument() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">business</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Institución:</span>\r\n <span class=\"info-value\">{{ getInstitution() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">apartment</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Dependencia:</span>\r\n <span class=\"info-value\">{{ getDependency() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">work</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Rol:</span>\r\n <span class=\"info-value\">{{ getRole() }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"user-panel-footer\">\r\n <button class=\"logout-btn-panel\" (click)=\"logoutAndRedirect()\" title=\"Cerrar sesión\">\r\n <span class=\"material-symbols-outlined\">logout</span>\r\n <span class=\"logout-text\">CERRAR SESIÓN</span>\r\n </button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Mobile Menu Overlay -->\r\n <div class=\"nav-overlay\" *ngIf=\"isMobileMenuOpen\" (click)=\"closeMobileMenu()\"></div>\r\n\r\n <!-- Navigation (Horizontal Desktop / Sidebar Mobile) -->\r\n <nav class=\"dashboard-nav\" [class.mobile-open]=\"isMobileMenuOpen\">\r\n <div class=\"nav-mobile-header\">\r\n <div class=\"nav-mobile-logo\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n <span class=\"nav-mobile-title\">Menú</span>\r\n </div>\r\n <button class=\"nav-close-btn\" (click)=\"closeMobileMenu()\" aria-label=\"Cerrar menú\">\r\n <span class=\"material-symbols-outlined\">close</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"nav-container\">\r\n <!-- Static Menu Items -->\r\n <ng-container *ngIf=\"getConfig('showStaticMenu')\">\r\n <a routerLink=\".\" \r\n routerLinkActive=\"active\" \r\n [routerLinkActiveOptions]=\"{exact: true}\" \r\n class=\"nav-item\"\r\n (click)=\"closeMobileMenu()\">\r\n <span class=\"material-symbols-outlined nav-icon\">home</span>\r\n <span class=\"nav-text\">Inicio</span>\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Separator -->\r\n <div class=\"nav-separator\" *ngIf=\"!isLoadingMenu && menuHierarchy.length > 0\"></div>\r\n \r\n <!-- Dynamic Menu -->\r\n <div class=\"dynamic-menu\" *ngIf=\"!isLoadingMenu && menuHierarchy.length > 0\">\r\n <ng-container *ngFor=\"let rootItem of getRootMenuItems()\">\r\n <div class=\"menu-item-container\" [class.has-children]=\"hasChildren(rootItem)\">\r\n <a \r\n [routerLink]=\"hasChildren(rootItem) ? null : rootItem.path\" \r\n routerLinkActive=\"active\" \r\n class=\"nav-item root-item\"\r\n [class.expandable]=\"hasChildren(rootItem)\"\r\n (click)=\"onMenuItemClick($event, rootItem)\">\r\n <span class=\"material-symbols-outlined nav-icon\">{{ getMenuIcon(rootItem) }}</span>\r\n <span class=\"nav-text\">{{ rootItem.name }}</span>\r\n <span class=\"material-symbols-outlined expand-icon\" *ngIf=\"hasChildren(rootItem)\">\r\n {{ isMenuItemOpen(rootItem.code) ? 'expand_more' : 'chevron_right' }}\r\n </span>\r\n </a>\r\n \r\n <!-- Submenu -->\r\n <div class=\"submenu\" *ngIf=\"hasChildren(rootItem) && isMenuItemOpen(rootItem.code)\">\r\n <ng-container *ngTemplateOutlet=\"menuTemplate; context: { items: rootItem.children, level: 2 }\"></ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Loading Indicator -->\r\n <div class=\"menu-loading\" *ngIf=\"isLoadingMenu\">\r\n <span class=\"material-symbols-outlined nav-icon\">hourglass_empty</span>\r\n <span class=\"nav-text\">Cargando menú...</span>\r\n </div>\r\n </div>\r\n </nav>\r\n\r\n <!-- Recursive Menu Template -->\r\n <ng-template #menuTemplate let-items=\"items\" let-level=\"level\">\r\n <ng-container *ngFor=\"let item of items\">\r\n <div class=\"menu-item-container\" [class.has-children]=\"hasChildren(item)\" [attr.data-level]=\"level\">\r\n <a \r\n [routerLink]=\"hasChildren(item) ? null : item.path\" \r\n routerLinkActive=\"active\" \r\n class=\"nav-item submenu-item\"\r\n [class.expandable]=\"hasChildren(item)\"\r\n (click)=\"onMenuItemClick($event, item)\">\r\n <span class=\"material-symbols-outlined nav-icon\">{{ getMenuIcon(item) }}</span>\r\n <span class=\"nav-text\">{{ item.name }}</span>\r\n <span class=\"material-symbols-outlined expand-icon\" *ngIf=\"hasChildren(item)\">\r\n {{ isMenuItemOpen(item.code) ? 'expand_more' : 'chevron_right' }}\r\n </span>\r\n </a>\r\n\r\n <!-- Recursive Submenu (max 5 levels) -->\r\n <div class=\"submenu\" *ngIf=\"hasChildren(item) && isMenuItemOpen(item.code) && level < 5\">\r\n <ng-container *ngTemplateOutlet=\"menuTemplate; context: { items: item.children, level: level + 1 }\"></ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Main Content -->\r\n <main class=\"dashboard-content\">\r\n <div class=\"content-wrapper\">\r\n <router-outlet></router-outlet>\r\n </div>\r\n </main>\r\n\r\n <!-- Footer -->\r\n <footer class=\"dashboard-footer\">\r\n <div class=\"footer-content\">\r\n <span class=\"footer-text\">\r\n {{ getConfig('footerText') }}\r\n <ng-container *ngIf=\"getConfig('showVersion')\">\r\n Versión {{ appVersion }}.\r\n </ng-container>\r\n Todos los derechos reservados.\r\n </span>\r\n </div>\r\n </footer>\r\n</div>\r\n","// ========================================\r\n// @dinafi/frmk - Public API\r\n// Angular Shared Library - Ministerio de Hacienda\r\n// ========================================\r\n\r\n// === VERSION ===\r\nexport { VERSION, VERSION_INFO } from './lib/version';\r\n\r\n// === MODELS / INTERFACES ===\r\nexport {\r\n // Login Configuration\r\n LoginConfig,\r\n DEFAULT_LOGIN_CONFIG,\r\n \r\n // Dashboard Configuration\r\n DashboardConfig,\r\n DEFAULT_DASHBOARD_CONFIG,\r\n \r\n // Application Configuration\r\n AppConfiguration,\r\n ConfigServerResponse,\r\n \r\n // Authorization\r\n AuthorizationRequest,\r\n AuthorizationResponse,\r\n MenuHierarchyItem,\r\n MenuHierarchyRequest,\r\n \r\n // Library Configuration (Injectable)\r\n FrmkLibraryConfig,\r\n DEFAULT_LIBRARY_CONFIG,\r\n FRMK_LIBRARY_CONFIG,\r\n provideFrmkConfig\r\n} from './lib/models';\r\n\r\n// === CONFIGURATION UTILITIES ===\r\nexport {\r\n // Library Configuration Initialization\r\n initializeLibraryConfig,\r\n getLibraryConfig,\r\n isLibraryConfigured,\r\n \r\n // Component Config Getters\r\n getLoginConfig,\r\n getDashboardConfig,\r\n \r\n // App Config Management\r\n getDefaultAppConfig,\r\n mapConfigServerResponse,\r\n setCurrentAppConfig,\r\n getCurrentAppConfig,\r\n getAppConfig,\r\n getAppConfigWithServerData,\r\n \r\n // OAuth2 Config\r\n getAuthConfig,\r\n getAuthConfigEnv\r\n} from './lib/config';\r\n\r\n// === SERVICES ===\r\nexport {\r\n // Authentication Service\r\n AuthService,\r\n \r\n // Authorization Service\r\n AuthorizationService,\r\n \r\n // Configuration Service\r\n ConfigService\r\n} from './lib/services';\r\n\r\n// === GUARDS ===\r\nexport { authGuard } from './lib/guards';\r\n\r\n// === COMPONENTS ===\r\nexport { \r\n LoginComponent \r\n} from './lib/components/login/login.component';\r\n\r\nexport { \r\n DashboardComponent\r\n} from './lib/components/dashboard/dashboard.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i2","i1","i2.AuthService","i3.ConfigService","i1.AuthService","i2.AuthorizationService"],"mappings":";;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AAEA;;;AAGG;AACI,MAAM,OAAO,GAAG;AAEvB;;AAEG;AACI,MAAM,YAAY,GAAG;AAC1B,IAAA,OAAO,EAAE,QAAQ;AACjB,IAAA,IAAI,EAAE,oBAAoB;AAC1B,IAAA,SAAS,EAAE,0BAA0B;AACrC,IAAA,OAAO,EAAE;;;ACoCX;;AAEG;AACI,MAAM,oBAAoB,GAAgB;AAC/C,IAAA,OAAO,EAAE,iCAAiC;AAC1C,IAAA,OAAO,EAAE,MAAM;AACf,IAAA,SAAS,EAAE,OAAO;AAClB,IAAA,UAAU,EAAE,OAAO;AACnB,IAAA,KAAK,EAAE,0BAA0B;AACjC,IAAA,eAAe,EAAE,uCAAuC;AACxD,IAAA,eAAe,EAAE,yBAAyB;AAC1C,IAAA,gBAAgB,EAAE,eAAe;AACjC,IAAA,mBAAmB,EAAE,iBAAiB;AACtC,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,OAAO,EAAE,OAAO;AAChB,IAAA,WAAW,EAAE,OAAO;AACpB,IAAA,gBAAgB,EAAE,IAAI;AACtB,IAAA,UAAU,EAAE;;;AClDd;;AAEG;AACI,MAAM,wBAAwB,GAAoB;AACvD,IAAA,KAAK,EAAE,SAAS;AAChB,IAAA,OAAO,EAAE,iCAAiC;AAC1C,IAAA,OAAO,EAAE,MAAM;AACf,IAAA,UAAU,EAAE,qCAAqC;AACjD,IAAA,WAAW,EAAE,IAAI;AACjB,IAAA,OAAO,EAAE,OAAO;AAChB,IAAA,cAAc,EAAE;;;ACiClB;;AAEG;AACI,MAAM,sBAAsB,GAA+B;AAChE,IAAA,iBAAiB,EAAE,wBAAwB;AAC3C,IAAA,UAAU,EAAE,KAAK;AACjB,IAAA,YAAY,EAAE,IAAI;AAClB,IAAA,oBAAoB,EAAE;;AAGxB;;;;;;;;;;;;;;;AAeG;MACU,mBAAmB,GAAG,IAAI,cAAc,CAAoB,mBAAmB;AAE5F;;;;;;;;;;;;;;;AAeG;AACG,SAAU,iBAAiB,CAAC,MAAyB,EAAA;IACzD,OAAO;AACL,QAAA,OAAO,EAAE,mBAAmB;AAC5B,QAAA,QAAQ,EAAE;AACR,YAAA,GAAG,sBAAsB;AACzB,YAAA,GAAG;AACJ;KACF;AACH;;AChHA;AACA,IAAI,gBAAgB,GAA4B,IAAI;AAEpD;AACA,IAAI,aAAa,GAA6B,IAAI;AAElD;;;;;AAKG;AACG,SAAU,uBAAuB,CAAC,MAAyB,EAAA;AAC/D,IAAA,aAAa,GAAG;AACd,QAAA,GAAG,sBAAsB;AACzB,QAAA,GAAG;KACiB;;IAGtB,gBAAgB,GAAG,IAAI;AACzB;AAEA;;;AAGG;SACa,gBAAgB,GAAA;IAC9B,IAAI,CAAC,aAAa,EAAE;QAClB,MAAM,IAAI,KAAK,CACb,6CAA6C;YAC7C,2EAA2E;AAC3E,YAAA,4EAA4E,CAC7E;IACH;AACA,IAAA,OAAO,aAAa;AACtB;AAEA;;AAEG;SACa,mBAAmB,GAAA;IACjC,OAAO,aAAa,KAAK,IAAI;AAC/B;AAEA;;;AAGG;SACa,cAAc,GAAA;AAC5B,IAAA,MAAM,SAAS,GAAG,mBAAmB,EAAE,GAAG,gBAAgB,EAAE,GAAG,IAAI;IACnE,OAAO;AACL,QAAA,GAAG,oBAAoB;AACvB,QAAA,IAAI,SAAS,EAAE,WAAW,IAAI,EAAE;KACjC;AACH;AAEA;;;AAGG;SACa,kBAAkB,GAAA;AAChC,IAAA,MAAM,SAAS,GAAG,mBAAmB,EAAE,GAAG,gBAAgB,EAAE,GAAG,IAAI;IACnE,OAAO;AACL,QAAA,GAAG,wBAAwB;AAC3B,QAAA,IAAI,SAAS,EAAE,eAAe,IAAI,EAAE;KACrC;AACH;AAEA;AACA,SAAS,sBAAsB,GAAA;AAC7B,IAAA,MAAM,SAAS,GAAG,gBAAgB,EAAE;IAEpC,OAAO;AACL,QAAA,KAAK,EAAE;YACL,YAAY,EAAE,SAAS,CAAC,gBAAgB;YACxC,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,EAAE;AACb,SAAA;AACD,QAAA,KAAK,EAAE;AACL,YAAA,aAAa,EAAE,SAAS,CAAC,iBAAiB,IAAI,wBAAwB;AACtE,YAAA,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI;AAC3B,SAAA;AACD,QAAA,YAAY,EAAE;YACZ,GAAG,EAAE,EAAE;YACP,QAAQ,EAAE,SAAS,CAAC;AACrB,SAAA;AACD,QAAA,IAAI,EAAE;YACJ,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,EAAE;YACZ,aAAa,EAAE,EAAE;YACjB,gBAAgB,EAAE,EAAE;YACpB,SAAS,EAAE,EAAE;AACb,YAAA,QAAQ,EAAE,EAAE;YACZ,WAAW,EAAE,EAAE;YACf,qBAAqB,EAAE,EAAE;YACzB,wBAAwB,EAAE,EAAE;AAC5B,YAAA,KAAK,EAAE;AACR,SAAA;AACD,QAAA,aAAa,EAAE;AACb,YAAA,OAAO,EAAE,EAAE;AACX,YAAA,cAAc,EAAE,6BAA6B;AAC7C,YAAA,iBAAiB,EAAE,iDAAiD;AACrE,SAAA;AACD,QAAA,WAAW,EAAE;AACX,YAAA,UAAU,EAAE,SAAS,CAAC,UAAU,IAAI,KAAK;AACzC,YAAA,YAAY,EAAE,SAAS,CAAC,YAAY,IAAI,IAAI;AAC5C,YAAA,oBAAoB,EAAE,SAAS,CAAC,oBAAoB,IAAI;AACzD;KACF;AACH;AAEA;SACgB,mBAAmB,GAAA;IACjC,OAAO,sBAAsB,EAAE;AACjC;AAEA;AACM,SAAU,uBAAuB,CAAC,gBAAsC,EAAA;IAC5E,MAAM,YAAY,GAA8B,EAAE;AAClD,IAAA,MAAM,aAAa,GAAG,mBAAmB,EAAE;;AAG3C,IAAA,mBAAmB,EAAE;;AAGrB,IAAA,kBAAkB,EAAE;;AAGpB,IAAA,sBAAsB,EAAE;;AAGxB,IAAA,6BAA6B,EAAE;;AAG/B,IAAA,mBAAmB,EAAE;;AAGrB,IAAA,sBAAsB,EAAE;;AAGxB,IAAA,yBAAyB,EAAE;;AAG3B,IAAA,uBAAuB,EAAE;AAEzB,IAAA,OAAO,YAAY;AAEnB,IAAA,SAAS,uBAAuB,GAAA;AAC9B,QAAA,IAAI,gBAAgB,CAAC,oBAAoB,CAAC,EAAE;YAC1C,YAAY,CAAC,WAAW,GAAG;gBACzB,GAAG,aAAa,CAAC,WAAW;AAC5B,gBAAA,IAAI,YAAY,CAAC,WAAW,IAAI,EAAE,CAAC;AACnC,gBAAA,YAAY,EAAE,gBAAgB,CAAC,oBAAoB;aACpD;QACH;IACF;AAEA,IAAA,SAAS,yBAAyB,GAAA;AAChC,QAAA,IAAI,gBAAgB,CAAC,uBAAuB,CAAC,EAAE;YAC7C,YAAY,CAAC,KAAK,GAAG;gBACnB,GAAG,aAAa,CAAC,KAAK;AACtB,gBAAA,IAAI,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC;AAC7B,gBAAA,QAAQ,EAAE,gBAAgB,CAAC,uBAAuB;aACnD;QACH;IACF;AAEA,IAAA,SAAS,sBAAsB,GAAA;AAC7B,QAAA,IAAI,gBAAgB,CAAC,uBAAuB,CAAC,EAAE;YAC7C,YAAY,CAAC,KAAK,GAAG;gBACnB,GAAG,aAAa,CAAC,KAAK;AACtB,gBAAA,IAAI,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC;AAC7B,gBAAA,QAAQ,EAAE,gBAAgB,CAAC,uBAAuB;aACnD;QACH;IACF;AAEA,IAAA,SAAS,mBAAmB,GAAA;AAC1B,QAAA,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,EAAE;YACtC,YAAY,CAAC,IAAI,GAAG;gBAClB,GAAG,aAAa,CAAC,IAAI;AACrB,gBAAA,IAAI,YAAY,CAAC,IAAI,IAAI,EAAE,CAAC;AAC5B,gBAAA,KAAK,EAAE,gBAAgB,CAAC,gBAAgB;aACzC;QACH;IACF;AAEA,IAAA,SAAS,6BAA6B,GAAA;AACpC,QAAA,IAAI,gBAAgB,CAAC,oBAAoB,CAAC,EAAE;YAC1C,YAAY,CAAC,aAAa,GAAG;gBAC3B,GAAG,aAAa,CAAC,aAAa;AAC9B,gBAAA,IAAI,YAAY,CAAC,aAAa,IAAI,EAAE,CAAC;AACrC,gBAAA,OAAO,EAAE,gBAAgB,CAAC,oBAAoB;aAC/C;QACH;IACF;AAEA,IAAA,SAAS,sBAAsB,GAAA;AAC7B,QAAA,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,EAAE;YACtC,YAAY,CAAC,KAAK,GAAG;gBACnB,GAAG,aAAa,CAAC,KAAK;AACtB,gBAAA,IAAI,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC;AAC7B,gBAAA,KAAK,EAAE,gBAAgB,CAAC,gBAAgB;aACzC;QACH;IACF;AAEA,IAAA,SAAS,kBAAkB,GAAA;AACzB,QAAA,IAAI,gBAAgB,CAAC,wBAAwB,CAAC,EAAE;YAC9C,YAAY,CAAC,IAAI,GAAG;gBAClB,GAAG,aAAa,CAAC,IAAI;AACrB,gBAAA,IAAI,YAAY,CAAC,IAAI,IAAI,EAAE,CAAC;AAC5B,gBAAA,QAAQ,EAAE,gBAAgB,CAAC,wBAAwB;aACpD;QACH;IACF;AAEA,IAAA,SAAS,mBAAmB,GAAA;AAC1B,QAAA,IAAI,gBAAgB,CAAC,mBAAmB,CAAC,EAAE;YACzC,YAAY,CAAC,KAAK,GAAG;gBACnB,GAAG,aAAa,CAAC,KAAK;AACtB,gBAAA,IAAI,YAAY,CAAC,KAAK,IAAI,EAAE,CAAC;AAC7B,gBAAA,UAAU,EAAE,gBAAgB,CAAC,mBAAmB;aACjD;QACH;IACF;AACF;AAEA;;;AAGG;AACG,SAAU,mBAAmB,CAAC,gBAAuC,EAAA;AACzE,IAAA,gBAAgB,GAAG,0BAA0B,CAAC,gBAAgB,CAAC;AACjE;AAEA;;;AAGG;SACa,mBAAmB,GAAA;AACjC,IAAA,OAAO,gBAAgB,IAAI,YAAY,EAAE;AAC3C;AAEA;SACgB,YAAY,GAAA;AAC1B,IAAA,MAAM,MAAM,GAAG,EAAE,GAAG,mBAAmB,EAAE,EAAE;;AAG3C,IAAA,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC,YAAY,GAAG,OAAO,GAAG,MAAM;;IAGxE,MAAM,CAAC,YAAY,CAAC,GAAG,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE;;IAGxG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,WAAW,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE;IAC/F,MAAM,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,WAAW,MAAM,CAAC,KAAK,CAAC,KAAK,+BAA+B;IAC9H,MAAM,CAAC,IAAI,CAAC,aAAa,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,eAAe,MAAM,CAAC,KAAK,CAAC,KAAK,gCAAgC;IAC1I,MAAM,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,eAAe,MAAM,CAAC,KAAK,CAAC,KAAK,mCAAmC;IAChJ,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,eAAe,MAAM,CAAC,KAAK,CAAC,KAAK,iCAAiC;;AAGvI,IAAA,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ;IAClF,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG,CAAA,EAAG,aAAa,QAAQ;IAClD,MAAM,CAAC,IAAI,CAAC,qBAAqB,GAAG,CAAA,EAAG,aAAa,QAAQ;;AAG5D,IAAA,MAAM,CAAC,aAAa,CAAC,OAAO,GAAG,CAAA,EAAG,aAAa,CAAA,GAAA,EAAM,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE;AAEnF,IAAA,OAAO,MAAM;AACf;AAEA;AACM,SAAU,0BAA0B,CAAC,gBAAuC,EAAA;AAChF,IAAA,IAAI,MAAM,GAAG,EAAE,GAAG,mBAAmB,EAAE,EAAE;;IAGzC,IAAI,gBAAgB,EAAE;AACpB,QAAA,MAAM,kBAAkB,GAAG,uBAAuB,CAAC,gBAAgB,CAAC;AACpE,QAAA,MAAM,GAAG,mBAAmB,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAC1D;;AAGA,IAAA,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC;AAEjC,IAAA,OAAO,MAAM;AACf;AAEA;AACA,SAAS,mBAAmB,CAAC,IAAsB,EAAE,QAAmC,EAAA;AACtF,IAAA,MAAM,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE;AAE1B,IAAA,IAAI,QAAQ,CAAC,KAAK,EAAE;AAClB,QAAA,MAAM,CAAC,KAAK,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE;IACvD;AACA,IAAA,IAAI,QAAQ,CAAC,KAAK,EAAE;AAClB,QAAA,MAAM,CAAC,KAAK,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE;IACvD;AACA,IAAA,IAAI,QAAQ,CAAC,YAAY,EAAE;AACzB,QAAA,MAAM,CAAC,YAAY,GAAG,EAAE,GAAG,MAAM,CAAC,YAAY,EAAE,GAAG,QAAQ,CAAC,YAAY,EAAE;IAC5E;AACA,IAAA,IAAI,QAAQ,CAAC,IAAI,EAAE;AACjB,QAAA,MAAM,CAAC,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE;IACpD;AACA,IAAA,IAAI,QAAQ,CAAC,aAAa,EAAE;AAC1B,QAAA,MAAM,CAAC,aAAa,GAAG,EAAE,GAAG,MAAM,CAAC,aAAa,EAAE,GAAG,QAAQ,CAAC,aAAa,EAAE;IAC/E;AACA,IAAA,IAAI,QAAQ,CAAC,WAAW,EAAE;AACxB,QAAA,MAAM,CAAC,WAAW,GAAG,EAAE,GAAG,MAAM,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,WAAW,EAAE;IACzE;AAEA,IAAA,OAAO,MAAM;AACf;AAEA;AACA,SAAS,gBAAgB,CAAC,MAAwB,EAAA;AAChD,IAAA,MAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC,YAAY,GAAG,OAAO,GAAG,MAAM;;IAGxE,MAAM,CAAC,YAAY,CAAC,GAAG,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE;;IAGxG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,WAAW,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE;IAC/F,MAAM,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,WAAW,MAAM,CAAC,KAAK,CAAC,KAAK,+BAA+B;IAC9H,MAAM,CAAC,IAAI,CAAC,aAAa,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,eAAe,MAAM,CAAC,KAAK,CAAC,KAAK,gCAAgC;IAC1I,MAAM,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,eAAe,MAAM,CAAC,KAAK,CAAC,KAAK,mCAAmC;IAChJ,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,CAAA,EAAG,aAAa,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,eAAe,MAAM,CAAC,KAAK,CAAC,KAAK,iCAAiC;;AAGvI,IAAA,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ;IAClF,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG,CAAA,EAAG,aAAa,QAAQ;IAClD,MAAM,CAAC,IAAI,CAAC,qBAAqB,GAAG,CAAA,EAAG,aAAa,QAAQ;;AAG5D,IAAA,MAAM,CAAC,aAAa,CAAC,OAAO,GAAG,CAAA,EAAG,aAAa,CAAA,GAAA,EAAM,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE;AAEnF,IAAA,OAAO,MAAM;AACf;;ACpVA;;;AAGG;SACa,aAAa,GAAA;AAC3B,IAAA,MAAM,SAAS,GAAG,mBAAmB,EAAE;IAEvC,OAAO;;AAEL,QAAA,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM;;AAG7B,QAAA,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ;AACjC,QAAA,aAAa,EAAE,SAAS,CAAC,IAAI,CAAC,aAAa;AAC3C,QAAA,gBAAgB,EAAE,SAAS,CAAC,IAAI,CAAC,gBAAgB;AACjD,QAAA,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS;;AAGnC,QAAA,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,WAAW;AACvC,QAAA,qBAAqB,EAAE,SAAS,CAAC,IAAI,CAAC,qBAAqB;;AAG3D,QAAA,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,QAAQ;;AAGjC,QAAA,YAAY,EAAE,MAAM;AACpB,QAAA,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,KAAK;;AAG3B,QAAA,kBAAkB,EAAE,IAAI;AACxB,QAAA,YAAY,EAAE,SAAS,CAAC,WAAW,CAAC,YAAY;AAChD,QAAA,oBAAoB,EAAE,SAAS,CAAC,WAAW,CAAC,oBAAoB;AAChE,QAAA,iCAAiC,EAAE,KAAK;AACxC,QAAA,eAAe,EAAE,IAAI;;AAGrB,QAAA,kBAAkB,EAAE,IAAI;AACxB,QAAA,iBAAiB,EAAE,EAAE;;AAGrB,QAAA,oBAAoB,EAAE,IAAI;AAC1B,QAAA,aAAa,EAAE,IAAI;;AAGnB,QAAA,oBAAoB,EAAE,KAAK;AAC3B,QAAA,mBAAmB,EAAE,IAAI;;AAGzB,QAAA,IAAI,EAAE;KACP;AACH;AAEA;SACgB,gBAAgB,GAAA;IAC9B,OAAO,aAAa,EAAE;AACxB;;MCjDa,WAAW,CAAA;AASO,IAAA,YAAA;AAA6C,IAAA,MAAA;AARzD,IAAA,uBAAuB,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC;AACvE,IAAA,gBAAgB,GAAG,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE;AAEpD,IAAA,qBAAqB,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC;AACrE,IAAA,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE;IAEzD,cAAc,GAAG,IAAI;IAE7B,WAAA,CAA6B,YAA0B,EAAmB,MAAc,EAAA;QAA3D,IAAA,CAAA,YAAY,GAAZ,YAAY;QAAiC,IAAA,CAAA,MAAM,GAAN,MAAM;;QAE9E,IAAI,CAAC,2BAA2B,EAAE;QAElC,IAAI,CAAC,YAAY,CAAC;AACf,aAAA,SAAS,CAAC,CAAC,KAAK,KAAI;AACnB,YAAA,IAAI,KAAK,YAAY,UAAU,EAAE;AAC/B,gBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE;oBACnC,IAAI,CAAC,8BAA8B,EAAE;gBACvC;AACA,gBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE;oBAC3B,IAAI,CAAC,YAAY,EAAE;gBACrB;AACA,gBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE;AAChC,oBAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;gBACvC;AACA,gBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE;oBACvC,IAAI,CAAC,mBAAmB,EAAE;gBAC5B;YACF;AACF,QAAA,CAAC,CAAC;IACN;AAEA;;;AAGG;IACK,2BAA2B,GAAA;QACjC,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;;;AAI7D,QAAA,MAAM,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;AACrB,YAAA,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACpB,YAAA,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC;AAC9B,YAAA,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;YACtB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;YAC7C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAE7D,IAAI,eAAe,EAAE;AACnB,YAAA,OAAO,CAAC,GAAG,CAAC,+DAA+D,CAAC;YAC5E;QACF;;AAGA,QAAA,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC;QAC5F,IAAI,SAAS,EAAE;YACb,MAAM,cAAc,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC;AAC9C,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;AAEtB,YAAA,IAAI,cAAc,GAAG,GAAG,EAAE;AACxB,gBAAA,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC;gBACrE,IAAI,CAAC,cAAc,EAAE;YACvB;QACF;IACF;AAEA;;AAEG;IACK,cAAc,GAAA;AACpB,QAAA,MAAM,YAAY,GAAG;AACnB,YAAA,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY;AACzD,YAAA,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe;YACvD,qBAAqB,EAAE,qBAAqB,EAAE,oBAAoB;YAClE;SACD;AAED,QAAA,YAAY,CAAC,OAAO,CAAC,GAAG,IAAG;AACzB,YAAA,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC;AAC5B,YAAA,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC;AAChC,QAAA,CAAC,CAAC;IACJ;AAEA;;;AAGG;IACK,uBAAuB,GAAA;;AAE7B,QAAA,MAAM,YAAY,GAAG;AACnB,YAAA,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY;YACzD,YAAY,EAAE,qBAAqB,EAAE,qBAAqB;AAC1D,YAAA,oBAAoB,EAAE;SACvB;AAED,QAAA,YAAY,CAAC,OAAO,CAAC,GAAG,IAAG;AACzB,YAAA,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC;AAC5B,YAAA,cAAc,CAAC,UAAU,CAAC,GAAG,CAAC;AAChC,QAAA,CAAC,CAAC;AAEF,QAAA,OAAO,CAAC,GAAG,CAAC,iFAAiF,CAAC;IAChG;IAEQ,8BAA8B,GAAA;AACpC,QAAA,IAAI,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE,EAAE;AAC3C,YAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;AACvC,YAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;;YAGrC,IAAI,CAAC,kBAAkB,EAAE;AAEzB,YAAA,IAAI,IAAI,CAAC,cAAc,EAAE;AACvB,gBAAA,IAAI,CAAC,cAAc,GAAG,KAAK;YAC7B;QACF;aAAO;AACL,YAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QACvC;IACF;AAEA;;;AAGG;IACK,kBAAkB,GAAA;AACxB,QAAA,IAAI;YACF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;YACzC,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,CAAC;YAChE,IAAI,cAAc,GAAG,KAAK;AAE1B,YAAA,cAAc,CAAC,OAAO,CAAC,KAAK,IAAG;gBAC7B,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAC/B,oBAAA,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;oBAC9B,cAAc,GAAG,IAAI;gBACvB;AACF,YAAA,CAAC,CAAC;YAEF,IAAI,cAAc,EAAE;;AAElB,gBAAA,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC/D,gBAAA,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC;YAC5D;QACF;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,IAAI,CAAC,4CAA4C,EAAE,KAAK,CAAC;QACnE;IACF;IAEQ,mBAAmB,GAAA;AACzB,QAAA,IAAI,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE,EAAE;AAC3C,YAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;AACvC,YAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QACvC;IACF;IAEQ,YAAY,GAAA;AAClB,QAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC;AACxC,QAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;IACvC;AAEA;;AAEG;IACK,iBAAiB,GAAA;QACvB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/B,QAAA,YAAY,CAAC,UAAU,CAAC,cAAc,CAAC;AACvC,QAAA,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC;AACxC,QAAA,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC;AACnC,QAAA,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC;AAChC,QAAA,YAAY,CAAC,UAAU,CAAC,YAAY,CAAC;AACrC,QAAA,cAAc,CAAC,UAAU,CAAC,cAAc,CAAC;AACzC,QAAA,cAAc,CAAC,UAAU,CAAC,eAAe,CAAC;AAC1C,QAAA,cAAc,CAAC,UAAU,CAAC,UAAU,CAAC;IACvC;AAEA;;AAEG;IACK,cAAc,GAAA;QACpB,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,wBAAwB,EAAE;QAC9D,IAAI,CAAC,SAAS,EAAE;YACd,OAAO,KAAK,CAAC;QACf;AACA,QAAA,OAAO,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE;IAC/B;AAEQ,IAAA,MAAM,uBAAuB,GAAA;AACnC,QAAA,IAAI;YACF,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC7D,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;YACrC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;YACvC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YACnC,MAAM,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC;YACtD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;;AAG1G,YAAA,MAAM,eAAe,GAAG,OAAO,IAAI,WAAW,KAAK,QAAQ,KAAK,MAAM,IAAI,eAAe,CAAC,CAAC;;YAG3F,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE;AAC7C,gBAAA,OAAO,CAAC,GAAG,CAAC,8EAA8E,CAAC;gBAC3F,IAAI,CAAC,iBAAiB,EAAE;AACxB,gBAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;gBACrC;YACF;;;YAIA,IAAI,eAAe,EAAE;AACnB,gBAAA,OAAO,CAAC,GAAG,CAAC,8EAA8E,CAAC;;gBAE3F,IAAI,CAAC,uBAAuB,EAAE;AAE9B,gBAAA,IAAI,CAAC,cAAc,GAAG,IAAI;AAC1B,gBAAA,MAAM,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE;YAC5C;YAEA,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE;YAE7D,IAAI,aAAa,EAAE;AACjB,gBAAA,IAAI,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE;AAC5B,oBAAA,IAAI,CAAC,cAAc,GAAG,KAAK;gBAC7B;gBACA,IAAI,CAAC,8BAA8B,EAAE;YACvC;iBAAO;AACL,gBAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;YACvC;QAEF;QAAE,OAAO,KAAU,EAAE;AACnB,YAAA,OAAO,CAAC,KAAK,CAAC,2DAA2D,EAAE,KAAK,CAAC;;AAGjF,YAAA,IAAI,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,IAAI,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE;gBAC7E,IAAI,CAAC,iBAAiB,EAAE;YAC1B;AAEA,YAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;QACvC;IACF;IAEQ,wBAAwB,GAAA;AAC9B,QAAA,MAAM,UAAU,GAAG,gBAAgB,EAAE;QACrC,IAAI,CAAC,YAAY,CAAC,aAAa,GAAG,UAAU,CAAC,aAAc;QAC3D,IAAI,CAAC,YAAY,CAAC,gBAAgB,GAAG,UAAU,CAAC,gBAAiB;QACjE,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,UAAU,CAAC,QAAS;QACjD,IAAI,CAAC,YAAY,CAAC,SAAS,GAAG,UAAU,CAAC,SAAU;QACnD,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,UAAU,CAAC,QAAS;QACjD,IAAI,CAAC,YAAY,CAAC,WAAW,GAAG,UAAU,CAAC,WAAY;QACvD,IAAI,CAAC,YAAY,CAAC,KAAK,GAAG,UAAU,CAAC,KAAM;QAC3C,IAAI,CAAC,YAAY,CAAC,YAAY,GAAG,UAAU,CAAC,YAAa;IAC3D;AAEO,IAAA,cAAc,CAAC,UAAsB,EAAA;AAC1C,QAAA,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC;;QAEvC,IAAI,CAAC,wBAAwB,EAAE;QAC/B,IAAI,CAAC,uBAAuB,EAAE;IAChC;IAEO,aAAa,GAAA;QAClB,OAAO,gBAAgB,EAAE;IAC3B;AAEO,IAAA,KAAK,CAAC,SAAkB,EAAA;AAC7B,QAAA,IAAI,CAAC,cAAc,GAAG,IAAI;AAE1B,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;YAC/B;QACF;AACA,QAAA,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE;YAClC;QACF;QAEA,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,SAAS,IAAI,SAAS,CAAC;IACzD;AAEO,IAAA,MAAM,MAAM,GAAA;AACjB,QAAA,IAAI;YACF,MAAM,IAAI,CAAC,0BAA0B,EAAE,CAAC,KAAK,CAAC,GAAG,IAAG;AAClD,gBAAA,OAAO,CAAC,IAAI,CAAC,wEAAwE,EAAE,GAAG,CAAC;AAC7F,YAAA,CAAC,CAAC;YAEF,IAAI,CAAC,kBAAkB,EAAE;QAE3B;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC;YAC5C,IAAI,CAAC,kBAAkB,EAAE;QAC3B;IACF;AAEQ,IAAA,MAAM,0BAA0B,GAAA;AACtC,QAAA,MAAM,UAAU,GAAG,gBAAgB,EAAE;AACrC,QAAA,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS;QAEtC,IAAI,YAAY,GAAkB,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE;QAErE,IAAI,CAAC,YAAY,EAAE;AACjB,YAAA,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,eAAe;mBAC9C,YAAY,CAAC,OAAO,CAAC,gBAAgB,GAAG,UAAU,CAAC,QAAQ;AAC3D,mBAAA,cAAc,CAAC,OAAO,CAAC,eAAe,CAAC;QAC9C;QAEA,IAAI,CAAC,SAAS,EAAE;AACd,YAAA,OAAO,CAAC,IAAI,CAAC,qDAAqD,CAAC;YACnE;QACF;QAEA,IAAI,CAAC,YAAY,EAAE;AACjB,YAAA,OAAO,CAAC,IAAI,CAAC,kDAAkD,CAAC;QAClE;AAEA,QAAA,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE;QAClC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,QAAS,CAAC;QAE3C,IAAI,YAAY,EAAE;AAChB,YAAA,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,YAAY,CAAC;QACzC;AAEA,QAAA,MAAM,OAAO,GAAgB;AAC3B,YAAA,cAAc,EAAE;SACjB;AAED,QAAA,IAAI;AACF,YAAA,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;AACtC,gBAAA,MAAM,EAAE,MAAM;gBACd,OAAO;AACP,gBAAA,IAAI,EAAE,IAAI,CAAC,QAAQ;AACpB,aAAA,CAAC;AAEF,YAAA,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;AAChB,gBAAA,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;AACvC,gBAAA,OAAO,CAAC,IAAI,CAAC,8DAA8D,EAAE,SAAS,CAAC;YACzF;QACF;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,IAAI,CAAC,0CAA0C,EAAE,KAAK,CAAC;QACjE;IACF;IAEQ,kBAAkB,GAAA;AACxB,QAAA,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;;AAG9B,QAAA,YAAY,CAAC,UAAU,CAAC,cAAc,CAAC;AACvC,QAAA,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC;AACnC,QAAA,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC;AACxC,QAAA,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC;AACxC,QAAA,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC;AAChC,QAAA,YAAY,CAAC,UAAU,CAAC,eAAe,CAAC;;AAGxC,QAAA,cAAc,CAAC,UAAU,CAAC,cAAc,CAAC;AACzC,QAAA,cAAc,CAAC,UAAU,CAAC,UAAU,CAAC;AACrC,QAAA,cAAc,CAAC,UAAU,CAAC,eAAe,CAAC;AAC1C,QAAA,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC;AAClC,QAAA,cAAc,CAAC,UAAU,CAAC,eAAe,CAAC;AAE1C,QAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC;AACxC,QAAA,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;AAErC,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG;AAClC,QAAA,IAAI,UAAU,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;YAC7D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC;QAClC;IACF;IAEO,iBAAiB,CAAC,YAAoB,QAAQ,EAAA;QACnD,IAAI,CAAC,MAAM,EAAE;QACb,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC;IACnC;IAEO,aAAa,GAAA;AAClB,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE;IAChD;AAEA,IAAA,IAAW,cAAc,GAAA;AACvB,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,iBAAiB,EAAE;IAC9C;AAEA,IAAA,IAAW,WAAW,GAAA;AACpB,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE;IAC3C;IAEO,YAAY,GAAA;AACjB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc;AAClC,QAAA,IAAI,MAAM,EAAE,KAAK,EAAE;YACjB,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QACpE;QAEA,IAAI,MAAM,EAAE;YACV,MAAM,KAAK,GAAa,EAAE;AAE1B,YAAA,IAAI,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE;gBAC9B,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC;YAC1C;AAEA,YAAA,MAAM,UAAU,GAAG,gBAAgB,EAAE;AACrC,YAAA,IAAI,MAAM,CAAC,eAAe,GAAG,UAAU,CAAC,QAAS,CAAC,EAAE,KAAK,EAAE;AACzD,gBAAA,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,QAAS,CAAC,CAAC,KAAK,CAAC;YACnE;AAEA,YAAA,OAAO,KAAK;QACd;AACA,QAAA,OAAO,EAAE;IACX;AAEO,IAAA,OAAO,CAAC,IAAY,EAAA;QACzB,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC3C;AAEO,IAAA,UAAU,CAAC,KAAe,EAAA;AAC/B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE;AACrC,QAAA,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrD;IAEO,aAAa,GAAA;AAClB,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc;QAClC,MAAM,MAAM,GAAa,EAAE;;QAG3B,IAAI,MAAM,EAAE;AACV,YAAA,IAAI,MAAM,CAAC,MAAM,EAAE;gBACjB,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;oBAChC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;gBAC/B;qBAAO;AACL,oBAAA,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;gBAC5B;YACF;AAEA,YAAA,IAAI,MAAM,CAAC,iBAAiB,EAAE;gBAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE;oBAC3C,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,iBAAiB,CAAC;gBAC1C;qBAAO;AACL,oBAAA,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;gBACvC;YACF;AAEA,YAAA,IAAI,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE;gBAC/B,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;YAC5C;QACF;;AAGA,QAAA,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;AACvB,YAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW;YACpC,IAAI,WAAW,EAAE;AACf,gBAAA,IAAI;oBACF,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC;AAClD,oBAAA,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,OAAO,CAAC;;AAG3D,oBAAA,IAAI,OAAO,CAAC,MAAM,EAAE;wBAClB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;4BACjC,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;wBAChC;6BAAO;AACL,4BAAA,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;wBAC7B;oBACF;;AAGA,oBAAA,IAAI,OAAO,CAAC,YAAY,EAAE,KAAK,EAAE;wBAC/B,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC;oBAC5C;;AAGA,oBAAA,IAAI,OAAO,CAAC,eAAe,EAAE;AAC3B,wBAAA,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,QAAa,KAAI;AAC/D,4BAAA,IAAI,QAAQ,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;gCACnD,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;4BAChC;AACF,wBAAA,CAAC,CAAC;oBACJ;gBACF;gBAAE,OAAO,KAAK,EAAE;AACd,oBAAA,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,KAAK,CAAC;gBACpE;YACF;QACF;QAEA,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;AACzC,QAAA,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,YAAY,CAAC;AAChE,QAAA,OAAO,YAAY;IACrB;AAEQ,IAAA,gBAAgB,CAAC,KAAa,EAAA;AACpC,QAAA,IAAI;YACF,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;AAC9B,YAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;AACtB,gBAAA,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC;YACvC;AACA,YAAA,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC;YACxB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACnE,YAAA,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QAC5B;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC;AAC3D,YAAA,OAAO,EAAE;QACX;IACF;wGA7eW,WAAW,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,YAAA,EAAA,EAAA,EAAA,KAAA,EAAAA,EAAA,CAAA,MAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAX,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAW,cAFV,MAAM,EAAA,CAAA;;4FAEP,WAAW,EAAA,UAAA,EAAA,CAAA;kBAHvB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE;AACb,iBAAA;;;MCCY,aAAa,CAAA;AAMK,IAAA,IAAA;IALrB,gBAAgB,GAAgC,IAAI;IACpD,cAAc,GAA4B,IAAI;IAC9C,QAAQ,GAAG,KAAK;IACP,gBAAgB,GAAG,YAAY,EAAE;AAElD,IAAA,WAAA,CAA6B,IAAgB,EAAA;QAAhB,IAAA,CAAA,IAAI,GAAJ,IAAI;IAAe;AAEhD;;AAEG;AACH,IAAA,MAAM,UAAU,GAAA;AACd,QAAA,IAAI;AACF,YAAA,MAAM,GAAG,GAAG,CAAA,EAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,GAAG,CAAA,CAAA,EAAI,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,QAAQ,EAAE;AAEtG,YAAA,IAAI,CAAC,gBAAgB,GAAG,MAAM,cAAc,CAC1C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAuB,GAAG,CAAC,CACzC;YAED,IAAI,CAAC,cAAc,GAAG,0BAA0B,CAAC,IAAI,CAAC,gBAAgB,CAAC;;AAGvE,YAAA,mBAAmB,CAAC,IAAI,CAAC,gBAAgB,CAAC;AAE1C,YAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;QACtB;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,GAAG,CAAC,mCAAmC,KAAK,CAAA,CAAE,CAAC;AACvD,YAAA,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,gBAAgB;AAC3C,YAAA,mBAAmB,EAAE;AACrB,YAAA,IAAI,CAAC,QAAQ,GAAG,IAAI;QACtB;IACF;AAEA;;AAEG;AACH,IAAA,GAAG,CAAC,GAAW,EAAA;AACb,QAAA,OAAO,IAAI,CAAC,gBAAgB,GAAG,GAAiC,CAAC;IACnE;AAEA;;AAEG;IACH,MAAM,GAAA;AACJ,QAAA,OAAO,IAAI,CAAC,gBAAgB,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE,GAAG,IAAI;IACpE;AAEA;;AAEG;IACH,cAAc,GAAA;QACZ,OAAO,IAAI,CAAC,QAAQ;IACtB;AAEA;;AAEG;IACH,YAAY,GAAA;AACV,QAAA,OAAO,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,gBAAgB;IACrD;AAEA;;AAEG;IACH,mBAAmB,GAAA;QACjB,OAAO,IAAI,CAAC,gBAAgB;IAC9B;wGAlEW,aAAa,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAC,IAAA,CAAA,UAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAb,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,aAAa,cAFZ,MAAM,EAAA,CAAA;;4FAEP,aAAa,EAAA,UAAA,EAAA,CAAA;kBAHzB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE;AACb,iBAAA;;;MCGY,oBAAoB,CAAA;AAGZ,IAAA,IAAA;AACA,IAAA,WAAA;AACA,IAAA,aAAA;AAHnB,IAAA,WAAA,CACmB,IAAgB,EAChB,WAAwB,EACxB,aAA4B,EAAA;QAF5B,IAAA,CAAA,IAAI,GAAJ,IAAI;QACJ,IAAA,CAAA,WAAW,GAAX,WAAW;QACX,IAAA,CAAA,aAAa,GAAb,aAAa;IAC7B;AAEH;;AAEG;AACH,IAAA,gBAAgB,CAAC,YAAoB,EAAE,aAAA,GAAwB,MAAM,EAAA;AACnE,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE;AAEhD,QAAA,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;AACvB,YAAA,OAAO,EAAE,CAAC,KAAK,CAAC;QAClB;AAEA,QAAA,MAAM,OAAO,GAAyB;AACpC,YAAA,QAAQ,EAAE,MAAM;AAChB,YAAA,WAAW,EAAE,MAAM,CAAC,YAAY,CAAC,QAAQ;AACzC,YAAA,YAAY,EAAE,YAAY;AAC1B,YAAA,aAAa,EAAE;SAChB;AAED,QAAA,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC;IACzC;AAEA;;AAEG;AACK,IAAA,kBAAkB,CAAC,OAA6B,EAAA;AACtD,QAAA,IAAI,MAAM,GAAG,IAAI,UAAU,EAAE;QAE7B,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;QAE5C,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,cAAc,CAAC;QAC/C,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,WAAW,CAAC;QACvD,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,YAAY,CAAC;QACzD,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,OAAO,CAAC,aAAa,CAAC;AAE3D,QAAA,IAAI,OAAO,GAAG,IAAI,WAAW,EAAE;QAE/B,MAAM,GAAG,GAAG,CAAA,EAAG,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC,aAAa,CAAC,OAAO,CAAA,EAAG,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC,aAAa,CAAC,cAAc,CAAA,CAAE;AAEzI,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAwB,GAAG,EAAE;YAC/C,MAAM;YACN;AACD,SAAA,CAAC,CAAC,IAAI,CACL,GAAG,CAAC,QAAQ,IAAG;YACb,OAAO,QAAQ,CAAC,aAAa;AAC/B,QAAA,CAAC,CAAC,EACF,UAAU,CAAC,MAAK;AACd,YAAA,OAAO,EAAE,CAAC,KAAK,CAAC;QAClB,CAAC,CAAC,CACH;IACH;AAEA;;AAEG;IACK,aAAa,GAAA;AACnB,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE;IACzC;AAEA;;AAEG;IACI,kBAAkB,GAAA;AACvB,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE;IACzC;AAEA;;AAEG;IACH,gBAAgB,GAAA;AACd,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,EAAE;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE;AAEhD,QAAA,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;AACvB,YAAA,OAAO,EAAE,CAAC,EAAE,CAAC;QACf;AAEA,QAAA,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACjE,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;AAE5C,QAAA,IAAI,MAAM,GAAG,IAAI,UAAU,EAAE;AAC7B,QAAA,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,EAAG,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;QACjE,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,cAAc,CAAC;AAE/C,QAAA,IAAI,OAAO,GAAG,IAAI,WAAW,EAAE;AAE/B,QAAA,MAAM,GAAG,GAAG,CAAA,EAAG,MAAM,CAAC,aAAa,CAAC,OAAO,CAAA,EAAG,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE;AAEtF,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAsB,GAAG,EAAE;YAC7C,MAAM;YACN;AACD,SAAA,CAAC,CAAC,IAAI,CACL,UAAU,CAAC,KAAK,IAAG;AACjB,YAAA,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC;AAC5D,YAAA,OAAO,EAAE,CAAC,EAAE,CAAC;QACf,CAAC,CAAC,CACH;IACH;AAEA;;AAEG;AACH,IAAA,gBAAgB,CAAC,aAAkC,EAAA;AACjD,QAAA,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;IACvD;AAEA;;AAEG;AACH,IAAA,iBAAiB,CAAC,aAAkC,EAAE,UAAkB,EAAE,KAAa,EAAA;AACrF,QAAA,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,IAC9B,IAAI,CAAC,KAAK,KAAK,KAAK;AACpB,YAAA,IAAI,CAAC,SAAS;AACd,YAAA,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAChC,IAAI,CAAC,IAAI,KAAK,UAAU;AACxB,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,CACjD;IACH;AAEA;;AAEG;IACH,WAAW,CAAC,aAAkC,EAAE,IAAuB,EAAA;QACrE,OAAO,IAAI,CAAC,iBAAiB,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC;IACpF;AAEA;;AAEG;AACK,IAAA,aAAa,CAAC,SAAiB,EAAE,UAAkB,EAAE,aAAqB,EAAA;QAChF,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;AAC3D,QAAA,MAAM,UAAU,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM;QAC3D,OAAO,UAAU,KAAK,CAAC;IACzB;AAEA;;AAEG;AACH,IAAA,yBAAyB,CAAC,WAA+D,EAAA;QACvF,MAAM,OAAO,GAA+B,EAAE;AAC9C,QAAA,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,IAC5C,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,YAAY,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC,IAAI,CAC3E,GAAG,CAAC,UAAU,KAAK;YACjB,GAAG,EAAE,CAAA,EAAG,UAAU,CAAC,YAAY,CAAA,CAAA,EAAI,UAAU,CAAC,aAAa,IAAI,MAAM,CAAA,CAAE;YACvE;SACD,CAAC,CAAC,CACJ,CACF;AAED,QAAA,OAAO,IAAI,UAAU,CAAC,QAAQ,IAAG;YAC/B,IAAI,SAAS,GAAG,CAAC;AACjB,YAAA,WAAW,CAAC,OAAO,CAAC,GAAG,IAAG;AACxB,gBAAA,GAAG,CAAC,SAAS,CAAC,MAAM,IAAG;oBACrB,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,UAAU;AACvC,oBAAA,SAAS,EAAE;AACX,oBAAA,IAAI,SAAS,KAAK,WAAW,CAAC,MAAM,EAAE;AACpC,wBAAA,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC;wBACtB,QAAQ,CAAC,QAAQ,EAAE;oBACrB;AACF,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;wGA1KW,oBAAoB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,IAAA,CAAA,UAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,WAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAApB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,oBAAoB,cAFnB,MAAM,EAAA,CAAA;;4FAEP,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBAHhC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE;AACb,iBAAA;;;MCLY,SAAS,GAAkB,CAAC,KAAK,EAAE,KAAK,KAAI;AACvD,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;AACvC,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAE7B,MAAM,mBAAmB,GAAG,MAAc;AACxC,QAAA,OAAO,IAAI;AACb,IAAA,CAAC;AAED,IAAA,MAAM,qBAAqB,GAAG,CAAC,UAAkB,KAAa;AAC5D,QAAA,IAAI,UAAU,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;AAC7D,YAAA,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE;AAC1B,gBAAA,WAAW,EAAE,EAAE,SAAS,EAAE,UAAU;AACrC,aAAA,CAAC;QACJ;AACA,QAAA,OAAO,KAAK;AACd,IAAA,CAAC;AAED,IAAA,OAAO,WAAW,CAAC,gBAAgB,CAAC,IAAI,CACtC,IAAI,CAAC,CAAC,CAAC,EACP,GAAG,CAAC,eAAe,IAAG;AACpB,QAAA,OAAO;cACH,mBAAmB;AACrB,cAAE,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC;IACtC,CAAC,CAAC,CACH;AACH;;MCfa,cAAc,CAAA;AAcN,IAAA,WAAA;AAbnB;;AAEG;IACM,MAAM,GAAyB,EAAE;IAE1C,WAAW,GAAG,KAAK;IACnB,aAAa,GAAG,EAAE;AACV,IAAA,gBAAgB;IAChB,oBAAoB,GAAG,KAAK;;AAG5B,IAAA,aAAa;AAErB,IAAA,WAAA,CAAmB,WAAwB,EAAA;QAAxB,IAAA,CAAA,WAAW,GAAX,WAAW;;AAE5B,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,aAAa,GAAG,cAAc,EAAE;QACvC;AAAE,QAAA,MAAM;AACN,YAAA,IAAI,CAAC,aAAa,GAAG,EAAE,GAAG,oBAAoB,EAAE;QAClD;IACF;IAEA,QAAQ,GAAA;;AAEN,QAAA,IAAI;AACF,YAAA,MAAM,YAAY,GAAG,cAAc,EAAE;YACrC,IAAI,CAAC,aAAa,GAAG;AACnB,gBAAA,GAAG,YAAY;gBACf,GAAG,IAAI,CAAC,MAAM;gBACd,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,YAAY,CAAC,OAAO,IAAI;aAC1D;QACH;AAAE,QAAA,MAAM;YACN,IAAI,CAAC,aAAa,GAAG;AACnB,gBAAA,GAAG,oBAAoB;gBACvB,GAAG,IAAI,CAAC,MAAM;AACd,gBAAA,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI;aAClC;QACH;;;AAIA,QAAA,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,CAAC;QACxE,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;QACrC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;QACnC,MAAM,eAAe,GAAG,SAAS,CAAC,GAAG,CAAC,eAAe,CAAC;AACtD,QAAA,MAAM,WAAW,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,EAAE,QAAQ,CAAC,cAAc,CAAC;AAC1D,YAAA,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC;QAEtE,IAAI,OAAO,IAAI,WAAW,IAAI,MAAM,IAAI,eAAe,EAAE;AACvD,YAAA,IAAI,CAAC,oBAAoB,GAAG,IAAI;AAChC,YAAA,IAAI,CAAC,aAAa,GAAG,6BAA6B;QACpD;;AAGA,QAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,SAAS,CAAC,eAAe,IAAG;YACpF,IAAI,eAAe,EAAE;AACnB,gBAAA,IAAI,CAAC,aAAa,GAAG,yCAAyC;;gBAE9D,UAAU,CAAC,MAAK;oBACd,IAAI,CAAC,kBAAkB,EAAE;gBAC3B,CAAC,EAAE,GAAG,CAAC;YACT;AACF,QAAA,CAAC,CAAC;IACJ;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE;AACzB,YAAA,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE;QACrC;IACF;AAEA;;AAEG;AACH,IAAA,SAAS,CAA8B,GAAM,EAAA;AAC3C,QAAA,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;IAChC;AAEA;;AAEG;IACH,eAAe,GAAA;QACb,MAAM,MAAM,GAA8B,EAAE;AAE5C,QAAA,IAAI,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE;YACnC,MAAM,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY;QAC7D;AACA,QAAA,IAAI,IAAI,CAAC,aAAa,CAAC,eAAe,EAAE;YACtC,MAAM,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,eAAe;QACjE;AACA,QAAA,IAAI,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;YAChC,MAAM,CAAC,oBAAoB,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS;QAC7D;AAEA,QAAA,OAAO,MAAM;IACf;IAEA,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI;AACvB,QAAA,IAAI,CAAC,aAAa,GAAG,+CAA+C;QAEpE,UAAU,CAAC,MAAK;AACd,YAAA,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;QAC1B,CAAC,EAAE,GAAG,CAAC;IACT;IAEA,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE;AACzB,QAAA,IAAI,CAAC,WAAW,GAAG,KAAK;AACxB,QAAA,IAAI,CAAC,aAAa,GAAG,EAAE;AACvB,QAAA,IAAI,CAAC,oBAAoB,GAAG,KAAK;IACnC;IAEA,aAAa,GAAA;QACX,IAAI,CAAC,kBAAkB,EAAE;IAC3B;IAEQ,kBAAkB,GAAA;AACxB,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW;AAClD,QAAA,IAAI,OAAO,UAAU,CAAC,QAAQ,KAAK,WAAW,EAAE;AAC9C,YAAA,MAAM,OAAO,GAAG,CAAA,EAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAA,EAAA,EAAK,UAAU,CAAC,QAAQ,CAAC,IAAI,EAAE;YAC9E,UAAU,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,OAAO,CAAA,EAAG,WAAW,CAAA,CAAE;QACvD;IACF;wGA5HW,cAAc,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAC,WAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAAd,cAAc,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECf3B,uqGAqFA,EAAA,MAAA,EAAA,CAAA,gxJAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED1EY,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,SAAA,EAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,CAAA;;4FAIX,cAAc,EAAA,UAAA,EAAA,CAAA;kBAP1B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,WAAW,EAAA,UAAA,EACT,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAAA,QAAA,EAAA,uqGAAA,EAAA,MAAA,EAAA,CAAA,gxJAAA,CAAA,EAAA;;sBAQtB;;;MECU,kBAAkB,CAAA;AAepB,IAAA,WAAA;AACU,IAAA,oBAAA;IAfV,MAAM,GAA6B,EAAE;IAE9C,QAAQ,GAAQ,IAAI;IACpB,SAAS,GAAa,EAAE;IACxB,aAAa,GAAwB,EAAE;IACvC,UAAU,GAAG,KAAK;IAClB,aAAa,GAAG,KAAK;AACrB,IAAA,aAAa,GAAgB,IAAI,GAAG,EAAE;IACtC,eAAe,GAAG,KAAK;IACvB,gBAAgB,GAAG,KAAK;AAEhB,IAAA,aAAa;IAErB,WAAA,CACS,WAAwB,EACd,oBAA0C,EAAA;QADpD,IAAA,CAAA,WAAW,GAAX,WAAW;QACD,IAAA,CAAA,oBAAoB,GAApB,oBAAoB;;AAGrC,QAAA,IAAI;AACF,YAAA,IAAI,CAAC,aAAa,GAAG,kBAAkB,EAAE;QAC3C;AAAE,QAAA,MAAM;AACN,YAAA,IAAI,CAAC,aAAa,GAAG,EAAE,GAAG,wBAAwB,EAAE;QACtD;IACF;IAEA,QAAQ,GAAA;;AAEN,QAAA,IAAI;AACF,YAAA,MAAM,YAAY,GAAG,kBAAkB,EAAE;YACzC,IAAI,CAAC,aAAa,GAAG;AACnB,gBAAA,GAAG,YAAY;gBACf,GAAG,IAAI,CAAC,MAAM;gBACd,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,YAAY,CAAC,OAAO,IAAI;aAC1D;QACH;AAAE,QAAA,MAAM;YACN,IAAI,CAAC,aAAa,GAAG;AACnB,gBAAA,GAAG,wBAAwB;gBAC3B,GAAG,IAAI,CAAC,MAAM;AACd,gBAAA,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI;aAClC;QACH;QACA,IAAI,CAAC,YAAY,EAAE;QACnB,IAAI,CAAC,iBAAiB,EAAE;IAC1B;AAEA,IAAA,SAAS,CAAkC,GAAM,EAAA;AAC/C,QAAA,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;IAChC;AAEA,IAAA,IAAI,UAAU,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO;IACnC;IAEQ,YAAY,GAAA;QAClB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,cAAc;QAC/C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE;IAClD;IAEQ,iBAAiB,GAAA;AACvB,QAAA,IAAI,CAAC,aAAa,GAAG,IAAI;AACzB,QAAA,IAAI,CAAC,oBAAoB,CAAC,gBAAgB,EAAE,CAAC,SAAS,CAAC;AACrD,YAAA,IAAI,EAAE,CAAC,SAAS,KAAI;gBAClB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC;AAC1D,gBAAA,IAAI,CAAC,aAAa,GAAG,KAAK;YAC5B,CAAC;AACD,YAAA,KAAK,EAAE,CAAC,KAAK,KAAI;AACf,gBAAA,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC;AACrD,gBAAA,IAAI,CAAC,aAAa,GAAG,EAAE;AACvB,gBAAA,IAAI,CAAC,aAAa,GAAG,KAAK;YAC5B;AACD,SAAA,CAAC;IACJ;AAEQ,IAAA,qBAAqB,CAAC,SAA8B,EAAA;AAC1D,QAAA,MAAM,OAAO,GAAG,IAAI,GAAG,EAA6B;AAEpD,QAAA,SAAS,CAAC,OAAO,CAAC,IAAI,IAAG;AACvB,YAAA,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AACnD,QAAA,CAAC,CAAC;QAEF,MAAM,SAAS,GAAwB,EAAE;AAEzC,QAAA,SAAS,CAAC,OAAO,CAAC,IAAI,IAAG;YACvB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAE;AAE3C,YAAA,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE;AACpB,gBAAA,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC;YAC7B;iBAAO;gBACL,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC;gBAC/C,IAAI,MAAM,EAAE;oBACV,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;AAC3C,oBAAA,IAAI,UAAU,EAAE,QAAQ,EAAE;AACxB,wBAAA,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;oBACvC;gBACF;YACF;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,OAAO,SAAS;IAClB;IAEQ,UAAU,CAAC,IAAuB,EAAE,QAA6B,EAAA;AACvE,QAAA,KAAK,MAAM,eAAe,IAAI,QAAQ,EAAE;YACtC,IAAI,eAAe,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,GAAG,CAAC;gBACxC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC;AAC1C,gBAAA,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC,IAAI,EAAE;AACtC,gBAAA,OAAO,eAAe;YACxB;QACF;AACA,QAAA,OAAO,IAAI;IACb;IAEA,cAAc,CAAC,MAAc,EAAE,IAAuB,EAAA;QACpD,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;QAEtD,IAAI,eAAe,EAAE;AACnB,YAAA,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC;QACnC;aAAO;AACL,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;AAC5B,YAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;QAChC;IACF;AAEQ,IAAA,oBAAoB,CAAC,MAAc,EAAA;AACzC,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC;QACjC,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;AAC7F,QAAA,YAAY,CAAC,OAAO,CAAC,EAAE,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3D;AAEQ,IAAA,iBAAiB,CAAC,WAA8B,EAAA;AACtD,QAAA,IAAI,WAAW,CAAC,KAAK,KAAK,CAAC,EAAE;AAC3B,YAAA,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE;AACzC,YAAA,SAAS,CAAC,OAAO,CAAC,QAAQ,IAAG;gBAC3B,IAAI,QAAQ,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,EAAE;AACtC,oBAAA,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAC1C;AACF,YAAA,CAAC,CAAC;QACJ;aAAO;YACL,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC;YAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,QAAQ,CAAC;AACrD,YAAA,IAAI,MAAM,EAAE,QAAQ,EAAE;AACpB,gBAAA,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,IAAG;oBAChC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,EAAE;AACrC,wBAAA,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC;oBACzC;AACF,gBAAA,CAAC,CAAC;YACJ;QACF;IACF;AAEQ,IAAA,gBAAgB,CAAC,KAA0B,EAAA;QACjD,MAAM,SAAS,GAAwB,EAAE;AAEzC,QAAA,MAAM,OAAO,GAAG,CAAC,QAA6B,KAAI;AAChD,YAAA,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAG;AACtB,gBAAA,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;AACpB,gBAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;AACjB,oBAAA,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACxB;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC;QAED,OAAO,CAAC,KAAK,CAAC;AACd,QAAA,OAAO,SAAS;IAClB;IAEA,eAAe,CAAC,KAAY,EAAE,IAAuB,EAAA;AACnD,QAAA,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;YAC1B,KAAK,CAAC,cAAc,EAAE;YACtB,KAAK,CAAC,eAAe,EAAE;YACvB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;QACtC;aAAO;;YAEL,IAAI,CAAC,eAAe,EAAE;QACxB;IACF;AAGA,IAAA,eAAe,CAAC,KAAY,EAAA;AAC1B,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB;QAC1C,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACnD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;QAEjD,IAAI,CAAC,UAAU,EAAE;AACf,YAAA,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;QAC5B;QAEA,IAAI,CAAC,SAAS,EAAE;AACd,YAAA,IAAI,CAAC,eAAe,GAAG,KAAK;QAC9B;IACF;AAEA,IAAA,eAAe,CAAC,KAAY,EAAA;QAC1B,KAAK,CAAC,eAAe,EAAE;AACvB,QAAA,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,eAAe;IAC9C;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB;AAAE,YAAA,OAAO,SAAS;AACxD,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB;QACjD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC;AACrC,QAAA,OAAO,OAAO,GAAG,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,QAAQ;IAChE;IAEA,eAAe,GAAA;AACb,QAAA,OAAO,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,SAAS;IACzC;IAEA,WAAW,GAAA;AACT,QAAA,OAAO,IAAI,CAAC,QAAQ,EAAE,GAAG,IAAI,KAAK;IACpC;IAEA,cAAc,GAAA;AACZ,QAAA,OAAO,IAAI,CAAC,QAAQ,EAAE,SAAS,IAAI,KAAK;IAC1C;IAEA,aAAa,GAAA;AACX,QAAA,OAAO,IAAI,CAAC,QAAQ,EAAE,WAAW,IAAI,KAAK;IAC5C;IAEA,OAAO,GAAA;AACL,QAAA,OAAO,IAAI,CAAC,QAAQ,EAAE,KAAK,IAAI,KAAK;IACtC;AAEA,IAAA,cAAc,CAAC,MAAc,EAAA;QAC3B,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC;IACvC;AAEA,IAAA,WAAW,CAAC,IAAuB,EAAA;AACjC,QAAA,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACtD;IAEA,gBAAgB,GAAA;AACd,QAAA,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;IAC5D;AAEA;;;AAGG;AACH,IAAA,WAAW,CAAC,IAAuB,EAAA;;AAEjC,QAAA,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YAC1C,OAAO,IAAI,CAAC,KAAK;QACnB;;AAGA,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE;AACpB,YAAA,OAAO,QAAQ;QACjB;AAAO,aAAA,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE;AAC3B,YAAA,OAAO,SAAS;QAClB;aAAO;AACL,YAAA,OAAO,wBAAwB;QACjC;IACF;IAEA,iBAAiB,GAAA;AACf,QAAA,IAAI,CAAC,WAAW,CAAC,iBAAiB,EAAE;IACtC;IAEA,eAAe,GAAA;QACb,IAAI,CAAC,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,GAAG;AAE9B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,IAAI,SAAS;QAChF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAE7B,QAAA,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE;YACrB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE;QAClD;aAAO;YACL,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE;QAC3C;IACF;IAEA,gBAAgB,GAAA;AACd,QAAA,IAAI,CAAC,gBAAgB,GAAG,CAAC,IAAI,CAAC,gBAAgB;IAChD;IAEA,eAAe,GAAA;AACb,QAAA,IAAI,CAAC,gBAAgB,GAAG,KAAK;QAC7B,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE;IACnC;wGAzRW,kBAAkB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,WAAA,EAAA,EAAA,EAAA,KAAA,EAAAC,oBAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,gBAAA,EAAA,yBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECpB/B,+vVA8PA,EAAA,MAAA,EAAA,CAAA,s5WAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,ED9OY,YAAY,saAAE,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,YAAA,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,kBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,QAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,UAAA,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,gBAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,uBAAA,EAAA,kBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;4FAIzB,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAP9B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,eAAe,cACb,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,EAAE,YAAY,CAAC,EAAA,QAAA,EAAA,+vVAAA,EAAA,MAAA,EAAA,CAAA,s5WAAA,CAAA,EAAA;;sBAKpC;;sBAiLA,YAAY;uBAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC;;;AEtM5C;AACA;AACA;AACA;AAEA;;ACLA;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"shared-lib-angular.mjs","sources":["../../src/lib/version.ts","../../src/lib/models/login-config.interface.ts","../../src/lib/models/dashboard-config.interface.ts","../../src/lib/models/library-config.interface.ts","../../src/lib/config/app.config.ts","../../src/lib/config/authentication.config.ts","../../src/lib/services/authentication.service.ts","../../src/lib/services/config.service.ts","../../src/lib/services/authorization.service.ts","../../src/lib/guards/authorization.guard.ts","../../src/lib/components/login/login.component.ts","../../src/lib/components/login/login.component.html","../../src/lib/components/dashboard/dashboard.component.ts","../../src/lib/components/dashboard/dashboard.component.html","../../src/public-api.ts","../../src/shared-lib-angular.ts"],"sourcesContent":["// ========================================\n// VERSION - Auto-generado por sync-version.js\n// ========================================\n// Ejecutar 'npm run sync-version' para actualizar manualmente\n// Se sincroniza automáticamente en prebuild\n\n/**\n * Versión actual de la librería @dinafi/frmk\n * Sincronizada con package.json\n */\nexport const VERSION = '1.0.32';\n\n/**\n * Información completa de la versión\n */\nexport const VERSION_INFO = {\n version: '1.0.32',\n name: 'shared-lib-angular',\n buildDate: '2026-02-05T17:56:18.182Z',\n angular: '^20.0.0'\n} as const;\n","/**\r\n * Interface for configuring the LoginComponent appearance and behavior\r\n */\r\nexport interface LoginConfig {\r\n // === IDENTITY ===\r\n /** URL of the logo image. Defaults to the Ministerio de Hacienda logo */\r\n logoUrl: string;\r\n /** Alt text for the logo image */\r\n logoAlt: string;\r\n /** Width of the logo (CSS value, e.g., '120px') */\r\n logoWidth: string;\r\n /** Height of the logo (CSS value, e.g., '120px') */\r\n logoHeight: string;\r\n\r\n // === TEXTS ===\r\n /** Main title displayed on the login page */\r\n title: string;\r\n /** Optional subtitle displayed below the title */\r\n subtitle?: string;\r\n /** Institution name displayed in the footer */\r\n institutionName: string;\r\n /** Text for the login button */\r\n loginButtonText: string;\r\n /** Text for the logout button */\r\n logoutButtonText: string;\r\n /** Text for the \"go to dashboard\" button when already authenticated */\r\n dashboardButtonText: string;\r\n\r\n // === VERSION ===\r\n /** Whether to show the version number */\r\n showVersion: boolean;\r\n /** Version string to display */\r\n version: string;\r\n\r\n // === COLORS (CSS custom properties override) ===\r\n /** Primary color (overrides --color-primary) */\r\n primaryColor?: string;\r\n /** Background color of the container */\r\n backgroundColor?: string;\r\n /** Text color */\r\n textColor?: string;\r\n\r\n // === BEHAVIOR ===\r\n /** URL to redirect after successful login */\r\n redirectUrl: string;\r\n /** Whether to show the logout button when authenticated */\r\n showLogoutButton: boolean;\r\n\r\n // === FOOTER ===\r\n /** Custom footer text */\r\n footerText?: string;\r\n /** Whether to show the footer */\r\n showFooter: boolean;\r\n}\r\n\r\n/**\r\n * Default configuration for the LoginComponent\r\n */\r\nexport const DEFAULT_LOGIN_CONFIG: LoginConfig = {\r\n logoUrl: 'assets/@dinafi/frmk/logo-mh.png',\r\n logoAlt: 'Logo',\r\n logoWidth: '120px',\r\n logoHeight: '120px',\r\n title: 'Sistema de Autenticación',\r\n institutionName: 'Ministerio de Hacienda de El Salvador',\r\n loginButtonText: 'Iniciar Sesión con OIDC',\r\n logoutButtonText: 'Cerrar Sesión',\r\n dashboardButtonText: 'Ir al Dashboard',\r\n showVersion: true,\r\n version: '1.0.0',\r\n redirectUrl: '/home',\r\n showLogoutButton: true,\r\n showFooter: true\r\n};\r\n","/**\r\n * Interface for configuring the DashboardComponent appearance and behavior\r\n */\r\nexport interface DashboardConfig {\r\n /** Application title displayed in the header */\r\n title: string;\r\n /** Optional subtitle */\r\n subtitle?: string;\r\n /** Logo URL */\r\n logoUrl: string;\r\n /** Logo alt text */\r\n logoAlt: string;\r\n /** Footer text */\r\n footerText: string;\r\n /** Whether to show the version in the footer */\r\n showVersion: boolean;\r\n /** Version string */\r\n version: string;\r\n /** Whether to show static menu items (Inicio, Página Ejemplo, Componentes UI) */\r\n showStaticMenu: boolean;\r\n}\r\n\r\n/**\r\n * Default configuration for the DashboardComponent\r\n */\r\nexport const DEFAULT_DASHBOARD_CONFIG: DashboardConfig = {\r\n title: 'Sistema',\r\n logoUrl: 'assets/@dinafi/frmk/logo-mh.png',\r\n logoAlt: 'Logo',\r\n footerText: 'Ministerio de Hacienda, El Salvador',\r\n showVersion: true,\r\n version: '1.0.0',\r\n showStaticMenu: true\r\n};\r\n","import { InjectionToken } from '@angular/core';\r\nimport { LoginConfig } from './login-config.interface';\r\nimport { DashboardConfig } from './dashboard-config.interface';\r\n\r\n/**\r\n * Configuración de la librería que debe ser proporcionada por la aplicación consumidora\r\n * Estos valores son críticos y deben ser configurados al inicializar la librería\r\n */\r\nexport interface FrmkLibraryConfig {\r\n /**\r\n * URL del servidor de configuración (Config Server)\r\n * Ejemplo: 'config-server.example.com' o 'localhost:8080'\r\n */\r\n configServerHost: string;\r\n\r\n /**\r\n * Identificador del frontend en el Config Server\r\n * Este valor identifica la aplicación para obtener su configuración específica\r\n * Ejemplo: 'mi-aplicacion-frontend'\r\n */\r\n frontendId: string;\r\n\r\n /**\r\n * Ruta del servicio de configuración (opcional)\r\n * Por defecto: '/api/v1/config/service'\r\n */\r\n configServicePath?: string;\r\n\r\n /**\r\n * Realm de autenticación (opcional)\r\n * Por defecto se obtiene del Config Server\r\n */\r\n realm?: string;\r\n\r\n /**\r\n * Si es ambiente de producción (opcional)\r\n * Por defecto: false\r\n */\r\n production?: boolean;\r\n\r\n /**\r\n * Si requiere HTTPS (opcional)\r\n * Por defecto: true\r\n */\r\n requireHttps?: boolean;\r\n\r\n /**\r\n * Mostrar información de debug (opcional)\r\n * Por defecto: false\r\n */\r\n showDebugInformation?: boolean;\r\n\r\n /**\r\n * Configuración del componente de Login (opcional)\r\n * Permite personalizar textos, logos y comportamiento del login\r\n */\r\n loginConfig?: Partial<LoginConfig>;\r\n\r\n /**\r\n * Configuración del componente Dashboard (opcional)\r\n * Permite personalizar el layout principal de la aplicación\r\n */\r\n dashboardConfig?: Partial<DashboardConfig>;\r\n}\r\n\r\n/**\r\n * Configuración por defecto de la librería\r\n */\r\nexport const DEFAULT_LIBRARY_CONFIG: Partial<FrmkLibraryConfig> = {\r\n configServicePath: '/api/v1/config/service',\r\n production: false,\r\n requireHttps: true,\r\n showDebugInformation: false\r\n};\r\n\r\n/**\r\n * Token de inyección para la configuración de la librería\r\n * \r\n * @example\r\n * // En el app.config.ts o app.module.ts de la aplicación consumidora:\r\n * providers: [\r\n * {\r\n * provide: FRMK_LIBRARY_CONFIG,\r\n * useValue: {\r\n * configServerHost: 'config-server.miempresa.com',\r\n * frontendId: 'mi-aplicacion-frontend',\r\n * production: environment.production\r\n * }\r\n * }\r\n * ]\r\n */\r\nexport const FRMK_LIBRARY_CONFIG = new InjectionToken<FrmkLibraryConfig>('FrmkLibraryConfig');\r\n\r\n/**\r\n * Función helper para crear la configuración de la librería\r\n * \r\n * @example\r\n * // En el app.config.ts:\r\n * import { provideFrmkConfig } from '@mh-dinafi-frmk/shared-lib-angular';\r\n * \r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideFrmkConfig({\r\n * configServerHost: environment.configServerHost,\r\n * frontendId: 'mi-aplicacion'\r\n * })\r\n * ]\r\n * };\r\n */\r\nexport function provideFrmkConfig(config: FrmkLibraryConfig) {\r\n return {\r\n provide: FRMK_LIBRARY_CONFIG,\r\n useValue: {\r\n ...DEFAULT_LIBRARY_CONFIG,\r\n ...config\r\n }\r\n };\r\n}\r\n","import { AppConfiguration, ConfigServerResponse } from '../models/app-config.interface';\r\nimport { FrmkLibraryConfig, DEFAULT_LIBRARY_CONFIG } from '../models/library-config.interface';\r\nimport { LoginConfig, DEFAULT_LOGIN_CONFIG } from '../models/login-config.interface';\r\nimport { DashboardConfig, DEFAULT_DASHBOARD_CONFIG } from '../models/dashboard-config.interface';\r\n\r\n// Variable global para almacenar la configuración actual\r\nlet currentAppConfig: AppConfiguration | null = null;\r\n\r\n// Variable global para almacenar la configuración de la librería\r\nlet libraryConfig: FrmkLibraryConfig | null = null;\r\n\r\n/**\r\n * Inicializa la configuración de la librería con los valores proporcionados por la aplicación\r\n * Esta función debe ser llamada antes de usar cualquier servicio de la librería\r\n * \r\n * @param config Configuración proporcionada por la aplicación consumidora\r\n */\r\nexport function initializeLibraryConfig(config: FrmkLibraryConfig): void {\r\n libraryConfig = {\r\n ...DEFAULT_LIBRARY_CONFIG,\r\n ...config\r\n } as FrmkLibraryConfig;\r\n \r\n // Resetear la configuración actual para que se reconstruya con los nuevos valores\r\n currentAppConfig = null;\r\n}\r\n\r\n/**\r\n * Obtiene la configuración de la librería\r\n * Lanza error si no ha sido inicializada\r\n */\r\nexport function getLibraryConfig(): FrmkLibraryConfig {\r\n if (!libraryConfig) {\r\n throw new Error(\r\n '[FRMK] La librería no ha sido configurada. ' +\r\n 'Debe proporcionar FRMK_LIBRARY_CONFIG en los providers de su aplicación. ' +\r\n 'Ejemplo: provideFrmkConfig({ configServerHost: \"...\", frontendId: \"...\" })'\r\n );\r\n }\r\n return libraryConfig;\r\n}\r\n\r\n/**\r\n * Verifica si la librería ha sido configurada\r\n */\r\nexport function isLibraryConfigured(): boolean {\r\n return libraryConfig !== null;\r\n}\r\n\r\n/**\r\n * Obtiene la configuración del componente Login\r\n * Combina los valores por defecto con los configurados en la librería\r\n */\r\nexport function getLoginConfig(): LoginConfig {\r\n const libConfig = isLibraryConfigured() ? getLibraryConfig() : null;\r\n return {\r\n ...DEFAULT_LOGIN_CONFIG,\r\n ...(libConfig?.loginConfig || {})\r\n };\r\n}\r\n\r\n/**\r\n * Obtiene la configuración del componente Dashboard\r\n * Combina los valores por defecto con los configurados en la librería\r\n */\r\nexport function getDashboardConfig(): DashboardConfig {\r\n const libConfig = isLibraryConfigured() ? getLibraryConfig() : null;\r\n return {\r\n ...DEFAULT_DASHBOARD_CONFIG,\r\n ...(libConfig?.dashboardConfig || {})\r\n };\r\n}\r\n\r\n// Función para crear la configuración por defecto usando los valores de la librería\r\nfunction createDefaultAppConfig(): AppConfiguration {\r\n const libConfig = getLibraryConfig();\r\n \r\n return {\r\n hosts: { \r\n configServer: libConfig.configServerHost,\r\n authServer: '', // Leído desde Config Server\r\n keycloak: '', // Leído desde Config Server\r\n localApp: '' // Leído desde Config Server\r\n },\r\n paths: {\r\n configService: libConfig.configServicePath || '/api/v1/config/service',\r\n realm: libConfig.realm || 'realm-to-create'\r\n },\r\n configServer: {\r\n url: '', // Se construirá dinámicamente\r\n frontend: libConfig.frontendId\r\n },\r\n auth: {\r\n issuer: '', // Se construirá dinámicamente\r\n loginUrl: '', // Se construirá dinámicamente\r\n tokenEndpoint: '', // Se construirá dinámicamente\r\n userinfoEndpoint: '', // Se construirá dinámicamente\r\n logoutUrl: '', // Se construirá dinámicamente\r\n clientId: '',\r\n redirectUri: '', // Se construirá dinámicamente\r\n postLogoutRedirectUri: '', // Se construirá dinámicamente\r\n silentRefreshRedirectUri: '', // Se construirá dinámicamente\r\n scope: 'openid email profile'\r\n },\r\n authorization: {\r\n baseUrl: '',\r\n verifyEndpoint: '/api/v1/authz/verify-groups',\r\n hierarchyEndpoint: '/api/v1/authz/hierarchy-by-component-and-groups',\r\n },\r\n environment: {\r\n production: libConfig.production ?? false,\r\n requireHttps: libConfig.requireHttps ?? true,\r\n showDebugInformation: libConfig.showDebugInformation ?? false\r\n }\r\n };\r\n}\r\n\r\n// Getter para obtener la configuración por defecto (lazy initialization)\r\nexport function getDefaultAppConfig(): AppConfiguration {\r\n return createDefaultAppConfig();\r\n}\r\n\r\n// Función para mapear la configuración del config server a la configuración de la aplicación\r\nexport function mapConfigServerResponse(configServerData: ConfigServerResponse): Partial<AppConfiguration> {\r\n const mappedConfig: Partial<AppConfiguration> = {};\r\n const defaultConfig = getDefaultAppConfig();\r\n \r\n // Mapear Auth URL\r\n configureAuthServer();\r\n\r\n // Mapear client ID\r\n initializeClientId();\r\n\r\n // Mapear realm\r\n initializeRealmMapping();\r\n\r\n // Mapear URL de autorización (authServer)\r\n initializeAuthorizationConfig();\r\n\r\n // Mapear scope de autorización\r\n initializeAuthScope();\r\n\r\n // Mapear keycloak URL\r\n initializeKeycloakHost();\r\n\r\n // Mapear callback URL (local app host)\r\n configureLocalAppCallback(); \r\n\r\n // Mapear callback URL (local app host)\r\n initializeHttpsSettings(); \r\n\r\n return mappedConfig;\r\n\r\n function initializeHttpsSettings() {\r\n if (configServerData[\"security.url.https\"]) {\r\n mappedConfig.environment = {\r\n ...defaultConfig.environment,\r\n ...(mappedConfig.environment || {}),\r\n requireHttps: configServerData[\"security.url.https\"]\r\n };\r\n }\r\n }\r\n\r\n function configureLocalAppCallback() {\r\n if (configServerData[\"security.url.callback\"]) {\r\n mappedConfig.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mappedConfig.hosts || {}),\r\n localApp: configServerData[\"security.url.callback\"]\r\n };\r\n }\r\n }\r\n\r\n function initializeKeycloakHost() {\r\n if (configServerData[\"security.url.keycloak\"]) {\r\n mappedConfig.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mappedConfig.hosts || {}),\r\n keycloak: configServerData[\"security.url.keycloak\"]\r\n };\r\n }\r\n }\r\n\r\n function initializeAuthScope() {\r\n if (configServerData[\"security.scope\"]) {\r\n mappedConfig.auth = {\r\n ...defaultConfig.auth,\r\n ...(mappedConfig.auth || {}),\r\n scope: configServerData[\"security.scope\"]\r\n };\r\n }\r\n }\r\n\r\n function initializeAuthorizationConfig() {\r\n if (configServerData[\"security.url.authz\"]) {\r\n mappedConfig.authorization = {\r\n ...defaultConfig.authorization,\r\n ...(mappedConfig.authorization || {}),\r\n baseUrl: configServerData[\"security.url.authz\"]\r\n };\r\n }\r\n }\r\n\r\n function initializeRealmMapping() {\r\n if (configServerData[\"security.realm\"]) {\r\n mappedConfig.paths = {\r\n ...defaultConfig.paths,\r\n ...(mappedConfig.paths || {}),\r\n realm: configServerData[\"security.realm\"]\r\n };\r\n }\r\n }\r\n\r\n function initializeClientId() {\r\n if (configServerData[\"quarkus.oidc.client-id\"]) {\r\n mappedConfig.auth = {\r\n ...defaultConfig.auth,\r\n ...(mappedConfig.auth || {}),\r\n clientId: configServerData[\"quarkus.oidc.client-id\"]\r\n };\r\n }\r\n }\r\n\r\n function configureAuthServer() {\r\n if (configServerData[\"security.url.auth\"]) {\r\n mappedConfig.hosts = {\r\n ...defaultConfig.hosts,\r\n ...(mappedConfig.hosts || {}),\r\n authServer: configServerData[\"security.url.auth\"]\r\n };\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Función para establecer la configuración actual con datos del config server\r\n * Esta función debe ser llamada desde el ConfigService después de cargar la configuración\r\n */\r\nexport function setCurrentAppConfig(configServerData?: ConfigServerResponse): void {\r\n currentAppConfig = getAppConfigWithServerData(configServerData);\r\n}\r\n\r\n/**\r\n * Función para obtener la configuración actual\r\n * Si no se ha establecido una configuración, devuelve la configuración por defecto\r\n */\r\nexport function getCurrentAppConfig(): AppConfiguration {\r\n return currentAppConfig || getAppConfig();\r\n}\r\n\r\n// Función para obtener la configuración con posibles sobrescrituras de variables de entorno\r\nexport function getAppConfig(): AppConfiguration {\r\n const config = { ...getDefaultAppConfig() };\r\n\r\n // Construir URLs dinámicamente\r\n const localProtocol = config.environment.requireHttps ? 'https' : 'http';\r\n \r\n // Config Server URL\r\n config.configServer.url = `${localProtocol}://${config.hosts.configServer}${config.paths.configService}`;\r\n \r\n // Auth URLs\r\n config.auth.issuer = `${localProtocol}://${config.hosts.keycloak}/realms/${config.paths.realm}`;\r\n config.auth.loginUrl = `${localProtocol}://${config.hosts.keycloak}/realms/${config.paths.realm}/protocol/openid-connect/auth`;\r\n config.auth.tokenEndpoint = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/token`;\r\n config.auth.userinfoEndpoint = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/userinfo`;\r\n config.auth.logoutUrl = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/logout`;\r\n \r\n // Redirect URLs (locales)\r\n const currentOrigin = globalThis.window?.location?.origin ?? config.hosts.localApp;\r\n config.auth.redirectUri = `${currentOrigin}/login`;\r\n config.auth.postLogoutRedirectUri = `${currentOrigin}/login`;\r\n \r\n // Authorization URL\r\n config.authorization.baseUrl = `${localProtocol}://${config.authorization.baseUrl}`;\r\n \r\n return config;\r\n}\r\n\r\n// Función para obtener la configuración aplicando primero la del config server y luego variables de entorno\r\nexport function getAppConfigWithServerData(configServerData?: ConfigServerResponse): AppConfiguration {\r\n let config = { ...getDefaultAppConfig() };\r\n \r\n // Aplicar configuración del config server si está disponible\r\n if (configServerData) {\r\n const serverMappedConfig = mapConfigServerResponse(configServerData);\r\n config = mergeConfigurations(config, serverMappedConfig);\r\n }\r\n \r\n // Construir URLs dinámicamente\r\n config = buildDynamicUrls(config);\r\n \r\n return config;\r\n}\r\n\r\n// Función auxiliar para fusionar configuraciones\r\nfunction mergeConfigurations(base: AppConfiguration, override: Partial<AppConfiguration>): AppConfiguration {\r\n const merged = { ...base };\r\n \r\n if (override.hosts) {\r\n merged.hosts = { ...merged.hosts, ...override.hosts };\r\n }\r\n if (override.paths) {\r\n merged.paths = { ...merged.paths, ...override.paths };\r\n }\r\n if (override.configServer) {\r\n merged.configServer = { ...merged.configServer, ...override.configServer };\r\n }\r\n if (override.auth) {\r\n merged.auth = { ...merged.auth, ...override.auth };\r\n }\r\n if (override.authorization) {\r\n merged.authorization = { ...merged.authorization, ...override.authorization };\r\n }\r\n if (override.environment) {\r\n merged.environment = { ...merged.environment, ...override.environment };\r\n }\r\n \r\n return merged;\r\n}\r\n\r\n// Función para construir URLs dinámicamente\r\nfunction buildDynamicUrls(config: AppConfiguration): AppConfiguration {\r\n const localProtocol = config.environment.requireHttps ? 'https' : 'http';\r\n \r\n // Config Server URL\r\n config.configServer.url = `${localProtocol}://${config.hosts.configServer}${config.paths.configService}`;\r\n \r\n // Auth URLs\r\n config.auth.issuer = `${localProtocol}://${config.hosts.keycloak}/realms/${config.paths.realm}`;\r\n config.auth.loginUrl = `${localProtocol}://${config.hosts.keycloak}/realms/${config.paths.realm}/protocol/openid-connect/auth`;\r\n config.auth.tokenEndpoint = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/token`;\r\n config.auth.userinfoEndpoint = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/userinfo`;\r\n config.auth.logoutUrl = `${localProtocol}://${config.hosts.authServer}/oidc/realm/${config.paths.realm}/protocol/openid-connect/logout`;\r\n \r\n // Redirect URLs (locales)\r\n const currentOrigin = globalThis.window?.location?.origin ?? config.hosts.localApp;\r\n config.auth.redirectUri = `${currentOrigin}/login`;\r\n config.auth.postLogoutRedirectUri = `${currentOrigin}/login`;\r\n\r\n // Authorization URL\r\n config.authorization.baseUrl = `${localProtocol}://${config.authorization.baseUrl}`;\r\n \r\n return config;\r\n}\r\n","import { AuthConfig } from 'angular-oauth2-oidc';\r\nimport { getCurrentAppConfig } from './app.config';\r\n\r\n/**\r\n * Función para obtener la configuración de autenticación actual\r\n * Esta función se evalúa cada vez que se llama, por lo que siempre tendrá la configuración más reciente\r\n */\r\nexport function getAuthConfig(): AuthConfig {\r\n const appConfig = getCurrentAppConfig();\r\n\r\n return {\r\n // URL base del servidor de identidad\r\n issuer: appConfig.auth.issuer,\r\n \r\n // URLs específicas para evitar discovery document\r\n loginUrl: appConfig.auth.loginUrl,\r\n tokenEndpoint: appConfig.auth.tokenEndpoint,\r\n userinfoEndpoint: appConfig.auth.userinfoEndpoint,\r\n logoutUrl: appConfig.auth.logoutUrl,\r\n \r\n // IMPORTANTE: URLs de redirección completas\r\n redirectUri: appConfig.auth.redirectUri,\r\n postLogoutRedirectUri: appConfig.auth.postLogoutRedirectUri,\r\n\r\n // Configuración del cliente\r\n clientId: appConfig.auth.clientId,\r\n\r\n // Configuración OAuth\r\n responseType: 'code',\r\n scope: appConfig.auth.scope,\r\n \r\n // Configuraciones para desarrollo\r\n disableAtHashCheck: true,\r\n requireHttps: appConfig.environment.requireHttps,\r\n showDebugInformation: appConfig.environment.showDebugInformation,\r\n strictDiscoveryDocumentValidation: false,\r\n skipIssuerCheck: true,\r\n\r\n // IMPORTANTE: Configuraciones para manejar state y session_state\r\n requestAccessToken: true,\r\n customQueryParams: {},\r\n\r\n // Timeouts\r\n silentRefreshTimeout: 5000,\r\n timeoutFactor: 0.25,\r\n \r\n // Session checks\r\n sessionChecksEnabled: false,\r\n clearHashAfterLogin: true,\r\n\r\n // Configuración OIDC\r\n oidc: true\r\n };\r\n}\r\n\r\n// Mantener la exportación original para compatibilidad\r\nexport function getAuthConfigEnv(): AuthConfig {\r\n return getAuthConfig();\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { AuthConfig, OAuthService, OAuthEvent } from 'angular-oauth2-oidc';\r\nimport { BehaviorSubject } from 'rxjs';\r\nimport { getAuthConfigEnv } from '../config/authentication.config';\r\n\r\n@Injectable({ \r\n providedIn: 'root'\r\n})\r\nexport class AuthService {\r\n private readonly isAuthenticatedSubject$ = new BehaviorSubject<boolean>(false);\r\n public isAuthenticated$ = this.isAuthenticatedSubject$.asObservable();\r\n\r\n private readonly isDoneLoadingSubject$ = new BehaviorSubject<boolean>(false);\r\n public isDoneLoading$ = this.isDoneLoadingSubject$.asObservable();\r\n\r\n private isInitialLogin = true;\r\n\r\n constructor(private readonly oauthService: OAuthService, private readonly router: Router) {\r\n // IMPORTANTE: Limpiar tokens expirados ANTES de cualquier otra operación\r\n this.clearExpiredTokensOnStartup();\r\n \r\n this.oauthService.events \r\n .subscribe((event) => {\r\n if (event instanceof OAuthEvent) {\r\n if (event.type === 'token_received') {\r\n this.handleSuccessfulAuthentication();\r\n }\r\n if (event.type === 'logout') {\r\n this.handleLogout();\r\n }\r\n if (event.type === 'token_error') {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n if (event.type === 'silently_refreshed') {\r\n this.handleSilentRefresh();\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Limpia tokens expirados al iniciar la aplicación\r\n * Solo limpia si NO estamos en un callback OAuth\r\n */\r\n private clearExpiredTokensOnStartup(): void {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n \r\n // Detectar TODOS los parámetros que indican un callback OAuth\r\n // Keycloak puede enviar: code, state, session_state, iss (RFC 9207)\r\n const isOAuthCallback = urlParams.has('code') || \r\n urlParams.has('iss') || \r\n urlParams.has('session_state') ||\r\n urlParams.has('state') ||\r\n window.location.hash.includes('access_token') ||\r\n window.location.hash.includes('code');\r\n \r\n if (isOAuthCallback) {\r\n console.log('[AuthService] OAuth callback detected, skipping token cleanup');\r\n return;\r\n }\r\n\r\n // Verificar si hay un token y si está expirado\r\n const expiresAt = localStorage.getItem('expires_at') || sessionStorage.getItem('expires_at');\r\n if (expiresAt) {\r\n const expirationTime = parseInt(expiresAt, 10);\r\n const now = Date.now();\r\n \r\n if (expirationTime < now) {\r\n console.log('[AuthService] Expired token detected, clearing storage');\r\n this.clearAllTokens();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Limpia todos los tokens del storage\r\n */\r\n private clearAllTokens(): void {\r\n const keysToRemove = [\r\n 'access_token', 'refresh_token', 'id_token', 'token_type',\r\n 'expires_at', 'nonce', 'PKCE_verifier', 'session_state',\r\n 'id_token_claims_obj', 'id_token_expires_at', 'id_token_stored_at',\r\n 'access_token_stored_at'\r\n ];\r\n \r\n keysToRemove.forEach(key => {\r\n localStorage.removeItem(key);\r\n sessionStorage.removeItem(key);\r\n });\r\n }\r\n\r\n /**\r\n * Limpia tokens antiguos pero MANTIENE state, nonce y PKCE_verifier\r\n * que son necesarios para validar el callback OAuth\r\n */\r\n private clearOldTokensKeepState(): void {\r\n // Solo limpiar tokens, NO state/nonce/PKCE_verifier\r\n const keysToRemove = [\r\n 'access_token', 'refresh_token', 'id_token', 'token_type',\r\n 'expires_at', 'id_token_claims_obj', 'id_token_expires_at', \r\n 'id_token_stored_at', 'access_token_stored_at'\r\n ];\r\n \r\n keysToRemove.forEach(key => {\r\n localStorage.removeItem(key);\r\n sessionStorage.removeItem(key);\r\n });\r\n \r\n console.log('[AuthService] Cleared old tokens, kept state/nonce/PKCE for callback validation');\r\n }\r\n\r\n private handleSuccessfulAuthentication(): void {\r\n if (this.oauthService.hasValidAccessToken()) {\r\n this.isAuthenticatedSubject$.next(true);\r\n this.isDoneLoadingSubject$.next(true);\r\n \r\n // Limpiar parámetros OAuth de la URL para evitar problemas al refrescar\r\n this.cleanupOAuthParams();\r\n \r\n if (this.isInitialLogin) {\r\n this.isInitialLogin = false;\r\n }\r\n } else {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n }\r\n\r\n /**\r\n * Limpia los parámetros OAuth de la URL después del login exitoso\r\n * Esto evita problemas cuando el usuario refresca la página\r\n */\r\n private cleanupOAuthParams(): void {\r\n try {\r\n const url = new URL(window.location.href);\r\n const paramsToRemove = ['code', 'state', 'session_state', 'iss'];\r\n let hasOAuthParams = false;\r\n \r\n paramsToRemove.forEach(param => {\r\n if (url.searchParams.has(param)) {\r\n url.searchParams.delete(param);\r\n hasOAuthParams = true;\r\n }\r\n });\r\n \r\n if (hasOAuthParams) {\r\n // Reemplazar URL sin recargar la página\r\n window.history.replaceState({}, document.title, url.toString());\r\n console.log('[AuthService] OAuth params cleaned from URL');\r\n }\r\n } catch (error) {\r\n console.warn('[AuthService] Error cleaning OAuth params:', error);\r\n }\r\n }\r\n\r\n private handleSilentRefresh(): void {\r\n if (this.oauthService.hasValidAccessToken()) {\r\n this.isAuthenticatedSubject$.next(true);\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n }\r\n\r\n private handleLogout(): void {\r\n this.isAuthenticatedSubject$.next(false);\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n\r\n /**\r\n * Limpia todos los tokens del storage\r\n */\r\n private clearTokenStorage(): void {\r\n this.oauthService.logOut(true); // true = no redirect, solo limpiar\r\n localStorage.removeItem('access_token');\r\n localStorage.removeItem('refresh_token');\r\n localStorage.removeItem('id_token');\r\n localStorage.removeItem('nonce');\r\n localStorage.removeItem('expires_at');\r\n sessionStorage.removeItem('access_token');\r\n sessionStorage.removeItem('refresh_token');\r\n sessionStorage.removeItem('id_token');\r\n }\r\n\r\n /**\r\n * Verifica si el token actual está expirado\r\n */\r\n private isTokenExpired(): boolean {\r\n const expiresAt = this.oauthService.getAccessTokenExpiration();\r\n if (!expiresAt) {\r\n return false; // Si no hay token, no está \"expirado\", simplemente no existe\r\n }\r\n return expiresAt < Date.now();\r\n }\r\n\r\n private async runInitialLoginSequence(): Promise<void> {\r\n try {\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hasCode = urlParams.has('code');\r\n const hasState = urlParams.has('state');\r\n const hasIss = urlParams.has('iss');\r\n const hasSessionState = urlParams.has('session_state');\r\n const hasFragment = window.location.hash.includes('access_token') || window.location.hash.includes('code');\r\n \r\n // Detectar si estamos en un callback OAuth (Keycloak envía code, state, session_state, iss)\r\n const isOAuthCallback = hasCode || hasFragment || (hasState && (hasIss || hasSessionState));\r\n\r\n // Si NO estamos en callback OAuth y hay tokens expirados, limpiar y terminar\r\n if (!isOAuthCallback && this.isTokenExpired()) {\r\n console.log('[AuthService] No OAuth callback detected and token expired, clearing storage');\r\n this.clearTokenStorage();\r\n this.isDoneLoadingSubject$.next(true);\r\n return;\r\n }\r\n\r\n // Si estamos en callback OAuth, SIEMPRE limpiar tokens anteriores para evitar conflictos\r\n // Esto es crítico: angular-oauth2-oidc valida tokens existentes antes de procesar el código nuevo\r\n if (isOAuthCallback) {\r\n console.log('[AuthService] OAuth callback detected, clearing old tokens before processing');\r\n // Limpiar solo tokens, NO el state/nonce que necesitamos para validar el callback\r\n this.clearOldTokensKeepState();\r\n \r\n this.isInitialLogin = true;\r\n await this.oauthService.tryLoginCodeFlow();\r\n } \r\n\r\n const hasValidToken = this.oauthService.hasValidAccessToken();\r\n \r\n if (hasValidToken) {\r\n if (!hasCode && !hasFragment) {\r\n this.isInitialLogin = false;\r\n }\r\n this.handleSuccessfulAuthentication();\r\n } else {\r\n this.isDoneLoadingSubject$.next(true);\r\n }\r\n \r\n } catch (error: any) {\r\n console.error('[AuthService] Error during authentication initialization:', error);\r\n \r\n // Si el error es por token expirado, limpiar y permitir nuevo login\r\n if (error?.message?.includes('expired') || error?.reason?.includes('expired')) {\r\n this.clearTokenStorage();\r\n }\r\n \r\n this.isDoneLoadingSubject$.next(true);\r\n } \r\n }\r\n\r\n private setupManualConfiguration(): void {\r\n const authConfig = getAuthConfigEnv();\r\n this.oauthService.tokenEndpoint = authConfig.tokenEndpoint!;\r\n this.oauthService.userinfoEndpoint = authConfig.userinfoEndpoint!;\r\n this.oauthService.loginUrl = authConfig.loginUrl!;\r\n this.oauthService.logoutUrl = authConfig.logoutUrl!;\r\n this.oauthService.clientId = authConfig.clientId!;\r\n this.oauthService.redirectUri = authConfig.redirectUri!;\r\n this.oauthService.scope = authConfig.scope!;\r\n this.oauthService.responseType = authConfig.responseType!;\r\n }\r\n\r\n public initializeAuth(authConfig: AuthConfig): void {\r\n // CRÍTICO: Limpiar tokens expirados ANTES de configurar OAuthService\r\n // angular-oauth2-oidc valida tokens existentes en configure() y lanza \"Token has expired\"\r\n const urlParams = new URLSearchParams(window.location.search);\r\n const hasCode = urlParams.has('code');\r\n const expiresAt = localStorage.getItem('expires_at');\r\n const isExpired = expiresAt && parseInt(expiresAt, 10) < Date.now();\r\n \r\n if (isExpired) {\r\n if (hasCode) {\r\n // Callback OAuth: limpiar tokens pero mantener state/nonce/PKCE para validar el callback\r\n console.log('[AuthService] Clearing expired tokens before configure (keeping state for callback)');\r\n this.clearOldTokensKeepState();\r\n } else {\r\n // No hay callback: limpiar todo\r\n console.log('[AuthService] Clearing all expired tokens before configure');\r\n this.clearAllTokens();\r\n }\r\n }\r\n \r\n // Ahora es seguro configurar OAuthService (no hay tokens expirados que validar)\r\n this.oauthService.configure(authConfig);\r\n // NO usar silent refresh - si expira, redirigir al login\r\n this.setupManualConfiguration();\r\n this.runInitialLoginSequence();\r\n }\r\n\r\n public getAuthConfig(): AuthConfig {\r\n return getAuthConfigEnv();\r\n }\r\n\r\n public login(targetUrl?: string): void {\r\n this.isInitialLogin = true;\r\n \r\n if (!this.oauthService.clientId) {\r\n return;\r\n }\r\n if (!this.oauthService.redirectUri) {\r\n return;\r\n }\r\n\r\n this.oauthService.initLoginFlow(targetUrl || undefined);\r\n }\r\n\r\n public async logout(): Promise<void> {\r\n try {\r\n await this.callKeycloakLogoutEndpoint().catch(err => {\r\n console.warn('Keycloak logout endpoint failed, but will continue with local cleanup:', err);\r\n });\r\n \r\n this.performLocalLogout();\r\n \r\n } catch (error) {\r\n console.error('Error during logout:', error);\r\n this.performLocalLogout();\r\n }\r\n }\r\n\r\n private async callKeycloakLogoutEndpoint(): Promise<void> {\r\n const authConfig = getAuthConfigEnv();\r\n const logoutUrl = authConfig.logoutUrl;\r\n \r\n let refreshToken: string | null = this.oauthService.getRefreshToken();\r\n \r\n if (!refreshToken) {\r\n refreshToken = localStorage.getItem('refresh_token') \r\n || localStorage.getItem('refresh_token_' + authConfig.clientId)\r\n || sessionStorage.getItem('refresh_token');\r\n }\r\n \r\n if (!logoutUrl) {\r\n console.warn('Logout URL not configured, skipping Keycloak logout');\r\n return;\r\n }\r\n\r\n if (!refreshToken) {\r\n console.warn('No refresh token found, logout endpoint may fail');\r\n }\r\n\r\n const body = new URLSearchParams();\r\n body.set('client_id', authConfig.clientId!);\r\n \r\n if (refreshToken) {\r\n body.set('refresh_token', refreshToken);\r\n }\r\n\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/x-www-form-urlencoded'\r\n };\r\n\r\n try {\r\n const response = await fetch(logoutUrl, {\r\n method: 'POST',\r\n headers,\r\n body: body.toString()\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n console.warn('Keycloak logout returned error, but local cleanup completed:', errorText);\r\n }\r\n } catch (error) {\r\n console.warn('Failed to call Keycloak logout endpoint:', error);\r\n }\r\n }\r\n\r\n private performLocalLogout(): void {\r\n this.oauthService.logOut(true);\r\n \r\n // Limpiar tokens del localStorage\r\n localStorage.removeItem('access_token');\r\n localStorage.removeItem('id_token');\r\n localStorage.removeItem('refresh_token');\r\n localStorage.removeItem('code_verifier');\r\n localStorage.removeItem('nonce');\r\n localStorage.removeItem('PKCE_verifier');\r\n \r\n // Limpiar tokens del sessionStorage\r\n sessionStorage.removeItem('access_token');\r\n sessionStorage.removeItem('id_token');\r\n sessionStorage.removeItem('refresh_token');\r\n sessionStorage.removeItem('nonce');\r\n sessionStorage.removeItem('PKCE_verifier');\r\n \r\n this.isAuthenticatedSubject$.next(false);\r\n this.isDoneLoadingSubject$.next(true);\r\n \r\n const currentUrl = this.router.url;\r\n if (currentUrl !== '/login' && !currentUrl.includes('/login')) {\r\n this.router.navigate(['/login']);\r\n }\r\n }\r\n\r\n public logoutAndRedirect(targetUrl: string = '/login'): void {\r\n this.logout();\r\n this.router.navigate([targetUrl]);\r\n }\r\n\r\n public hasValidToken(): boolean {\r\n return this.oauthService.hasValidAccessToken();\r\n }\r\n\r\n public get identityClaims(): any {\r\n return this.oauthService.getIdentityClaims();\r\n }\r\n\r\n public get accessToken(): string {\r\n return this.oauthService.getAccessToken();\r\n }\r\n\r\n public getUserRoles(): string[] {\r\n const claims = this.identityClaims;\r\n if (claims?.roles) {\r\n return Array.isArray(claims.roles) ? claims.roles : [claims.roles];\r\n }\r\n \r\n if (claims) {\r\n const roles: string[] = [];\r\n \r\n if (claims.realm_access?.roles) {\r\n roles.push(...claims.realm_access.roles);\r\n }\r\n \r\n const authConfig = getAuthConfigEnv();\r\n if (claims.resource_access?.[authConfig.clientId!]?.roles) {\r\n roles.push(...claims.resource_access[authConfig.clientId!].roles);\r\n }\r\n \r\n return roles;\r\n }\r\n return [];\r\n }\r\n\r\n public hasRole(role: string): boolean {\r\n return this.getUserRoles().includes(role);\r\n }\r\n\r\n public hasAnyRole(roles: string[]): boolean {\r\n const userRoles = this.getUserRoles();\r\n return roles.some(role => userRoles.includes(role));\r\n }\r\n\r\n public getUserGroups(): string[] {\r\n const claims = this.identityClaims;\r\n const groups: string[] = [];\r\n\r\n // First, try to get groups from identity claims (ID token)\r\n if (claims) {\r\n if (claims.groups) {\r\n if (Array.isArray(claims.groups)) {\r\n groups.push(...claims.groups);\r\n } else {\r\n groups.push(claims.groups);\r\n }\r\n }\r\n\r\n if (claims.accessTokenGroups) {\r\n if (Array.isArray(claims.accessTokenGroups)) {\r\n groups.push(...claims.accessTokenGroups);\r\n } else {\r\n groups.push(claims.accessTokenGroups);\r\n }\r\n }\r\n\r\n if (claims.realm_access?.groups) {\r\n groups.push(...claims.realm_access.groups);\r\n }\r\n }\r\n\r\n // If no groups found in ID token, try to decode access token\r\n if (groups.length === 0) {\r\n const accessToken = this.accessToken;\r\n if (accessToken) {\r\n try {\r\n const payload = this.decodeJwtPayload(accessToken);\r\n console.log('[AuthService] Access token payload:', payload);\r\n\r\n // Extract groups from access token\r\n if (payload.groups) {\r\n if (Array.isArray(payload.groups)) {\r\n groups.push(...payload.groups);\r\n } else {\r\n groups.push(payload.groups);\r\n }\r\n }\r\n\r\n // Also check realm_access.roles as groups (Keycloak pattern)\r\n if (payload.realm_access?.roles) {\r\n groups.push(...payload.realm_access.roles);\r\n }\r\n\r\n // Check resource_access for client-specific roles\r\n if (payload.resource_access) {\r\n Object.values(payload.resource_access).forEach((resource: any) => {\r\n if (resource.roles && Array.isArray(resource.roles)) {\r\n groups.push(...resource.roles);\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n console.error('[AuthService] Error decoding access token:', error);\r\n }\r\n }\r\n }\r\n\r\n const uniqueGroups = [...new Set(groups)];\r\n console.log('[AuthService] getUserGroups result:', uniqueGroups);\r\n return uniqueGroups;\r\n }\r\n\r\n private decodeJwtPayload(token: string): any {\r\n try {\r\n const parts = token.split('.');\r\n if (parts.length !== 3) {\r\n throw new Error('Invalid JWT format');\r\n }\r\n const payload = parts[1];\r\n const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));\r\n return JSON.parse(decoded);\r\n } catch (error) {\r\n console.error('[AuthService] Failed to decode JWT:', error);\r\n return {};\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpClient } from '@angular/common/http';\r\nimport { firstValueFrom } from 'rxjs';\r\nimport { AppConfiguration, ConfigServerResponse } from '../models/app-config.interface';\r\nimport { getAppConfig, getAppConfigWithServerData, setCurrentAppConfig } from '../config/app.config';\r\n\r\n@Injectable({ \r\n providedIn: 'root' \r\n})\r\nexport class ConfigService {\r\n private configServerData: ConfigServerResponse | null = null;\r\n private finalAppConfig: AppConfiguration | null = null;\r\n private isLoaded = false;\r\n private readonly initialAppConfig = getAppConfig();\r\n\r\n constructor(private readonly http: HttpClient) {}\r\n\r\n /**\r\n * Carga la configuración desde el config-server\r\n */\r\n async loadConfig(): Promise<void> {\r\n try {\r\n const url = `${this.initialAppConfig.configServer.url}/${this.initialAppConfig.configServer.frontend}`;\r\n \r\n this.configServerData = await firstValueFrom(\r\n this.http.get<ConfigServerResponse>(url)\r\n );\r\n \r\n this.finalAppConfig = getAppConfigWithServerData(this.configServerData);\r\n \r\n // IMPORTANTE: Establecer la configuración actual para que esté disponible globalmente\r\n setCurrentAppConfig(this.configServerData);\r\n \r\n this.isLoaded = true;\r\n } catch (error) {\r\n console.log(`Exception while loading config: ${error}`);\r\n this.finalAppConfig = this.initialAppConfig;\r\n setCurrentAppConfig();\r\n this.isLoaded = true;\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene un valor de configuración por clave del config server\r\n */\r\n get(key: string): string | boolean | undefined {\r\n return this.configServerData?.[key as keyof ConfigServerResponse];\r\n }\r\n\r\n /**\r\n * Obtiene toda la configuración del config server\r\n */\r\n getAll(): ConfigServerResponse | null {\r\n return this.configServerData ? { ...this.configServerData } : null;\r\n }\r\n\r\n /**\r\n * Verifica si la configuración ha sido cargada\r\n */\r\n isConfigLoaded(): boolean {\r\n return this.isLoaded;\r\n }\r\n\r\n /**\r\n * Obtiene la configuración final de la aplicación (con valores del config server aplicados)\r\n */\r\n getAppConfig(): AppConfiguration {\r\n return this.finalAppConfig || this.initialAppConfig;\r\n }\r\n\r\n /**\r\n * Obtiene los datos raw del config server\r\n */\r\n getConfigServerData(): ConfigServerResponse | null {\r\n return this.configServerData;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';\r\nimport { Observable, of } from 'rxjs';\r\nimport { catchError, map } from 'rxjs/operators';\r\nimport { AuthService } from './authentication.service';\r\nimport { ConfigService } from './config.service';\r\nimport { AuthorizationRequest, AuthorizationResponse, MenuHierarchyItem } from '../models/authorization.interface';\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class AuthorizationService {\r\n\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly authService: AuthService,\r\n private readonly configService: ConfigService\r\n ) {}\r\n\r\n /**\r\n * Verifica si el usuario tiene permisos para acceder a un recurso específico\r\n */\r\n verifyPermission(resourcePath: string, operationName: string = 'VIEW'): Observable<boolean> {\r\n const groups = this.getUserGroups();\r\n const config = this.configService.getAppConfig();\r\n \r\n if (groups.length === 0) {\r\n return of(false);\r\n }\r\n\r\n const request: AuthorizationRequest = {\r\n groupIds: groups,\r\n componentId: config.configServer.frontend,\r\n resourcePath: resourcePath,\r\n operationName: operationName\r\n };\r\n\r\n return this.checkAuthorization(request);\r\n }\r\n\r\n /**\r\n * Realiza la llamada HTTP al servicio de autorización\r\n */\r\n private checkAuthorization(request: AuthorizationRequest): Observable<boolean> {\r\n let params = new HttpParams();\r\n \r\n const cleanGroups = request.groupIds.map(group => group.replace(/\\//g, ''));\r\n const groupIdsString = cleanGroups.join(',');\r\n \r\n params = params.set('groupIds', groupIdsString);\r\n params = params.set('componentId', request.componentId);\r\n params = params.set('resourcePath', request.resourcePath);\r\n params = params.set('operationName', request.operationName);\r\n\r\n let headers = new HttpHeaders();\r\n\r\n const url = `${this.configService.getAppConfig().authorization.baseUrl}${this.configService.getAppConfig().authorization.verifyEndpoint}`;\r\n\r\n return this.http.get<AuthorizationResponse>(url, { \r\n params,\r\n headers\r\n }).pipe(\r\n map(response => {\r\n return response.hasPermission;\r\n }),\r\n catchError(() => {\r\n return of(false);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene los grupos del usuario desde el access token\r\n */\r\n private getUserGroups(): string[] {\r\n return this.authService.getUserGroups();\r\n }\r\n\r\n /** \r\n * Método público para obtener los grupos del usuario (útil para debugging)\r\n */\r\n public getUserGroupsDebug(): string[] {\r\n return this.authService.getUserGroups();\r\n }\r\n\r\n /**\r\n * Obtiene la jerarquía de menús basada en el componente y los grupos del usuario\r\n */\r\n getMenuHierarchy(): Observable<MenuHierarchyItem[]> {\r\n const groups = this.getUserGroups();\r\n const config = this.configService.getAppConfig();\r\n \r\n if (groups.length === 0) {\r\n return of([]);\r\n }\r\n\r\n const cleanGroups = groups.map(group => group.replace(/\\//g, ''));\r\n const groupIdsString = cleanGroups.join(',');\r\n\r\n let params = new HttpParams();\r\n params = params.set('componentId', config.configServer.frontend);\r\n params = params.set('groupIds', groupIdsString);\r\n\r\n let headers = new HttpHeaders();\r\n\r\n const url = `${config.authorization.baseUrl}${config.authorization.hierarchyEndpoint}`;\r\n\r\n return this.http.get<MenuHierarchyItem[]>(url, { \r\n params,\r\n headers\r\n }).pipe(\r\n catchError(error => {\r\n console.error('Error obteniendo jerarquía de menús:', error);\r\n return of([]);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Obtiene elementos de menú de nivel raíz (level 1)\r\n */\r\n getRootMenuItems(menuHierarchy: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n return menuHierarchy.filter(item => item.level === 1);\r\n }\r\n\r\n /**\r\n * Obtiene elementos hijos de un elemento padre específico por path\r\n */\r\n getChildMenuItems(menuHierarchy: MenuHierarchyItem[], parentPath: string, level: number): MenuHierarchyItem[] {\r\n return menuHierarchy.filter(item => \r\n item.level === level && \r\n item.hasParent && \r\n item.path.startsWith(parentPath) &&\r\n item.path !== parentPath &&\r\n this.isDirectChild(item.path, parentPath, level)\r\n );\r\n }\r\n\r\n /**\r\n * Verifica si un elemento tiene hijos\r\n */\r\n hasChildren(menuHierarchy: MenuHierarchyItem[], item: MenuHierarchyItem): boolean {\r\n return this.getChildMenuItems(menuHierarchy, item.path, item.level + 1).length > 0;\r\n }\r\n\r\n /**\r\n * Verifica si un path es hijo directo de otro path\r\n */\r\n private isDirectChild(childPath: string, parentPath: string, expectedLevel: number): boolean {\r\n const relativePath = childPath.substring(parentPath.length);\r\n const slashCount = (relativePath.match(/\\//g) || []).length;\r\n return slashCount === 1;\r\n }\r\n\r\n /**\r\n * Verifica múltiples permisos a la vez\r\n */\r\n verifyMultiplePermissions(permissions: { resourcePath: string, operationName?: string }[]): Observable<{ [key: string]: boolean }> {\r\n const results: { [key: string]: boolean } = {};\r\n const observables = permissions.map(permission => \r\n this.verifyPermission(permission.resourcePath, permission.operationName).pipe(\r\n map(authorized => ({ \r\n key: `${permission.resourcePath}_${permission.operationName || 'VIEW'}`, \r\n authorized \r\n }))\r\n )\r\n );\r\n\r\n return new Observable(observer => {\r\n let completed = 0;\r\n observables.forEach(obs => {\r\n obs.subscribe(result => {\r\n results[result.key] = result.authorized;\r\n completed++;\r\n if (completed === observables.length) {\r\n observer.next(results);\r\n observer.complete();\r\n }\r\n });\r\n });\r\n });\r\n }\r\n}\r\n","import { inject } from '@angular/core';\r\nimport { CanActivateFn, Router } from '@angular/router';\r\nimport { AuthService } from '../services/authentication.service';\r\nimport { map, take } from 'rxjs/operators';\r\n\r\nexport const authGuard: CanActivateFn = (route, state) => {\r\n const authService = inject(AuthService);\r\n const router = inject(Router);\r\n\r\n const handleAuthenticated = (): boolean => {\r\n return true;\r\n };\r\n\r\n const handleUnauthenticated = (currentUrl: string): boolean => {\r\n if (currentUrl !== '/login' && !currentUrl.includes('/login')) {\r\n router.navigate(['/login'], { \r\n queryParams: { returnUrl: currentUrl } \r\n });\r\n }\r\n return false;\r\n }; \r\n\r\n return authService.isAuthenticated$.pipe(\r\n take(1),\r\n map(isAuthenticated => {\r\n return isAuthenticated \r\n ? handleAuthenticated() \r\n : handleUnauthenticated(state.url);\r\n })\r\n );\r\n};\r\n","import { Component, OnInit, OnDestroy, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Subscription } from 'rxjs';\r\nimport { AuthService } from '../../services/authentication.service';\r\nimport { LoginConfig, DEFAULT_LOGIN_CONFIG } from '../../models/login-config.interface';\r\nimport { getLoginConfig } from '../../config/app.config';\r\nimport { VERSION } from '../../version';\r\n\r\n@Component({\r\n selector: 'lib-login',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './login.component.html',\r\n styleUrls: ['./login.component.scss']\r\n})\r\nexport class LoginComponent implements OnInit, OnDestroy {\r\n /**\r\n * Configuration object to customize the login component appearance and behavior\r\n */\r\n @Input() config: Partial<LoginConfig> = {};\r\n\r\n isLoggingIn = false;\r\n statusMessage = '';\r\n private authSubscription?: Subscription;\r\n private isProcessingCallback = false;\r\n\r\n // Merged configuration with defaults - initialize with defaults immediately\r\n private _mergedConfig: LoginConfig;\r\n\r\n constructor(public authService: AuthService) {\r\n // Initialize with global config in constructor to avoid template errors\r\n try {\r\n this._mergedConfig = getLoginConfig();\r\n } catch {\r\n this._mergedConfig = { ...DEFAULT_LOGIN_CONFIG };\r\n }\r\n }\r\n\r\n ngOnInit() {\r\n // Get global config from library, then merge with component input\r\n try {\r\n const globalConfig = getLoginConfig();\r\n this._mergedConfig = {\r\n ...globalConfig,\r\n ...this.config,\r\n version: this.config?.version || globalConfig.version || VERSION\r\n };\r\n } catch {\r\n this._mergedConfig = {\r\n ...DEFAULT_LOGIN_CONFIG,\r\n ...this.config,\r\n version: this.config?.version || VERSION\r\n };\r\n }\r\n\r\n // Check if processing OAuth callback\r\n // Also check for 'iss' and 'session_state' which indicate we came from OAuth even if 'code' was already processed\r\n const urlParams = new URLSearchParams(globalThis.location?.search || '');\r\n const hasCode = urlParams.has('code');\r\n const hasIss = urlParams.has('iss');\r\n const hasSessionState = urlParams.has('session_state');\r\n const hasFragment = (globalThis.location?.hash || '').includes('access_token') || \r\n (globalThis.location?.hash || '').includes('code');\r\n \r\n if (hasCode || hasFragment || hasIss || hasSessionState) {\r\n this.isProcessingCallback = true;\r\n this.statusMessage = 'Procesando autenticación...';\r\n }\r\n\r\n // Subscribe to authentication state changes\r\n this.authSubscription = this.authService.isAuthenticated$.subscribe(isAuthenticated => {\r\n if (isAuthenticated) {\r\n this.statusMessage = '¡Autenticación exitosa! Redirigiendo...';\r\n // Small delay to show success message, then redirect\r\n setTimeout(() => {\r\n this.navigateToRedirect();\r\n }, 500);\r\n }\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n if (this.authSubscription) {\r\n this.authSubscription.unsubscribe();\r\n }\r\n }\r\n\r\n /**\r\n * Get merged configuration value\r\n */\r\n getConfig<K extends keyof LoginConfig>(key: K): LoginConfig[K] {\r\n return this._mergedConfig[key];\r\n }\r\n\r\n /**\r\n * Get custom CSS styles for theming\r\n */\r\n getCustomStyles(): { [key: string]: string } {\r\n const styles: { [key: string]: string } = {};\r\n \r\n if (this._mergedConfig.primaryColor) {\r\n styles['--color-primary'] = this._mergedConfig.primaryColor;\r\n }\r\n if (this._mergedConfig.backgroundColor) {\r\n styles['--login-bg-color'] = this._mergedConfig.backgroundColor;\r\n }\r\n if (this._mergedConfig.textColor) {\r\n styles['--login-text-color'] = this._mergedConfig.textColor;\r\n }\r\n \r\n return styles;\r\n }\r\n\r\n login(): void {\r\n this.isLoggingIn = true;\r\n this.statusMessage = 'Redirigiendo al proveedor de autenticación...';\r\n \r\n setTimeout(() => {\r\n this.authService.login();\r\n }, 500);\r\n }\r\n\r\n logout(): void {\r\n this.authService.logout();\r\n this.isLoggingIn = false;\r\n this.statusMessage = '';\r\n this.isProcessingCallback = false;\r\n }\r\n\r\n goToDashboard(): void {\r\n this.navigateToRedirect();\r\n }\r\n\r\n private navigateToRedirect(): void {\r\n const redirectUrl = this._mergedConfig.redirectUrl;\r\n if (typeof globalThis.location !== 'undefined') {\r\n const baseUrl = `${globalThis.location.protocol}//${globalThis.location.host}`;\r\n globalThis.location.href = `${baseUrl}${redirectUrl}`;\r\n }\r\n }\r\n}\r\n","<div class=\"login-page\" [ngStyle]=\"getCustomStyles()\">\r\n <div class=\"login-page__container\">\r\n <!-- Logo -->\r\n <div class=\"login-page__logo\">\r\n <img \r\n [src]=\"getConfig('logoUrl')\" \r\n [alt]=\"getConfig('logoAlt')\" \r\n class=\"login-page__logo-img\"\r\n [style.width]=\"getConfig('logoWidth')\"\r\n [style.height]=\"getConfig('logoHeight')\" />\r\n </div>\r\n\r\n <!-- Header -->\r\n <div class=\"login-page__header\">\r\n <h1>{{ getConfig('title') }}</h1>\r\n <p *ngIf=\"getConfig('subtitle')\" class=\"subtitle\">{{ getConfig('subtitle') }}</p>\r\n </div>\r\n \r\n <!-- Login Form -->\r\n <div *ngIf=\"(authService.isDoneLoading$ | async)\" class=\"login-page__form\">\r\n <div *ngIf=\"!(authService.isAuthenticated$ | async)\">\r\n <!-- Status Message -->\r\n <div *ngIf=\"statusMessage\" class=\"auth-alert auth-alert--info\">\r\n <div class=\"auth-alert__content\">\r\n <p>{{ statusMessage }}</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Login Button -->\r\n <button \r\n class=\"btn btn--primary btn--lg\" \r\n (click)=\"login()\" \r\n [disabled]=\"isLoggingIn\"\r\n [class.loading]=\"isLoggingIn\">\r\n {{ isLoggingIn ? 'Redirigiendo...' : getConfig('loginButtonText') }}\r\n </button>\r\n\r\n <!-- Footer -->\r\n <div class=\"login-page__footer\" *ngIf=\"getConfig('showFooter')\">\r\n <p *ngIf=\"getConfig('footerText'); else defaultFooter\">\r\n {{ getConfig('footerText') }}\r\n </p>\r\n <ng-template #defaultFooter>\r\n <p>\r\n Acceso seguro para usuarios de \r\n <strong>{{ getConfig('institutionName') }}</strong>\r\n </p>\r\n </ng-template>\r\n </div>\r\n </div>\r\n \r\n <!-- Already Authenticated -->\r\n <div *ngIf=\"authService.isAuthenticated$ | async\" class=\"auth-alert auth-alert--success\">\r\n <div class=\"auth-alert__content\">\r\n <h4>¡Sesión activa!</h4>\r\n <p>Ya tienes una sesión iniciada en el sistema.</p>\r\n </div>\r\n \r\n <div class=\"login-page__actions\">\r\n <button class=\"btn btn--primary btn--lg\" (click)=\"goToDashboard()\">\r\n {{ getConfig('dashboardButtonText') }}\r\n </button>\r\n \r\n <button \r\n *ngIf=\"getConfig('showLogoutButton')\"\r\n class=\"btn btn--secondary btn--lg\" \r\n (click)=\"logout()\">\r\n {{ getConfig('logoutButtonText') }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Loading State -->\r\n <div *ngIf=\"!(authService.isDoneLoading$ | async)\" class=\"auth-loading\">\r\n <div class=\"auth-loading__spinner\"></div>\r\n <p class=\"auth-loading__text\">Procesando autenticación...</p>\r\n </div>\r\n\r\n <!-- Version -->\r\n <div *ngIf=\"getConfig('showVersion')\" class=\"login-page__version\">\r\n <span>v{{ getConfig('version') }}</span>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, OnInit, HostListener, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { RouterModule } from '@angular/router';\r\nimport { AuthService } from '../../services/authentication.service';\r\nimport { AuthorizationService } from '../../services/authorization.service';\r\nimport { MenuHierarchyItem } from '../../models/authorization.interface';\r\nimport { DashboardConfig, DEFAULT_DASHBOARD_CONFIG } from '../../models/dashboard-config.interface';\r\nimport { getDashboardConfig } from '../../config/app.config';\r\nimport { VERSION } from '../../version';\r\n\r\n// Re-export for backwards compatibility\r\nexport { DashboardConfig } from '../../models/dashboard-config.interface';\r\n\r\n@Component({\r\n selector: 'lib-dashboard',\r\n standalone: true,\r\n imports: [CommonModule, RouterModule],\r\n templateUrl: './dashboard.component.html',\r\n styleUrls: ['./dashboard.component.scss']\r\n})\r\nexport class DashboardComponent implements OnInit {\r\n @Input() config: Partial<DashboardConfig> = {};\r\n\r\n userInfo: any = null;\r\n userRoles: string[] = [];\r\n menuHierarchy: MenuHierarchyItem[] = [];\r\n isMenuOpen = false;\r\n isLoadingMenu = false;\r\n openMenuItems: Set<string> = new Set();\r\n isUserPanelOpen = false;\r\n isMobileMenuOpen = false;\r\n\r\n private _mergedConfig: DashboardConfig;\r\n\r\n constructor(\r\n public authService: AuthService,\r\n private readonly authorizationService: AuthorizationService\r\n ) {\r\n // Initialize with global config in constructor to avoid template errors\r\n try {\r\n this._mergedConfig = getDashboardConfig();\r\n } catch {\r\n this._mergedConfig = { ...DEFAULT_DASHBOARD_CONFIG };\r\n }\r\n }\r\n\r\n ngOnInit(): void {\r\n // Get global config from library, then merge with component input\r\n try {\r\n const globalConfig = getDashboardConfig();\r\n this._mergedConfig = {\r\n ...globalConfig,\r\n ...this.config,\r\n version: this.config?.version || globalConfig.version || VERSION\r\n };\r\n } catch {\r\n this._mergedConfig = {\r\n ...DEFAULT_DASHBOARD_CONFIG,\r\n ...this.config,\r\n version: this.config?.version || VERSION\r\n };\r\n }\r\n this.loadUserInfo();\r\n this.loadMenuHierarchy();\r\n }\r\n\r\n getConfig<K extends keyof DashboardConfig>(key: K): DashboardConfig[K] {\r\n return this._mergedConfig[key];\r\n }\r\n\r\n get appVersion(): string {\r\n return this._mergedConfig.version;\r\n }\r\n\r\n private loadUserInfo(): void {\r\n this.userInfo = this.authService.identityClaims;\r\n this.userRoles = this.authService.getUserRoles();\r\n }\r\n\r\n private loadMenuHierarchy(): void {\r\n this.isLoadingMenu = true;\r\n this.authorizationService.getMenuHierarchy().subscribe({\r\n next: (menuItems) => {\r\n this.menuHierarchy = this.buildHierarchicalMenu(menuItems);\r\n this.isLoadingMenu = false;\r\n },\r\n error: (error) => {\r\n console.error('Error loading menu hierarchy:', error);\r\n this.menuHierarchy = [];\r\n this.isLoadingMenu = false;\r\n }\r\n });\r\n }\r\n\r\n private buildHierarchicalMenu(flatItems: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n const itemMap = new Map<string, MenuHierarchyItem>();\r\n \r\n flatItems.forEach(item => {\r\n itemMap.set(item.path, { ...item, children: [] });\r\n });\r\n\r\n const rootItems: MenuHierarchyItem[] = [];\r\n \r\n flatItems.forEach(item => {\r\n const currentItem = itemMap.get(item.path)!;\r\n \r\n if (item.level === 1) {\r\n rootItems.push(currentItem);\r\n } else {\r\n const parent = this.findParent(item, flatItems);\r\n if (parent) {\r\n const parentItem = itemMap.get(parent.path);\r\n if (parentItem?.children) {\r\n parentItem.children.push(currentItem);\r\n }\r\n }\r\n }\r\n });\r\n\r\n return rootItems;\r\n }\r\n\r\n private findParent(item: MenuHierarchyItem, allItems: MenuHierarchyItem[]): MenuHierarchyItem | null {\r\n for (const potentialParent of allItems) {\r\n if (potentialParent.level === item.level - 1 && \r\n item.path.startsWith(potentialParent.path) &&\r\n item.path !== potentialParent.path) {\r\n return potentialParent;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n toggleMenuItem(itemId: string, item: MenuHierarchyItem): void {\r\n const isCurrentlyOpen = this.openMenuItems.has(itemId);\r\n \r\n if (isCurrentlyOpen) {\r\n this.closeMenuAndChildren(itemId);\r\n } else {\r\n this.closeSiblingMenus(item);\r\n this.openMenuItems.add(itemId);\r\n }\r\n }\r\n\r\n private closeMenuAndChildren(itemId: string): void {\r\n this.openMenuItems.delete(itemId);\r\n const itemsToClose = Array.from(this.openMenuItems).filter(id => id.startsWith(itemId + '-'));\r\n itemsToClose.forEach(id => this.openMenuItems.delete(id));\r\n }\r\n\r\n private closeSiblingMenus(currentItem: MenuHierarchyItem): void {\r\n if (currentItem.level === 1) {\r\n const rootItems = this.getRootMenuItems();\r\n rootItems.forEach(rootItem => {\r\n if (rootItem.code !== currentItem.code) {\r\n this.closeMenuAndChildren(rootItem.code);\r\n }\r\n });\r\n } else {\r\n const allItems = this.flattenMenuItems(this.menuHierarchy);\r\n const parent = this.findParent(currentItem, allItems);\r\n if (parent?.children) {\r\n parent.children.forEach(sibling => {\r\n if (sibling.code !== currentItem.code) {\r\n this.closeMenuAndChildren(sibling.code);\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n private flattenMenuItems(items: MenuHierarchyItem[]): MenuHierarchyItem[] {\r\n const flattened: MenuHierarchyItem[] = [];\r\n \r\n const flatten = (itemList: MenuHierarchyItem[]) => {\r\n itemList.forEach(item => {\r\n flattened.push(item);\r\n if (item.children) {\r\n flatten(item.children);\r\n }\r\n });\r\n };\r\n \r\n flatten(items);\r\n return flattened;\r\n }\r\n\r\n onMenuItemClick(event: Event, item: MenuHierarchyItem): void {\r\n if (this.hasChildren(item)) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.toggleMenuItem(item.code, item);\r\n } else {\r\n // Close mobile menu when navigating to a page\r\n this.closeMobileMenu();\r\n }\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onDocumentClick(event: Event): void {\r\n const target = event.target as HTMLElement;\r\n const navElement = target.closest('.dashboard-nav');\r\n const userPanel = target.closest('.user-profile');\r\n \r\n if (!navElement) {\r\n this.openMenuItems.clear();\r\n }\r\n \r\n if (!userPanel) {\r\n this.isUserPanelOpen = false;\r\n }\r\n }\r\n\r\n toggleUserPanel(event: Event): void {\r\n event.stopPropagation();\r\n this.isUserPanelOpen = !this.isUserPanelOpen;\r\n }\r\n\r\n getUsername(): string {\r\n if (!this.userInfo?.preferred_username) return 'usuario';\r\n const username = this.userInfo.preferred_username;\r\n const atIndex = username.indexOf('@');\r\n return atIndex > 0 ? username.substring(0, atIndex) : username;\r\n }\r\n\r\n getUserFullName(): string {\r\n return this.userInfo?.name || 'Usuario';\r\n }\r\n\r\n getDocument(): string {\r\n return this.userInfo?.dui || 'N/A';\r\n }\r\n\r\n getInstitution(): string {\r\n return this.userInfo?.direccion || 'N/A';\r\n }\r\n\r\n getDependency(): string {\r\n return this.userInfo?.dependencia || 'N/A';\r\n }\r\n\r\n getRole(): string {\r\n return this.userInfo?.cargo || 'N/A';\r\n }\r\n\r\n isMenuItemOpen(itemId: string): boolean {\r\n return this.openMenuItems.has(itemId);\r\n }\r\n\r\n hasChildren(item: MenuHierarchyItem): boolean {\r\n return !!(item.children && item.children.length > 0);\r\n }\r\n\r\n getRootMenuItems(): MenuHierarchyItem[] {\r\n return this.menuHierarchy.filter(item => item.level === 1);\r\n }\r\n\r\n /**\r\n * Obtiene el icono para un item del menú.\r\n * Si el item tiene un icono definido, lo usa; de lo contrario, usa un icono por defecto según el nivel.\r\n */\r\n getMenuIcon(item: MenuHierarchyItem): string {\r\n // Si tiene icono definido, usarlo\r\n if (item.icono && item.icono.trim() !== '') {\r\n return item.icono;\r\n }\r\n \r\n // Iconos por defecto según el nivel\r\n if (item.level === 1) {\r\n return 'folder';\r\n } else if (item.level === 2) {\r\n return 'article';\r\n } else {\r\n return 'radio_button_unchecked';\r\n }\r\n }\r\n\r\n logoutAndRedirect(): void {\r\n this.authService.logoutAndRedirect();\r\n }\r\n\r\n getUserInitials(): string {\r\n if (!this.userInfo) return 'U';\r\n \r\n const name = this.userInfo.name || this.userInfo.preferred_username || 'Usuario';\r\n const words = name.split(' ');\r\n \r\n if (words.length >= 2) {\r\n return (words[0][0] + words[1][0]).toUpperCase();\r\n } else {\r\n return name.substring(0, 2).toUpperCase();\r\n }\r\n }\r\n\r\n toggleMobileMenu(): void {\r\n this.isMobileMenuOpen = !this.isMobileMenuOpen;\r\n }\r\n\r\n closeMobileMenu(): void {\r\n this.isMobileMenuOpen = false;\r\n document.body.style.overflow = '';\r\n }\r\n}\r\n","<div class=\"dashboard\">\r\n <!-- Header -->\r\n <header class=\"dashboard-header\">\r\n <!-- Mobile Header Top -->\r\n <div class=\"header-mobile-top\">\r\n <div class=\"ministry-logo-mobile\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n </div>\r\n <h1 class=\"mobile-title\">{{ getConfig('title') }}</h1>\r\n </div>\r\n\r\n <!-- Mobile Header Bottom -->\r\n <div class=\"header-mobile-bottom\">\r\n <button class=\"hamburger-btn\" \r\n (click)=\"toggleMobileMenu()\"\r\n [class.active]=\"isMobileMenuOpen\"\r\n aria-label=\"Toggle menu\">\r\n <span class=\"hamburger-line\"></span>\r\n <span class=\"hamburger-line\"></span>\r\n <span class=\"hamburger-line\"></span>\r\n </button>\r\n\r\n <div class=\"user-profile mobile-user\" *ngIf=\"userInfo\">\r\n <button class=\"user-info-trigger\" \r\n (click)=\"toggleUserPanel($event)\"\r\n [attr.aria-expanded]=\"isUserPanelOpen\"\r\n aria-label=\"Abrir menú de usuario\">\r\n <div class=\"user-avatar\">\r\n <span>{{ getUserInitials() }}</span>\r\n </div>\r\n <div class=\"user-details\">\r\n <span class=\"user-name\">{{ getUsername() }}</span>\r\n </div>\r\n <span class=\"material-symbols-outlined dropdown-icon\">\r\n {{ isUserPanelOpen ? 'expand_less' : 'expand_more' }}\r\n </span>\r\n </button>\r\n \r\n <!-- User Panel -->\r\n <ng-container *ngTemplateOutlet=\"userPanelTemplate\"></ng-container>\r\n </div>\r\n </div>\r\n\r\n <!-- Desktop Header -->\r\n <div class=\"header-desktop-layout\">\r\n <div class=\"header-left\">\r\n <div class=\"ministry-logo\">\r\n <div class=\"logo-icon\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n </div>\r\n <div class=\"ministry-info\">\r\n <h1>{{ getConfig('title') }}</h1>\r\n <span class=\"subtitle\" *ngIf=\"getConfig('subtitle')\">{{ getConfig('subtitle') }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <div class=\"header-right\">\r\n <div class=\"user-profile desktop-user\" *ngIf=\"userInfo\">\r\n <button class=\"user-info-trigger\" \r\n (click)=\"toggleUserPanel($event)\"\r\n [attr.aria-expanded]=\"isUserPanelOpen\"\r\n aria-label=\"Abrir menú de usuario\">\r\n <div class=\"user-avatar\">\r\n <span>{{ getUserInitials() }}</span>\r\n </div>\r\n <div class=\"user-details\">\r\n <span class=\"user-name\">{{ getUsername() }}</span>\r\n </div>\r\n <span class=\"material-symbols-outlined dropdown-icon\">\r\n {{ isUserPanelOpen ? 'expand_less' : 'expand_more' }}\r\n </span>\r\n </button>\r\n \r\n <!-- User Panel -->\r\n <ng-container *ngTemplateOutlet=\"userPanelTemplate\"></ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n </header>\r\n\r\n <!-- User Panel Template -->\r\n <ng-template #userPanelTemplate>\r\n <div class=\"user-panel\" *ngIf=\"isUserPanelOpen\">\r\n <div class=\"user-panel-header\">\r\n <span class=\"panel-title\">Perfil de Usuario</span>\r\n </div>\r\n <div class=\"user-panel-content\">\r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">person</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Código de Usuario:</span>\r\n <span class=\"info-value\">{{ getUsername() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">badge</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Nombre de Usuario:</span>\r\n <span class=\"info-value\">{{ getUserFullName() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item\">\r\n <span class=\"material-symbols-outlined info-icon\">credit_card</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Documento:</span>\r\n <span class=\"info-value\">{{ getDocument() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">business</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Institución:</span>\r\n <span class=\"info-value\">{{ getInstitution() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">apartment</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Dependencia:</span>\r\n <span class=\"info-value\">{{ getDependency() }}</span>\r\n </div>\r\n </div>\r\n \r\n <div class=\"user-info-item mobile-hidden\">\r\n <span class=\"material-symbols-outlined info-icon\">work</span>\r\n <div class=\"info-content\">\r\n <span class=\"info-label\">Rol:</span>\r\n <span class=\"info-value\">{{ getRole() }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"user-panel-footer\">\r\n <button class=\"logout-btn-panel\" (click)=\"logoutAndRedirect()\" title=\"Cerrar sesión\">\r\n <span class=\"material-symbols-outlined\">logout</span>\r\n <span class=\"logout-text\">CERRAR SESIÓN</span>\r\n </button>\r\n </div>\r\n </div>\r\n </ng-template>\r\n\r\n <!-- Mobile Menu Overlay -->\r\n <div class=\"nav-overlay\" *ngIf=\"isMobileMenuOpen\" (click)=\"closeMobileMenu()\"></div>\r\n\r\n <!-- Navigation (Horizontal Desktop / Sidebar Mobile) -->\r\n <nav class=\"dashboard-nav\" [class.mobile-open]=\"isMobileMenuOpen\">\r\n <div class=\"nav-mobile-header\">\r\n <div class=\"nav-mobile-logo\">\r\n <img [src]=\"getConfig('logoUrl')\" [alt]=\"getConfig('logoAlt')\" />\r\n <span class=\"nav-mobile-title\">Menú</span>\r\n </div>\r\n <button class=\"nav-close-btn\" (click)=\"closeMobileMenu()\" aria-label=\"Cerrar menú\">\r\n <span class=\"material-symbols-outlined\">close</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"nav-container\">\r\n <!-- Static Menu Items -->\r\n <ng-container *ngIf=\"getConfig('showStaticMenu')\">\r\n <a routerLink=\".\" \r\n routerLinkActive=\"active\" \r\n [routerLinkActiveOptions]=\"{exact: true}\" \r\n class=\"nav-item\"\r\n (click)=\"closeMobileMenu()\">\r\n <span class=\"material-symbols-outlined nav-icon\">home</span>\r\n <span class=\"nav-text\">Inicio</span>\r\n </a>\r\n </ng-container>\r\n\r\n <!-- Separator -->\r\n <div class=\"nav-separator\" *ngIf=\"!isLoadingMenu && menuHierarchy.length > 0\"></div>\r\n \r\n <!-- Dynamic Menu -->\r\n <div class=\"dynamic-menu\" *ngIf=\"!isLoadingMenu && menuHierarchy.length > 0\">\r\n <ng-container *ngFor=\"let rootItem of getRootMenuItems()\">\r\n <div class=\"menu-item-container\" [class.has-children]=\"hasChildren(rootItem)\">\r\n <a \r\n [routerLink]=\"hasChildren(rootItem) ? null : rootItem.path\" \r\n routerLinkActive=\"active\" \r\n class=\"nav-item root-item\"\r\n [class.expandable]=\"hasChildren(rootItem)\"\r\n (click)=\"onMenuItemClick($event, rootItem)\">\r\n <span class=\"material-symbols-outlined nav-icon\">{{ getMenuIcon(rootItem) }}</span>\r\n <span class=\"nav-text\">{{ rootItem.name }}</span>\r\n <span class=\"material-symbols-outlined expand-icon\" *ngIf=\"hasChildren(rootItem)\">\r\n {{ isMenuItemOpen(rootItem.code) ? 'expand_more' : 'chevron_right' }}\r\n </span>\r\n </a>\r\n \r\n <!-- Submenu -->\r\n <div class=\"submenu\" *ngIf=\"hasChildren(rootItem) && isMenuItemOpen(rootItem.code)\">\r\n <ng-container *ngTemplateOutlet=\"menuTemplate; context: { items: rootItem.children, level: 2 }\"></ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n \r\n <!-- Loading Indicator -->\r\n <div class=\"menu-loading\" *ngIf=\"isLoadingMenu\">\r\n <span class=\"material-symbols-outlined nav-icon\">hourglass_empty</span>\r\n <span class=\"nav-text\">Cargando menú...</span>\r\n </div>\r\n </div>\r\n </nav>\r\n\r\n <!-- Recursive Menu Template -->\r\n <ng-template #menuTemplate let-items=\"items\" let-level=\"level\">\r\n <ng-container *ngFor=\"let item of items\">\r\n <div class=\"menu-item-container\" [class.has-children]=\"hasChildren(item)\" [attr.data-level]=\"level\">\r\n <a \r\n [routerLink]=\"hasChildren(item) ? null : item.path\" \r\n routerLinkActive=\"active\" \r\n class=\"nav-item submenu-item\"\r\n [class.expandable]=\"hasChildren(item)\"\r\n (click)=\"onMenuItemClick($event, item)\">\r\n <span class=\"material-symbols-outlined nav-icon\">{{ getMenuIcon(item) }}</span>\r\n <span class=\"nav-text\">{{ item.name }}</span>\r\n <span class=\"material-symbols-outlined expand-icon\" *ngIf=\"hasChildren(item)\">\r\n {{ isMenuItemOpen(item.code) ? 'expand_more' : 'chevron_right' }}\r\n </span>\r\n </a>\r\n\r\n <!-- Recursive Submenu (max 5 levels) -->\r\n <div class=\"submenu\" *ngIf=\"hasChildren(item) && isMenuItemOpen(item.code) && level < 5\">\r\n <ng-container *ngTemplateOutlet=\"menuTemplate; context: { items: item.children, level: level + 1 }\"></ng-container>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </ng-template>\r\n\r\n <!-- Main Content -->\r\n <main class=\"dashboard-content\">\r\n <div class=\"content-wrapper\">\r\n <router-outlet></router-outlet>\r\n </div>\r\n </main>\r\n\r\n <!-- Footer -->\r\n <footer class=\"dashboard-footer\">\r\n <div class=\"footer-content\">\r\n <span class=\"footer-text\">\r\n {{ getConfig('footerText') }}\r\n <ng-container *ngIf=\"getConfig('showVersion')\">\r\n Versión {{ appVersion }}.\r\n </ng-container>\r\n Todos los derechos reservados.\r\n </span>\r\n </div>\r\n </footer>\r\n</div>\r\n","// ========================================\r\n// @dinafi/frmk - Public API\r\n// Angular Shared Library - Ministerio de Hacienda\r\n// ========================================\r\n\r\n// === VERSION ===\r\nexport { VERSION, VERSION_INFO } from './lib/version';\r\n\r\n// === MODELS / INTERFACES ===\r\nexport {\r\n // Login Configuration\r\n LoginConfig,\r\n DEFAULT_LOGIN_CONFIG,\r\n \r\n // Dashboard Configuration\r\n DashboardConfig,\r\n DEFAULT_DASHBOARD_CONFIG,\r\n \r\n // Application Configuration\r\n AppConfiguration,\r\n ConfigServerResponse,\r\n \r\n // Authorization\r\n AuthorizationRequest,\r\n AuthorizationResponse,\r\n MenuHierarchyItem,\r\n MenuHierarchyRequest,\r\n \r\n // Library Configuration (Injectable)\r\n FrmkLibraryConfig,\r\n DEFAULT_LIBRARY_CONFIG,\r\n FRMK_LIBRARY_CONFIG,\r\n provideFrmkConfig\r\n} from './lib/models';\r\n\r\n// === CONFIGURATION UTILITIES ===\r\nexport {\r\n // Library Configuration Initialization\r\n initializeLibraryConfig,\r\n getLibraryConfig,\r\n isLibraryConfigured,\r\n \r\n // Component Config Getters\r\n getLoginConfig,\r\n getDashboardConfig,\r\n \r\n // App Config Management\r\n getDefaultAppConfig,\r\n mapConfigServerResponse,\r\n setCurrentAppConfig,\r\n getCurrentAppConfig,\r\n getAppConfig,\r\n getAppConfigWithServerData,\r\n \r\n // OAuth2 Config\r\n getAuthConfig,\r\n getAuthConfigEnv\r\n} from './lib/config';\r\n\r\n// === SERVICES ===\r\nexport {\r\n // Authentication Service\r\n AuthService,\r\n \r\n // Authorization Service\r\n AuthorizationService,\r\n \r\n // Configuration Service\r\n ConfigService\r\n} from './lib/services';\r\n\r\n// === GUARDS ===\r\nexport { authGuard } from './lib/guards';\r\n\r\n// === COMPONENTS ===\r\nexport { \r\n LoginComponent \r\n} from './lib/components/login/login.component';\r\n\r\nexport { \r\n DashboardComponent\r\n} from './lib/components/dashboard/dashboard.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i2","i1","i2.AuthService","i3.ConfigService","i1.AuthService","i2.AuthorizationService"],"mappings":"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"}
|
package/index.d.ts
CHANGED
|
@@ -10,14 +10,14 @@ import { HttpClient } from '@angular/common/http';
|
|
|
10
10
|
* Versión actual de la librería @dinafi/frmk
|
|
11
11
|
* Sincronizada con package.json
|
|
12
12
|
*/
|
|
13
|
-
declare const VERSION = "1.0.
|
|
13
|
+
declare const VERSION = "1.0.32";
|
|
14
14
|
/**
|
|
15
15
|
* Información completa de la versión
|
|
16
16
|
*/
|
|
17
17
|
declare const VERSION_INFO: {
|
|
18
|
-
readonly version: "1.0.
|
|
18
|
+
readonly version: "1.0.32";
|
|
19
19
|
readonly name: "shared-lib-angular";
|
|
20
|
-
readonly buildDate: "2026-02-05T17:
|
|
20
|
+
readonly buildDate: "2026-02-05T17:56:18.182Z";
|
|
21
21
|
readonly angular: "^20.0.0";
|
|
22
22
|
};
|
|
23
23
|
|