From c47f624e4a958e42aa98e5287728f89593625e39 Mon Sep 17 00:00:00 2001 From: Soltectos Date: Thu, 14 May 2026 17:35:51 -0500 Subject: [PATCH 01/21] =?UTF-8?q?Refactorizaci=C3=B3n=20de=20seguridad=20y?= =?UTF-8?q?=20arquitectura=20-=20Versi=C3=B3n=200.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Cambios críticos de seguridad - Agregado .gitignore completo para .NET - Creado appsettings.Example.json como plantilla - Sanitizadas credenciales en appsettings.json - Corregido manejo de excepciones con logging apropiado - Cambiado DateTime.Now a DateTime.UtcNow para evitar problemas de zona horaria ## Mejoras de arquitectura - Reemplazado EnsureCreatedAsync() por MigrateAsync() en Program.cs - Movida lógica de negocio del método Fallar de controlador a servicio - Agregado método FallarHabito en IServicioHabitos y ServicioHabitos ## Mejoras de código - Creada clase ConstantesGamificacion para valores de XP - Extraída lógica de configuración de cookies a métodos helper - Reemplazados valores mágicos por constantes en sistema de gamificación - Eliminados archivos temporales (compare.py, diff.txt, run_output.txt) ## Documentación - Agregado CAMBIOS_REALIZADOS.md con resumen completo de cambios - Documentadas instrucciones de configuración post-cambios - Listadas próximas mejoras recomendadas 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/copilot-instructions.md | 4 + .gitignore | 421 + Ayudantes/.gitkeep | 0 Ayudantes/CalculadorXP.cs | 94 + Ayudantes/ConstantesGamificacion.cs | 33 + Ayudantes/GeneradorCodigo.cs | 22 + Ayudantes/RespuestaApi.cs | 30 + CAMBIOS_REALIZADOS.md | 157 + Controllers/AdminController.cs | 164 + Controllers/Api/.gitkeep | 0 Controllers/Api/ApiAuthController.cs | 65 + Controllers/Api/ApiDashboardController.cs | 64 + Controllers/Api/ApiEstadoAnimoController.cs | 65 + Controllers/Api/ApiGamificacionController.cs | 64 + Controllers/Api/ApiHabitosController.cs | 146 + Controllers/Api/ApiMisionesController.cs | 47 + Controllers/Api/ApiPomodoroController.cs | 107 + Controllers/Api/ApiProgresoController.cs | 54 + Controllers/AutenticacionController.cs | 136 + Controllers/HabitosController.cs | 269 + Controllers/HomeController.cs | 83 + Controllers/MisionesController.cs | 161 + Controllers/PomodoroController.cs | 90 + Controllers/ProgresoController.cs | 71 + DTOs/.gitkeep | 0 Datos/.gitkeep | 0 Datos/ContextoAplicacion.cs | 166 + Datos/Semilla/.gitkeep | 0 Datos/Semilla/DatosSemilla.cs | 350 + Documentacion/EPYCUS_WEB_Documento_Base.md | 1779 +++ .../EPYCUS_WEB_Especificacion_Tecnica.md | 1376 ++ EPYCUS WEB v0.1.csproj | 31 + EPYCUS WEB v0.1.slnx | 3 + Middleware/.gitkeep | 0 .../20260512134829_InitialMerge.Designer.cs | 1273 ++ Migrations/20260512134829_InitialMerge.cs | 980 ++ Migrations/ContextoAplicacionModelSnapshot.cs | 1270 ++ Modelos/Entidades/.gitkeep | 0 Modelos/Entidades/Carrera.cs | 12 + Modelos/Entidades/Categoria.cs | 13 + Modelos/Entidades/ConfiguracionPomodoro.cs | 15 + Modelos/Entidades/EstadoAnimo.cs | 13 + Modelos/Entidades/FraseMotivacional.cs | 10 + Modelos/Entidades/Habito.cs | 23 + Modelos/Entidades/ImagenNivelPersonaje.cs | 12 + Modelos/Entidades/Log.cs | 13 + Modelos/Entidades/Logro.cs | 14 + Modelos/Entidades/LogroUsuario.cs | 12 + Modelos/Entidades/Mision.cs | 22 + Modelos/Entidades/Nivel.cs | 12 + Modelos/Entidades/Personaje.cs | 14 + Modelos/Entidades/PersonajeUsuario.cs | 13 + Modelos/Entidades/ProgresoUsuario.cs | 18 + Modelos/Entidades/RecuperacionContrasena.cs | 13 + Modelos/Entidades/RegistroHabito.cs | 13 + Modelos/Entidades/Rol.cs | 8 + Modelos/Entidades/SesionPomodoro.cs | 18 + Modelos/Entidades/Suscripcion.cs | 16 + Modelos/Entidades/Tema.cs | 15 + Modelos/Entidades/TemaUsuario.cs | 12 + Modelos/Entidades/TipPomodoro.cs | 9 + Modelos/Entidades/TokenRefresh.cs | 13 + Modelos/Entidades/Usuario.cs | 37 + Modelos/Entidades/VerificacionCorreo.cs | 13 + Modelos/Enums/.gitkeep | 0 Modelos/Enums/CondicionLogro.cs | 12 + Modelos/Enums/EstadoAnimoEnum.cs | 11 + Modelos/Enums/EstadoMision.cs | 10 + Modelos/Enums/FrecuenciaHabito.cs | 9 + Modelos/Enums/PrioridadMision.cs | 9 + Models/ErrorViewModel.cs | 9 + Program.cs | 114 + Properties/launchSettings.json | 23 + Servicios/Implementaciones/.gitkeep | 0 Servicios/Implementaciones/ServicioAdmin.cs | 119 + .../Implementaciones/ServicioAutenticacion.cs | 348 + .../Implementaciones/ServicioBienestar.cs | 166 + Servicios/Implementaciones/ServicioCorreo.cs | 17 + .../Implementaciones/ServicioGamificacion.cs | 190 + Servicios/Implementaciones/ServicioHabitos.cs | 294 + .../Implementaciones/ServicioMisiones.cs | 128 + Servicios/Implementaciones/ServicioPerfil.cs | 29 + .../Implementaciones/ServicioPomodoro.cs | 145 + .../Implementaciones/ServicioProgreso.cs | 83 + Servicios/Interfaces/.gitkeep | 0 Servicios/Interfaces/AlertaBienestar.cs | 10 + Servicios/Interfaces/IServicioAdmin.cs | 15 + .../Interfaces/IServicioAutenticacion.cs | 15 + Servicios/Interfaces/IServicioBienestar.cs | 9 + Servicios/Interfaces/IServicioCorreo.cs | 8 + Servicios/Interfaces/IServicioGamificacion.cs | 10 + Servicios/Interfaces/IServicioHabitos.cs | 20 + Servicios/Interfaces/IServicioMisiones.cs | 16 + Servicios/Interfaces/IServicioPerfil.cs | 13 + Servicios/Interfaces/IServicioPomodoro.cs | 16 + Servicios/Interfaces/IServicioProgreso.cs | 14 + ViewModels/Admin/AdminDashboardViewModel.cs | 10 + ViewModels/Admin/AdminLoginViewModel.cs | 20 + ViewModels/Autenticacion/LoginViewModel.cs | 20 + ViewModels/CrearHabitoViewModel.cs | 36 + ViewModels/CrearMisionViewModel.cs | 27 + ViewModels/EditarHabitoViewModel.cs | 34 + ViewModels/EditarMisionViewModel.cs | 29 + ViewModels/HabitoViewModel.cs | 22 + ViewModels/HabitosDashboardViewModel.cs | 16 + ViewModels/HabitosIndexViewModel.cs | 10 + ViewModels/HomeDashboardViewModel.cs | 14 + ViewModels/PerfilViewModel.cs | 6 + ViewModels/PomodoroIndexViewModel.cs | 29 + ViewModels/ProgresoViewModel.cs | 16 + ViewModels/RegistroViewModel.cs | 39 + Views/Admin/DetalleUsuario.cshtml | 80 + Views/Admin/Frases.cshtml | 84 + Views/Admin/Index.cshtml | 67 + Views/Admin/Login.cshtml | 43 + Views/Admin/Usuarios.cshtml | 91 + Views/Autenticacion/Login.cshtml | 66 + Views/Autenticacion/Registro.cshtml | 88 + Views/Habitos/Crear.cshtml | 78 + Views/Habitos/Editar.cshtml | 85 + Views/Habitos/Index.cshtml | 482 + Views/Home/Index.cshtml | 254 + Views/Home/Privacy.cshtml | 14 + Views/Misiones/Crear.cshtml | 74 + Views/Misiones/Editar.cshtml | 75 + Views/Misiones/Index.cshtml | 92 + Views/Pomodoro/Configuracion.cshtml | 42 + Views/Pomodoro/Index.cshtml | 464 + Views/Progreso/Index.cshtml | 125 + Views/Shared/Error.cshtml | 22 + Views/Shared/_Layout.cshtml | 115 + Views/Shared/_Layout.cshtml.css | 48 + Views/Shared/_LayoutAdmin.cshtml | 61 + Views/Shared/_LayoutAuth.cshtml | 91 + Views/Shared/_ValidationScriptsPartial.cshtml | 2 + Views/_ViewImports.cshtml | 3 + Views/_ViewStart.cshtml | 3 + appsettings.Example.json | 27 + appsettings.json | 27 + wwwroot/css/site.css | 759 + wwwroot/css/temas/.gitkeep | 0 wwwroot/css/temas/tema-noche-epica.css | 37 + wwwroot/css/temas/tema-sakura.css | 37 + wwwroot/favicon.ico | Bin 0 -> 5430 bytes wwwroot/img/logros/.gitkeep | 0 .../img/personajes/generico/femenino/.gitkeep | 0 .../personajes/generico/masculino/.gitkeep | 0 .../personajes/ing-sistemas/femenino/.gitkeep | 0 .../ing-sistemas/masculino/.gitkeep | 0 wwwroot/js/.gitkeep | 0 wwwroot/js/site.js | 25 + wwwroot/lib/bootstrap/LICENSE | 22 + .../lib/bootstrap/dist/css/bootstrap-grid.css | 4085 ++++++ .../bootstrap/dist/css/bootstrap-grid.css.map | 1 + .../bootstrap/dist/css/bootstrap-grid.min.css | 6 + .../dist/css/bootstrap-grid.min.css.map | 1 + .../bootstrap/dist/css/bootstrap-grid.rtl.css | 4084 ++++++ .../dist/css/bootstrap-grid.rtl.css.map | 1 + .../dist/css/bootstrap-grid.rtl.min.css | 6 + .../dist/css/bootstrap-grid.rtl.min.css.map | 1 + .../bootstrap/dist/css/bootstrap-reboot.css | 597 + .../dist/css/bootstrap-reboot.css.map | 1 + .../dist/css/bootstrap-reboot.min.css | 6 + .../dist/css/bootstrap-reboot.min.css.map | 1 + .../dist/css/bootstrap-reboot.rtl.css | 594 + .../dist/css/bootstrap-reboot.rtl.css.map | 1 + .../dist/css/bootstrap-reboot.rtl.min.css | 6 + .../dist/css/bootstrap-reboot.rtl.min.css.map | 1 + .../dist/css/bootstrap-utilities.css | 5402 +++++++ .../dist/css/bootstrap-utilities.css.map | 1 + .../dist/css/bootstrap-utilities.min.css | 6 + .../dist/css/bootstrap-utilities.min.css.map | 1 + .../dist/css/bootstrap-utilities.rtl.css | 5393 +++++++ .../dist/css/bootstrap-utilities.rtl.css.map | 1 + .../dist/css/bootstrap-utilities.rtl.min.css | 6 + .../css/bootstrap-utilities.rtl.min.css.map | 1 + wwwroot/lib/bootstrap/dist/css/bootstrap.css | 12057 ++++++++++++++++ .../lib/bootstrap/dist/css/bootstrap.css.map | 1 + .../lib/bootstrap/dist/css/bootstrap.min.css | 6 + .../bootstrap/dist/css/bootstrap.min.css.map | 1 + .../lib/bootstrap/dist/css/bootstrap.rtl.css | 12030 +++++++++++++++ .../bootstrap/dist/css/bootstrap.rtl.css.map | 1 + .../bootstrap/dist/css/bootstrap.rtl.min.css | 6 + .../dist/css/bootstrap.rtl.min.css.map | 1 + .../lib/bootstrap/dist/js/bootstrap.bundle.js | 6314 ++++++++ .../bootstrap/dist/js/bootstrap.bundle.js.map | 1 + .../bootstrap/dist/js/bootstrap.bundle.min.js | 7 + .../dist/js/bootstrap.bundle.min.js.map | 1 + .../lib/bootstrap/dist/js/bootstrap.esm.js | 4447 ++++++ .../bootstrap/dist/js/bootstrap.esm.js.map | 1 + .../bootstrap/dist/js/bootstrap.esm.min.js | 7 + .../dist/js/bootstrap.esm.min.js.map | 1 + wwwroot/lib/bootstrap/dist/js/bootstrap.js | 4494 ++++++ .../lib/bootstrap/dist/js/bootstrap.js.map | 1 + .../lib/bootstrap/dist/js/bootstrap.min.js | 7 + .../bootstrap/dist/js/bootstrap.min.js.map | 1 + .../jquery-validation-unobtrusive/LICENSE.txt | 23 + .../dist/jquery.validate.unobtrusive.js | 435 + .../dist/jquery.validate.unobtrusive.min.js | 8 + wwwroot/lib/jquery-validation/LICENSE.md | 22 + .../dist/additional-methods.js | 1505 ++ .../dist/additional-methods.min.js | 4 + .../jquery-validation/dist/jquery.validate.js | 1703 +++ .../dist/jquery.validate.min.js | 4 + wwwroot/lib/jquery/LICENSE.txt | 21 + wwwroot/lib/jquery/dist/jquery.js | 10716 ++++++++++++++ wwwroot/lib/jquery/dist/jquery.min.js | 2 + wwwroot/lib/jquery/dist/jquery.min.map | 1 + wwwroot/lib/jquery/dist/jquery.slim.js | 8617 +++++++++++ wwwroot/lib/jquery/dist/jquery.slim.min.js | 2 + wwwroot/lib/jquery/dist/jquery.slim.min.map | 1 + 211 files changed, 98383 insertions(+) create mode 100644 .github/copilot-instructions.md create mode 100644 .gitignore create mode 100644 Ayudantes/.gitkeep create mode 100644 Ayudantes/CalculadorXP.cs create mode 100644 Ayudantes/ConstantesGamificacion.cs create mode 100644 Ayudantes/GeneradorCodigo.cs create mode 100644 Ayudantes/RespuestaApi.cs create mode 100644 CAMBIOS_REALIZADOS.md create mode 100644 Controllers/AdminController.cs create mode 100644 Controllers/Api/.gitkeep create mode 100644 Controllers/Api/ApiAuthController.cs create mode 100644 Controllers/Api/ApiDashboardController.cs create mode 100644 Controllers/Api/ApiEstadoAnimoController.cs create mode 100644 Controllers/Api/ApiGamificacionController.cs create mode 100644 Controllers/Api/ApiHabitosController.cs create mode 100644 Controllers/Api/ApiMisionesController.cs create mode 100644 Controllers/Api/ApiPomodoroController.cs create mode 100644 Controllers/Api/ApiProgresoController.cs create mode 100644 Controllers/AutenticacionController.cs create mode 100644 Controllers/HabitosController.cs create mode 100644 Controllers/HomeController.cs create mode 100644 Controllers/MisionesController.cs create mode 100644 Controllers/PomodoroController.cs create mode 100644 Controllers/ProgresoController.cs create mode 100644 DTOs/.gitkeep create mode 100644 Datos/.gitkeep create mode 100644 Datos/ContextoAplicacion.cs create mode 100644 Datos/Semilla/.gitkeep create mode 100644 Datos/Semilla/DatosSemilla.cs create mode 100644 Documentacion/EPYCUS_WEB_Documento_Base.md create mode 100644 Documentacion/EPYCUS_WEB_Especificacion_Tecnica.md create mode 100644 EPYCUS WEB v0.1.csproj create mode 100644 EPYCUS WEB v0.1.slnx create mode 100644 Middleware/.gitkeep create mode 100644 Migrations/20260512134829_InitialMerge.Designer.cs create mode 100644 Migrations/20260512134829_InitialMerge.cs create mode 100644 Migrations/ContextoAplicacionModelSnapshot.cs create mode 100644 Modelos/Entidades/.gitkeep create mode 100644 Modelos/Entidades/Carrera.cs create mode 100644 Modelos/Entidades/Categoria.cs create mode 100644 Modelos/Entidades/ConfiguracionPomodoro.cs create mode 100644 Modelos/Entidades/EstadoAnimo.cs create mode 100644 Modelos/Entidades/FraseMotivacional.cs create mode 100644 Modelos/Entidades/Habito.cs create mode 100644 Modelos/Entidades/ImagenNivelPersonaje.cs create mode 100644 Modelos/Entidades/Log.cs create mode 100644 Modelos/Entidades/Logro.cs create mode 100644 Modelos/Entidades/LogroUsuario.cs create mode 100644 Modelos/Entidades/Mision.cs create mode 100644 Modelos/Entidades/Nivel.cs create mode 100644 Modelos/Entidades/Personaje.cs create mode 100644 Modelos/Entidades/PersonajeUsuario.cs create mode 100644 Modelos/Entidades/ProgresoUsuario.cs create mode 100644 Modelos/Entidades/RecuperacionContrasena.cs create mode 100644 Modelos/Entidades/RegistroHabito.cs create mode 100644 Modelos/Entidades/Rol.cs create mode 100644 Modelos/Entidades/SesionPomodoro.cs create mode 100644 Modelos/Entidades/Suscripcion.cs create mode 100644 Modelos/Entidades/Tema.cs create mode 100644 Modelos/Entidades/TemaUsuario.cs create mode 100644 Modelos/Entidades/TipPomodoro.cs create mode 100644 Modelos/Entidades/TokenRefresh.cs create mode 100644 Modelos/Entidades/Usuario.cs create mode 100644 Modelos/Entidades/VerificacionCorreo.cs create mode 100644 Modelos/Enums/.gitkeep create mode 100644 Modelos/Enums/CondicionLogro.cs create mode 100644 Modelos/Enums/EstadoAnimoEnum.cs create mode 100644 Modelos/Enums/EstadoMision.cs create mode 100644 Modelos/Enums/FrecuenciaHabito.cs create mode 100644 Modelos/Enums/PrioridadMision.cs create mode 100644 Models/ErrorViewModel.cs create mode 100644 Program.cs create mode 100644 Properties/launchSettings.json create mode 100644 Servicios/Implementaciones/.gitkeep create mode 100644 Servicios/Implementaciones/ServicioAdmin.cs create mode 100644 Servicios/Implementaciones/ServicioAutenticacion.cs create mode 100644 Servicios/Implementaciones/ServicioBienestar.cs create mode 100644 Servicios/Implementaciones/ServicioCorreo.cs create mode 100644 Servicios/Implementaciones/ServicioGamificacion.cs create mode 100644 Servicios/Implementaciones/ServicioHabitos.cs create mode 100644 Servicios/Implementaciones/ServicioMisiones.cs create mode 100644 Servicios/Implementaciones/ServicioPerfil.cs create mode 100644 Servicios/Implementaciones/ServicioPomodoro.cs create mode 100644 Servicios/Implementaciones/ServicioProgreso.cs create mode 100644 Servicios/Interfaces/.gitkeep create mode 100644 Servicios/Interfaces/AlertaBienestar.cs create mode 100644 Servicios/Interfaces/IServicioAdmin.cs create mode 100644 Servicios/Interfaces/IServicioAutenticacion.cs create mode 100644 Servicios/Interfaces/IServicioBienestar.cs create mode 100644 Servicios/Interfaces/IServicioCorreo.cs create mode 100644 Servicios/Interfaces/IServicioGamificacion.cs create mode 100644 Servicios/Interfaces/IServicioHabitos.cs create mode 100644 Servicios/Interfaces/IServicioMisiones.cs create mode 100644 Servicios/Interfaces/IServicioPerfil.cs create mode 100644 Servicios/Interfaces/IServicioPomodoro.cs create mode 100644 Servicios/Interfaces/IServicioProgreso.cs create mode 100644 ViewModels/Admin/AdminDashboardViewModel.cs create mode 100644 ViewModels/Admin/AdminLoginViewModel.cs create mode 100644 ViewModels/Autenticacion/LoginViewModel.cs create mode 100644 ViewModels/CrearHabitoViewModel.cs create mode 100644 ViewModels/CrearMisionViewModel.cs create mode 100644 ViewModels/EditarHabitoViewModel.cs create mode 100644 ViewModels/EditarMisionViewModel.cs create mode 100644 ViewModels/HabitoViewModel.cs create mode 100644 ViewModels/HabitosDashboardViewModel.cs create mode 100644 ViewModels/HabitosIndexViewModel.cs create mode 100644 ViewModels/HomeDashboardViewModel.cs create mode 100644 ViewModels/PerfilViewModel.cs create mode 100644 ViewModels/PomodoroIndexViewModel.cs create mode 100644 ViewModels/ProgresoViewModel.cs create mode 100644 ViewModels/RegistroViewModel.cs create mode 100644 Views/Admin/DetalleUsuario.cshtml create mode 100644 Views/Admin/Frases.cshtml create mode 100644 Views/Admin/Index.cshtml create mode 100644 Views/Admin/Login.cshtml create mode 100644 Views/Admin/Usuarios.cshtml create mode 100644 Views/Autenticacion/Login.cshtml create mode 100644 Views/Autenticacion/Registro.cshtml create mode 100644 Views/Habitos/Crear.cshtml create mode 100644 Views/Habitos/Editar.cshtml create mode 100644 Views/Habitos/Index.cshtml create mode 100644 Views/Home/Index.cshtml create mode 100644 Views/Home/Privacy.cshtml create mode 100644 Views/Misiones/Crear.cshtml create mode 100644 Views/Misiones/Editar.cshtml create mode 100644 Views/Misiones/Index.cshtml create mode 100644 Views/Pomodoro/Configuracion.cshtml create mode 100644 Views/Pomodoro/Index.cshtml create mode 100644 Views/Progreso/Index.cshtml create mode 100644 Views/Shared/Error.cshtml create mode 100644 Views/Shared/_Layout.cshtml create mode 100644 Views/Shared/_Layout.cshtml.css create mode 100644 Views/Shared/_LayoutAdmin.cshtml create mode 100644 Views/Shared/_LayoutAuth.cshtml create mode 100644 Views/Shared/_ValidationScriptsPartial.cshtml create mode 100644 Views/_ViewImports.cshtml create mode 100644 Views/_ViewStart.cshtml create mode 100644 appsettings.Example.json create mode 100644 appsettings.json create mode 100644 wwwroot/css/site.css create mode 100644 wwwroot/css/temas/.gitkeep create mode 100644 wwwroot/css/temas/tema-noche-epica.css create mode 100644 wwwroot/css/temas/tema-sakura.css create mode 100644 wwwroot/favicon.ico create mode 100644 wwwroot/img/logros/.gitkeep create mode 100644 wwwroot/img/personajes/generico/femenino/.gitkeep create mode 100644 wwwroot/img/personajes/generico/masculino/.gitkeep create mode 100644 wwwroot/img/personajes/ing-sistemas/femenino/.gitkeep create mode 100644 wwwroot/img/personajes/ing-sistemas/masculino/.gitkeep create mode 100644 wwwroot/js/.gitkeep create mode 100644 wwwroot/js/site.js create mode 100644 wwwroot/lib/bootstrap/LICENSE create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap.min.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css create mode 100644 wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.js create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.js.map create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.min.js create mode 100644 wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map create mode 100644 wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt create mode 100644 wwwroot/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.js create mode 100644 wwwroot/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js create mode 100644 wwwroot/lib/jquery-validation/LICENSE.md create mode 100644 wwwroot/lib/jquery-validation/dist/additional-methods.js create mode 100644 wwwroot/lib/jquery-validation/dist/additional-methods.min.js create mode 100644 wwwroot/lib/jquery-validation/dist/jquery.validate.js create mode 100644 wwwroot/lib/jquery-validation/dist/jquery.validate.min.js create mode 100644 wwwroot/lib/jquery/LICENSE.txt create mode 100644 wwwroot/lib/jquery/dist/jquery.js create mode 100644 wwwroot/lib/jquery/dist/jquery.min.js create mode 100644 wwwroot/lib/jquery/dist/jquery.min.map create mode 100644 wwwroot/lib/jquery/dist/jquery.slim.js create mode 100644 wwwroot/lib/jquery/dist/jquery.slim.min.js create mode 100644 wwwroot/lib/jquery/dist/jquery.slim.min.map diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..e1f6f74 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,4 @@ +# Copilot Instructions + +## Directrices del proyecto +- El proyecto EPYCUS WEB debe usar nombres de clases, variables, métodos y comentarios en español. \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7dba8dd --- /dev/null +++ b/.gitignore @@ -0,0 +1,421 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these files are unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +.idea/ + +# User secrets (sensitive configuration) +appsettings.Development.json +secrets.json + +# Temporary files +*.tmp +compare.py +diff.txt +run_output.txt + +# Database files +*.db +*.db-shm +*.db-wal +*.sqlite +*.sqlite3 + +# Environment files +.env +.env.local +.env.production diff --git a/Ayudantes/.gitkeep b/Ayudantes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Ayudantes/CalculadorXP.cs b/Ayudantes/CalculadorXP.cs new file mode 100644 index 0000000..f264dcd --- /dev/null +++ b/Ayudantes/CalculadorXP.cs @@ -0,0 +1,94 @@ +namespace EPYCUS_WEB_v0._1.Ayudantes +{ + public static class CalculadorXP + { + public const int XP_LOGIN_DIARIO = 10; + public const int XP_HABITO_COMPLETADO = 20; + public const int XP_BONUS_RACHA_7_DIAS = 10; + public const int XP_MISION_BAJA = 30; + public const int XP_MISION_MEDIA = 50; + public const int XP_MISION_ALTA = 80; + public const int XP_POMODORO_POR_CICLO = 15; + public const int XP_BONUS_RACHA_GLOBAL_7 = 50; + public const int XP_BONUS_RACHA_GLOBAL_30 = 200; + public const int NIVEL_MAXIMO = 20; + + public static int XpParaSiguienteNivel(int nivelActual) + { + return 100 + (nivelActual * 50); + } + + public static int XpTotalParaNivel(int nivel) + { + if (nivel <= 1) + { + return 0; + } + + var acumulado = 0; + + for (var i = 1; i < nivel; i++) + { + acumulado += XpParaSiguienteNivel(i); + } + + return acumulado; + } + + public static int NivelParaXp(int xpTotal) + { + for (var nivel = 1; nivel < NIVEL_MAXIMO; nivel++) + { + var xpSiguiente = XpTotalParaNivel(nivel + 1); + + if (xpTotal < xpSiguiente) + { + return nivel; + } + } + + return NIVEL_MAXIMO; + } + + public static int XpDentroDelNivelActual(int xpTotal, int nivelActual) + { + return xpTotal - XpTotalParaNivel(nivelActual); + } + + public static decimal PorcentajeProgreso(int xpTotal, int nivelActual) + { + var xpNivelActual = XpDentroDelNivelActual(xpTotal, nivelActual); + var xpSiguiente = XpParaSiguienteNivel(nivelActual); + + if (xpSiguiente <= 0) + { + return 0; + } + + var porcentaje = (decimal)xpNivelActual / xpSiguiente * 100m; + + if (porcentaje < 0) + { + return 0; + } + + if (porcentaje > 100) + { + return 100; + } + + return porcentaje; + } + + public static int XpPorMision(string prioridad) + { + return prioridad switch + { + "Alta" => XP_MISION_ALTA, + "Media" => XP_MISION_MEDIA, + "Baja" => XP_MISION_BAJA, + _ => XP_MISION_MEDIA + }; + } + } +} diff --git a/Ayudantes/ConstantesGamificacion.cs b/Ayudantes/ConstantesGamificacion.cs new file mode 100644 index 0000000..818f9a1 --- /dev/null +++ b/Ayudantes/ConstantesGamificacion.cs @@ -0,0 +1,33 @@ +namespace EPYCUS_WEB_v0._1.Ayudantes +{ + /// + /// Constantes para el sistema de gamificación + /// + public static class ConstantesGamificacion + { + /// + /// Experiencia base otorgada al completar un hábito + /// + public const int XP_BASE_HABITO = 20; + + /// + /// Bonus de experiencia por racha de 7 días + /// + public const int XP_BONUS_RACHA_SEMANAL = 10; + + /// + /// Días necesarios para obtener bonus de racha + /// + public const int DIAS_RACHA_BONUS = 7; + + /// + /// Experiencia base otorgada al completar una misión + /// + public const int XP_BASE_MISION = 50; + + /// + /// Experiencia otorgada por completar una sesión Pomodoro + /// + public const int XP_BASE_POMODORO = 15; + } +} diff --git a/Ayudantes/GeneradorCodigo.cs b/Ayudantes/GeneradorCodigo.cs new file mode 100644 index 0000000..100f2f7 --- /dev/null +++ b/Ayudantes/GeneradorCodigo.cs @@ -0,0 +1,22 @@ +using System.Text; + +namespace EPYCUS_WEB_v0._1.Ayudantes +{ + public static class GeneradorCodigo + { + private const string Caracteres = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; + + public static string GenerarCodigoUsuario() + { + var resultado = new StringBuilder(8); + + for (var i = 0; i < 8; i++) + { + var indice = Random.Shared.Next(Caracteres.Length); + resultado.Append(Caracteres[indice]); + } + + return $"EPY-{resultado}"; + } + } +} diff --git a/Ayudantes/RespuestaApi.cs b/Ayudantes/RespuestaApi.cs new file mode 100644 index 0000000..33515b8 --- /dev/null +++ b/Ayudantes/RespuestaApi.cs @@ -0,0 +1,30 @@ +namespace EPYCUS_WEB_v0._1.Ayudantes +{ + public class RespuestaApi + { + public bool Exito { get; set; } + public string? Mensaje { get; set; } + public T? Datos { get; set; } + public List? Errores { get; set; } + + public static RespuestaApi Exitosa(T datos, string? mensaje = null) + { + return new RespuestaApi + { + Exito = true, + Datos = datos, + Mensaje = mensaje + }; + } + + public static RespuestaApi Fallida(string mensaje, List? errores = null) + { + return new RespuestaApi + { + Exito = false, + Mensaje = mensaje, + Errores = errores + }; + } + } +} diff --git a/CAMBIOS_REALIZADOS.md b/CAMBIOS_REALIZADOS.md new file mode 100644 index 0000000..ef3aec8 --- /dev/null +++ b/CAMBIOS_REALIZADOS.md @@ -0,0 +1,157 @@ +# Cambios Realizados - EPYCUS WEB v0.1 + +Este documento detalla las correcciones y mejoras implementadas en el proyecto. + +## ✅ Problemas Críticos Resueltos + +### 1. Seguridad +- ✅ **Creado `.gitignore`** completo para proyectos .NET +- ✅ **Creado `appsettings.Example.json`** con placeholders para credenciales +- ✅ **Limpiadas credenciales** de `appsettings.json` (reemplazadas con placeholders) +- ✅ **Corregido manejo de excepciones** en `ServicioHabitos.cs` (catch con logging) +- ✅ **Cambiado `DateTime.Now` a `DateTime.UtcNow`** en entidad Usuario + +### 2. Arquitectura +- ✅ **Reemplazado `EnsureCreatedAsync()` por `MigrateAsync()`** en Program.cs +- ✅ **Movida lógica de negocio** del método `Fallar` del controlador API al servicio +- ✅ **Creada clase `ConstantesGamificacion`** para valores de XP y gamificación + +### 3. Código +- ✅ **Extraída lógica de cookies** a métodos helper en `AutenticacionController` +- ✅ **Eliminados archivos temporales** (compare.py, diff.txt, run_output.txt) +- ✅ **Reemplazados valores mágicos** por constantes en sistema de gamificación + +--- + +## 📝 Instrucciones Post-Cambios + +### Configurar Credenciales + +Antes de ejecutar el proyecto, debes configurar tus credenciales: + +1. Copia `appsettings.Example.json` y renómbralo a `appsettings.Development.json` (este archivo está en .gitignore) +2. Edita `appsettings.Development.json` con tus credenciales reales: + +```json +{ + "ConnectionStrings": { + "ConexionPrincipal": "Server=localhost;Port=3306;Database=epycus_db;User=root;Password=TU_PASSWORD_AQUI;" + }, + "Jwt": { + "Clave": "TU_CLAVE_SECRETA_DE_AL_MENOS_32_CARACTERES_AQUI!", + "Emisor": "EpycusWeb", + "Audiencia": "EpycusUsuarios", + "ExpiracionMinutos": 60, + "ExpiracionRefreshDias": 7 + }, + "Google": { + "ClientId": "TU_GOOGLE_CLIENT_ID.apps.googleusercontent.com", + "ClientSecret": "TU_GOOGLE_CLIENT_SECRET" + }, + "Correo": { + "Servidor": "smtp.gmail.com", + "Puerto": 587, + "Usuario": "tu-email@gmail.com", + "Contrasena": "TU_APP_PASSWORD_DE_GMAIL", + "NombreRemitente": "Epycus App" + }, + "App": { + "UrlBase": "https://localhost:7000", + "Version": "1.0.0" + } +} +``` + +### Aplicar Migraciones + +Como se cambió de `EnsureCreatedAsync()` a `MigrateAsync()`, necesitas ejecutar: + +```bash +dotnet ef migrations add InitialMigration +dotnet ef database update +``` + +--- + +## 🔄 Próximas Mejoras Recomendadas + +### Prioridad Media + +1. **Eliminar acceso directo a DbContext en controladores** + - Actualmente: `HomeController`, `AutenticacionController` y `ApiHabitosController` acceden directamente al DbContext + - Solución: Mover toda la lógica a servicios + +2. **Implementar DTOs para APIs** + - Crear clases DTO en lugar de tipos anónimos + - Ubicación sugerida: `/DTOs/Respuestas/` + +3. **Estandarizar nombres de carpetas** + - Decidir entre español o inglés (recomendado: inglés) + - Renombrar: `Ayudantes` → `Helpers`, `Datos` → `Data`, `Modelos` → `Models`, `Servicios` → `Services` + +4. **Extraer JavaScript inline a archivos separados** + - Mover JS de `_Layout.cshtml` y vistas a archivos `.js` + - Ubicación: `/wwwroot/js/` + +5. **Decidir sobre AutoMapper** + - Opción A: Implementar perfiles de mapeo y descomentar configuración en Program.cs + - Opción B: Desinstalar el paquete si no se va a usar + +### Prioridad Baja + +6. **Mejorar accesibilidad** + - Agregar atributos ARIA + - Mejorar navegación por teclado + +7. **Implementar sistema de notificaciones** + - Reemplazar `alert()` con toasts/notificaciones modernas + +8. **Descargar dependencias CDN localmente** + - Bootstrap, Bootstrap Icons, Chart.js + - O usar npm/webpack para gestionar dependencias + +9. **Agregar comentarios XML** + - Documentar interfaces públicas y métodos complejos + +10. **Implementar logging apropiado** + - Reemplazar `Debug.WriteLine` con ILogger + - Configurar diferentes niveles de log + +--- + +## 📊 Resumen de Archivos Modificados + +### Archivos Creados +- `.gitignore` +- `appsettings.Example.json` +- `Ayudantes/ConstantesGamificacion.cs` +- `CAMBIOS_REALIZADOS.md` (este archivo) + +### Archivos Modificados +- `appsettings.json` (credenciales sanitizadas) +- `Program.cs` (MigrateAsync) +- `Modelos/Entidades/Usuario.cs` (DateTime.UtcNow) +- `Servicios/Implementaciones/ServicioHabitos.cs` (excepciones, constantes, método FallarHabito) +- `Servicios/Interfaces/IServicioHabitos.cs` (método FallarHabito) +- `Controllers/AutenticacionController.cs` (métodos helper para cookies) +- `Controllers/Api/ApiHabitosController.cs` (uso de servicio y constantes) + +### Archivos Eliminados +- `compare.py` +- `diff.txt` +- `run_output.txt` + +--- + +## ⚠️ Notas Importantes + +1. **No commitees `appsettings.Development.json`** - está en .gitignore por seguridad +2. **Genera una clave JWT segura** - usa al menos 32 caracteres aleatorios +3. **Configura Google OAuth** si vas a usar login con Google +4. **Configura App Password de Gmail** si vas a usar el servicio de correo + +--- + +## 🚀 Siguiente Paso Sugerido + +Priorizar la eliminación del acceso directo a DbContext en los controladores, moviendo toda la lógica a servicios. Esto mejorará significativamente la arquitectura y facilitará el testing. diff --git a/Controllers/AdminController.cs b/Controllers/AdminController.cs new file mode 100644 index 0000000..19dfa0b --- /dev/null +++ b/Controllers/AdminController.cs @@ -0,0 +1,164 @@ +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.ViewModels.Admin; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace EPYCUS_WEB_v0._1.Controllers +{ + public class AdminController : Controller + { + private readonly IServicioAdmin _servicioAdmin; + private readonly IServicioAutenticacion _servicioAutenticacion; + + public AdminController(IServicioAdmin servicioAdmin, IServicioAutenticacion servicioAutenticacion) + { + _servicioAdmin = servicioAdmin; + _servicioAutenticacion = servicioAutenticacion; + } + + [AllowAnonymous] + [HttpGet("/admin/login")] + public IActionResult Login() + { + if (User.Identity != null && User.Identity.IsAuthenticated && User.IsInRole("Administrador")) + { + return RedirectToAction(nameof(Index)); + } + + return View(); + } + + [AllowAnonymous] + [HttpPost("/admin/login")] + [ValidateAntiForgeryToken] + public async Task Login(AdminLoginViewModel modelo) + { + if (!ModelState.IsValid) + { + return View(modelo); + } + + var (exito, mensaje, token, _) = await _servicioAutenticacion.Login(modelo.CorreoElectronico, modelo.Contrasena); + + if (!exito || string.IsNullOrWhiteSpace(token)) + { + ModelState.AddModelError(string.Empty, mensaje); + return View(modelo); + } + + var cookieOptions = new CookieOptions + { + HttpOnly = true, + Secure = true, + SameSite = SameSiteMode.Strict, + Expires = DateTime.UtcNow.AddHours(2) + }; + + if (modelo.Recordarme) + { + cookieOptions.Expires = DateTime.UtcNow.AddDays(3); + } + + Response.Cookies.Append("admin_jwt_token", token, cookieOptions); + + return RedirectToAction(nameof(Index)); + } + + [Authorize(Roles = "Administrador")] + [HttpPost("/admin/logout")] + [ValidateAntiForgeryToken] + public IActionResult Logout() + { + Response.Cookies.Delete("admin_jwt_token"); + return RedirectToAction(nameof(Login)); + } + + [Authorize(Roles = "Administrador")] + public async Task Index() + { + var usuarios = await _servicioAdmin.ObtenerTodosUsuarios(); + var frases = await _servicioAdmin.ObtenerFrases(); + + var suscripcionesActivas = usuarios + .SelectMany(u => u.Suscripciones) + .Count(s => s.EstaActiva); + + var modelo = new AdminDashboardViewModel + { + TotalUsuarios = usuarios.Count, + UsuariosActivos = usuarios.Count(u => u.EstaActivo), + SuscripcionesActivas = suscripcionesActivas, + TotalFrases = frases.Count + }; + + return View(modelo); + } + + [Authorize(Roles = "Administrador")] + public async Task Usuarios() + { + var usuarios = await _servicioAdmin.ObtenerTodosUsuarios(); + return View(usuarios); + } + + [Authorize(Roles = "Administrador")] + public async Task DetalleUsuario(int id) + { + var usuario = await _servicioAdmin.ObtenerUsuarioPorId(id); + if (usuario == null) + { + return NotFound(); + } + + return View(usuario); + } + + [Authorize(Roles = "Administrador")] + [HttpPost] + [ValidateAntiForgeryToken] + public async Task ActivarSuscripcion(int usuarioId) + { + var adminId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + await _servicioAdmin.ActivarSuscripcion(usuarioId, adminId); + TempData["Exito"] = "Suscripción activada correctamente."; + return RedirectToAction(nameof(Usuarios)); + } + + [Authorize(Roles = "Administrador")] + [HttpPost] + [ValidateAntiForgeryToken] + public async Task DesactivarSuscripcion(int usuarioId) + { + await _servicioAdmin.DesactivarSuscripcion(usuarioId); + TempData["Exito"] = "Suscripción desactivada correctamente."; + return RedirectToAction(nameof(Usuarios)); + } + + [Authorize(Roles = "Administrador")] + public async Task Frases() + { + var frases = await _servicioAdmin.ObtenerFrases(); + return View(frases); + } + + [Authorize(Roles = "Administrador")] + [HttpPost] + [ValidateAntiForgeryToken] + public async Task CrearFrase(string frase, string autor) + { + await _servicioAdmin.CrearFrase(frase, autor); + TempData["Exito"] = "Frase creada correctamente."; + return RedirectToAction(nameof(Frases)); + } + + [Authorize(Roles = "Administrador")] + [HttpPost] + [ValidateAntiForgeryToken] + public async Task EliminarFrase(int id) + { + await _servicioAdmin.EliminarFrase(id); + TempData["Exito"] = "Frase eliminada correctamente."; + return RedirectToAction(nameof(Frases)); + } + } +} diff --git a/Controllers/Api/.gitkeep b/Controllers/Api/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Controllers/Api/ApiAuthController.cs b/Controllers/Api/ApiAuthController.cs new file mode 100644 index 0000000..2118c88 --- /dev/null +++ b/Controllers/Api/ApiAuthController.cs @@ -0,0 +1,65 @@ +using EPYCUS_WEB_v0._1.Ayudantes; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace EPYCUS_WEB_v0._1.Controllers.Api +{ + [ApiController] + [Route("api/auth")] + public class ApiAuthController : ControllerBase + { + private readonly IServicioAutenticacion _servicioAutenticacion; + + public ApiAuthController(IServicioAutenticacion servicioAutenticacion) + { + _servicioAutenticacion = servicioAutenticacion; + } + + [HttpPost("login")] + [AllowAnonymous] + public async Task Login([FromBody] LoginDto request) + { + var (exito, mensaje, token, refreshToken) = await _servicioAutenticacion.Login(request.Correo, request.Contrasena); + if (!exito || token == null || refreshToken == null) + { + return BadRequest(RespuestaApi.Fallida(mensaje)); + } + + return Ok(RespuestaApi.Exitosa(new { token, refreshToken })); + } + + [HttpPost("refresh")] + [AllowAnonymous] + public async Task Refresh([FromBody] RefreshDto request) + { + var (exito, mensaje, token, refreshToken) = await _servicioAutenticacion.RenovarToken(request.RefreshToken); + if (!exito || token == null || refreshToken == null) + { + return BadRequest(RespuestaApi.Fallida(mensaje)); + } + + return Ok(RespuestaApi.Exitosa(new { token, refreshToken })); + } + + [HttpPost("logout")] + [Authorize] + public async Task Logout() + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + await _servicioAutenticacion.CerrarSesion(usuarioId); + return Ok(RespuestaApi.Exitosa(new { success = true })); + } + + public class LoginDto + { + public string Correo { get; set; } = string.Empty; + public string Contrasena { get; set; } = string.Empty; + } + + public class RefreshDto + { + public string RefreshToken { get; set; } = string.Empty; + } + } +} diff --git a/Controllers/Api/ApiDashboardController.cs b/Controllers/Api/ApiDashboardController.cs new file mode 100644 index 0000000..7975093 --- /dev/null +++ b/Controllers/Api/ApiDashboardController.cs @@ -0,0 +1,64 @@ +using EPYCUS_WEB_v0._1.Ayudantes; +using EPYCUS_WEB_v0._1.Datos; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace EPYCUS_WEB_v0._1.Controllers.Api +{ + [ApiController] + [Route("api/dashboard")] + [Authorize] + public class ApiDashboardController : ControllerBase + { + private readonly ContextoAplicacion _contexto; + + public ApiDashboardController(ContextoAplicacion contexto) + { + _contexto = contexto; + } + + [HttpGet("resumen")] + public async Task Resumen() + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + var hoy = DateOnly.FromDateTime(DateTime.Today); + + var habitosPendientes = await _contexto.Habitos + .Include(h => h.Registros) + .Where(h => h.UsuarioId == usuarioId && h.EstaActivo) + .CountAsync(h => !h.Registros.Any(r => r.Fecha == hoy && r.Estado == "Completado")); + + var misionesPendientes = await _contexto.Misiones + .CountAsync(m => m.UsuarioId == usuarioId && (m.Estado == "Pendiente" || m.Estado == "EnProgreso")); + + var frase = await _contexto.FrasesMotivacionales + .Where(f => f.EstaActiva) + .OrderBy(f => Guid.NewGuid()) + .Select(f => new { frase = f.Frase, autor = f.Autor }) + .FirstOrDefaultAsync(); + + var respuesta = new + { + kpis = new { habitosPendientes, misionesPendientes }, + habitosPendientes, + misionesPendientes, + frase + }; + + return Ok(RespuestaApi.Exitosa(respuesta)); + } + + [HttpGet("frase-del-dia")] + public async Task FraseDelDia() + { + var frase = await _contexto.FrasesMotivacionales + .Where(f => f.EstaActiva) + .OrderBy(f => Guid.NewGuid()) + .Select(f => new { frase = f.Frase, autor = f.Autor }) + .FirstOrDefaultAsync(); + + return Ok(RespuestaApi.Exitosa(frase)); + } + } +} diff --git a/Controllers/Api/ApiEstadoAnimoController.cs b/Controllers/Api/ApiEstadoAnimoController.cs new file mode 100644 index 0000000..34ad39a --- /dev/null +++ b/Controllers/Api/ApiEstadoAnimoController.cs @@ -0,0 +1,65 @@ +using EPYCUS_WEB_v0._1.Ayudantes; +using EPYCUS_WEB_v0._1.Datos; +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace EPYCUS_WEB_v0._1.Controllers.Api +{ + [ApiController] + [Route("api/estado-animo")] + [Authorize] + public class ApiEstadoAnimoController : ControllerBase + { + private readonly ContextoAplicacion _contexto; + private readonly IServicioBienestar _servicioBienestar; + + public ApiEstadoAnimoController(ContextoAplicacion contexto, IServicioBienestar servicioBienestar) + { + _contexto = contexto; + _servicioBienestar = servicioBienestar; + } + + [HttpPost] + public async Task Registrar([FromBody] EstadoAnimoDto dto) + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + + var estado = new EstadoAnimo + { + UsuarioId = usuarioId, + Estado = dto.Estado, + Nota = dto.Nota, + Fecha = DateOnly.FromDateTime(DateTime.Today), + FechaRegistro = DateTime.UtcNow + }; + + _contexto.EstadosAnimo.Add(estado); + await _contexto.SaveChangesAsync(); + + var alerta = await _servicioBienestar.VerificarAnimoNegativoConsecutivo(usuarioId); + return Ok(RespuestaApi.Exitosa(new { success = true, alertaBienestar = alerta })); + } + + [HttpGet("historial")] + public async Task Historial() + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + var historial = await _contexto.EstadosAnimo + .Where(e => e.UsuarioId == usuarioId) + .OrderByDescending(e => e.Fecha) + .Select(e => new { fecha = e.Fecha, estado = e.Estado, nota = e.Nota }) + .ToListAsync(); + + return Ok(RespuestaApi.Exitosa(historial)); + } + + public class EstadoAnimoDto + { + public string Estado { get; set; } = string.Empty; + public string? Nota { get; set; } + } + } +} diff --git a/Controllers/Api/ApiGamificacionController.cs b/Controllers/Api/ApiGamificacionController.cs new file mode 100644 index 0000000..1ee0516 --- /dev/null +++ b/Controllers/Api/ApiGamificacionController.cs @@ -0,0 +1,64 @@ +using EPYCUS_WEB_v0._1.Ayudantes; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace EPYCUS_WEB_v0._1.Controllers.Api +{ + [ApiController] + [Route("api/gamificacion")] + [Authorize] + public class ApiGamificacionController : ControllerBase + { + private readonly IServicioGamificacion _servicioGamificacion; + private readonly IServicioProgreso _servicioProgreso; + + public ApiGamificacionController(IServicioGamificacion servicioGamificacion, IServicioProgreso servicioProgreso) + { + _servicioGamificacion = servicioGamificacion; + _servicioProgreso = servicioProgreso; + } + + [HttpGet("mi-progreso")] + public async Task ObtenerProgreso() + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + var progreso = await _servicioProgreso.ObtenerProgreso(usuarioId); + var nivelActual = progreso.NivelActual; + var porcentaje = CalculadorXP.PorcentajeProgreso(progreso.XpTotal, nivelActual.Numero); + var xpParaSiguiente = CalculadorXP.XpParaSiguienteNivel(nivelActual.Numero); + var imagen = await _servicioProgreso.ObtenerImagenPersonaje(usuarioId, nivelActual.Numero); + + var respuesta = new + { + xpTotal = progreso.XpTotal, + nivel = nivelActual.Numero, + titulo = nivelActual.Titulo, + rachaActual = progreso.RachaActual, + xpParaSiguienteNivel = xpParaSiguiente, + porcentajeProgreso = porcentaje, + imagenPersonaje = imagen + }; + + return Ok(RespuestaApi.Exitosa(respuesta)); + } + + [HttpGet("logros")] + public async Task ObtenerLogros() + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + var logros = await _servicioProgreso.ObtenerTodosLosLogros(); + var desbloqueados = await _servicioProgreso.ObtenerLogrosUsuario(usuarioId); + + var respuesta = logros.Select(l => new + { + logro = l, + desbloqueado = desbloqueados.Any(d => d.LogroId == l.Id), + progreso = 0, + meta = l.CondicionValor + }); + + return Ok(RespuestaApi.Exitosa(respuesta)); + } + } +} diff --git a/Controllers/Api/ApiHabitosController.cs b/Controllers/Api/ApiHabitosController.cs new file mode 100644 index 0000000..1504111 --- /dev/null +++ b/Controllers/Api/ApiHabitosController.cs @@ -0,0 +1,146 @@ +using System; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using EPYCUS_WEB_v0._1.Ayudantes; +using EPYCUS_WEB_v0._1.Datos; +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; + +namespace EPYCUS_WEB_v0._1.Controllers.Api +{ + [ApiController] + [Route("api/[controller]")] + [Authorize] + public class ApiHabitosController : ControllerBase + { + private readonly IServicioHabitos _servicioHabitos; + private readonly ContextoAplicacion _contexto; + + public ApiHabitosController(IServicioHabitos servicioHabitos, ContextoAplicacion contexto) + { + _servicioHabitos = servicioHabitos; + _contexto = contexto; + } + + private int? ObtenerUsuarioId() + { + var claim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + return int.TryParse(claim, out var usuarioId) ? usuarioId : null; + } + + [HttpGet] + public async Task ObtenerHabitos() + { + var usuarioId = ObtenerUsuarioId(); + if (!usuarioId.HasValue) + { + return Unauthorized(RespuestaApi.Fallida("No autenticado")); + } + + var hoy = DateOnly.FromDateTime(DateTime.Today); + + var habitos = await _contexto.Habitos + .Include(h => h.Categoria) + .Include(h => h.Registros) + .Where(h => h.UsuarioId == usuarioId) + .ToListAsync(); + + var respuesta = habitos.Select(h => new + { + id = h.Id, + nombre = h.Nombre, + estado = h.Registros.FirstOrDefault(r => r.Fecha == hoy)?.Estado ?? "Pendiente", + rachaActual = h.RachaActual, + categoria = h.Categoria?.Nombre ?? string.Empty + }); + + return Ok(RespuestaApi.Exitosa(respuesta)); + } + + [HttpGet("hoy")] + public async Task ObtenerHabitosHoy() + { + var usuarioId = ObtenerUsuarioId(); + if (!usuarioId.HasValue) + { + return Unauthorized(RespuestaApi.Fallida("No autenticado")); + } + + var hoy = DateOnly.FromDateTime(DateTime.Today); + + var habitos = await _contexto.Habitos + .Include(h => h.Registros) + .Where(h => h.UsuarioId == usuarioId && h.EstaActivo) + .ToListAsync(); + + var respuesta = habitos.Select(h => new + { + id = h.Id, + nombre = h.Nombre, + estadoHoy = h.Registros.FirstOrDefault(r => r.Fecha == hoy)?.Estado ?? "Pendiente", + xpPotencial = Ayudantes.ConstantesGamificacion.XP_BASE_HABITO + }); + + return Ok(RespuestaApi.Exitosa(respuesta)); + } + + [HttpPost("{id}/completar")] + public async Task Completar(int id) + { + var usuarioId = ObtenerUsuarioId(); + if (!usuarioId.HasValue) + { + return Unauthorized(RespuestaApi.Fallida("No autenticado")); + } + + var resultado = await _servicioHabitos.CompletarHabito(id, usuarioId.Value); + if (!resultado.Exito) + return BadRequest(RespuestaApi.Fallida("No se pudo completar el hábito")); + + return Ok(RespuestaApi.Exitosa(new { xpGanado = resultado.XpGanado })); + } + + [HttpPost("{id}/fallar")] + public async Task Fallar(int id) + { + var usuarioId = ObtenerUsuarioId(); + if (!usuarioId.HasValue) + { + return Unauthorized(RespuestaApi.Fallida("No autenticado")); + } + + var resultado = await _servicioHabitos.FallarHabito(id, usuarioId.Value); + + if (!resultado.Exito) + { + return BadRequest(RespuestaApi.Fallida(resultado.Mensaje)); + } + + return Ok(RespuestaApi.Exitosa(new { rachaRota = true })); + } + + [HttpGet("{id}/semana")] + public async Task Semana(int id) + { + var usuarioId = ObtenerUsuarioId(); + if (!usuarioId.HasValue) + { + return Unauthorized(RespuestaApi.Fallida("No autenticado")); + } + + var desde = DateOnly.FromDateTime(DateTime.Today.AddDays(-6)); + var registros = await _contexto.RegistrosHabito + .Include(r => r.Habito) + .Where(r => r.HabitoId == id && r.Habito.UsuarioId == usuarioId.Value && r.Fecha >= desde) + .OrderBy(r => r.Fecha) + .Select(r => new { dia = r.Fecha.ToString("yyyy-MM-dd"), estado = r.Estado }) + .ToListAsync(); + + return Ok(RespuestaApi.Exitosa(registros)); + } + } +} diff --git a/Controllers/Api/ApiMisionesController.cs b/Controllers/Api/ApiMisionesController.cs new file mode 100644 index 0000000..477cab1 --- /dev/null +++ b/Controllers/Api/ApiMisionesController.cs @@ -0,0 +1,47 @@ +using EPYCUS_WEB_v0._1.Ayudantes; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace EPYCUS_WEB_v0._1.Controllers.Api +{ + [ApiController] + [Route("api/misiones")] + [Authorize] + public class ApiMisionesController : ControllerBase + { + private readonly IServicioMisiones _servicioMisiones; + + public ApiMisionesController(IServicioMisiones servicioMisiones) + { + _servicioMisiones = servicioMisiones; + } + + [HttpPost("{id}/completar")] + public async Task Completar(int id) + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + var resultado = await _servicioMisiones.CompletarMision(id, usuarioId); + + if (!resultado.Exito) + { + return BadRequest(RespuestaApi.Fallida("No se pudo completar la misión")); + } + + return Ok(RespuestaApi.Exitosa(new { xpGanado = resultado.XpGanado })); + } + + [HttpPost("{id}/estado")] + public async Task CambiarEstado(int id, [FromBody] EstadoDto dto) + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + await _servicioMisiones.CambiarEstado(id, dto.Estado, usuarioId); + return Ok(RespuestaApi.Exitosa(new { success = true })); + } + + public class EstadoDto + { + public string Estado { get; set; } = string.Empty; + } + } +} diff --git a/Controllers/Api/ApiPomodoroController.cs b/Controllers/Api/ApiPomodoroController.cs new file mode 100644 index 0000000..a47c738 --- /dev/null +++ b/Controllers/Api/ApiPomodoroController.cs @@ -0,0 +1,107 @@ +using System.Security.Claims; +using System.Threading.Tasks; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.Ayudantes; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace EPYCUS_WEB_v0._1.Controllers.Api +{ + [Authorize] + [ApiController] + [Route("api/[controller]")] + public class ApiPomodoroController : ControllerBase + { + private readonly IServicioPomodoro _servicioPomodoro; + + public ApiPomodoroController(IServicioPomodoro servicioPomodoro) + { + _servicioPomodoro = servicioPomodoro; + } + + private int ObtenerUsuarioIdActual() + { + var claim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + if (int.TryParse(claim, out var usuarioId) && usuarioId > 0) + return usuarioId; + return 0; + } + + public class IniciarRequest { public int? HabitoId { get; set; } public int? MisionId { get; set; } } + + [HttpPost("iniciar")] + public async Task Iniciar([FromBody] IniciarRequest req) + { + int usuarioId = ObtenerUsuarioIdActual(); + if (usuarioId == 0) + { + return Unauthorized(RespuestaApi.Fallida("No autenticado")); + } + var sesion = await _servicioPomodoro.IniciarSesion(usuarioId, req?.HabitoId, req?.MisionId); + return Ok(RespuestaApi.Exitosa(new { sesionId = sesion.Id, fechaInicio = sesion.FechaInicio })); + } + + public class CicloCompletadoRequest { public int CiclosCompletados { get; set; } } + + [HttpPost("{sesionId}/ciclo-completado")] + public async Task CicloCompletado(int sesionId, [FromBody] CicloCompletadoRequest req) + { + var resultado = await _servicioPomodoro.RegistrarCiclo(sesionId, req?.CiclosCompletados ?? 0); + return Ok(RespuestaApi.Exitosa(new { xpGanado = resultado.XpGanado, sugerirDescanso = resultado.SugerirDescanso, pausaActiva = resultado.PausaActiva })); + } + + [HttpPost("{sesionId}/finalizar")] + public async Task Finalizar(int sesionId, [FromBody] CicloCompletadoRequest req) + { + await _servicioPomodoro.FinalizarSesion(sesionId, req?.CiclosCompletados ?? 0); + + // Recalcular xpTotal de la sesión para devolverlo (o leerlo de base de datos) + var sesion = await _servicioPomodoro.ObtenerSesion(sesionId); + return Ok(RespuestaApi.Exitosa(new { xpTotal = sesion?.XpOtorgado ?? 0, sesionGuardada = true })); + } + + [HttpPost("{sesionId}/cancelar")] + public async Task Cancelar(int sesionId) + { + await _servicioPomodoro.CancelarSesion(sesionId); + return Ok(RespuestaApi.Exitosa(new { success = true })); + } + + [HttpGet("configuracion")] + public async Task ObtenerConfiguracion() + { + int usuarioId = ObtenerUsuarioIdActual(); + if (usuarioId == 0) + { + return Unauthorized(RespuestaApi.Fallida("No autenticado")); + } + var config = await _servicioPomodoro.ObtenerConfiguracion(usuarioId); + return Ok(RespuestaApi.Exitosa(new { + tiempoEstudio = config.TiempoEstudioMin, + tiempoDescanso = config.TiempoDescansoMin, + tiempoDescansoLargo = config.TiempoDescansoLargoMin, + ciclosAntesDescansoLargo = config.CiclosAntesDescansoLargo, + sonidoActivo = config.SonidoActivo + })); + } + + [HttpPut("configuracion")] + public async Task ActualizarConfiguracion([FromBody] EPYCUS_WEB_v0._1.Modelos.Entidades.ConfiguracionPomodoro config) + { + int usuarioId = ObtenerUsuarioIdActual(); + if (usuarioId == 0) + { + return Unauthorized(RespuestaApi.Fallida("No autenticado")); + } + await _servicioPomodoro.ActualizarConfiguracion(usuarioId, config); + return Ok(RespuestaApi.Exitosa(new { success = true })); + } + + [HttpGet("tip-aleatorio")] + public async Task ObtenerTip() + { + var tip = await _servicioPomodoro.ObtenerTipAleatorio(); + return Ok(RespuestaApi.Exitosa(new { tip })); + } + } +} diff --git a/Controllers/Api/ApiProgresoController.cs b/Controllers/Api/ApiProgresoController.cs new file mode 100644 index 0000000..67c98db --- /dev/null +++ b/Controllers/Api/ApiProgresoController.cs @@ -0,0 +1,54 @@ +using EPYCUS_WEB_v0._1.Ayudantes; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace EPYCUS_WEB_v0._1.Controllers.Api +{ + [ApiController] + [Route("api/progreso")] + [Authorize] + public class ApiProgresoController : ControllerBase + { + private readonly IServicioProgreso _servicioProgreso; + + public ApiProgresoController(IServicioProgreso servicioProgreso) + { + _servicioProgreso = servicioProgreso; + } + + [HttpGet] + public async Task Obtener() + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + var progreso = await _servicioProgreso.ObtenerProgreso(usuarioId); + var nivelSiguiente = await _servicioProgreso.ObtenerNivelSiguiente(progreso.NivelActual.Numero); + var xpParaSiguiente = CalculadorXP.XpParaSiguienteNivel(progreso.NivelActual.Numero); + var porcentaje = CalculadorXP.PorcentajeProgreso(progreso.XpTotal, progreso.NivelActual.Numero); + + return Ok(RespuestaApi.Exitosa(new + { + progreso, + nivelSiguiente, + xpParaSiguiente, + porcentaje + })); + } + + [HttpGet("logros")] + public async Task Logros() + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + var logros = await _servicioProgreso.ObtenerLogrosUsuario(usuarioId); + return Ok(RespuestaApi.Exitosa(logros)); + } + + [HttpGet("historial-animo")] + public async Task HistorialAnimo() + { + var usuarioId = int.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)!.Value); + var historial = await _servicioProgreso.ObtenerHistorialAnimo(usuarioId); + return Ok(RespuestaApi.Exitosa(historial)); + } + } +} diff --git a/Controllers/AutenticacionController.cs b/Controllers/AutenticacionController.cs new file mode 100644 index 0000000..a1e2ce0 --- /dev/null +++ b/Controllers/AutenticacionController.cs @@ -0,0 +1,136 @@ +using System.Linq; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.ViewModels.Autenticacion; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace EPYCUS_WEB_v0._1.Controllers +{ + public class AutenticacionController : Controller + { + private readonly IServicioAutenticacion _servicioAutenticacion; + private readonly Datos.ContextoAplicacion _contexto; + + public AutenticacionController(IServicioAutenticacion servicioAutenticacion, Datos.ContextoAplicacion contexto) + { + _servicioAutenticacion = servicioAutenticacion; + _contexto = contexto; + } + + private CookieOptions CrearOpcionesCookie(int expiracionDias = 7) + { + return new CookieOptions + { + HttpOnly = true, + Secure = true, + SameSite = SameSiteMode.Strict, + Expires = DateTime.UtcNow.AddDays(expiracionDias) + }; + } + + private CookieOptions CrearOpcionesCookie(int expiracionMinutos, bool recordarme) + { + return new CookieOptions + { + HttpOnly = true, + Secure = true, + SameSite = SameSiteMode.Strict, + Expires = recordarme + ? DateTime.UtcNow.AddDays(7) + : DateTime.UtcNow.AddMinutes(expiracionMinutos) + }; + } + + [HttpGet] + [AllowAnonymous] + public IActionResult Registro() + { + ViewBag.Carreras = _contexto.Carreras.Where(c => c.EstaActiva).ToList(); + return View(new EPYCUS_WEB_v0._1.ViewModels.RegistroViewModel()); + } + + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Registro(EPYCUS_WEB_v0._1.ViewModels.RegistroViewModel modelo) + { + if (!ModelState.IsValid) + { + ViewBag.Carreras = _contexto.Carreras.Where(c => c.EstaActiva).ToList(); + return View(modelo); + } + + var (exito, mensaje, token, refreshToken) = await _servicioAutenticacion.RegistrarUsuario(modelo); + if (!exito || string.IsNullOrWhiteSpace(token)) + { + ModelState.AddModelError(string.Empty, mensaje); + ViewBag.Carreras = _contexto.Carreras.Where(c => c.EstaActiva).ToList(); + return View(modelo); + } + + var cookieOptions = CrearOpcionesCookie(7); + + Response.Cookies.Append("jwt_token", token, cookieOptions); + + if (!string.IsNullOrEmpty(refreshToken)) + { + Response.Cookies.Append("refresh_token", refreshToken, cookieOptions); + } + + return RedirectToAction("Index", "Home"); + } + + [HttpGet] + [AllowAnonymous] + public IActionResult Login() + { + if (User.Identity != null && User.Identity.IsAuthenticated) + { + return RedirectToAction("Index", "Home"); + } + return View(); + } + + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Login(LoginViewModel modelo) + { + if (!ModelState.IsValid) + { + return View(modelo); + } + + var (exito, mensaje, token, refreshToken) = await _servicioAutenticacion.Login(modelo.CorreoElectronico, modelo.Contrasena); + + if (exito && !string.IsNullOrEmpty(token)) + { + // Guardar el token en una cookie segura para las peticiones MVC + var cookieOptions = CrearOpcionesCookie(60, modelo.Recordarme); + + Response.Cookies.Append("jwt_token", token, cookieOptions); + + if (!string.IsNullOrEmpty(refreshToken)) + { + var cookieRefreshOptions = CrearOpcionesCookie(modelo.Recordarme ? 7 : 1); + Response.Cookies.Append("refresh_token", refreshToken, cookieRefreshOptions); + } + + return RedirectToAction("Index", "Home"); + } + + ModelState.AddModelError(string.Empty, mensaje); + return View(modelo); + } + + [HttpPost] + [Authorize] + [ValidateAntiForgeryToken] + public IActionResult Logout() + { + Response.Cookies.Delete("jwt_token"); + Response.Cookies.Delete("refresh_token"); + return RedirectToAction("Login"); + } + } +} diff --git a/Controllers/HabitosController.cs b/Controllers/HabitosController.cs new file mode 100644 index 0000000..6c9218b --- /dev/null +++ b/Controllers/HabitosController.cs @@ -0,0 +1,269 @@ +using System; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.ViewModels; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +namespace EPYCUS_WEB_v0._1.Controllers +{ + [Authorize] + public class HabitosController : Controller + { + private readonly IServicioHabitos _servicioHabitos; + private readonly Microsoft.Extensions.Logging.ILogger _logger; + + public HabitosController(IServicioHabitos servicioHabitos, Microsoft.Extensions.Logging.ILogger logger) + { + _servicioHabitos = servicioHabitos; + _logger = logger; + } + + [AllowAnonymous] + public async Task Index() + { + var claim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + int usuarioId = 1; // Por defecto usuario 1 para depuración + if (int.TryParse(claim, out var parsed) && parsed != 0) + { + usuarioId = parsed; + } + + var lista = await _servicioHabitos.ObtenerHabitosViewModel(usuarioId); + var dashboard = await _servicioHabitos.ObtenerDashboard(usuarioId); + // pasar categorias para el modal de creación + var categorias = await _servicioHabitos.ObtenerCategoriasActivas(); + ViewBag.Categorias = categorias; + + var modelo = new EPYCUS_WEB_v0._1.ViewModels.HabitosIndexViewModel + { + Habitos = lista, + Dashboard = dashboard + }; + + return View(modelo); + } + + public async Task Crear() + { + // Obtener categorías activas para el select + var categorias = await _servicioHabitos.ObtenerCategoriasActivas(); + ViewBag.Categorias = categorias; + return View(new CrearHabitoViewModel()); + } + + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Crear(CrearHabitoViewModel modelo) + { + // Asegurar que tomamos valores incluso si el binding falló (p. ej. al enviar desde modal) + // Rellenar desde Request.Form cuando falte información en el modelo + if (modelo == null) + modelo = new CrearHabitoViewModel(); + + var nombreForm = Request.Form["Nombre"].FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(nombreForm)) modelo.Nombre = nombreForm; + + var descForm = Request.Form["Descripcion"].FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(descForm)) modelo.Descripcion = descForm; + + var catForm = Request.Form["CategoriaId"].FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(catForm) && int.TryParse(catForm, out var catId)) modelo.CategoriaId = catId; + + var freqForm = Request.Form["Frecuencia"].FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(freqForm)) modelo.Frecuencia = freqForm; + + var diasRaw = Request.Form["DiasSemana"].FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(diasRaw) && (modelo.DiasSemana == null || !modelo.DiasSemana.Any())) + { + try + { + modelo.DiasSemana = diasRaw.Split(',', StringSplitOptions.RemoveEmptyEntries) + .Select(s => int.Parse(s.Trim())).ToList(); + } + catch + { + ModelState.AddModelError("DiasSemana", "Formato de días inválido. Use: 1,3,5"); + } + } + + // Checkboxes suelen enviar "on" si están marcados + modelo.ConPomodoro = Request.Form.ContainsKey("ConPomodoro") && (Request.Form["ConPomodoro"] == "on" || Request.Form["ConPomodoro"] == "true"); + modelo.EstaActivo = Request.Form.ContainsKey("EstaActivo") && (Request.Form["EstaActivo"] == "on" || Request.Form["EstaActivo"] == "true"); + + var horaForm = Request.Form["RecordatorioHora"].FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(horaForm) && TimeSpan.TryParse(horaForm, out var ts)) modelo.RecordatorioHora = ts; + + var categorias = await _servicioHabitos.ObtenerCategoriasActivas(); + ViewBag.Categorias = categorias; + + // Validar con atributos de data annotations + TryValidateModel(modelo); + + if (!ModelState.IsValid) + { + var isAjaxError = Request.Headers["X-Requested-With"] == "XMLHttpRequest" || Request.Headers["Accept"].ToString().Contains("application/json"); + if (isAjaxError) + { + var errors = ModelState.Where(kvp => kvp.Value.Errors.Any()) + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()); + return BadRequest(new { success = false, errors }); + } + + // Limpiar valores booleanos problemáticos del ModelState antes de renderizar la vista + ModelState.Remove("ConPomodoro"); + ModelState.Remove("EstaActivo"); + + // Si hay errores, mostrar el formulario Crear (página completa) con errores para facilitar corrección. + return View(modelo); + } + + var claim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + int usuarioId = 1; // Por defecto usuario 1 para depuración + if (int.TryParse(claim, out var parsed) && parsed != 0) + { + usuarioId = parsed; + } + + try + { + await _servicioHabitos.CrearHabito(modelo, usuarioId); + // Placeholder for future post-create logic (no-op for now). + // e.g., send notification, enqueue background job, etc. + } + catch (ArgumentException ex) + { + _logger.LogWarning(ex, "Categoría inválida al crear hábito para usuario {UsuarioId}", usuarioId); + ModelState.AddModelError(string.Empty, ex.Message); + // si es petición AJAX devolver errores en JSON + var isAjax = Request.Headers["X-Requested-With"] == "XMLHttpRequest" || Request.Headers["Accept"].ToString().Contains("application/json"); + if (isAjax) + { + var errors = ModelState.Where(kvp => kvp.Value.Errors.Any()) + .ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()); + return BadRequest(new { success = false, errors }); + } + return View(modelo); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error al crear hábito para usuario {UsuarioId}", usuarioId); + ModelState.AddModelError(string.Empty, "Error inesperado al crear el hábito. Intente de nuevo más tarde."); + var isAjax = Request.Headers["X-Requested-With"] == "XMLHttpRequest" || Request.Headers["Accept"].ToString().Contains("application/json"); + if (isAjax) + { + return StatusCode(500, new { success = false, message = "Error inesperado al crear el hábito." }); + } + return View(modelo); + } + + var isAjaxSuccess = Request.Headers["X-Requested-With"] == "XMLHttpRequest" || Request.Headers["Accept"].ToString().Contains("application/json"); + if (isAjaxSuccess) + return Json(new { success = true }); + + return RedirectToAction(nameof(Index)); + } + + [AllowAnonymous] + public async Task Editar(int id) + { + var claim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + int usuarioId = 1; // Por defecto usuario 1 para depuración + if (int.TryParse(claim, out var parsed) && parsed != 0) + { + usuarioId = parsed; + } + + var vm = await _servicioHabitos.ObtenerPorIdViewModel(id); + if (vm is null) + return NotFound(); + + var modelo = new EditarHabitoViewModel + { + Id = vm.Id, + Nombre = vm.Nombre, + Descripcion = vm.Descripcion, + CategoriaId = vm.CategoriaId, + Frecuencia = vm.Frecuencia, + DiasSemana = vm.DiasSemana, + ConPomodoro = vm.ConPomodoro, + RecordatorioHora = vm.RecordatorioHora, + EstaActivo = vm.EstaActivo + }; + + // pasar categorias activas + var categorias = await _servicioHabitos.ObtenerCategoriasActivas(); + ViewBag.Categorias = categorias; + + return View(modelo); + } + + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Editar(EditarHabitoViewModel modelo) + { + // parsear DiasSemana si viene como texto + var diasRaw = Request.Form["DiasSemana"].FirstOrDefault(); + if (!string.IsNullOrWhiteSpace(diasRaw) && (modelo.DiasSemana == null || !modelo.DiasSemana.Any())) + { + try + { + modelo.DiasSemana = diasRaw.Split(',', StringSplitOptions.RemoveEmptyEntries) + .Select(s => int.Parse(s.Trim())).ToList(); + } + catch + { + ModelState.AddModelError("DiasSemana", "Formato de días inválido. Use: 1,3,5"); + } + } + + var categorias = await _servicioHabitos.ObtenerCategoriasActivas(); + ViewBag.Categorias = categorias; + + if (!ModelState.IsValid) + { + ModelState.Remove("ConPomodoro"); + ModelState.Remove("EstaActivo"); + return View(modelo); + } + + var claim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + int usuarioId = 1; // Por defecto usuario 1 para depuración + if (int.TryParse(claim, out var parsed) && parsed != 0) + { + usuarioId = parsed; + } + + try + { + await _servicioHabitos.EditarHabito(modelo, usuarioId); + return RedirectToAction(nameof(Index)); + } + catch (Exception ex) + { + ModelState.AddModelError(string.Empty, "Error inesperado al guardar cambios: " + ex.Message); + return View(modelo); + } + } + + [HttpPost] + [AllowAnonymous] + [ValidateAntiForgeryToken] + public async Task Eliminar(int id) + { + var claim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + int usuarioId = 1; // Por defecto usuario 1 para depuración + if (int.TryParse(claim, out var parsed) && parsed != 0) + { + usuarioId = parsed; + } + + await _servicioHabitos.EliminarHabito(id, usuarioId); + return RedirectToAction(nameof(Index)); + } + } +} diff --git a/Controllers/HomeController.cs b/Controllers/HomeController.cs new file mode 100644 index 0000000..f03aa23 --- /dev/null +++ b/Controllers/HomeController.cs @@ -0,0 +1,83 @@ +using System.Diagnostics; +using System.Security.Claims; +using EPYCUS_WEB_v0._1.Models; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.ViewModels; +using Microsoft.AspNetCore.Mvc; +using EPYCUS_WEB_v0._1.Datos; +using Microsoft.EntityFrameworkCore; + +namespace EPYCUS_WEB_v0._1.Controllers +{ + public class HomeController : Controller + { + private readonly IServicioHabitos _servicioHabitos; + private readonly ContextoAplicacion _contexto; + + public HomeController(IServicioHabitos servicioHabitos, ContextoAplicacion contexto) + { + _servicioHabitos = servicioHabitos; + _contexto = contexto; + } + + public async Task Index() + { + var modelo = new HomeDashboardViewModel(); + + var claim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + int usuarioId = 0; + + if (User.Identity != null && User.Identity.IsAuthenticated && int.TryParse(claim, out var parsed) && parsed != 0) + { + usuarioId = parsed; + modelo.EstaAutenticado = true; + + var usuario = await _contexto.Usuarios.FindAsync(usuarioId); + if (usuario != null) + { + modelo.NombreUsuario = usuario.Nombre; + } + + // Obtener datos del dashboard + modelo.Estadisticas = await _servicioHabitos.ObtenerDashboard(usuarioId); + + // Obtener hábitos de hoy + var todosLosHabitos = await _servicioHabitos.ObtenerHabitosViewModel(usuarioId); + var hoy = (int)DateTime.Today.DayOfWeek; + + modelo.HabitosHoy = todosLosHabitos + .Where(h => h.EstaActivo && + (h.Frecuencia == "Diaria" || + (h.DiasSemana != null && h.DiasSemana.Contains(hoy)))) + .ToList(); + + // Obtener frase motivacional + var frase = await _contexto.FrasesMotivacionales + .Where(f => f.EstaActiva) + .OrderBy(f => Guid.NewGuid()) + .FirstOrDefaultAsync(); + + if (frase != null) + { + modelo.FraseMotivacional = frase.Frase; + modelo.AutorFrase = frase.Autor; + } + + return View(modelo); + } + + return RedirectToAction("Login", "Autenticacion"); + } + + public IActionResult Privacy() + { + return View(); + } + + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + public IActionResult Error() + { + return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); + } + } +} diff --git a/Controllers/MisionesController.cs b/Controllers/MisionesController.cs new file mode 100644 index 0000000..22cf573 --- /dev/null +++ b/Controllers/MisionesController.cs @@ -0,0 +1,161 @@ +using EPYCUS_WEB_v0._1.Datos; +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.ViewModels; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Rendering; + +namespace EPYCUS_WEB_v0._1.Controllers +{ + public class MisionesController : Controller + { + private readonly IServicioMisiones _servicioMisiones; + private readonly ContextoAplicacion _contexto; + private readonly int _usuarioIdPrueba = 1; + + public MisionesController(IServicioMisiones servicioMisiones, ContextoAplicacion contexto) + { + _servicioMisiones = servicioMisiones; + _contexto = contexto; + } + + private void AsegurarUsuarioPrueba() + { + if (!_contexto.Usuarios.Any(u => u.Id == _usuarioIdPrueba)) + { + var usuario = new Usuario + { + Id = _usuarioIdPrueba, + Nombre = "Usuario Prueba", + CorreoElectronico = "prueba@epycus.com", + ContrasenaHash = "123456", + RolId = _contexto.Roles.First().Id, + CarreraId = _contexto.Carreras.First().Id, + CodigoUnico = "USR-001" + }; + + var progreso = new ProgresoUsuario + { + Id = 1, + UsuarioId = _usuarioIdPrueba, + NivelActualId = _contexto.Niveles.First().Id, + XpTotal = 0, + RachaActual = 0, + RachaMaxima = 0 + }; + _contexto.Usuarios.Add(usuario); + _contexto.ProgresosUsuario.Add(progreso); + _contexto.SaveChanges(); + } + } + + public async Task Index() + { + AsegurarUsuarioPrueba(); + var misiones = await _servicioMisiones.ObtenerMisionesDeUsuario(_usuarioIdPrueba); + return View(misiones); + } + + public IActionResult Crear() + { + AsegurarUsuarioPrueba(); + CargarCategorias(); + return View(new CrearMisionViewModel { FechaLimite = DateTime.Today.AddDays(1) }); + } + + [HttpPost] + public async Task Crear(CrearMisionViewModel modelo) + { + if (ModelState.IsValid) + { + await _servicioMisiones.CrearMision(modelo, _usuarioIdPrueba); + return RedirectToAction(nameof(Index)); + } + CargarCategorias(); + return View(modelo); + } + + public async Task Editar(int id) + { + AsegurarUsuarioPrueba(); + var mision = await _servicioMisiones.ObtenerPorId(id); + if (mision == null || mision.UsuarioId != _usuarioIdPrueba) return NotFound(); + + if (mision.Estado == "Completado" || mision.Estado == "Fallido") + { + TempData["Error"] = "No se puede editar una misión completada o fallida."; + return RedirectToAction(nameof(Index)); + } + + var modelo = new EditarMisionViewModel + { + Id = mision.Id, + Nombre = mision.Nombre, + Descripcion = mision.Descripcion, + NombreCurso = mision.NombreCurso, + FechaLimite = mision.FechaLimite.ToDateTime(TimeOnly.MinValue), + Prioridad = mision.Prioridad, + ConPomodoro = mision.ConPomodoro, + CategoriaId = mision.CategoriaId + }; + + CargarCategorias(); + return View(modelo); + } + + [HttpPost] + public async Task Editar(EditarMisionViewModel modelo) + { + if (ModelState.IsValid) + { + try + { + await _servicioMisiones.EditarMision(modelo, _usuarioIdPrueba); + return RedirectToAction(nameof(Index)); + } + catch (Exception ex) + { + ModelState.AddModelError("", ex.Message); + } + } + CargarCategorias(); + return View(modelo); + } + + [HttpPost] + public async Task CambiarEstado(int id, string estado) + { + await _servicioMisiones.CambiarEstado(id, estado, _usuarioIdPrueba); + return RedirectToAction(nameof(Index)); + } + + [HttpPost] + public async Task Completar(int id) + { + var resultado = await _servicioMisiones.CompletarMision(id, _usuarioIdPrueba); + if (resultado.Exito) + { + TempData["Exito"] = $"¡Misión completada! Ganaste {resultado.XpGanado} XP."; + } + else + { + TempData["Error"] = "No se pudo completar la misión."; + } + return RedirectToAction(nameof(Index)); + } + + [HttpPost] + public async Task Eliminar(int id) + { + await _servicioMisiones.EliminarMision(id, _usuarioIdPrueba); + return RedirectToAction(nameof(Index)); + } + + private void CargarCategorias() + { + ViewBag.Categorias = new SelectList( + _contexto.Categorias.Where(c => c.Tipo == "Mision" || c.Tipo == "Ambos"), + "Id", "Nombre"); + } + } +} diff --git a/Controllers/PomodoroController.cs b/Controllers/PomodoroController.cs new file mode 100644 index 0000000..4e863e9 --- /dev/null +++ b/Controllers/PomodoroController.cs @@ -0,0 +1,90 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using EPYCUS_WEB_v0._1.ViewModels; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.Datos; +using Microsoft.EntityFrameworkCore; +using System.Security.Claims; +using System.Linq; +using System.Threading.Tasks; +using System; +using System.Collections.Generic; + +namespace EPYCUS_WEB_v0._1.Controllers +{ + [Authorize] + public class PomodoroController : Controller + { + private readonly IServicioPomodoro _servicioPomodoro; + private readonly ContextoAplicacion _contexto; + + public PomodoroController(IServicioPomodoro servicioPomodoro, ContextoAplicacion contexto) + { + _servicioPomodoro = servicioPomodoro; + _contexto = contexto; + } + + [AllowAnonymous] + [HttpGet("")] + [HttpGet("Index")] + public async Task Index() + { + var modelo = new PomodoroIndexViewModel(); + + var claim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + if (User.Identity != null && User.Identity.IsAuthenticated && int.TryParse(claim, out var usuarioId) && usuarioId != 0) + { + // Configuración + modelo.Configuracion = await _servicioPomodoro.ObtenerConfiguracion(usuarioId); + + // Estadísticas e Historial de Hoy + var hoy = DateTime.Today; + var sesionesHoy = await _contexto.SesionesPomodoro + .Where(s => s.UsuarioId == usuarioId && s.FechaInicio >= hoy) + .OrderByDescending(s => s.FechaInicio) + .ToListAsync(); + + modelo.HistorialHoy = sesionesHoy; + + modelo.EstadisticasHoy.CiclosCompletados = sesionesHoy.Sum(s => s.CiclosCompletados); + // Calcular minutos enfocados basado en la configuración del usuario + int tiempoEnfoque = modelo.Configuracion.TiempoEstudioMin; + modelo.EstadisticasHoy.MinutosEnfocados = modelo.EstadisticasHoy.CiclosCompletados * tiempoEnfoque; + modelo.EstadisticasHoy.XpGanado = sesionesHoy.Sum(s => s.XpOtorgado); + + // Misiones completadas hoy (se pueden consultar en la tabla Misiones) + modelo.EstadisticasHoy.MisionesCompletadas = await _contexto.Misiones + .Where(m => m.UsuarioId == usuarioId && m.Estado == "Completado" && m.FechaCompletado != null && m.FechaCompletado.Value.Date == hoy) + .CountAsync(); + + // Tareas Enfoque (Sólo las creadas con Pomodoro) + var habitos = await _contexto.Habitos + .Include(h => h.Categoria) + .Where(h => h.UsuarioId == usuarioId && h.EstaActivo && h.ConPomodoro) + .Select(h => new TareaPomodoro + { + Id = h.Id, + Nombre = h.Nombre, + CategoriaNombre = h.Categoria != null ? h.Categoria.Nombre : "Sin categoría", + Tipo = "Habito" + }).ToListAsync(); + + var misiones = await _contexto.Misiones + .Include(m => m.Categoria) + .Where(m => m.UsuarioId == usuarioId && m.Estado != "Completado" && m.ConPomodoro) + .Select(m => new TareaPomodoro + { + Id = m.Id, + Nombre = m.Nombre, + CategoriaNombre = m.Categoria != null ? m.Categoria.Nombre : "Sin categoría", + Tipo = "Mision" + }).ToListAsync(); + + modelo.TareasEnfoque.AddRange(habitos); + modelo.TareasEnfoque.AddRange(misiones); + } + + return View(modelo); + } + } +} diff --git a/Controllers/ProgresoController.cs b/Controllers/ProgresoController.cs new file mode 100644 index 0000000..33e6891 --- /dev/null +++ b/Controllers/ProgresoController.cs @@ -0,0 +1,71 @@ +using EPYCUS_WEB_v0._1.Datos; +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.ViewModels; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Linq; +using System.Security.Claims; +using System.Threading.Tasks; + +namespace EPYCUS_WEB_v0._1.Controllers +{ + [Authorize] + public class ProgresoController : Controller + { + private readonly IServicioProgreso _servicioProgreso; + private readonly ContextoAplicacion _contexto; + + public ProgresoController(IServicioProgreso servicioProgreso, ContextoAplicacion contexto) + { + _servicioProgreso = servicioProgreso; + _contexto = contexto; + } + + [AllowAnonymous] + public async Task Index() + { + var claim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; + if (string.IsNullOrEmpty(claim) || !int.TryParse(claim, out var usuarioId)) + { + // Usuario anónimo o sin sesión + var nivelInicial = _contexto.Niveles.OrderBy(n => n.Numero).FirstOrDefault(); + var progresoDefecto = new ProgresoUsuario + { + UsuarioId = 0, + NivelActual = nivelInicial ?? new Nivel { Numero = 1, Descripcion = "Novato", Titulo = "Principiante" }, + NivelActualId = nivelInicial?.Id ?? 1, + XpTotal = 0, + RachaActual = 0, + RachaMaxima = 0 + }; + + return View(new ProgresoViewModel + { + Progreso = progresoDefecto, + NivelSiguiente = await _servicioProgreso.ObtenerNivelSiguiente(progresoDefecto.NivelActual.Numero), + TodosLosLogros = await _servicioProgreso.ObtenerTodosLosLogros(), + LogrosDesbloqueadosIds = new System.Collections.Generic.List(), + ImagenPersonajeUrl = "https://ui-avatars.com/api/?name=User&background=0D8ABC&color=fff&size=200" + }); + } + + var progreso = await _servicioProgreso.ObtenerProgreso(usuarioId); + var nivelSiguiente = await _servicioProgreso.ObtenerNivelSiguiente(progreso.NivelActual.Numero); + var todosLosLogros = await _servicioProgreso.ObtenerTodosLosLogros(); + var logrosUsuario = await _servicioProgreso.ObtenerLogrosUsuario(usuarioId); + var imagenUrl = await _servicioProgreso.ObtenerImagenPersonaje(usuarioId, progreso.NivelActual.Numero); + + var viewModel = new ProgresoViewModel + { + Progreso = progreso, + NivelSiguiente = nivelSiguiente, + TodosLosLogros = todosLosLogros, + LogrosDesbloqueadosIds = logrosUsuario.Select(l => l.LogroId).ToList(), + ImagenPersonajeUrl = imagenUrl + }; + + return View(viewModel); + } + } +} diff --git a/DTOs/.gitkeep b/DTOs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Datos/.gitkeep b/Datos/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Datos/ContextoAplicacion.cs b/Datos/ContextoAplicacion.cs new file mode 100644 index 0000000..a77fd9b --- /dev/null +++ b/Datos/ContextoAplicacion.cs @@ -0,0 +1,166 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using Microsoft.EntityFrameworkCore; + +namespace EPYCUS_WEB_v0._1.Datos +{ + public class ContextoAplicacion : DbContext + { + public ContextoAplicacion(DbContextOptions options) + : base(options) + { + } + + public DbSet Usuarios { get; set; } = null!; + public DbSet Roles { get; set; } = null!; + public DbSet Carreras { get; set; } = null!; + public DbSet Niveles { get; set; } = null!; + public DbSet ProgresosUsuario { get; set; } = null!; + public DbSet Personajes { get; set; } = null!; + public DbSet ImagenesNivelPersonaje { get; set; } = null!; + public DbSet PersonajesUsuario { get; set; } = null!; + public DbSet Logros { get; set; } = null!; + public DbSet LogrosUsuario { get; set; } = null!; + public DbSet Categorias { get; set; } = null!; + public DbSet Habitos { get; set; } = null!; + public DbSet RegistrosHabito { get; set; } = null!; + public DbSet ConfiguracionesPomodoro { get; set; } = null!; + public DbSet SesionesPomodoro { get; set; } = null!; + public DbSet Misiones { get; set; } = null!; + public DbSet EstadosAnimo { get; set; } = null!; + public DbSet FrasesMotivacionales { get; set; } = null!; + public DbSet TipsPomodoro { get; set; } = null!; + public DbSet Temas { get; set; } = null!; + public DbSet TemasUsuario { get; set; } = null!; + public DbSet Suscripciones { get; set; } = null!; + public DbSet TokensRefresh { get; set; } = null!; + public DbSet VerificacionesCorreo { get; set; } = null!; + public DbSet RecuperacionesContrasena { get; set; } = null!; + public DbSet Logs { get; set; } = null!; + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity() + .HasIndex(u => u.CorreoElectronico) + .IsUnique(); + + modelBuilder.Entity() + .HasIndex(u => u.CodigoUnico) + .IsUnique(); + + modelBuilder.Entity() + .HasIndex(u => u.GoogleId) + .IsUnique(); + + modelBuilder.Entity() + .HasOne(u => u.Rol) + .WithMany() + .HasForeignKey(u => u.RolId) + .OnDelete(DeleteBehavior.Restrict); + + modelBuilder.Entity() + .HasOne(u => u.Carrera) + .WithMany(c => c.Usuarios) + .HasForeignKey(u => u.CarreraId) + .OnDelete(DeleteBehavior.Restrict); + + modelBuilder.Entity() + .HasOne(u => u.TemaActual) + .WithMany() + .HasForeignKey(u => u.TemaActualId) + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(false); + + modelBuilder.Entity() + .HasIndex(p => p.UsuarioId) + .IsUnique(); + + modelBuilder.Entity() + .HasOne(p => p.Usuario) + .WithOne(u => u.Progreso) + .HasForeignKey(p => p.UsuarioId) + .OnDelete(DeleteBehavior.Cascade); + + modelBuilder.Entity() + .HasOne(p => p.NivelActual) + .WithMany(n => n.Progresos) + .HasForeignKey(p => p.NivelActualId) + .OnDelete(DeleteBehavior.Restrict); + + modelBuilder.Entity() + .HasOne(h => h.Usuario) + .WithMany(u => u.Habitos) + .HasForeignKey(h => h.UsuarioId) + .OnDelete(DeleteBehavior.Cascade); + + modelBuilder.Entity() + .HasOne(h => h.Categoria) + .WithMany(c => c.Habitos) + .HasForeignKey(h => h.CategoriaId) + .OnDelete(DeleteBehavior.Restrict); + + modelBuilder.Entity() + .HasOne(r => r.Habito) + .WithMany(h => h.Registros) + .HasForeignKey(r => r.HabitoId) + .OnDelete(DeleteBehavior.Cascade); + + modelBuilder.Entity() + .HasOne(s => s.Usuario) + .WithMany(u => u.SesionesPomodoro) + .HasForeignKey(s => s.UsuarioId) + .OnDelete(DeleteBehavior.Cascade); + + modelBuilder.Entity() + .HasOne(s => s.Habito) + .WithMany(h => h.SesionesPomodoro) + .HasForeignKey(s => s.HabitoId) + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(false); + + modelBuilder.Entity() + .HasOne(s => s.Mision) + .WithMany(m => m.SesionesPomodoro) + .HasForeignKey(s => s.MisionId) + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(false); + + modelBuilder.Entity() + .HasOne(m => m.Usuario) + .WithMany(u => u.Misiones) + .HasForeignKey(m => m.UsuarioId) + .OnDelete(DeleteBehavior.Cascade); + + modelBuilder.Entity() + .HasOne(m => m.Categoria) + .WithMany(c => c.Misiones) + .HasForeignKey(m => m.CategoriaId) + .OnDelete(DeleteBehavior.Restrict); + + modelBuilder.Entity() + .HasOne(p => p.Carrera) + .WithMany() + .HasForeignKey(p => p.CarreraId) + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(false); + + modelBuilder.Entity() + .HasOne(i => i.Personaje) + .WithMany(p => p.Imagenes) + .HasForeignKey(i => i.PersonajeId) + .OnDelete(DeleteBehavior.Cascade); + + modelBuilder.Entity() + .HasOne(s => s.Usuario) + .WithMany(u => u.Suscripciones) + .HasForeignKey(s => s.UsuarioId) + .OnDelete(DeleteBehavior.Cascade); + + modelBuilder.Entity() + .HasOne() + .WithMany() + .HasForeignKey(s => s.ActivadaPorAdminId) + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(false); + } + } +} diff --git a/Datos/Semilla/.gitkeep b/Datos/Semilla/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Datos/Semilla/DatosSemilla.cs b/Datos/Semilla/DatosSemilla.cs new file mode 100644 index 0000000..e65e09a --- /dev/null +++ b/Datos/Semilla/DatosSemilla.cs @@ -0,0 +1,350 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; + +namespace EPYCUS_WEB_v0._1.Datos.Semilla +{ + public static class DatosSemilla + { + public static async Task InicializarAsync(ContextoAplicacion contexto) + { + if (!contexto.Roles.Any()) + { + contexto.Roles.AddRange( + new Rol { Nombre = "Usuario" }, + new Rol { Nombre = "Administrador" }); + await contexto.SaveChangesAsync(); + } + + if (!contexto.Carreras.Any()) + { + contexto.Carreras.AddRange( + new Carrera { Nombre = "Ingeniería de Sistemas", Area = "Ingeniería", Codigo = "ing-sistemas", EstaActiva = true }, + new Carrera { Nombre = "Ingeniería Civil", Area = "Ingeniería", Codigo = "ing-civil", EstaActiva = true }, + new Carrera { Nombre = "Ingeniería Industrial", Area = "Ingeniería", Codigo = "ing-industrial", EstaActiva = true }, + new Carrera { Nombre = "Administración de Empresas", Area = "Administración", Codigo = "administracion", EstaActiva = true }, + new Carrera { Nombre = "Contabilidad", Area = "Negocios", Codigo = "contabilidad", EstaActiva = true }, + new Carrera { Nombre = "Derecho", Area = "Legal", Codigo = "derecho", EstaActiva = true }, + new Carrera { Nombre = "Medicina Humana", Area = "Salud", Codigo = "medicina", EstaActiva = true }, + new Carrera { Nombre = "Enfermería", Area = "Salud", Codigo = "enfermeria", EstaActiva = true }, + new Carrera { Nombre = "Psicología", Area = "Salud", Codigo = "psicologia", EstaActiva = true }, + new Carrera { Nombre = "Educación", Area = "Educación", Codigo = "educacion", EstaActiva = true }, + new Carrera { Nombre = "Arquitectura", Area = "Arquitectura", Codigo = "arquitectura", EstaActiva = true }, + new Carrera { Nombre = "Comunicaciones", Area = "Comunicaciones", Codigo = "comunicaciones", EstaActiva = true }); + await contexto.SaveChangesAsync(); + } + + if (!contexto.Niveles.Any()) + { + contexto.Niveles.AddRange( + new Nivel { Numero = 0, Titulo = "Novato", XpRequerido = 0, Descripcion = "Aún no llevas el título, pero el camino comienza hoy. Bienvenido." }, + new Nivel { Numero = 1, Titulo = "Curioso", XpRequerido = 100, Descripcion = "La curiosidad es el primer paso de todo gran profesional." }, + new Nivel { Numero = 2, Titulo = "Aprendiz", XpRequerido = 250, Descripcion = "Estás absorbiendo conocimiento. Cada hábito cuenta." }, + new Nivel { Numero = 3, Titulo = "Estudiante Comprometido", XpRequerido = 450, Descripcion = "Tu constancia ya te diferencia de la mayoría." }, + new Nivel { Numero = 4, Titulo = "Practicante", XpRequerido = 700, Descripcion = "Empiezas a aplicar lo que aprendes. El mundo te espera." }, + new Nivel { Numero = 5, Titulo = "Asistente", XpRequerido = 1000, Descripcion = "Ya formas parte del campo profesional. Sigue creciendo." }, + new Nivel { Numero = 6, Titulo = "Junior", XpRequerido = 1350, Descripcion = "Tienes base sólida. Los desafíos reales ya no te asustan." }, + new Nivel { Numero = 7, Titulo = "Semi-Senior", XpRequerido = 1750, Descripcion = "Tu experiencia empieza a hablar por ti." }, + new Nivel { Numero = 8, Titulo = "Profesional", XpRequerido = 2200, Descripcion = "Dominas los fundamentos y resuelves problemas con soltura." }, + new Nivel { Numero = 9, Titulo = "Especialista", XpRequerido = 2700, Descripcion = "Tienes un área en la que pocos te superan." }, + new Nivel { Numero = 10, Titulo = "Senior", XpRequerido = 3250, Descripcion = "Mitad del camino. Tu criterio vale más que el de muchos." }, + new Nivel { Numero = 11, Titulo = "Senior Avanzado", XpRequerido = 3850, Descripcion = "Lideras con el ejemplo. Otros aprenden de ti." }, + new Nivel { Numero = 12, Titulo = "Experto", XpRequerido = 4500, Descripcion = "Tu nivel de profundidad es notable. Eres referente." }, + new Nivel { Numero = 13, Titulo = "Consultor", XpRequerido = 5200, Descripcion = "Te buscan cuando el problema es difícil. Eso es poder." }, + new Nivel { Numero = 14, Titulo = "Líder", XpRequerido = 5950, Descripcion = "No solo resuelves: diriges, inspiras y construyes equipos." }, + new Nivel { Numero = 15, Titulo = "Maestro", XpRequerido = 6750, Descripcion = "Tu conocimiento trasciende lo técnico. Ya es sabiduría." }, + new Nivel { Numero = 16, Titulo = "Arquitecto", XpRequerido = 7600, Descripcion = "Diseñas sistemas, estrategias y futuros completos." }, + new Nivel { Numero = 17, Titulo = "Eminencia", XpRequerido = 8500, Descripcion = "Tu nombre es sinónimo de excelencia en tu campo." }, + new Nivel { Numero = 18, Titulo = "Gran Maestro", XpRequerido = 9450, Descripcion = "Has forjado a otros profesionales con tu guía." }, + new Nivel { Numero = 19, Titulo = "Leyenda en Ascenso", XpRequerido = 10450, Descripcion = "El umbral del máximo poder está justo frente a ti." }, + new Nivel { Numero = 20, Titulo = "Leyenda Viviente", XpRequerido = 11500, Descripcion = "Has llegado a la cima. Eres la definición de tu profesión." }); + await contexto.SaveChangesAsync(); + } + + if (!contexto.Usuarios.Any()) + { + var rolUsuarioId = contexto.Roles.Where(r => r.Nombre == "Usuario").Select(r => r.Id).FirstOrDefault(); + var carreraId = contexto.Carreras.Select(c => c.Id).FirstOrDefault(); + + var nuevoUsuario = new Usuario + { + Id = 1, + CodigoUnico = "USR-001", + Nombre = "Usuario Prueba", + CorreoElectronico = "prueba@test.com", + ContrasenaHash = BCrypt.Net.BCrypt.HashPassword("123456", workFactor: 12), + FechaNacimiento = new DateTime(2000, 1, 1), + Genero = "Prefiero no decirlo", + CorreoVerificado = true, + AceptoTerminos = true, + EstaActivo = true, + FechaRegistro = DateTime.Now, + RolId = rolUsuarioId == 0 ? 1 : rolUsuarioId, + CarreraId = carreraId == 0 ? 1 : carreraId + }; + + contexto.Usuarios.Add(nuevoUsuario); + await contexto.SaveChangesAsync(); + + // Inicializar progreso del usuario + var nivelInicial = contexto.Niveles.Select(n => n.Id).FirstOrDefault(); + contexto.ProgresosUsuario.Add(new ProgresoUsuario + { + UsuarioId = nuevoUsuario.Id, + NivelActualId = nivelInicial == 0 ? 1 : nivelInicial, + XpTotal = 0, + RachaActual = 0, + RachaMaxima = 0 + }); + await contexto.SaveChangesAsync(); + } + + + if (!contexto.Categorias.Any()) + { + contexto.Categorias.AddRange( + new Categoria { Nombre = "Salud y Bienestar", Icono = "bi-heart-pulse", Tipo = "Ambos", EstaActiva = true }, + new Categoria { Nombre = "Estudio", Icono = "bi-book", Tipo = "Ambos", EstaActiva = true }, + new Categoria { Nombre = "Ejercicio", Icono = "bi-activity", Tipo = "Habito", EstaActiva = true }, + new Categoria { Nombre = "Sueño", Icono = "bi-moon-stars", Tipo = "Habito", EstaActiva = true }, + new Categoria { Nombre = "Hidratación", Icono = "bi-droplet", Tipo = "Habito", EstaActiva = true }, + new Categoria { Nombre = "Nutrición", Icono = "bi-egg-fried", Tipo = "Habito", EstaActiva = true }, + new Categoria { Nombre = "Meditación", Icono = "bi-peace", Tipo = "Habito", EstaActiva = true }, + new Categoria { Nombre = "Tarea Académica", Icono = "bi-file-earmark-text", Tipo = "Mision", EstaActiva = true }, + new Categoria { Nombre = "Proyecto", Icono = "bi-kanban", Tipo = "Mision", EstaActiva = true }, + new Categoria { Nombre = "Lectura", Icono = "bi-book-half", Tipo = "Ambos", EstaActiva = true }, + new Categoria { Nombre = "Hábito Personal", Icono = "bi-star", Tipo = "Habito", EstaActiva = true }); + await contexto.SaveChangesAsync(); + } + + if (!contexto.Temas.Any()) + { + contexto.Temas.AddRange( + new Tema + { + Nombre = "Noche Épica", + Modo = "Oscuro", + ArchivoCss = "tema-noche-epica.css", + EsPremium = false, + Precio = 0, + EstaActivo = true + }, + new Tema + { + Nombre = "Sakura", + Modo = "Claro", + ArchivoCss = "tema-sakura.css", + EsPremium = false, + Precio = 0, + EstaActivo = true + }); + await contexto.SaveChangesAsync(); + } + + if (!contexto.Personajes.Any()) + { + var carreraSistemasId = contexto.Carreras + .Where(c => c.Codigo == "ing-sistemas") + .Select(c => c.Id) + .FirstOrDefault(); + + contexto.Personajes.AddRange( + new Personaje { Nombre = "Kai", Genero = "Masculino", CarreraId = carreraSistemasId, EstaActivo = true }, + new Personaje { Nombre = "Luna", Genero = "Femenino", CarreraId = carreraSistemasId, EstaActivo = true }, + new Personaje { Nombre = "Ares", Genero = "Masculino", CarreraId = null, EstaActivo = true }, + new Personaje { Nombre = "Nova", Genero = "Femenino", CarreraId = null, EstaActivo = true }); + await contexto.SaveChangesAsync(); + } + + if (!contexto.ImagenesNivelPersonaje.Any()) + { + var kaiId = contexto.Personajes.Where(p => p.Nombre == "Kai").Select(p => p.Id).FirstOrDefault(); + var lunaId = contexto.Personajes.Where(p => p.Nombre == "Luna").Select(p => p.Id).FirstOrDefault(); + var aresId = contexto.Personajes.Where(p => p.Nombre == "Ares").Select(p => p.Id).FirstOrDefault(); + var novaId = contexto.Personajes.Where(p => p.Nombre == "Nova").Select(p => p.Id).FirstOrDefault(); + + contexto.ImagenesNivelPersonaje.AddRange( + new ImagenNivelPersonaje + { + PersonajeId = kaiId, + NivelNumero = 0, + ImagenUrl = "/img/personajes/ing-sistemas/masculino/nivel_0.png", + EsPlaceholder = false + }, + new ImagenNivelPersonaje + { + PersonajeId = lunaId, + NivelNumero = 0, + ImagenUrl = "/img/personajes/ing-sistemas/femenino/nivel_0.png", + EsPlaceholder = false + }, + new ImagenNivelPersonaje + { + PersonajeId = aresId, + NivelNumero = 0, + ImagenUrl = "/img/personajes/generico/masculino/placeholder.png", + EsPlaceholder = true + }, + new ImagenNivelPersonaje + { + PersonajeId = novaId, + NivelNumero = 0, + ImagenUrl = "/img/personajes/generico/femenino/placeholder.png", + EsPlaceholder = true + }); + await contexto.SaveChangesAsync(); + } + + if (!contexto.Logros.Any()) + { + contexto.Logros.AddRange( + new Logro + { + Nombre = "Primer Paso", + Descripcion = "Completa tu primer hábito.", + IconoUrl = "/img/logros/primer_paso.png", + CondicionTipo = "HabitosCompletados", + CondicionValor = 1, + XpRecompensa = 10, + EstaActivo = true + }, + new Logro + { + Nombre = "Semana Perfecta", + Descripcion = "Mantén una racha de 7 días.", + IconoUrl = "/img/logros/semana_perfecta.png", + CondicionTipo = "RachaDias", + CondicionValor = 7, + XpRecompensa = 50, + EstaActivo = true + }, + new Logro + { + Nombre = "Mes Imparable", + Descripcion = "Mantén una racha de 30 días.", + IconoUrl = "/img/logros/mes_imparable.png", + CondicionTipo = "RachaDias", + CondicionValor = 30, + XpRecompensa = 200, + EstaActivo = true + }, + new Logro + { + Nombre = "Primera Misión", + Descripcion = "Completa tu primera misión.", + IconoUrl = "/img/logros/primera_mision.png", + CondicionTipo = "MisionesCompletadas", + CondicionValor = 1, + XpRecompensa = 20, + EstaActivo = true + }, + new Logro + { + Nombre = "Productivo", + Descripcion = "Completa 10 misiones.", + IconoUrl = "/img/logros/productivo.png", + CondicionTipo = "MisionesCompletadas", + CondicionValor = 10, + XpRecompensa = 80, + EstaActivo = true + }, + new Logro + { + Nombre = "Maestro del Foco", + Descripcion = "Completa 50 sesiones Pomodoro.", + IconoUrl = "/img/logros/maestro_foco.png", + CondicionTipo = "SesionesPomodoro", + CondicionValor = 50, + XpRecompensa = 100, + EstaActivo = true + }, + new Logro + { + Nombre = "Asistente", + Descripcion = "Alcanza el nivel 5.", + IconoUrl = "/img/logros/nivel_5.png", + CondicionTipo = "NivelAlcanzado", + CondicionValor = 5, + XpRecompensa = 150, + EstaActivo = true + }, + new Logro + { + Nombre = "Profesional", + Descripcion = "Alcanza el nivel 10.", + IconoUrl = "/img/logros/nivel_10.png", + CondicionTipo = "NivelAlcanzado", + CondicionValor = 10, + XpRecompensa = 300, + EstaActivo = true + }, + new Logro + { + Nombre = "Gran Maestro", + Descripcion = "Alcanza el nivel 18.", + IconoUrl = "/img/logros/nivel_18.png", + CondicionTipo = "NivelAlcanzado", + CondicionValor = 18, + XpRecompensa = 700, + EstaActivo = true + }, + new Logro + { + Nombre = "Leyenda Viviente", + Descripcion = "Alcanza el nivel máximo: nivel 20.", + IconoUrl = "/img/logros/leyenda.png", + CondicionTipo = "NivelAlcanzado", + CondicionValor = 20, + XpRecompensa = 1000, + EstaActivo = true + }); + await contexto.SaveChangesAsync(); + } + + if (!contexto.FrasesMotivacionales.Any()) + { + contexto.FrasesMotivacionales.AddRange( + new FraseMotivacional { Frase = "El secreto para avanzar es comenzar.", Autor = "Mark Twain", EstaActiva = true }, + new FraseMotivacional { Frase = "No cuentes los días, haz que los días cuenten.", Autor = "Muhammad Ali", EstaActiva = true }, + new FraseMotivacional { Frase = "Sé el cambio que quieres ver en el mundo.", Autor = "Mahatma Gandhi", EstaActiva = true }, + new FraseMotivacional { Frase = "El éxito es la suma de pequeños esfuerzos repetidos día tras día.", Autor = "Robert Collier", EstaActiva = true }, + new FraseMotivacional { Frase = "No importa lo lento que vayas, siempre y cuando no te detengas.", Autor = "Confucio", EstaActiva = true }, + new FraseMotivacional { Frase = "La disciplina es el puente entre metas y logros.", Autor = "Jim Rohn", EstaActiva = true }, + new FraseMotivacional { Frase = "Cree que puedes y ya estarás a mitad de camino.", Autor = "Theodore Roosevelt", EstaActiva = true }, + new FraseMotivacional { Frase = "Cada día es una nueva oportunidad para mejorar.", Autor = "Anónimo", EstaActiva = true }, + new FraseMotivacional { Frase = "La constancia es la madre del éxito.", Autor = "Anónimo", EstaActiva = true }, + new FraseMotivacional { Frase = "Haz de cada día tu obra maestra.", Autor = "John Wooden", EstaActiva = true }); + await contexto.SaveChangesAsync(); + } + + if (!contexto.TipsPomodoro.Any()) + { + contexto.TipsPomodoro.AddRange( + new TipPomodoro + { + Tip = "Pon tu teléfono en modo avión durante el tiempo de estudio. Cada notificación interrumpida son 23 minutos de concentración perdida.", + EstaActivo = true + }, + new TipPomodoro + { + Tip = "Prepara todo antes de empezar: agua, apuntes y la tarea específica. No busques materiales mientras el temporizador corre.", + EstaActivo = true + }, + new TipPomodoro + { + Tip = "En el descanso, aléjate de la pantalla. Estira las manos, camina un poco o mira por la ventana. Tu cerebro lo necesita.", + EstaActivo = true + }, + new TipPomodoro + { + Tip = "Si una idea te distrae, anótala rápido en un papel y regresa al foco. La anotarás después, no la perderás.", + EstaActivo = true + }, + new TipPomodoro + { + Tip = "Después de 4 ciclos completos, tómate 20-30 minutos de descanso largo. Comer algo ligero y caminar ayuda a resetear tu energía.", + EstaActivo = true + }); + await contexto.SaveChangesAsync(); + } + } + } +} diff --git a/Documentacion/EPYCUS_WEB_Documento_Base.md b/Documentacion/EPYCUS_WEB_Documento_Base.md new file mode 100644 index 0000000..e438bb2 --- /dev/null +++ b/Documentacion/EPYCUS_WEB_Documento_Base.md @@ -0,0 +1,1779 @@ +# EPYCUS WEB — Documento Base del Proyecto +**ASP.NET 10 Core MVC · MariaDB · Entity Framework Core** +**Metodología: Scrumban | Equipo: 4 integrantes | Fecha límite: 25 de mayo de 2026** + +--- + +> **¿Para qué sirve este documento?** +> Es la única fuente de verdad del proyecto. Antes de escribir cualquier línea de código, todos deben leer y respetar este documento. Cuando uses Copilot, pégale la sección relevante como contexto para que genere código consistente con el resto del equipo. + +--- + +## Índice + +1. [Esquema de Base de Datos y Reglas de Negocio](#1-esquema-de-base-de-datos-y-reglas-de-negocio) +2. [Arquitectura del Sistema](#2-arquitectura-del-sistema) +3. [Convenciones de Código](#3-convenciones-de-código) +4. [Colores, Estilo y Librerías CSS](#4-colores-estilo-y-librerías-css) +5. [División de Módulos por Integrante](#5-división-de-módulos-por-integrante) + +--- + +## 1. Esquema de Base de Datos y Reglas de Negocio + +### 1.1 Tablas de la Base de Datos + +> **Configuración de conexión:** XAMPP · MariaDB · usuario `root` · sin contraseña +> **Nombre de la BD:** `epycus_db` + +--- + +#### AUTENTICACION Y USUARIOS + +--- + +**Tabla: `Roles`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `Nombre` | VARCHAR(50) | NOT NULL, UNIQUE | `"Usuario"` o `"Administrador"` | + +**Seed inicial:** +```sql +INSERT INTO Roles (Nombre) VALUES ('Usuario'), ('Administrador'); +``` + +--- + +**Tabla: `Carreras`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `Nombre` | VARCHAR(150) | NOT NULL | Ej: `"Ingeniería de Sistemas"` | +| `Area` | VARCHAR(100) | NOT NULL | Ej: `"Ingeniería y Tecnología"` | +| `Codigo` | VARCHAR(30) | NOT NULL, UNIQUE | Slug para rutas de imágenes: `"ing-sistemas"` | +| `EstaActiva` | TINYINT(1) | DEFAULT 1 | | + +**Seed inicial:** +```sql +INSERT INTO Carreras (Nombre, Area, Codigo) VALUES +('Ingeniería de Sistemas', 'Ingeniería y Tecnología', 'ing-sistemas'), +('Ingeniería Civil', 'Ingeniería y Tecnología', 'ing-civil'), +('Ingeniería Industrial', 'Ingeniería y Tecnología', 'ing-industrial'), +('Administración de Empresas', 'Ciencias Empresariales', 'administracion'), +('Contabilidad', 'Ciencias Empresariales', 'contabilidad'), +('Derecho', 'Ciencias Jurídicas', 'derecho'), +('Medicina Humana', 'Ciencias de la Salud', 'medicina'), +('Enfermería', 'Ciencias de la Salud', 'enfermeria'), +('Psicología', 'Ciencias de la Salud', 'psicologia'), +('Educación', 'Ciencias de la Educación', 'educacion'), +('Arquitectura', 'Ingeniería y Tecnología', 'arquitectura'), +('Comunicaciones', 'Humanidades', 'comunicaciones'); +``` + +--- + +**Tabla: `Usuarios`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `CodigoUnico` | VARCHAR(20) | NOT NULL, UNIQUE | Formato: `EPY-XXXXXXXX` generado automáticamente | +| `Nombre` | VARCHAR(150) | NOT NULL | | +| `CorreoElectronico` | VARCHAR(200) | NOT NULL, UNIQUE | | +| `ContrasenaHash` | VARCHAR(255) | NULL | NULL si usa solo Google | +| `FechaNacimiento` | DATE | NOT NULL | | +| `Genero` | ENUM('Masculino','Femenino','Prefiero no decir') | NOT NULL | | +| `CarreraId` | INT | FK → Carreras.Id | | +| `RolId` | INT | FK → Roles.Id, DEFAULT 1 | 1=Usuario, 2=Administrador | +| `GoogleId` | VARCHAR(255) | NULL, UNIQUE | ID de cuenta Google vinculada | +| `FotoGoogleUrl` | VARCHAR(500) | NULL | Foto de perfil de Google | +| `CorreoVerificado` | TINYINT(1) | DEFAULT 0 | | +| `AceptoTerminos` | TINYINT(1) | DEFAULT 0 | | +| `EstaActivo` | TINYINT(1) | DEFAULT 1 | | +| `FechaRegistro` | DATETIME | DEFAULT NOW() | | +| `UltimoAcceso` | DATETIME | NULL | | +| `TemaActualId` | INT | FK → Temas.Id, NULL | Tema visual activo | + +--- + +**Tabla: `TokensRefresh`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `Token` | VARCHAR(500) | NOT NULL | Token de refresco JWT | +| `ExpiraEn` | DATETIME | NOT NULL | | +| `Revocado` | TINYINT(1) | DEFAULT 0 | | +| `FechaCreacion` | DATETIME | DEFAULT NOW() | | + +--- + +**Tabla: `VerificacionesCorreo`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `Token` | VARCHAR(255) | NOT NULL | Token UUID aleatorio | +| `ExpiraEn` | DATETIME | NOT NULL | NOW() + 24 horas | +| `Usado` | TINYINT(1) | DEFAULT 0 | | +| `FechaCreacion` | DATETIME | DEFAULT NOW() | | + +--- + +**Tabla: `RecuperacionesContrasena`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `Token` | VARCHAR(255) | NOT NULL | Token UUID aleatorio | +| `ExpiraEn` | DATETIME | NOT NULL | NOW() + 1 hora | +| `Usado` | TINYINT(1) | DEFAULT 0 | | +| `FechaCreacion` | DATETIME | DEFAULT NOW() | | + +--- + +#### GAMIFICACION + +--- + +**Tabla: `Niveles`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `Numero` | INT | NOT NULL, UNIQUE | Del 0 al 20 | +| `Titulo` | VARCHAR(100) | NOT NULL | Título genérico de la etapa profesional | +| `XpRequerido` | INT | NOT NULL | XP acumulado total para alcanzar este nivel | +| `Descripcion` | VARCHAR(255) | NULL | Frase motivacional del nivel | + +**Sistema de progresión profesional — 20 niveles:** + +> El sistema representa la evolución del usuario desde que llega a la universidad sin experiencia hasta convertirse en un profesional legendario en su carrera. Los títulos son genéricos y se combinan con el nombre de la carrera del usuario en la interfaz. +> +> Ejemplo para Ingeniería de Sistemas: **nivel 6 → "Junior en Ingeniería de Sistemas"** +> Ejemplo para Medicina: **nivel 10 → "Senior en Medicina"** +> Ejemplo para Derecho: **nivel 20 → "Abogado Leyenda Viviente"** +> +> **Fórmula de XP:** `XP_para_siguiente_nivel = 100 + (nivel_actual × 50)` + +```sql +INSERT INTO Niveles (Numero, Titulo, XpRequerido, Descripcion) VALUES +(0, 'Novato', 0, 'Aún no llevas el título, pero el camino comienza hoy. Bienvenido.'), +(1, 'Curioso', 100, 'La curiosidad es el primer paso de todo gran profesional.'), +(2, 'Aprendiz', 250, 'Estás absorbiendo conocimiento. Cada hábito cuenta.'), +(3, 'Estudiante Comprometido', 450, 'Tu constancia ya te diferencia de la mayoría.'), +(4, 'Practicante', 700, 'Empiezas a aplicar lo que aprendes. El mundo te espera.'), +(5, 'Asistente', 1000, 'Ya formas parte del campo profesional. Sigue creciendo.'), +(6, 'Junior', 1350, 'Tienes base sólida. Los desafíos reales ya no te asustan.'), +(7, 'Semi-Senior', 1750, 'Tu experiencia empieza a hablar por ti.'), +(8, 'Profesional', 2200, 'Dominas los fundamentos y resuelves problemas con soltura.'), +(9, 'Especialista', 2700, 'Tienes un área en la que pocos te superan.'), +(10, 'Senior', 3250, 'Mitad del camino. Tu criterio vale más que el de muchos.'), +(11, 'Senior Avanzado', 3850, 'Lideras con el ejemplo. Otros aprenden de ti.'), +(12, 'Experto', 4500, 'Tu nivel de profundidad es notable. Eres referente.'), +(13, 'Consultor', 5200, 'Te buscan cuando el problema es difícil. Eso es poder.'), +(14, 'Líder', 5950, 'No solo resuelves: diriges, inspiras y construyes equipos.'), +(15, 'Maestro', 6750, 'Tu conocimiento trasciende lo técnico. Ya es sabiduría.'), +(16, 'Arquitecto', 7600, 'Diseñas sistemas, estrategias y futuros completos.'), +(17, 'Eminencia', 8500, 'Tu nombre es sinónimo de excelencia en tu campo.'), +(18, 'Gran Maestro', 9450, 'Has forjado a otros profesionales con tu guía.'), +(19, 'Leyenda en Ascenso', 10450, 'El umbral del máximo poder está justo frente a ti.'), +(20, 'Leyenda Viviente', 11500, 'Has llegado a la cima. Eres la definición de tu profesión.'); +``` + +--- + +**Tabla de referencia XP por nivel:** +| Nivel | Título | XP Acumulado | XP para subir al siguiente | +|---|---|---|---| +| 0 | Novato | 0 | 100 | +| 1 | Curioso | 100 | 150 | +| 2 | Aprendiz | 250 | 200 | +| 3 | Estudiante Comprometido | 450 | 250 | +| 4 | Practicante | 700 | 300 | +| 5 | Asistente | 1,000 | 350 | +| 6 | Junior | 1,350 | 400 | +| 7 | Semi-Senior | 1,750 | 450 | +| 8 | Profesional | 2,200 | 500 | +| 9 | Especialista | 2,700 | 550 | +| 10 | Senior | 3,250 | 600 | +| 11 | Senior Avanzado | 3,850 | 650 | +| 12 | Experto | 4,500 | 700 | +| 13 | Consultor | 5,200 | 750 | +| 14 | Líder | 5,950 | 800 | +| 15 | Maestro | 6,750 | 850 | +| 16 | Arquitecto | 7,600 | 900 | +| 17 | Eminencia | 8,500 | 950 | +| 18 | Gran Maestro | 9,450 | 1,000 | +| 19 | Leyenda en Ascenso | 10,450 | 1,050 | +| 20 | Leyenda Viviente | 11,500 | — | + +--- + +**Tabla: `ProgresosUsuario`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id, UNIQUE | Un registro por usuario | +| `XpTotal` | INT | DEFAULT 0 | XP acumulado total (nunca disminuye) | +| `NivelActualId` | INT | FK → Niveles.Id, DEFAULT 1 | Nivel 0 al inicio | +| `RachaActual` | INT | DEFAULT 0 | Días consecutivos activos | +| `RachaMaxima` | INT | DEFAULT 0 | Máxima racha histórica | +| `FechaUltimaActividad` | DATE | NULL | Último día con al menos 1 acción | +| `FechaInicioRacha` | DATE | NULL | Cuándo inició la racha actual | +| `DiaDeGraciaUsado` | TINYINT(1) | DEFAULT 0 | Si ya usó el día de gracia en esta racha | +| `ProductividadDiaria` | DECIMAL(5,2) | DEFAULT 0.00 | % de hábitos completados hoy | + +--- + +#### PERSONAJES + +> Los personajes son ilustraciones originales del equipo: estudiantes universitarios peruanos vestidos con ropa y accesorios propios de su carrera profesional. Cada personaje tiene versión masculina y femenina. La imagen del personaje cambia visualmente conforme el usuario sube de nivel: ropa más elaborada, accesorios profesionales, postura más segura, mayor detalle visual. + +--- + +**Tabla: `Personajes`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `Nombre` | VARCHAR(100) | NOT NULL | Nombre del personaje | +| `Genero` | ENUM('Masculino','Femenino') | NOT NULL | | +| `CarreraId` | INT | FK → Carreras.Id, NULL | NULL = genérico (aplica a todas las carreras) | +| `EstaActivo` | TINYINT(1) | DEFAULT 1 | | + +**Seed inicial:** +```sql +INSERT INTO Personajes (Nombre, Genero, CarreraId) VALUES +('Kai', 'Masculino', 1), -- Ingeniería de Sistemas (imagen real disponible) +('Luna', 'Femenino', 1), -- Ingeniería de Sistemas (imagen real disponible) +('Ares', 'Masculino', NULL), -- Genérico masculino (placeholder para otras carreras) +('Nova', 'Femenino', NULL); -- Genérico femenino (placeholder para otras carreras) +``` + +--- + +**Tabla: `ImagenesNivelPersonaje`** + +> Esta tabla registra qué imágenes existen para cada personaje en cada nivel. Permite agregar nuevas imágenes de nivel sin tener las 21 disponibles desde el inicio. El sistema usa la imagen disponible más cercana hacia abajo si la del nivel exacto no existe. + +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `PersonajeId` | INT | FK → Personajes.Id | | +| `NivelNumero` | INT | NOT NULL | 0 al 20 | +| `ImagenUrl` | VARCHAR(500) | NOT NULL | Ruta relativa: `/img/personajes/...` | +| `EsPlaceholder` | TINYINT(1) | DEFAULT 0 | 1 si es imagen temporal/silueta | + +**Seed inicial:** +```sql +-- Kai: imagen real nivel 0 disponible +INSERT INTO ImagenesNivelPersonaje (PersonajeId, NivelNumero, ImagenUrl, EsPlaceholder) VALUES +(1, 0, '/img/personajes/ing-sistemas/masculino/nivel_0.png', 0); + +-- Luna: imagen real nivel 0 disponible +INSERT INTO ImagenesNivelPersonaje (PersonajeId, NivelNumero, ImagenUrl, EsPlaceholder) VALUES +(2, 0, '/img/personajes/ing-sistemas/femenino/nivel_0.png', 0); + +-- Ares: placeholder genérico masculino +INSERT INTO ImagenesNivelPersonaje (PersonajeId, NivelNumero, ImagenUrl, EsPlaceholder) VALUES +(3, 0, '/img/personajes/generico/masculino/placeholder.png', 1); + +-- Nova: placeholder genérico femenino +INSERT INTO ImagenesNivelPersonaje (PersonajeId, NivelNumero, ImagenUrl, EsPlaceholder) VALUES +(4, 0, '/img/personajes/generico/femenino/placeholder.png', 1); +``` + +**Convención de nombres de archivo:** +``` +/img/personajes/{codigo-carrera}/{masculino|femenino}/nivel_{0-20}.png + +Ejemplos: + /img/personajes/ing-sistemas/masculino/nivel_0.png → Novato: mochila universitaria, ropa casual + /img/personajes/ing-sistemas/masculino/nivel_5.png → Asistente: laptop, ropa semiformal + /img/personajes/ing-sistemas/masculino/nivel_10.png → Senior: auriculares, tablet, confianza + /img/personajes/ing-sistemas/masculino/nivel_20.png → Leyenda: traje, postura de líder total + /img/personajes/generico/masculino/placeholder.png → Silueta azul genérica + /img/personajes/generico/femenino/placeholder.png → Silueta rosada genérica +``` + +**Lógica de selección de imagen en el servicio:** +``` +1. Obtener nivel actual del usuario (ej: nivel 7) +2. Obtener PersonajeId activo del usuario +3. Buscar en ImagenesNivelPersonaje: + WHERE PersonajeId = X AND NivelNumero <= 7 + ORDER BY NivelNumero DESC + LIMIT 1 +4. Si no encuentra ninguna → usar placeholder según género del usuario +``` + +--- + +**Tabla: `PersonajesUsuario`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `PersonajeId` | INT | FK → Personajes.Id | | +| `EstaSeleccionado` | TINYINT(1) | DEFAULT 0 | Solo uno puede ser true por usuario | +| `FechaObtenido` | DATETIME | DEFAULT NOW() | | + +--- + +#### LOGROS + +--- + +**Tabla: `Logros`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `Nombre` | VARCHAR(150) | NOT NULL | | +| `Descripcion` | VARCHAR(300) | NOT NULL | | +| `IconoUrl` | VARCHAR(500) | NOT NULL | `/img/logros/nombre.png` | +| `CondicionTipo` | ENUM('HabitosCompletados','MisionesCompletadas','RachaDias','SesionesPomodoro','XpTotal','NivelAlcanzado') | NOT NULL | | +| `CondicionValor` | INT | NOT NULL | Cantidad requerida para desbloquearlo | +| `XpRecompensa` | INT | DEFAULT 0 | XP bonus al desbloquear | +| `EstaActivo` | TINYINT(1) | DEFAULT 1 | | + +**Seed inicial:** +```sql +INSERT INTO Logros (Nombre, Descripcion, IconoUrl, CondicionTipo, CondicionValor, XpRecompensa) VALUES +('Primer Paso', 'Completa tu primer hábito.', '/img/logros/primer_paso.png', 'HabitosCompletados', 1, 10), +('Semana Perfecta', 'Mantén una racha de 7 días.', '/img/logros/semana_perfecta.png', 'RachaDias', 7, 50), +('Mes Imparable', 'Mantén una racha de 30 días.', '/img/logros/mes_imparable.png', 'RachaDias', 30, 200), +('Primera Misión', 'Completa tu primera misión.', '/img/logros/primera_mision.png', 'MisionesCompletadas', 1, 20), +('Productivo', 'Completa 10 misiones.', '/img/logros/productivo.png', 'MisionesCompletadas', 10, 80), +('Maestro del Foco', 'Completa 50 sesiones Pomodoro.', '/img/logros/maestro_foco.png', 'SesionesPomodoro', 50, 100), +('Asistente', 'Alcanza el nivel 5.', '/img/logros/nivel_5.png', 'NivelAlcanzado', 5, 150), +('Profesional', 'Alcanza el nivel 10.', '/img/logros/nivel_10.png', 'NivelAlcanzado', 10, 300), +('Gran Maestro', 'Alcanza el nivel 18.', '/img/logros/nivel_18.png', 'NivelAlcanzado', 18, 700), +('Leyenda Viviente', 'Alcanza el nivel máximo: nivel 20.', '/img/logros/leyenda.png', 'NivelAlcanzado', 20, 1000); +``` + +--- + +**Tabla: `LogrosUsuario`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `LogroId` | INT | FK → Logros.Id | | +| `FechaObtenido` | DATETIME | DEFAULT NOW() | | + +--- + +#### HABITOS + +--- + +**Tabla: `Categorias`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `Nombre` | VARCHAR(100) | NOT NULL | | +| `Icono` | VARCHAR(100) | NOT NULL | Nombre del ícono Bootstrap Icons | +| `Tipo` | ENUM('Habito','Mision','Ambos') | NOT NULL | | +| `EstaActiva` | TINYINT(1) | DEFAULT 1 | | + +**Seed inicial:** +```sql +INSERT INTO Categorias (Nombre, Icono, Tipo) VALUES +('Salud y Bienestar', 'bi-heart-pulse', 'Ambos'), +('Estudio', 'bi-book', 'Ambos'), +('Ejercicio', 'bi-activity', 'Habito'), +('Sueño', 'bi-moon-stars', 'Habito'), +('Hidratación', 'bi-droplet', 'Habito'), +('Nutrición', 'bi-egg-fried', 'Habito'), +('Meditación', 'bi-peace', 'Habito'), +('Tarea Académica', 'bi-file-earmark-text', 'Mision'), +('Proyecto', 'bi-kanban', 'Mision'), +('Lectura', 'bi-book-half', 'Ambos'), +('Hábito Personal', 'bi-star', 'Habito'); +``` + +--- + +**Tabla: `Habitos`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `CategoriaId` | INT | FK → Categorias.Id | | +| `Nombre` | VARCHAR(200) | NOT NULL | | +| `Descripcion` | VARCHAR(500) | NULL | | +| `Frecuencia` | ENUM('Diaria','Semanal','Personalizada') | NOT NULL | | +| `DiasSemana` | VARCHAR(20) | NULL | JSON: `"[1,3,5]"` (Lun=1 … Dom=7) | +| `ConPomodoro` | TINYINT(1) | DEFAULT 0 | | +| `RecordatorioHora` | TIME | NULL | | +| `RachaActual` | INT | DEFAULT 0 | Racha individual del hábito | +| `RachaMaxima` | INT | DEFAULT 0 | | +| `EstaActivo` | TINYINT(1) | DEFAULT 1 | | +| `FechaCreacion` | DATETIME | DEFAULT NOW() | | + +--- + +**Tabla: `RegistrosHabito`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `HabitoId` | INT | FK → Habitos.Id | | +| `Fecha` | DATE | NOT NULL | Fecha del registro | +| `Estado` | ENUM('Completado','Fallido','Pendiente') | DEFAULT 'Pendiente' | | +| `XpOtorgado` | INT | DEFAULT 0 | XP ganado al completar | +| `FechaRegistro` | DATETIME | DEFAULT NOW() | | + +--- + +#### POMODORO + +--- + +**Tabla: `ConfiguracionesPomodoro`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id, UNIQUE | Una configuración por usuario | +| `TiempoEstudioMin` | INT | DEFAULT 25 | | +| `TiempoDescansoMin` | INT | DEFAULT 5 | | +| `TiempoDescansoLargoMin` | INT | DEFAULT 15 | | +| `CiclosAntesDescansoLargo` | INT | DEFAULT 4 | | +| `SonidoActivo` | TINYINT(1) | DEFAULT 1 | | +| `FechaActualizacion` | DATETIME | DEFAULT NOW() | | + +--- + +**Tabla: `SesionesPomodoro`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `HabitoId` | INT | FK → Habitos.Id, NULL | Opcional | +| `MisionId` | INT | FK → Misiones.Id, NULL | Opcional | +| `FechaInicio` | DATETIME | NOT NULL | | +| `FechaFin` | DATETIME | NULL | NULL si no terminó | +| `CiclosCompletados` | INT | DEFAULT 0 | | +| `XpOtorgado` | INT | DEFAULT 0 | | +| `FueCompletada` | TINYINT(1) | DEFAULT 0 | | + +--- + +#### MISIONES + +--- + +**Tabla: `Misiones`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `CategoriaId` | INT | FK → Categorias.Id | | +| `Nombre` | VARCHAR(200) | NOT NULL | | +| `Descripcion` | VARCHAR(500) | NULL | | +| `NombreCurso` | VARCHAR(150) | NULL | Nombre del curso universitario | +| `FechaLimite` | DATE | NOT NULL | | +| `Prioridad` | ENUM('Baja','Media','Alta') | DEFAULT 'Media' | | +| `Estado` | ENUM('Pendiente','EnProgreso','Completado','Fallido') | DEFAULT 'Pendiente' | | +| `ConPomodoro` | TINYINT(1) | DEFAULT 0 | | +| `XpOtorgado` | INT | DEFAULT 0 | Se calcula al completar según prioridad | +| `FechaCreacion` | DATETIME | DEFAULT NOW() | | +| `FechaCompletado` | DATETIME | NULL | | + +--- + +#### BIENESTAR + +--- + +**Tabla: `EstadosAnimo`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `Fecha` | DATE | NOT NULL | | +| `Estado` | ENUM('Feliz','Bien','Neutral','Cansado','Estresado') | NOT NULL | | +| `Nota` | VARCHAR(300) | NULL | Nota opcional | +| `FechaRegistro` | DATETIME | DEFAULT NOW() | | + +--- + +#### CONTENIDO DEL SISTEMA + +--- + +**Tabla: `FrasesMotivacionales`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `Frase` | VARCHAR(500) | NOT NULL | | +| `Autor` | VARCHAR(150) | DEFAULT 'Anónimo' | | +| `EstaActiva` | TINYINT(1) | DEFAULT 1 | Gestionable desde admin | + +**Seed inicial (10 de 100 — el resto se agrega desde el panel admin):** +```sql +INSERT INTO FrasesMotivacionales (Frase, Autor) VALUES +('El secreto para avanzar es comenzar.', 'Mark Twain'), +('No cuentes los días, haz que los días cuenten.', 'Muhammad Ali'), +('Sé el cambio que quieres ver en el mundo.', 'Mahatma Gandhi'), +('El éxito es la suma de pequeños esfuerzos repetidos día tras día.', 'Robert Collier'), +('No importa lo lento que vayas, siempre y cuando no te detengas.', 'Confucio'), +('La disciplina es el puente entre metas y logros.', 'Jim Rohn'), +('Cree que puedes y ya estarás a mitad de camino.', 'Theodore Roosevelt'), +('Cada día es una nueva oportunidad para mejorar.', 'Anónimo'), +('La constancia es la madre del éxito.', 'Anónimo'), +('Haz de cada día tu obra maestra.', 'John Wooden'); +``` + +--- + +**Tabla: `TipsPomodoro`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `Tip` | VARCHAR(500) | NOT NULL | | +| `EstaActivo` | TINYINT(1) | DEFAULT 1 | | + +**Seed completo (5 tips):** +```sql +INSERT INTO TipsPomodoro (Tip) VALUES +('Pon tu teléfono en modo avión durante el tiempo de estudio. Cada notificación interrumpida son 23 minutos de concentración perdida.'), +('Prepara todo antes de empezar: agua, apuntes y la tarea específica. No busques materiales mientras el temporizador corre.'), +('En el descanso, aléjate de la pantalla. Estira las manos, camina un poco o mira por la ventana. Tu cerebro lo necesita.'), +('Si una idea te distrae, anótala rápido en un papel y regresa al foco. La anotarás después, no la perderás.'), +('Después de 4 ciclos completos, tómate 20-30 minutos de descanso largo. Comer algo ligero y caminar ayuda a resetear tu energía.'); +``` + +--- + +#### TEMAS VISUALES + +--- + +**Tabla: `Temas`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `Nombre` | VARCHAR(100) | NOT NULL | | +| `Descripcion` | VARCHAR(300) | NULL | | +| `Modo` | ENUM('Oscuro','Claro') | NOT NULL | | +| `ArchivoCss` | VARCHAR(100) | NOT NULL | Nombre del archivo en `/wwwroot/css/temas/` | +| `ImagenPreviewUrl` | VARCHAR(500) | NULL | Preview en la pantalla de ajustes | +| `EsPremium` | TINYINT(1) | DEFAULT 0 | 0 = gratis | +| `Precio` | DECIMAL(6,2) | DEFAULT 0.00 | En soles | +| `EstaActivo` | TINYINT(1) | DEFAULT 1 | | + +**Seed inicial:** +```sql +INSERT INTO Temas (Nombre, Descripcion, Modo, ArchivoCss, EsPremium, Precio) VALUES +('Noche Épica', 'Modo oscuro con azules eléctricos y detalles en cyan. Para quienes estudian de noche con intensidad.', 'Oscuro', 'tema-noche-epica.css', 0, 0.00), +('Sakura', 'Modo claro en tonos pastel: lavanda, rosa y menta. Suave, ordenado y motivador.', 'Claro', 'tema-sakura.css', 0, 0.00); +``` + +--- + +**Tabla: `TemasUsuario`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `TemaId` | INT | FK → Temas.Id | | +| `FechaObtenido` | DATETIME | DEFAULT NOW() | | + +--- + +#### SUSCRIPCIONES Y ADMIN + +--- + +**Tabla: `Suscripciones`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id | | +| `Plan` | VARCHAR(50) | NOT NULL | Ej: `"Premium Mensual"` | +| `PrecioSoles` | DECIMAL(6,2) | NOT NULL | | +| `FechaInicio` | DATE | NOT NULL | | +| `FechaFin` | DATE | NOT NULL | | +| `EstaActiva` | TINYINT(1) | DEFAULT 0 | Lo activa manualmente el admin | +| `ActivadaPorAdminId` | INT | FK → Usuarios.Id, NULL | | +| `FechaActivacion` | DATETIME | NULL | | + +--- + +**Tabla: `Logs`** +| Columna | Tipo | Restricciones | Descripción | +|---|---|---|---| +| `Id` | INT | PK, AUTO_INCREMENT | | +| `UsuarioId` | INT | FK → Usuarios.Id, NULL | NULL si es acción del sistema | +| `Accion` | VARCHAR(100) | NOT NULL | Ej: `"Login"`, `"CompletarHabito"` | +| `Detalle` | VARCHAR(500) | NULL | Información adicional | +| `DireccionIp` | VARCHAR(45) | NULL | | +| `FechaRegistro` | DATETIME | DEFAULT NOW() | | + +--- + +### 1.2 Sistema de XP (Reglas de Negocio de Gamificación) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ TABLA DE XP POR ACCIÓN │ +├─────────────────────────────────────────┬───────────────────┤ +│ Acción │ XP Ganado │ +├─────────────────────────────────────────┼───────────────────┤ +│ Login diario │ +10 XP │ +│ Completar un hábito │ +20 XP │ +│ Completar hábito (bonus racha x7) │ +10 XP extra │ +│ Completar misión — Prioridad Baja │ +30 XP │ +│ Completar misión — Prioridad Media │ +50 XP │ +│ Completar misión — Prioridad Alta │ +80 XP │ +│ Completar 1 ciclo Pomodoro │ +15 XP │ +│ Mantener racha de 7 días │ +50 XP bonus │ +│ Mantener racha de 30 días │ +200 XP bonus │ +│ Desbloquear un logro │ XP del logro │ +└─────────────────────────────────────────┴───────────────────┘ +``` + +> REGLA CLAVE: El XP nunca se descuenta. Solo la racha se pierde por inactividad. + +--- + +### 1.3 Sistema de Rachas (Reglas de Negocio) + +``` +RACHA ACTIVA: + - El usuario completa al menos 1 hábito en el día → RachaActual++ + - FechaUltimaActividad = HOY + +DÍA DE GRACIA: + - Si hoy == FechaUltimaActividad + 2 días Y DiaDeGraciaUsado == false + → La racha no se pierde, DiaDeGraciaUsado = true + → Al día siguiente DEBE completar al menos 1 hábito + +PÉRDIDA DE RACHA: + - Si hoy > FechaUltimaActividad + 2 días (o ya usó el día de gracia) + → RachaActual = 0, DiaDeGraciaUsado = false + → No se pierden XP acumulados (nunca) + +EVALUACIÓN: Al hacer login y mediante un job programado a medianoche. +``` + +--- + +### 1.4 Fórmula de Productividad Diaria + +``` +ProductividadDiaria = (HábitosCompletadosHoy / HábitosProgramadosHoy) x 100 + +Si no hay hábitos programados para hoy: mostrar "Sin hábitos programados hoy" +``` + +--- + +## 2. Arquitectura del Sistema + +### 2.1 Stack Tecnológico + +| Componente | Tecnología | +|---|---| +| Framework | ASP.NET 10 Core MVC | +| ORM | Entity Framework Core | +| Base de datos | MariaDB (vía XAMPP) | +| Autenticación | JWT + Refresh Tokens + Google OAuth | +| Frontend | Razor Views + Bootstrap 5.3 | +| Iconos | Bootstrap Icons 1.11 | +| Gráficos | Chart.js 4 (CDN) | +| Hash contraseñas | BCrypt.Net-Next | +| Correos | MailKit | +| Mapeo | AutoMapper | +| IA (futuro) | Google Gemini API | + +--- + +### 2.2 Paquetes NuGet + +> Los paquetes de Entity Framework Core y el conector Pomelo para MariaDB se instalan manualmente desde el Administrador de paquetes NuGet de Visual Studio. +> +> Los siguientes paquetes adicionales se instalan via consola o NuGet Manager: + +``` +Microsoft.AspNetCore.Authentication.JwtBearer +Microsoft.AspNetCore.Authentication.Google +BCrypt.Net-Next +AutoMapper.Extensions.Microsoft.DependencyInjection +MailKit +``` + +--- + +### 2.3 Estructura de Carpetas del Proyecto + +``` +EpycusWeb/ +│ +├── Controllers/ +│ ├── AutenticacionController.cs +│ ├── DashboardController.cs +│ ├── HabitosController.cs +│ ├── PomodoroController.cs +│ ├── MisionesController.cs +│ ├── ProgresoController.cs +│ ├── PerfilController.cs +│ ├── AjustesController.cs +│ └── Admin/ +│ └── AdminController.cs +│ +├── Views/ +│ ├── Autenticacion/ +│ │ ├── Login.cshtml +│ │ ├── Registro.cshtml +│ │ ├── CompletarPerfil.cshtml +│ │ ├── VerificarCorreo.cshtml +│ │ └── RecuperarContrasena.cshtml +│ ├── Dashboard/ +│ │ └── Index.cshtml +│ ├── Habitos/ +│ │ ├── Index.cshtml +│ │ ├── Crear.cshtml +│ │ └── Editar.cshtml +│ ├── Pomodoro/ +│ │ └── Index.cshtml +│ ├── Misiones/ +│ │ ├── Index.cshtml +│ │ ├── Crear.cshtml +│ │ └── Editar.cshtml +│ ├── Progreso/ +│ │ └── Index.cshtml +│ ├── Perfil/ +│ │ └── Index.cshtml +│ ├── Ajustes/ +│ │ └── Index.cshtml +│ ├── Admin/ +│ │ ├── Index.cshtml +│ │ └── Usuarios.cshtml +│ └── Shared/ +│ ├── _Layout.cshtml +│ ├── _LayoutAdmin.cshtml +│ ├── _LayoutAuth.cshtml +│ └── _Parciales/ +│ ├── _NavbarLateral.cshtml +│ ├── _BarraXP.cshtml +│ └── _Notificaciones.cshtml +│ +├── ViewModels/ +│ ├── Autenticacion/ +│ │ ├── LoginViewModel.cs +│ │ ├── RegistroViewModel.cs +│ │ └── CompletarPerfilViewModel.cs +│ ├── Dashboard/ +│ │ └── DashboardViewModel.cs +│ ├── Habitos/ +│ │ ├── HabitoViewModel.cs +│ │ └── CrearHabitoViewModel.cs +│ ├── Misiones/ +│ │ ├── MisionViewModel.cs +│ │ └── CrearMisionViewModel.cs +│ ├── Progreso/ +│ │ └── ProgresoViewModel.cs +│ ├── Perfil/ +│ │ └── PerfilViewModel.cs +│ └── Admin/ +│ └── AdminUsuariosViewModel.cs +│ +├── Modelos/ +│ ├── Entidades/ +│ │ ├── Usuario.cs +│ │ ├── Rol.cs +│ │ ├── Carrera.cs +│ │ ├── ProgresoUsuario.cs +│ │ ├── Nivel.cs +│ │ ├── Personaje.cs +│ │ ├── ImagenNivelPersonaje.cs +│ │ ├── PersonajeUsuario.cs +│ │ ├── Logro.cs +│ │ ├── LogroUsuario.cs +│ │ ├── Habito.cs +│ │ ├── RegistroHabito.cs +│ │ ├── ConfiguracionPomodoro.cs +│ │ ├── SesionPomodoro.cs +│ │ ├── Mision.cs +│ │ ├── Categoria.cs +│ │ ├── EstadoAnimo.cs +│ │ ├── FraseMotivacional.cs +│ │ ├── TipPomodoro.cs +│ │ ├── Tema.cs +│ │ ├── TemaUsuario.cs +│ │ ├── Suscripcion.cs +│ │ ├── TokenRefresh.cs +│ │ ├── VerificacionCorreo.cs +│ │ ├── RecuperacionContrasena.cs +│ │ └── Log.cs +│ └── Enums/ +│ ├── EstadoMision.cs +│ ├── PrioridadMision.cs +│ ├── FrecuenciaHabito.cs +│ ├── EstadoAnimoEnum.cs +│ └── CondicionLogro.cs +│ +├── Servicios/ +│ ├── Interfaces/ +│ │ ├── IServicioAutenticacion.cs +│ │ ├── IServicioGamificacion.cs +│ │ ├── IServicioHabitos.cs +│ │ ├── IServicioPomodoro.cs +│ │ ├── IServicioMisiones.cs +│ │ ├── IServicioProgreso.cs +│ │ ├── IServicioPerfil.cs +│ │ ├── IServicioCorreo.cs +│ │ └── IServicioAdmin.cs +│ └── Implementaciones/ +│ ├── ServicioAutenticacion.cs +│ ├── ServicioGamificacion.cs +│ ├── ServicioHabitos.cs +│ ├── ServicioPomodoro.cs +│ ├── ServicioMisiones.cs +│ ├── ServicioProgreso.cs +│ ├── ServicioPerfil.cs +│ ├── ServicioCorreo.cs +│ └── ServicioAdmin.cs +│ +├── Datos/ +│ ├── ContextoAplicacion.cs +│ └── Semilla/ +│ └── DatosSemilla.cs +│ +├── DTOs/ +│ ├── UsuarioDto.cs +│ ├── HabitoDto.cs +│ ├── MisionDto.cs +│ └── ProgresoDto.cs +│ +├── Ayudantes/ +│ ├── GeneradorCodigo.cs +│ ├── CalculadorXP.cs +│ └── ExtensionesString.cs +│ +├── Middleware/ +│ └── ManejadorExcepciones.cs +│ +├── wwwroot/ +│ ├── css/ +│ │ ├── site.css +│ │ └── temas/ +│ │ ├── tema-noche-epica.css +│ │ └── tema-sakura.css +│ ├── js/ +│ │ ├── site.js +│ │ ├── pomodoro.js +│ │ └── graficos.js +│ └── img/ +│ ├── personajes/ +│ │ ├── ing-sistemas/ +│ │ │ ├── masculino/ +│ │ │ │ └── nivel_0.png +│ │ │ └── femenino/ +│ │ │ └── nivel_0.png +│ │ └── generico/ +│ │ ├── masculino/ +│ │ │ └── placeholder.png +│ │ └── femenino/ +│ │ └── placeholder.png +│ └── logros/ +│ └── placeholder_logro.png +│ +├── appsettings.json +├── appsettings.Development.json +└── Program.cs +``` + +--- + +### 2.4 Capas del Sistema + +``` +Usuario (Navegador) + │ + ▼ +┌──────────────────────────────────────────┐ +│ CAPA DE PRESENTACIÓN │ +│ Controller recibe la petición HTTP │ +│ Valida el ViewModel (DataAnnotations) │ +│ Llama al Servicio correspondiente │ +└─────────────────┬────────────────────────┘ + │ llama a + ▼ +┌──────────────────────────────────────────┐ +│ CAPA DE APLICACIÓN │ +│ Servicio contiene la lógica de negocio │ +│ Usa DTOs para transferir datos │ +│ Llama al ContextoAplicacion (EF Core) │ +└─────────────────┬────────────────────────┘ + │ consulta + ▼ +┌──────────────────────────────────────────┐ +│ CAPA DE INFRAESTRUCTURA │ +│ ContextoAplicacion.cs (DbContext) │ +│ Entity Framework Core → MariaDB │ +└──────────────────────────────────────────┘ + │ + ▼ + Base de Datos + epycus_db +``` + +--- + +### 2.5 Configuración de `appsettings.json` + +```json +{ + "ConnectionStrings": { + "ConexionPrincipal": "Server=localhost;Port=3306;Database=epycus_db;User=root;Password=;" + }, + "Jwt": { + "Clave": "TU_CLAVE_SECRETA_MUY_LARGA_AQUI_MINIMO_32_CARACTERES", + "Emisor": "EpycusWeb", + "Audiencia": "EpycusUsuarios", + "ExpiracionMinutos": 60, + "ExpiracionRefreshDias": 7 + }, + "Google": { + "ClientId": "TU_CLIENT_ID_GOOGLE", + "ClientSecret": "TU_CLIENT_SECRET_GOOGLE" + }, + "Correo": { + "Servidor": "smtp.gmail.com", + "Puerto": 587, + "Usuario": "epycusapp@gmail.com", + "Contrasena": "TU_APP_PASSWORD_GMAIL", + "NombreRemitente": "Epycus App" + }, + "App": { + "UrlBase": "https://localhost:7000", + "Version": "1.0.0" + } +} +``` + +--- + +## 3. Convenciones de Código + +> REGLA DE ORO: Si todos siguen estas convenciones, Copilot generará código compatible entre módulos sin necesidad de reescribir nada. + +--- + +### 3.1 Nombres de Archivos y Clases + +| Elemento | Convención | Ejemplo | +|---|---|---| +| Controladores | PascalCase + sufijo Controller | `HabitosController.cs` | +| Vistas | PascalCase, carpeta = controlador | `Views/Habitos/Crear.cshtml` | +| ViewModels | PascalCase + sufijo ViewModel | `CrearHabitoViewModel.cs` | +| Entidades | PascalCase singular | `Habito.cs`, `Usuario.cs` | +| Servicios (interfaz) | PascalCase con prefijo I | `IServicioHabitos.cs` | +| Servicios (clase) | PascalCase + prefijo Servicio | `ServicioHabitos.cs` | +| DTOs | PascalCase + sufijo Dto | `HabitoDto.cs` | +| Enums | PascalCase | `EstadoMision.cs` | +| Ayudantes | PascalCase descriptivo | `CalculadorXP.cs` | + +--- + +### 3.2 Variables y Propiedades en C# + +```csharp +// CORRECTO — Propiedades de clase: PascalCase +public string NombreCompleto { get; set; } +public int XpTotal { get; set; } +public DateTime FechaRegistro { get; set; } + +// CORRECTO — Variables locales: camelCase +var nombreUsuario = "Carlos"; +int xpGanado = 20; +bool estaActivo = true; + +// CORRECTO — Parámetros de método: camelCase +public async Task CompletarHabito(int habitoId, int usuarioId) + +// CORRECTO — Constantes: MAYUSCULAS_CON_GUION_BAJO +private const int XP_POR_HABITO = 20; +private const int DIAS_GRACIA = 1; + +// INCORRECTO — no usar snake_case ni campos públicos sin propiedad +public string nombre_completo { get; set; } +public string NombreCompleto; +var HabitoId = 5; +``` + +--- + +### 3.3 Nombres en Base de Datos + +``` +Tablas: PascalCase, plural → Usuarios, Habitos, RegistrosHabito +Columnas: PascalCase → NombreCompleto, XpTotal, FechaRegistro +Claves foráneas: NombreTablaOrigen + Id → UsuarioId, HabitoId, CarreraId +``` + +--- + +### 3.4 Estructura de Métodos en Controladores + +```csharp +public class HabitosController : Controller +{ + private readonly IServicioHabitos _servicioHabitos; + + public HabitosController(IServicioHabitos servicioHabitos) + { + _servicioHabitos = servicioHabitos; + } + + // GET: /Habitos + public async Task Index() + { + var usuarioId = ObtenerUsuarioIdActual(); + var habitos = await _servicioHabitos.ObtenerHabitosDeUsuario(usuarioId); + return View(habitos); + } + + // GET: /Habitos/Crear + public IActionResult Crear() + { + return View(new CrearHabitoViewModel()); + } + + // POST: /Habitos/Crear + [HttpPost] + [ValidateAntiForgeryToken] + public async Task Crear(CrearHabitoViewModel modelo) + { + if (!ModelState.IsValid) + return View(modelo); + + await _servicioHabitos.CrearHabito(modelo, ObtenerUsuarioIdActual()); + TempData["Exito"] = "Hábito creado correctamente."; + return RedirectToAction(nameof(Index)); + } + + private int ObtenerUsuarioIdActual() + { + return int.Parse(User.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? "0"); + } +} +``` + +--- + +### 3.5 Comentarios + +```csharp +// Comentario de una línea para aclarar lógica no obvia +// El día de gracia solo se puede usar una vez por racha activa + +/// +/// Calcula el XP necesario para pasar al siguiente nivel. +/// Fórmula: 100 + (nivelActual x 50) +/// +public int CalcularXpParaSiguienteNivel(int nivelActual) +{ + return 100 + (nivelActual * 50); +} +``` + +--- + +### 3.6 Validaciones en ViewModels + +```csharp +public class CrearHabitoViewModel +{ + [Required(ErrorMessage = "El nombre del hábito es obligatorio.")] + [MaxLength(200, ErrorMessage = "El nombre no puede tener más de 200 caracteres.")] + public string Nombre { get; set; } + + [Required(ErrorMessage = "Selecciona una categoría.")] + public int CategoriaId { get; set; } + + [Required(ErrorMessage = "Selecciona la frecuencia del hábito.")] + public string Frecuencia { get; set; } + + public bool ConPomodoro { get; set; } = false; +} +``` + +--- + +### 3.7 Nombrado de Rutas + +``` +/ → Dashboard +/autenticacion/login → Login +/autenticacion/registro → Registro +/habitos → Lista de hábitos +/habitos/crear → Crear hábito +/habitos/editar/{id} → Editar hábito +/pomodoro → Módulo Pomodoro +/misiones → Lista de misiones +/misiones/crear → Crear misión +/progreso → Estadísticas +/perfil → Perfil del usuario +/ajustes → Ajustes +/admin → Panel admin (requiere rol Administrador) +``` + +--- + +## 4. Colores, Estilo y Librerías CSS + +### 4.1 Librería CSS: Bootstrap 5.3 + +**Por qué Bootstrap 5:** +- No requiere proceso de compilación. Funciona con CDN o archivos locales, listo para subir a Hostinger VPS. +- Copilot lo conoce muy bien y genera código correcto y consistente. +- Las variables CSS nativas hacen que cambiar de tema sea solo intercambiar un archivo. +- Bootstrap Icons incluye más de 2,000 íconos sin dependencias extra. +- Documentación extensa, ideal para principiantes. + +**CDN para `_Layout.cshtml`:** +```html + + + + + + + + + + + + + + + + + + + + + +``` + +--- + +### 4.2 Paleta — Modo Oscuro "Noche Épica" + +> Fondo negro azulado, azul eléctrico como color principal, cyan como acento brillante. Para sesiones nocturnas de estudio intenso. + +```css +/* Archivo: /wwwroot/css/temas/tema-noche-epica.css */ + +:root { + /* Fondos */ + --ep-fondo: #070B14; + --ep-superficie: #0E1420; + --ep-superficie-2: #141B2D; + --ep-borde: #1E293B; + + /* Colores principales */ + --ep-primario: #3B82F6; + --ep-primario-hover: #2563EB; + --ep-acento: #6366F1; + --ep-neon: #00D4FF; + --ep-neon-suave: rgba(0, 212, 255, 0.12); + --ep-neon-borde: rgba(0, 212, 255, 0.30); + + /* Textos */ + --ep-texto: #F1F5F9; + --ep-texto-secundario: #94A3B8; + --ep-texto-apagado: #475569; + + /* Estados */ + --ep-exito: #10B981; + --ep-advertencia: #F59E0B; + --ep-peligro: #EF4444; + --ep-info: #38BDF8; + + /* Gamificación */ + --ep-xp: #FACC15; + --ep-xp-suave: rgba(250, 204, 21, 0.15); + --ep-racha: #F97316; + --ep-racha-suave: rgba(249, 115, 22, 0.15); + --ep-nivel: #A78BFA; + + /* Barra XP */ + --ep-barra-xp-fondo: #1E293B; + --ep-barra-xp-relleno: linear-gradient(90deg, #3B82F6, #00D4FF); + + /* Navegación */ + --ep-nav-fondo: #0A0F1E; + --ep-nav-item-hover: rgba(59, 130, 246, 0.15); + --ep-nav-item-activo: rgba(59, 130, 246, 0.25); + --ep-nav-texto: #94A3B8; + --ep-nav-texto-activo: #00D4FF; + + /* Sombras */ + --ep-sombra: 0 4px 24px rgba(0, 0, 0, 0.60); + --ep-sombra-neon: 0 0 20px rgba(0, 212, 255, 0.20); + --ep-sombra-primario: 0 4px 15px rgba(59, 130, 246, 0.30); + + /* Radios */ + --ep-radio: 12px; + --ep-radio-sm: 8px; + --ep-radio-lg: 20px; +} +``` + +**Referencia rápida de colores:** +``` +Fondos: #070B14 · #0E1420 · #141B2D · #1E293B +Colores: #3B82F6 (primario) · #6366F1 (acento) · #00D4FF (neon) +Textos: #F1F5F9 · #94A3B8 · #475569 +Extra: #FACC15 (XP) · #F97316 (racha) · #10B981 (exito) +``` + +--- + +### 4.3 Paleta — Modo Claro "Sakura" + +> Fondo lavanda suave, púrpura como color principal, rosa como acento. Ordenado, luminoso y motivador. + +```css +/* Archivo: /wwwroot/css/temas/tema-sakura.css */ + +:root { + /* Fondos */ + --ep-fondo: #FDF4FF; + --ep-superficie: #FFFFFF; + --ep-superficie-2: #F5E6FF; + --ep-borde: #E9D5FF; + + /* Colores principales */ + --ep-primario: #A855F7; + --ep-primario-hover: #9333EA; + --ep-acento: #EC4899; + --ep-neon: #C084FC; + --ep-neon-suave: rgba(192, 132, 252, 0.12); + --ep-neon-borde: rgba(192, 132, 252, 0.40); + + /* Textos */ + --ep-texto: #1E1B4B; + --ep-texto-secundario: #6B7280; + --ep-texto-apagado: #9CA3AF; + + /* Estados */ + --ep-exito: #059669; + --ep-advertencia: #D97706; + --ep-peligro: #DC2626; + --ep-info: #7C3AED; + + /* Gamificación */ + --ep-xp: #F59E0B; + --ep-xp-suave: rgba(245, 158, 11, 0.12); + --ep-racha: #F97316; + --ep-racha-suave: rgba(249, 115, 22, 0.10); + --ep-nivel: #A855F7; + + /* Barra XP */ + --ep-barra-xp-fondo: #E9D5FF; + --ep-barra-xp-relleno: linear-gradient(90deg, #A855F7, #EC4899); + + /* Navegación */ + --ep-nav-fondo: #FFFFFF; + --ep-nav-item-hover: rgba(168, 85, 247, 0.08); + --ep-nav-item-activo: rgba(168, 85, 247, 0.15); + --ep-nav-texto: #6B7280; + --ep-nav-texto-activo: #A855F7; + + /* Sombras */ + --ep-sombra: 0 4px 24px rgba(168, 85, 247, 0.10); + --ep-sombra-neon: 0 0 20px rgba(192, 132, 252, 0.15); + --ep-sombra-primario: 0 4px 15px rgba(168, 85, 247, 0.20); + + /* Radios */ + --ep-radio: 12px; + --ep-radio-sm: 8px; + --ep-radio-lg: 20px; +} +``` + +**Referencia rápida de colores:** +``` +Fondos: #FDF4FF · #FFFFFF · #F5E6FF · #E9D5FF +Colores: #A855F7 (primario) · #EC4899 (acento) · #C084FC (neon) +Textos: #1E1B4B · #6B7280 · #9CA3AF +Extra: #F59E0B (XP) · #F97316 (racha) · #059669 (exito) +``` + +--- + +### 4.4 Archivo `site.css` — Estilos Globales + +```css +/* ================================================ + EPYCUS WEB — Estilos Globales + Se carga siempre, independiente del tema activo + ================================================ */ + +body { + font-family: 'Inter', sans-serif; + background-color: var(--ep-fondo); + color: var(--ep-texto); + transition: background-color 0.3s ease, color 0.3s ease; +} + +/* Cards */ +.ep-card { + background-color: var(--ep-superficie); + border: 1px solid var(--ep-borde); + border-radius: var(--ep-radio); + box-shadow: var(--ep-sombra); + padding: 1.5rem; + transition: box-shadow 0.2s ease; +} +.ep-card:hover { box-shadow: var(--ep-sombra-neon); } +.ep-card-neon { border-color: var(--ep-neon-borde); box-shadow: var(--ep-sombra-neon); } + +/* Barra de XP */ +.ep-barra-xp { + height: 10px; + border-radius: 99px; + background-color: var(--ep-barra-xp-fondo); + overflow: hidden; +} +.ep-barra-xp-relleno { + height: 100%; + background: var(--ep-barra-xp-relleno); + border-radius: 99px; + transition: width 0.6s ease; +} + +/* Badges */ +.ep-badge-nivel { + background: var(--ep-neon-suave); + border: 1px solid var(--ep-neon-borde); + color: var(--ep-neon); + border-radius: 99px; + padding: 0.25rem 0.75rem; + font-size: 0.75rem; + font-weight: 600; +} +.ep-badge-xp { + background: var(--ep-xp-suave); + border: 1px solid var(--ep-xp); + color: var(--ep-xp); + border-radius: 99px; + padding: 0.25rem 0.75rem; + font-size: 0.75rem; + font-weight: 700; +} +.ep-badge-racha { + background: var(--ep-racha-suave); + border: 1px solid var(--ep-racha); + color: var(--ep-racha); + border-radius: 99px; + padding: 0.25rem 0.75rem; + font-size: 0.75rem; + font-weight: 700; +} + +/* Botones */ +.btn-ep { + background-color: var(--ep-primario); + color: #fff; + border: none; + border-radius: var(--ep-radio-sm); + padding: 0.6rem 1.5rem; + font-weight: 600; + transition: background-color 0.2s, box-shadow 0.2s; +} +.btn-ep:hover { + background-color: var(--ep-primario-hover); + box-shadow: var(--ep-sombra-primario); + color: #fff; +} +.btn-ep-outline { + background-color: transparent; + color: var(--ep-primario); + border: 1.5px solid var(--ep-primario); + border-radius: var(--ep-radio-sm); + padding: 0.6rem 1.5rem; + font-weight: 600; + transition: all 0.2s; +} +.btn-ep-outline:hover { background-color: var(--ep-primario); color: #fff; } + +/* Inputs */ +.ep-input { + background-color: var(--ep-superficie-2); + border: 1px solid var(--ep-borde); + border-radius: var(--ep-radio-sm); + color: var(--ep-texto); + padding: 0.6rem 1rem; + width: 100%; + transition: border-color 0.2s, box-shadow 0.2s; +} +.ep-input:focus { + border-color: var(--ep-primario); + box-shadow: 0 0 0 3px var(--ep-neon-suave); + outline: none; + background-color: var(--ep-superficie-2); + color: var(--ep-texto); +} + +/* Sidebar */ +.ep-sidebar { + background-color: var(--ep-nav-fondo); + border-right: 1px solid var(--ep-borde); + width: 260px; + min-height: 100vh; + position: fixed; + top: 0; + left: 0; +} +.ep-nav-item { + display: flex; + align-items: center; + gap: 0.75rem; + padding: 0.75rem 1.25rem; + color: var(--ep-nav-texto); + text-decoration: none; + border-radius: var(--ep-radio-sm); + margin: 0.1rem 0.5rem; + font-weight: 500; + transition: all 0.2s; +} +.ep-nav-item:hover { background-color: var(--ep-nav-item-hover); color: var(--ep-nav-texto-activo); } +.ep-nav-item.activo { background-color: var(--ep-nav-item-activo); color: var(--ep-nav-texto-activo); } + +/* Contenido principal */ +.ep-contenido { + margin-left: 260px; + padding: 2rem; + min-height: 100vh; +} + +/* Estados */ +.ep-estado-completado { color: var(--ep-exito); } +.ep-estado-pendiente { color: var(--ep-advertencia); } +.ep-estado-fallido { color: var(--ep-peligro); } + +/* Título con gradiente */ +.ep-texto-gradiente { + background: linear-gradient(135deg, var(--ep-primario), var(--ep-neon)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +/* Separador */ +.ep-separador { + border: none; + border-top: 1px solid var(--ep-borde); + margin: 1.5rem 0; +} + +/* Responsive */ +@media (max-width: 768px) { + .ep-sidebar { display: none; } + .ep-contenido { margin-left: 0; padding: 1rem; } +} +``` + +--- + +### 4.5 Tipografía + +| Uso | Tamaño | Peso | +|---|---|---| +| Título de página | `1.75rem` | 700 | +| Subtítulo / Card | `1.1rem` | 600 | +| Texto normal | `1rem` | 400 | +| Texto secundario / labels | `0.875rem` | 400 | +| Badges / Tags | `0.75rem` | 600 | +| Número XP grande | `2rem` | 700 | + +**Fuente:** `Inter` (Google Fonts) — moderna, legible, gratuita. + +--- + +### 4.6 Sistema de Cambio de Tema + +```javascript +/* /wwwroot/js/site.js */ + +function cambiarTema(nombreArchivoCss) { + const hojaTema = document.getElementById('hoja-tema'); + hojaTema.href = '/css/temas/' + nombreArchivoCss; + localStorage.setItem('epycus_tema', nombreArchivoCss); +} + +document.addEventListener('DOMContentLoaded', function () { + const temaGuardado = localStorage.getItem('epycus_tema'); + if (temaGuardado) { + const hojaTema = document.getElementById('hoja-tema'); + if (hojaTema) hojaTema.href = '/css/temas/' + temaGuardado; + } +}); +``` + +> Para agregar un tema futuro: crear el archivo `.css` con las mismas variables `--ep-*`, guardarlo en `/css/temas/`, y registrarlo en la tabla `Temas`. No hay que tocar ningún otro archivo. + +--- + +## 5. División de Módulos por Integrante + +### 5.1 Asignación de Módulos + +| Integrante | Módulos | Complejidad | +|---|---|---| +| Tú (Líder) | Auth + Gamificación + Dashboard | Alta | +| Integrante 2 | Hábitos + Pomodoro | Media | +| Integrante 3 | Misiones + Progreso | Media | +| Integrante 4 | Perfil + Ajustes + Admin | Media-Baja | + +--- + +### 5.2 Detalle de Tareas por Módulo + +--- + +#### TU (LIDER) — Auth · Gamificación · Dashboard + +**Semana 1 (antes del jueves 7):** +- [ ] Crear proyecto ASP.NET 10 Core MVC en Visual Studio 2026 +- [ ] Configurar conexión a MariaDB con EF Core +- [ ] Crear todas las entidades en `Modelos/Entidades/` +- [ ] Crear `ContextoAplicacion.cs` con todos los DbSets +- [ ] Ejecutar migraciones y verificar tablas en XAMPP +- [ ] Ejecutar seed de datos iniciales (Niveles, Logros, Frases, Tips, Temas, Carreras) +- [ ] Implementar registro manual (correo + contraseña con BCrypt) +- [ ] Implementar login con Google OAuth +- [ ] Pantalla "Completar Perfil" después de Google +- [ ] Verificación de correo electrónico +- [ ] Recuperación de contraseña +- [ ] Generación de código único `EPY-XXXXXXXX` +- [ ] Middleware de autenticación y autorización por roles +- [ ] Subir proyecto base a carpeta `01_Principal` en Drive + +**Semana 2 (antes del jueves 14):** +- [ ] `ServicioGamificacion`: sumar XP, verificar subida de nivel, actualizar racha con día de gracia +- [ ] `CalculadorXP.cs`: fórmulas de XP y niveles +- [ ] Verificación automática de logros después de cada acción que da XP +- [ ] Selección automática de personaje al registrarse (según carrera y género) +- [ ] Lógica de imagen del personaje según nivel actual +- [ ] `DashboardController` + vista completa con: personaje, barra XP, nivel, título, racha, frase del día, hábitos pendientes, estado de ánimo + +--- + +#### INTEGRANTE 2 — Hábitos + Pomodoro + +> Siempre descargar desde `01_Principal` en Drive. No modificar archivos fuera de tu módulo. + +**Semana 1 (antes del jueves 7):** +- [ ] Leer este documento completo +- [ ] Explorar entidades: `Habito`, `RegistroHabito`, `Categoria`, `ConfiguracionPomodoro`, `SesionPomodoro` + +**Semana 2 (antes del jueves 14):** +- [ ] `HabitosController`: Index, Crear, Editar, Eliminar, Completar (acción POST) +- [ ] `Views/Habitos/Index.cshtml`: lista con pestañas Pendientes / Completados / Fallidos +- [ ] `Views/Habitos/Crear.cshtml`: formulario con categoría, frecuencia, recordatorio, opción Pomodoro +- [ ] Seguimiento semanal visual Lunes a Domingo con íconos +- [ ] `ServicioHabitos`: CRUD + marcar completado + racha del hábito +- [ ] Al completar hábito: llamar `_servicioGamificacion.SumarXP(usuarioId, 20)` + +**Semana 3 (antes del jueves 21):** +- [ ] `PomodoroController` + `Views/Pomodoro/Index.cshtml` +- [ ] Temporizador en `pomodoro.js`: cuenta regresiva, ciclos, pantalla completa +- [ ] Guardar sesión al terminar en `SesionesPomodoro` +- [ ] Al completar ciclo: llamar `_servicioGamificacion.SumarXP(usuarioId, 15)` +- [ ] Mostrar tips del Pomodoro de forma aleatoria +- [ ] Configuración personalizable: tiempo de estudio, descanso, ciclos +- [ ] Sonido de notificación al terminar el ciclo + +--- + +#### INTEGRANTE 3 — Misiones + Progreso + +> Siempre descargar desde `01_Principal` en Drive. No modificar archivos fuera de tu módulo. + +**Semana 1 (antes del jueves 7):** +- [ ] Leer este documento completo +- [ ] Explorar entidades: `Mision`, `Categoria`, `LogroUsuario`, `EstadoAnimo`, `ProgresoUsuario` + +**Semana 2 (antes del jueves 14):** +- [ ] `MisionesController`: Index, Crear, Editar, Eliminar, CambiarEstado +- [ ] `Views/Misiones/Index.cshtml`: lista con filtros por estado y prioridad, colores por prioridad +- [ ] `Views/Misiones/Crear.cshtml`: formulario con categoría, nombre de curso, fecha límite, prioridad +- [ ] `ServicioMisiones`: CRUD + cambio de estado + XP al completar según prioridad +- [ ] Al completar: llamar `_servicioGamificacion.SumarXP(usuarioId, xp)` (30/50/80 según prioridad) + +**Semana 3 (antes del jueves 21):** +- [ ] `ProgresoController` + `Views/Progreso/Index.cshtml` +- [ ] Gráfico de hábitos completados por semana (Chart.js — barras) +- [ ] Gráfico de XP acumulado por semana (Chart.js — líneas) +- [ ] Lista de logros: desbloqueados con fecha y bloqueados con barra de progreso +- [ ] Historial de estados de ánimo con ícono por tipo +- [ ] KPIs: hábitos completados, misiones totales, racha máxima, XP total, sesiones Pomodoro + +--- + +#### INTEGRANTE 4 — Perfil + Ajustes + Admin + +> Siempre descargar desde `01_Principal` en Drive. No modificar archivos fuera de tu módulo. + +**Semana 1 (antes del jueves 7):** +- [ ] Leer este documento completo +- [ ] Explorar entidades: `Usuario`, `Personaje`, `ImagenNivelPersonaje`, `PersonajeUsuario`, `Tema`, `Suscripcion` + +**Semana 2 (antes del jueves 14):** +- [ ] `PerfilController` + `Views/Perfil/Index.cshtml` +- [ ] Mostrar: nombre, código `EPY-XXXXXXXX`, carrera, nivel con título combinado, personaje con imagen del nivel actual +- [ ] Editar: nombre, fecha de nacimiento, género, carrera +- [ ] Galería de personajes con selector visual + +**Semana 3 (antes del jueves 21):** +- [ ] `AjustesController` + `Views/Ajustes/Index.cshtml` +- [ ] Cambio de contraseña con validación BCrypt +- [ ] Selector de tema visual con preview (Noche Épica / Sakura) +- [ ] Vinculación y desvinculación de Google +- [ ] Eliminación de cuenta con pantalla de aviso y confirmación +- [ ] `AdminController` con atributo `[Authorize(Roles = "Administrador")]`: + - Lista paginada de usuarios, buscable por nombre, correo o código único + - Ver detalle del usuario por ID + - Activar/desactivar suscripción premium manualmente + - CRUD de frases motivacionales + - Métricas: total usuarios, activos hoy, suscripciones activas + +--- + +### 5.3 Cronograma Scrumban + +``` +SEMANA 1: Sprint Arranque — 4 al 7 de mayo +─────────────────────────────────────────────────────── +Lun 04/05 REUNION DE INICIO (5:00 – 5:30 pm) + - Presentar este documento al equipo + - Mostrar la estructura del proyecto en VS + - Cada uno descarga el proyecto base de 01_Principal + - Asignar módulos formalmente +Mar 05/05 Clase Capstone (presencial) + - Lectura del documento + explorar entidades asignadas +Mié 06/05 Trabajo individual con Copilot +Jue 07/05 REUNION DE REVISION + - Cada uno muestra su avance y entiende su módulo + - Líder integra en 01_Principal y todos descargan + +SEMANA 2: Sprint Módulos Principales — 7 al 14 de mayo +─────────────────────────────────────────────────────── +Vie 08/05 Trabajo individual +Lun 11/05 REUNION DE SEGUIMIENTO + - Mostrar avances: Auth/Dashboard, Hábitos, Misiones, Perfil + - Resolver dudas de integración +Mar 12/05 Clase Capstone (presencial) +Mié 13/05 Trabajo individual / correcciones +Jue 14/05 REUNION DE REVISION + - Integración de módulos principales + - Líder sube versión integrada a 01_Principal + - Todos descargan y continúan + +SEMANA 3: Sprint Módulos Secundarios — 14 al 21 de mayo +─────────────────────────────────────────────────────── +Lun 18/05 REUNION DE SEGUIMIENTO + - Mostrar: Pomodoro, Progreso, Ajustes, Admin + - Verificar que el cambio de tema funciona +Mar 19/05 Clase Capstone (presencial) +Mié 20/05 Trabajo individual / ajustes y pruebas +Jue 21/05 REUNION DE REVISION + - Integración final de todos los módulos + - Pruebas en conjunto + +SEMANA 4: Cierre — 21 al 25 de mayo +─────────────────────────────────────────────────────── +Lun 25/05 ENTREGA FINAL + - Sistema completo y funcionando + - Líder sube el proyecto final a GitHub + - Presentación para Capstone Project +``` + +--- + +### 5.4 Flujo de Trabajo con Google Drive + +``` +ESTRUCTURA DE CARPETAS EN DRIVE: +────────────────────────────────────────────────────── +📁 EPYCUS_WEB/ +│ +├── 📁 01_Principal/ ← Versión integrada y funcional +│ └── EpycusWeb_v1.0.zip (actualizada cada jueves por el líder) +│ +├── 📁 02_Lider/ +│ └── EpycusWeb_lider.zip +│ +├── 📁 03_Integrante2/ +│ └── EpycusWeb_int2.zip +│ +├── 📁 04_Integrante3/ +│ └── EpycusWeb_int3.zip +│ +└── 📁 05_Integrante4/ + └── EpycusWeb_int4.zip + +FLUJO CADA JUEVES: + 1. Cada integrante comprime su carpeta del proyecto + 2. Sube el .zip a SU carpeta personal en Drive + 3. El líder descarga los 3 .zip + 4. Copia SOLO los archivos del módulo de cada uno + al proyecto principal + 5. Prueba que todo funcione junto + 6. Sube el proyecto integrado a 01_Principal/ + 7. Cada integrante descarga el nuevo 01_Principal para continuar + +QUE EXCLUIR AL COMPRIMIR (para que el .zip no sea muy pesado): + - Carpeta bin/ + - Carpeta obj/ + - Carpeta .vs/ + Solo comprimir código fuente y wwwroot. + +REGLA FUNDAMENTAL: + Cada integrante SOLO modifica los archivos de SU módulo. + Si necesitas cambiar algo de otro módulo, consúltalo + primero con el líder antes de tocarlo. +``` + +--- + +### 5.5 Instrucción para Copilot (Dar a cada integrante) + +> Copia este texto y pégalo en Copilot al inicio de cada sesión de trabajo, antes de pedir cualquier código. + +``` +Estoy trabajando en el proyecto EPYCUS WEB. Reglas obligatorias del proyecto: + +Framework: ASP.NET 10 Core MVC con Razor Views +Base de datos: MariaDB con Entity Framework Core (Pomelo.EntityFrameworkCore.MySql) +CSS: Bootstrap 5.3 + Bootstrap Icons 1.11 +Gráficos: Chart.js 4 (solo en el módulo de Progreso) +Idioma del código: TODO en español (variables, métodos, clases, comentarios) + +Convenciones: +- Clases y propiedades: PascalCase +- Variables locales y parámetros: camelCase +- Controladores: sufijo Controller (ej: HabitosController) +- Interfaces de servicios: prefijo I (ej: IServicioHabitos) +- Clases de servicios: prefijo Servicio (ej: ServicioHabitos) +- DbContext se llama: ContextoAplicacion +- Mensajes de validación: siempre en español +- Los controladores inyectan servicios por interfaz en el constructor con _nombreServicio +- Toda acción que da XP debe llamar a IServicioGamificacion +- Nunca usar inglés en nombres de variables, métodos ni comentarios +``` + +--- + +*Documento base EPYCUS WEB — Capstone Project 2026* +*Versión 2.0 — Mayo 2026* diff --git a/Documentacion/EPYCUS_WEB_Especificacion_Tecnica.md b/Documentacion/EPYCUS_WEB_Especificacion_Tecnica.md new file mode 100644 index 0000000..9b1e431 --- /dev/null +++ b/Documentacion/EPYCUS_WEB_Especificacion_Tecnica.md @@ -0,0 +1,1376 @@ +# EPYCUS WEB — Especificación Técnica Complementaria +**Complemento obligatorio del Documento Base** +**ASP.NET 10 Core MVC · MariaDB · Entity Framework Core** + +--- + +> **¿Para qué sirve este documento?** +> El Documento Base define la BD, arquitectura, convenciones y división de trabajo. +> Este documento define lo que una IA necesita para generar código correcto: +> relaciones de entidades, endpoints, reglas de negocio exactas, lógica de bienestar ODS 3 y seguridad. +> Ambos documentos deben leerse juntos antes de escribir cualquier línea de código. + +--- + +## Índice + +1. [Relaciones del Modelo de Datos](#1-relaciones-del-modelo-de-datos) +2. [Arquitectura MVC vs API — Separación Clara](#2-arquitectura-mvc-vs-api--separación-clara) +3. [Catálogo de Endpoints](#3-catálogo-de-endpoints) +4. [Reglas de Negocio Determinísticas](#4-reglas-de-negocio-determinísticas) +5. [Lógica ODS 3 — Bienestar Explícito](#5-lógica-ods-3--bienestar-explícito) +6. [Seguridad y Autorización](#6-seguridad-y-autorización) +7. [Configuración de Entity Framework Core](#7-configuración-de-entity-framework-core) + +--- + +## 1. Relaciones del Modelo de Datos + +### 1.1 Mapa de Relaciones + +``` +Roles ──────────────── (1:N) ──────────────── Usuarios +Carreras ───────────── (1:N) ──────────────── Usuarios +Usuarios ───────────── (1:1) ──────────────── ProgresosUsuario +Usuarios ───────────── (1:N) ──────────────── Habitos +Usuarios ───────────── (1:N) ──────────────── Misiones +Usuarios ───────────── (1:N) ──────────────── SesionesPomodoro +Usuarios ───────────── (1:1) ──────────────── ConfiguracionesPomodoro +Usuarios ───────────── (1:N) ──────────────── PersonajesUsuario +Usuarios ───────────── (1:N) ──────────────── LogrosUsuario +Usuarios ───────────── (1:N) ──────────────── EstadosAnimo +Usuarios ───────────── (1:N) ──────────────── Suscripciones +Usuarios ───────────── (1:N) ──────────────── TemasUsuario +Usuarios ───────────── (1:N) ──────────────── TokensRefresh +Usuarios ───────────── (1:N) ──────────────── VerificacionesCorreo +Usuarios ───────────── (1:N) ──────────────── RecuperacionesContrasena +Niveles ────────────── (1:N) ──────────────── ProgresosUsuario +Habitos ────────────── (1:N) ──────────────── RegistrosHabito +Habitos ────────────── (1:N) ──────────────── SesionesPomodoro (opcional) +Misiones ───────────── (1:N) ──────────────── SesionesPomodoro (opcional) +Categorias ─────────── (1:N) ──────────────── Habitos +Categorias ─────────── (1:N) ──────────────── Misiones +Personajes ─────────── (1:N) ──────────────── PersonajesUsuario +Personajes ─────────── (1:N) ──────────────── ImagenesNivelPersonaje +Logros ─────────────── (1:N) ──────────────── LogrosUsuario +Temas ──────────────── (1:N) ──────────────── TemasUsuario +``` + +--- + +### 1.2 Entidades C# con Propiedades de Navegación + +> Estas clases van en `Modelos/Entidades/`. Copiar exactamente para que EF Core genere las migraciones correctas. + +#### `Usuario.cs` +```csharp +public class Usuario +{ + public int Id { get; set; } + public string CodigoUnico { get; set; } // EPY-XXXXXXXX + public string Nombre { get; set; } + public string CorreoElectronico { get; set; } + public string? ContrasenaHash { get; set; } // null si usa solo Google + public DateTime FechaNacimiento { get; set; } + public string Genero { get; set; } + public bool CorreoVerificado { get; set; } = false; + public bool AceptoTerminos { get; set; } = false; + public bool EstaActivo { get; set; } = true; + public DateTime FechaRegistro { get; set; } = DateTime.Now; + public DateTime? UltimoAcceso { get; set; } + public string? GoogleId { get; set; } + public string? FotoGoogleUrl { get; set; } + + // Claves foráneas + public int RolId { get; set; } + public int CarreraId { get; set; } + public int? TemaActualId { get; set; } + + // Navegación + public Rol Rol { get; set; } + public Carrera Carrera { get; set; } + public Tema? TemaActual { get; set; } + public ProgresoUsuario Progreso { get; set; } + public ICollection Habitos { get; set; } + public ICollection Misiones { get; set; } + public ICollection SesionesPomodoro { get; set; } + public ConfiguracionPomodoro ConfiguracionPomodoro { get; set; } + public ICollection PersonajesUsuario { get; set; } + public ICollection LogrosUsuario { get; set; } + public ICollection EstadosAnimo { get; set; } + public ICollection Suscripciones { get; set; } + public ICollection TemasUsuario { get; set; } + public ICollection TokensRefresh { get; set; } +} +``` + +#### `ProgresoUsuario.cs` +```csharp +public class ProgresoUsuario +{ + public int Id { get; set; } + public int XpTotal { get; set; } = 0; + public int RachaActual { get; set; } = 0; + public int RachaMaxima { get; set; } = 0; + public DateTime? FechaUltimaActividad { get; set; } + public DateTime? FechaInicioRacha { get; set; } + public bool DiaDeGraciaUsado { get; set; } = false; + public decimal ProductividadDiaria { get; set; } = 0; + + // Claves foráneas + public int UsuarioId { get; set; } + public int NivelActualId { get; set; } + + // Navegación + public Usuario Usuario { get; set; } + public Nivel NivelActual { get; set; } +} +``` + +#### `Habito.cs` +```csharp +public class Habito +{ + public int Id { get; set; } + public string Nombre { get; set; } + public string? Descripcion { get; set; } + public string Frecuencia { get; set; } // "Diaria", "Semanal", "Personalizada" + public string? DiasSemana { get; set; } // JSON: "[1,3,5]" + public bool ConPomodoro { get; set; } = false; + public TimeSpan? RecordatorioHora { get; set; } + public int RachaActual { get; set; } = 0; + public int RachaMaxima { get; set; } = 0; + public bool EstaActivo { get; set; } = true; + public DateTime FechaCreacion { get; set; } = DateTime.Now; + + // Claves foráneas + public int UsuarioId { get; set; } + public int CategoriaId { get; set; } + + // Navegación + public Usuario Usuario { get; set; } + public Categoria Categoria { get; set; } + public ICollection Registros { get; set; } + public ICollection SesionesPomodoro { get; set; } +} +``` + +#### `RegistroHabito.cs` +```csharp +public class RegistroHabito +{ + public int Id { get; set; } + public DateOnly Fecha { get; set; } + public string Estado { get; set; } // "Completado", "Fallido", "Pendiente" + public int XpOtorgado { get; set; } = 0; + public DateTime FechaRegistro { get; set; } = DateTime.Now; + + // Claves foráneas + public int HabitoId { get; set; } + + // Navegación + public Habito Habito { get; set; } +} +``` + +#### `Mision.cs` +```csharp +public class Mision +{ + public int Id { get; set; } + public string Nombre { get; set; } + public string? Descripcion { get; set; } + public string? NombreCurso { get; set; } + public DateOnly FechaLimite { get; set; } + public string Prioridad { get; set; } // "Baja", "Media", "Alta" + public string Estado { get; set; } // "Pendiente", "EnProgreso", "Completado", "Fallido" + public bool ConPomodoro { get; set; } = false; + public int XpOtorgado { get; set; } = 0; + public DateTime FechaCreacion { get; set; } = DateTime.Now; + public DateTime? FechaCompletado { get; set; } + + // Claves foráneas + public int UsuarioId { get; set; } + public int CategoriaId { get; set; } + + // Navegación + public Usuario Usuario { get; set; } + public Categoria Categoria { get; set; } + public ICollection SesionesPomodoro { get; set; } +} +``` + +#### `SesionPomodoro.cs` +```csharp +public class SesionPomodoro +{ + public int Id { get; set; } + public DateTime FechaInicio { get; set; } + public DateTime? FechaFin { get; set; } + public int CiclosCompletados { get; set; } = 0; + public int XpOtorgado { get; set; } = 0; + public bool FueCompletada { get; set; } = false; + + // Claves foráneas + public int UsuarioId { get; set; } + public int? HabitoId { get; set; } // Opcional + public int? MisionId { get; set; } // Opcional + + // Navegación + public Usuario Usuario { get; set; } + public Habito? Habito { get; set; } + public Mision? Mision { get; set; } +} +``` + +#### `EstadoAnimo.cs` +```csharp +public class EstadoAnimo +{ + public int Id { get; set; } + public DateOnly Fecha { get; set; } + public string Estado { get; set; } // "Feliz", "Bien", "Neutral", "Cansado", "Estresado" + public string? Nota { get; set; } + public DateTime FechaRegistro { get; set; } = DateTime.Now; + + // Clave foránea + public int UsuarioId { get; set; } + + // Navegación + public Usuario Usuario { get; set; } +} +``` + +#### `Nivel.cs` +```csharp +public class Nivel +{ + public int Id { get; set; } + public int Numero { get; set; } // 0 al 20 + public string Titulo { get; set; } + public int XpRequerido { get; set; } + public string? Descripcion { get; set; } + + // Navegación + public ICollection Progresos { get; set; } +} +``` + +#### `Personaje.cs` +```csharp +public class Personaje +{ + public int Id { get; set; } + public string Nombre { get; set; } + public string Genero { get; set; } // "Masculino", "Femenino" + public bool EstaActivo { get; set; } = true; + public int? CarreraId { get; set; } // null = genérico para todas + + // Navegación + public Carrera? Carrera { get; set; } + public ICollection Imagenes { get; set; } + public ICollection PersonajesUsuario { get; set; } +} +``` + +#### `ImagenNivelPersonaje.cs` +```csharp +public class ImagenNivelPersonaje +{ + public int Id { get; set; } + public int NivelNumero { get; set; } // 0 al 20 + public string ImagenUrl { get; set; } + public bool EsPlaceholder { get; set; } = false; + + // Clave foránea + public int PersonajeId { get; set; } + + // Navegación + public Personaje Personaje { get; set; } +} +``` + +--- + +## 2. Arquitectura MVC vs API — Separación Clara + +### 2.1 Decisión de Arquitectura + +Este proyecto usa **ASP.NET Core MVC con Razor Views** como arquitectura principal. Dentro del mismo proyecto existen dos tipos de controladores: + +``` +EpycusWeb/ +├── Controllers/ ← Controladores MVC (devuelven Views HTML) +│ ├── DashboardController.cs +│ ├── HabitosController.cs +│ └── ... +└── Controllers/Api/ ← Controladores API (devuelven JSON para AJAX) + ├── ApiHabitosController.cs + ├── ApiPomodoroController.cs + ├── ApiGamificacionController.cs + └── ApiEstadoAnimoController.cs +``` + +### 2.2 ¿Cuándo usar MVC (Razor View)? + +Usar cuando la acción carga una página completa: +- Navegar al módulo de Hábitos → `GET /habitos` → devuelve `Index.cshtml` +- Abrir formulario de crear hábito → `GET /habitos/crear` → devuelve `Crear.cshtml` +- Hacer login → `POST /autenticacion/login` → redirige o devuelve `Login.cshtml` con errores + +### 2.3 ¿Cuándo usar API (JSON)? + +Usar cuando la acción ocurre **sin recargar la página** (AJAX desde JavaScript): +- Marcar un hábito como completado con un click → `POST /api/habitos/{id}/completar` +- Guardar el estado de ánimo diario → `POST /api/estado-animo` +- Actualizar el temporizador Pomodoro → `POST /api/pomodoro/iniciar` +- Obtener el XP actualizado después de una acción → `GET /api/gamificacion/mi-progreso` + +### 2.4 Decoradores de los Controladores + +```csharp +// Controlador MVC — devuelve Views +public class HabitosController : Controller { ... } + +// Controlador API — devuelve JSON +[ApiController] +[Route("api/[controller]")] +public class ApiHabitosController : ControllerBase { ... } +``` + +--- + +## 3. Catálogo de Endpoints + +### 3.1 Rutas MVC (Razor Views) + +| Método | Ruta | Controlador / Acción | Auth | Descripción | +|---|---|---|---|---| +| GET | `/autenticacion/login` | `Autenticacion/Login` | No | Formulario de login | +| POST | `/autenticacion/login` | `Autenticacion/Login` | No | Procesar login | +| GET | `/autenticacion/registro` | `Autenticacion/Registro` | No | Formulario de registro | +| POST | `/autenticacion/registro` | `Autenticacion/Registro` | No | Procesar registro | +| GET | `/autenticacion/completar-perfil` | `Autenticacion/CompletarPerfil` | Sí | Completar datos tras Google | +| POST | `/autenticacion/completar-perfil` | `Autenticacion/CompletarPerfil` | Sí | Guardar datos faltantes | +| GET | `/autenticacion/verificar-correo` | `Autenticacion/VerificarCorreo` | No | Verificar token de email | +| GET | `/autenticacion/recuperar` | `Autenticacion/RecuperarContrasena` | No | Solicitar recuperación | +| POST | `/autenticacion/recuperar` | `Autenticacion/RecuperarContrasena` | No | Enviar correo | +| POST | `/autenticacion/nueva-contrasena` | `Autenticacion/NuevaContrasena` | No | Guardar nueva contraseña | +| GET | `/autenticacion/cerrar-sesion` | `Autenticacion/CerrarSesion` | Sí | Logout | +| GET | `/` | `Dashboard/Index` | Sí | Dashboard principal | +| GET | `/habitos` | `Habitos/Index` | Sí | Lista de hábitos | +| GET | `/habitos/crear` | `Habitos/Crear` | Sí | Formulario crear hábito | +| POST | `/habitos/crear` | `Habitos/Crear` | Sí | Guardar nuevo hábito | +| GET | `/habitos/editar/{id}` | `Habitos/Editar` | Sí | Formulario editar | +| POST | `/habitos/editar/{id}` | `Habitos/Editar` | Sí | Guardar edición | +| POST | `/habitos/eliminar/{id}` | `Habitos/Eliminar` | Sí | Eliminar hábito | +| GET | `/pomodoro` | `Pomodoro/Index` | Sí | Módulo Pomodoro | +| GET | `/misiones` | `Misiones/Index` | Sí | Lista de misiones | +| GET | `/misiones/crear` | `Misiones/Crear` | Sí | Formulario crear misión | +| POST | `/misiones/crear` | `Misiones/Crear` | Sí | Guardar misión | +| GET | `/misiones/editar/{id}` | `Misiones/Editar` | Sí | Formulario editar | +| POST | `/misiones/editar/{id}` | `Misiones/Editar` | Sí | Guardar edición | +| POST | `/misiones/eliminar/{id}` | `Misiones/Eliminar` | Sí | Eliminar misión | +| GET | `/progreso` | `Progreso/Index` | Sí | Estadísticas y logros | +| GET | `/perfil` | `Perfil/Index` | Sí | Perfil del usuario | +| POST | `/perfil/editar` | `Perfil/Editar` | Sí | Guardar cambios de perfil | +| POST | `/perfil/cambiar-personaje/{id}` | `Perfil/CambiarPersonaje` | Sí | Cambiar personaje activo | +| GET | `/ajustes` | `Ajustes/Index` | Sí | Pantalla de ajustes | +| POST | `/ajustes/cambiar-contrasena` | `Ajustes/CambiarContrasena` | Sí | Actualizar contraseña | +| POST | `/ajustes/cambiar-tema/{temaId}` | `Ajustes/CambiarTema` | Sí | Cambiar tema visual | +| POST | `/ajustes/desvincular-google` | `Ajustes/DesvincularGoogle` | Sí | Quitar Google OAuth | +| POST | `/ajustes/eliminar-cuenta` | `Ajustes/EliminarCuenta` | Sí | Borrar cuenta completa | +| GET | `/admin` | `Admin/Index` | Admin | Panel admin | +| GET | `/admin/usuarios` | `Admin/Usuarios` | Admin | Lista de usuarios | +| GET | `/admin/usuario/{id}` | `Admin/DetalleUsuario` | Admin | Detalle de un usuario | +| POST | `/admin/suscripcion/activar/{usuarioId}` | `Admin/ActivarSuscripcion` | Admin | Activar premium | +| POST | `/admin/suscripcion/desactivar/{usuarioId}` | `Admin/DesactivarSuscripcion` | Admin | Quitar premium | +| GET | `/admin/frases` | `Admin/Frases` | Admin | Gestionar frases | +| POST | `/admin/frases/crear` | `Admin/CrearFrase` | Admin | Agregar frase | +| POST | `/admin/frases/eliminar/{id}` | `Admin/EliminarFrase` | Admin | Eliminar frase | + +--- + +### 3.2 Rutas API (JSON — usadas por AJAX desde JavaScript) + +**Base URL:** `/api/` +**Headers requeridos:** `Content-Type: application/json` · `Authorization: Bearer {jwt_token}` + +--- + +#### AUTH +| Método | Ruta | Auth | Request Body | Response | +|---|---|---|---|---| +| POST | `/api/auth/login` | No | `{ correo, contrasena }` | `{ token, refreshToken, usuario }` | +| POST | `/api/auth/refresh` | No | `{ refreshToken }` | `{ token, refreshToken }` | +| POST | `/api/auth/logout` | Sí | — | `{ success: true }` | + +--- + +#### HÁBITOS +| Método | Ruta | Auth | Request Body | Response | +|---|---|---|---|---| +| GET | `/api/habitos` | Sí | — | `[{ id, nombre, estado, rachaActual, ... }]` | +| GET | `/api/habitos/hoy` | Sí | — | `[{ id, nombre, estadoHoy, xpPotencial }]` | +| POST | `/api/habitos/{id}/completar` | Sí | — | `{ xpGanado, nuevoXpTotal, subioDeNivel, nivelNuevo? }` | +| POST | `/api/habitos/{id}/fallar` | Sí | — | `{ rachaRota: bool }` | +| GET | `/api/habitos/{id}/semana` | Sí | — | `[{ dia, estado }]` × 7 días | + +--- + +#### POMODORO +| Método | Ruta | Auth | Request Body | Response | +|---|---|---|---|---| +| POST | `/api/pomodoro/iniciar` | Sí | `{ habitoId?, misionId? }` | `{ sesionId, fechaInicio }` | +| POST | `/api/pomodoro/{sesionId}/ciclo-completado` | Sí | `{ ciclosCompletados }` | `{ xpGanado, sugerirDescanso: bool }` | +| POST | `/api/pomodoro/{sesionId}/finalizar` | Sí | `{ ciclosCompletados }` | `{ xpTotal, sesionGuardada: true }` | +| POST | `/api/pomodoro/{sesionId}/cancelar` | Sí | — | `{ success: true }` | +| GET | `/api/pomodoro/configuracion` | Sí | — | `{ tiempoEstudio, tiempoDescanso, ciclos, ... }` | +| PUT | `/api/pomodoro/configuracion` | Sí | `{ tiempoEstudio, tiempoDescanso, ... }` | `{ success: true }` | +| GET | `/api/pomodoro/tip-aleatorio` | Sí | — | `{ tip }` | + +--- + +#### MISIONES +| Método | Ruta | Auth | Request Body | Response | +|---|---|---|---|---| +| POST | `/api/misiones/{id}/completar` | Sí | — | `{ xpGanado, nuevoXpTotal, subioDeNivel }` | +| POST | `/api/misiones/{id}/estado` | Sí | `{ estado }` | `{ success: true }` | + +--- + +#### GAMIFICACIÓN +| Método | Ruta | Auth | Request Body | Response | +|---|---|---|---|---| +| GET | `/api/gamificacion/mi-progreso` | Sí | — | `{ xpTotal, nivel, titulo, rachaActual, xpParaSiguienteNivel, porcentajeProgreso, imagenPersonaje }` | +| GET | `/api/gamificacion/logros` | Sí | — | `[{ logro, desbloqueado, progreso, meta }]` | + +--- + +#### ESTADO DE ÁNIMO +| Método | Ruta | Auth | Request Body | Response | +|---|---|---|---|---| +| POST | `/api/estado-animo` | Sí | `{ estado, nota? }` | `{ success: true, alertaBienestar? }` | +| GET | `/api/estado-animo/historial` | Sí | — | `[{ fecha, estado, nota }]` | + +--- + +#### DASHBOARD +| Método | Ruta | Auth | Request Body | Response | +|---|---|---|---|---| +| GET | `/api/dashboard/resumen` | Sí | — | `{ kpis, habitosPendientes, misionesPendientes, frase }` | +| GET | `/api/dashboard/frase-del-dia` | Sí | — | `{ frase, autor }` | + +--- + +### 3.3 Contrato de Respuesta Estándar de la API + +Todos los endpoints API deben devolver la misma estructura: + +```csharp +// Clase: Ayudantes/RespuestaApi.cs +public class RespuestaApi +{ + public bool Exito { get; set; } + public string? Mensaje { get; set; } + public T? Datos { get; set; } + public List? Errores { get; set; } + + public static RespuestaApi Exitosa(T datos, string? mensaje = null) + => new() { Exito = true, Datos = datos, Mensaje = mensaje }; + + public static RespuestaApi Fallida(string mensaje, List? errores = null) + => new() { Exito = false, Mensaje = mensaje, Errores = errores }; +} + +// Ejemplo de uso en controlador API: +[HttpPost("{id}/completar")] +public async Task Completar(int id) +{ + var resultado = await _servicioHabitos.CompletarHabito(id, ObtenerUsuarioIdActual()); + if (!resultado.Exito) + return BadRequest(RespuestaApi.Fallida(resultado.Mensaje)); + + return Ok(RespuestaApi.Exitosa(resultado.Datos)); +} +``` + +--- + +## 4. Reglas de Negocio Determinísticas + +### 4.1 Sistema de XP — Lógica Exacta + +```csharp +// Clase: Ayudantes/CalculadorXP.cs + +public static class CalculadorXP +{ + // XP por acción + public const int XP_LOGIN_DIARIO = 10; + public const int XP_HABITO_COMPLETADO = 20; + public const int XP_BONUS_RACHA_7_DIAS = 10; // extra por cada hábito con racha múltiplo de 7 + public const int XP_MISION_BAJA = 30; + public const int XP_MISION_MEDIA = 50; + public const int XP_MISION_ALTA = 80; + public const int XP_POMODORO_POR_CICLO = 15; + public const int XP_BONUS_RACHA_GLOBAL_7 = 50; // racha global de 7 días + public const int XP_BONUS_RACHA_GLOBAL_30 = 200; // racha global de 30 días + public const int NIVEL_MAXIMO = 20; + + /// + /// XP adicional necesario para pasar del nivel actual al siguiente. + /// Fórmula: 100 + (nivelActual × 50) + /// + public static int XpParaSiguienteNivel(int nivelActual) + { + if (nivelActual >= NIVEL_MAXIMO) return 0; + return 100 + (nivelActual * 50); + } + + /// + /// XP total acumulado necesario para ALCANZAR un nivel. + /// Suma de todos los XP requeridos desde nivel 0. + /// + public static int XpTotalParaNivel(int nivel) + { + int total = 0; + for (int i = 0; i < nivel; i++) + total += XpParaSiguienteNivel(i); + return total; + } + + /// + /// Determina el nivel correspondiente a un total de XP. + /// + public static int NivelParaXp(int xpTotal) + { + int nivel = 0; + while (nivel < NIVEL_MAXIMO && xpTotal >= XpTotalParaNivel(nivel + 1)) + nivel++; + return nivel; + } + + /// + /// XP del usuario dentro de su nivel actual (para mostrar barra de progreso). + /// + public static int XpDentroDelNivelActual(int xpTotal, int nivelActual) + => xpTotal - XpTotalParaNivel(nivelActual); + + /// + /// Porcentaje de progreso hacia el siguiente nivel (0 a 100). + /// + public static decimal PorcentajeProgreso(int xpTotal, int nivelActual) + { + if (nivelActual >= NIVEL_MAXIMO) return 100; + int xpEnNivel = XpDentroDelNivelActual(xpTotal, nivelActual); + int xpNecesario = XpParaSiguienteNivel(nivelActual); + return Math.Round((decimal)xpEnNivel / xpNecesario * 100, 1); + } + + /// + /// XP por completar una misión según su prioridad. + /// + public static int XpPorMision(string prioridad) => prioridad switch + { + "Alta" => XP_MISION_ALTA, + "Media" => XP_MISION_MEDIA, + "Baja" => XP_MISION_BAJA, + _ => XP_MISION_BAJA + }; +} +``` + +--- + +### 4.2 Sistema de Rachas — Lógica Exacta + +``` +DEFINICIÓN: Un día "activo" es aquel en que el usuario completa al menos 1 hábito programado. + +CASO 1 — Usuario activo hoy: + Condición: Hoy hay al menos 1 hábito marcado como "Completado" + Acción: + - Si FechaUltimaActividad == ayer → RachaActual++ + - Si FechaUltimaActividad == hoy → no cambiar (ya se contó) + - Si FechaUltimaActividad es anterior a ayer → racha rota (ver CASO 3) + - Actualizar FechaUltimaActividad = hoy + - DiaDeGraciaUsado = false (se resetea al ser activo de nuevo) + - Si RachaActual > RachaMaxima → RachaMaxima = RachaActual + - Verificar bonuses de racha (7 días, 30 días) + +CASO 2 — Día de gracia: + Condición: + - Hoy == FechaUltimaActividad + 2 días + - DiaDeGraciaUsado == false + - El usuario hace al menos 1 acción de login + Acción: + - DiaDeGraciaUsado = true + - La racha NO se rompe + - Mostrar notificación: "¡Usaste tu día de gracia! Mañana debes completar al menos un hábito." + - NO sumar RachaActual (el día de gracia es un puente, no un día activo) + +CASO 3 — Racha rota: + Condición: + - Hoy > FechaUltimaActividad + 2 días + - O: DiaDeGraciaUsado == true Y hoy > FechaUltimaActividad + 1 día sin actividad + Acción: + - RachaActual = 0 + - DiaDeGraciaUsado = false + - FechaInicioRacha = null + - El XP acumulado NO cambia (nunca se descuenta) + - Mostrar notificación: "Tu racha se rompió. ¡Empieza una nueva hoy!" + +EVALUACIÓN: Se ejecuta en dos momentos: + 1. Al hacer login (verificar si la racha cambió desde ayer) + 2. Job nocturno a las 00:01 (marcar hábitos sin registro como "Fallido") +``` + +--- + +### 4.3 Hábitos — Estados Exactos + +``` +ESTADOS DE UN HÁBITO EN UN DÍA: + +"Pendiente": + - El hábito está programado para hoy + - Aún no se ha marcado como completado ni fallido + - Estado por defecto al inicio del día + +"Completado": + - El usuario hizo clic en "Completar" durante el día + - Se registra en RegistrosHabito con Estado = "Completado" + - Se otorga XP inmediatamente + +"Fallido": + - El hábito estaba programado para hoy pero el día terminó sin completarse + - Se marca automáticamente a las 00:01 del día siguiente (job nocturno) + - O si el usuario activa manualmente el modo "No lo hice hoy" + - NO se otorga XP + - Rompe la racha individual del hábito (no la racha global) + +REGLA: Un hábito solo puede estar en un estado por día. +Una vez marcado como "Completado", no puede cambiarse a "Fallido" ni viceversa. + +¿CUÁNDO ESTÁ PROGRAMADO UN HÁBITO? + Frecuencia "Diaria": Todos los días + Frecuencia "Semanal": Solo el día de la semana configurado + Frecuencia "Personalizada": Los días guardados en DiasSemana (JSON "[1,3,5]" = Lun/Mié/Vie) + +RACHA INDIVIDUAL DEL HÁBITO (Habito.RachaActual): + - Sube 1 por cada día que se completa + - Vuelve a 0 cuando el hábito es "Fallido" + - Es independiente de la racha global del usuario +``` + +--- + +### 4.4 Misiones — Estados Exactos y Transiciones + +``` +ESTADOS DE UNA MISIÓN: + +"Pendiente" → Estado inicial al crear +"EnProgreso" → El usuario la inicia manualmente (clic en "Iniciar") +"Completado" → El usuario la marca como terminada → se otorga XP +"Fallido" → La FechaLimite pasó y la misión no estaba "Completado" + +TRANSICIONES VÁLIDAS: + Pendiente → EnProgreso (usuario hace clic en "Iniciar") + Pendiente → Completado (usuario la completa sin pasar por EnProgreso) + EnProgreso → Completado (usuario la termina) + EnProgreso → Fallido (usuario abandona O la fecha límite pasó) + Pendiente → Fallido (la fecha límite pasó sin acción) + +TRANSICIONES INVÁLIDAS (no permitir en la UI ni en el servicio): + Completado → cualquier estado (irreversible) + Fallido → cualquier estado (irreversible) + +REGLA DE FECHA LÍMITE: + Un job nocturno a las 00:01 revisa todas las misiones donde: + FechaLimite < hoy AND Estado IN ("Pendiente", "EnProgreso") + Y las marca como "Fallido" automáticamente. + +XP AL COMPLETAR: + Baja: 30 XP + Media: 50 XP + Alta: 80 XP + Se guarda en Mision.XpOtorgado y se suma al ProgresosUsuario.XpTotal +``` + +--- + +### 4.5 Pomodoro — Reglas Exactas + +``` +CICLO ESTÁNDAR (configurable por usuario): + Tiempo de estudio: 25 min (configurable: 5–90 min) + Tiempo de descanso: 5 min (configurable: 1–30 min) + Tiempo descanso largo: 15 min (configurable: 10–60 min) + Ciclos antes de largo: 4 (configurable: 2–8) + +FLUJO DE UNA SESIÓN: + 1. Usuario hace clic en "Iniciar" → POST /api/pomodoro/iniciar + → Se crea SesionPomodoro con FechaInicio = ahora + 2. Temporizador corre en el navegador (JavaScript puro, sin servidor) + 3. Al completar cada ciclo → POST /api/pomodoro/{id}/ciclo-completado + → Se otorga XP: 15 XP por ciclo + → Si ciclosCompletados >= 4 → sugerirDescanso = true + 4. Al terminar la sesión → POST /api/pomodoro/{id}/finalizar + → Se registra FechaFin y FueCompletada = true + 5. Si el usuario cancela → POST /api/pomodoro/{id}/cancelar + → FueCompletada = false, pero los ciclos completados se guardan + +XP POR POMODORO: + Por cada ciclo completado: +15 XP (se otorga ciclo por ciclo, no al final) + +REGLA DE USO EXCESIVO (ODS 3): + Si ciclosCompletados >= 4 en una sola sesión: + → Devolver sugerirDescanso = true en la respuesta + → En el frontend: mostrar mensaje "Llevas 4 ciclos seguidos. ¡Tómate un descanso largo!" + Si el usuario inicia una nueva sesión con menos de 15 minutos desde la última: + → Mostrar advertencia: "Acabas de terminar una sesión. ¿Seguro que quieres continuar?" +``` + +--- + +### 4.6 Productividad Diaria — Cálculo Exacto + +```csharp +// En ServicioGamificacion.cs + +public async Task CalcularProductividadDiaria(int usuarioId) +{ + var hoy = DateOnly.FromDateTime(DateTime.Today); + + // Obtener todos los hábitos programados para hoy + var habitosProgramadosHoy = await _contexto.Habitos + .Where(h => h.UsuarioId == usuarioId && h.EstaActivo) + .Where(h => EstaProgradoParaHoy(h, hoy)) + .CountAsync(); + + if (habitosProgramadosHoy == 0) return 0; // Sin hábitos hoy + + // Obtener cuántos se completaron hoy + var habitosCompletadosHoy = await _contexto.RegistrosHabito + .Where(r => r.Habito.UsuarioId == usuarioId + && r.Fecha == hoy + && r.Estado == "Completado") + .CountAsync(); + + return Math.Round((decimal)habitosCompletadosHoy / habitosProgramadosHoy * 100, 1); +} + +private bool EstaProgradoParaHoy(Habito habito, DateOnly hoy) +{ + return habito.Frecuencia switch + { + "Diaria" => true, + "Semanal" => (int)hoy.DayOfWeek == ObtenerDiaSemana(habito), + "Personalizada" => ObtenerDiasSemana(habito.DiasSemana).Contains((int)hoy.DayOfWeek), + _ => false + }; +} +``` + +--- + +## 5. Lógica ODS 3 — Bienestar Explícito + +> ODS 3: Salud y Bienestar. Las siguientes reglas generan alertas y sugerencias automáticas. +> Se evalúan al hacer login, al registrar estado de ánimo, y en el job nocturno. + +### 5.1 Reglas de Alerta Activa + +```csharp +// Clase: Servicios/Interfaces/IServicioBienestar.cs +// Implementación: Servicios/Implementaciones/ServicioBienestar.cs + +public class AlertaBienestar +{ + public string Tipo { get; set; } // "Descanso", "Estres", "Sobrecarga", "Logro" + public string Mensaje { get; set; } + public string Icono { get; set; } + public bool EsCritica { get; set; } +} + +public class ServicioBienestar +{ + // REGLA 1: Uso excesivo de Pomodoro + // Si el usuario completó más de 4 ciclos Pomodoro sin registrar + // un descanso (estado de ánimo posterior), generar alerta. + public async Task VerificarUsoExcesivoPomodoro(int usuarioId) + { + var hoy = DateTime.Today; + var ciclosHoy = await _contexto.SesionesPomodoro + .Where(s => s.UsuarioId == usuarioId + && s.FechaInicio.Date == hoy + && s.FueCompletada) + .SumAsync(s => s.CiclosCompletados); + + if (ciclosHoy > 8) + return new AlertaBienestar + { + Tipo = "Sobrecarga", + Mensaje = "Llevas más de 8 ciclos Pomodoro hoy. Es momento de una pausa real. Tu cerebro lo necesita.", + Icono = "bi-exclamation-triangle", + EsCritica = true + }; + + return null; + } + + // REGLA 2: Estado de ánimo negativo consecutivo + // Si el usuario registró "Cansado" o "Estresado" 3 o más días seguidos. + public async Task VerificarAnimoNegativoConsecutivo(int usuarioId) + { + var ultimosTresEstados = await _contexto.EstadosAnimo + .Where(e => e.UsuarioId == usuarioId) + .OrderByDescending(e => e.Fecha) + .Take(3) + .Select(e => e.Estado) + .ToListAsync(); + + bool tresNegativosConsecutivos = ultimosTresEstados.Count == 3 + && ultimosTresEstados.All(e => e == "Cansado" || e == "Estresado"); + + if (tresNegativosConsecutivos) + return new AlertaBienestar + { + Tipo = "Estres", + Mensaje = "Has registrado estrés o cansancio 3 días seguidos. Considera reducir la carga de hábitos por hoy y priorizar el descanso.", + Icono = "bi-heart-pulse", + EsCritica = true + }; + + return null; + } + + // REGLA 3: Hábito de sueño no registrado + // Si el usuario tiene un hábito de categoría "Sueño" y no lo ha completado + // en los últimos 3 días, generar sugerencia. + public async Task VerificarHabitoSueno(int usuarioId) + { + var categoriasSueno = new[] { "Sueño" }; + var hace3dias = DateOnly.FromDateTime(DateTime.Today.AddDays(-3)); + + var tieneHabitoSueno = await _contexto.Habitos + .AnyAsync(h => h.UsuarioId == usuarioId + && h.EstaActivo + && categoriasSueno.Contains(h.Categoria.Nombre)); + + if (!tieneHabitoSueno) return null; + + var suenoCumplido = await _contexto.RegistrosHabito + .AnyAsync(r => r.Habito.UsuarioId == usuarioId + && r.Habito.Categoria.Nombre == "Sueño" + && r.Fecha >= hace3dias + && r.Estado == "Completado"); + + if (!suenoCumplido) + return new AlertaBienestar + { + Tipo = "Descanso", + Mensaje = "No has registrado tu hábito de sueño en 3 días. El descanso es fundamental para tu rendimiento académico.", + Icono = "bi-moon-stars", + EsCritica = false + }; + + return null; + } + + // REGLA 4: Sobrecarga de misiones vencidas próximas + // Si el usuario tiene 3 o más misiones con fecha límite en los próximos 2 días. + public async Task VerificarSobrecargaMisiones(int usuarioId) + { + var en2dias = DateOnly.FromDateTime(DateTime.Today.AddDays(2)); + var hoy = DateOnly.FromDateTime(DateTime.Today); + + var misionesUrgentes = await _contexto.Misiones + .CountAsync(m => m.UsuarioId == usuarioId + && m.FechaLimite >= hoy + && m.FechaLimite <= en2dias + && (m.Estado == "Pendiente" || m.Estado == "EnProgreso")); + + if (misionesUrgentes >= 3) + return new AlertaBienestar + { + Tipo = "Sobrecarga", + Mensaje = $"Tienes {misionesUrgentes} misiones que vencen en los próximos 2 días. Prioriza y divide el trabajo en sesiones Pomodoro.", + Icono = "bi-lightning", + EsCritica = true + }; + + return null; + } + + // REGLA 5: Recomendación de pausas activas en Pomodoro + // Se envía en la respuesta de ciclo-completado cuando corresponde. + public string? RecomendacionPausaActiva(int ciclosCompletados) + { + return ciclosCompletados switch + { + 2 => "Estira los dedos y mueve las muñecas. 30 segundos.", + 4 => "Párate, camina y mira por la ventana. 5 minutos.", + 6 => "Come algo ligero y toma agua. Tu cerebro necesita glucosa.", + _ => null + }; + } + + // REGLA 6: Racha alta — refuerzo positivo + // Mensaje especial cuando el usuario lleva una racha importante. + public string? MensajeRefuerzoRacha(int rachaActual) + { + return rachaActual switch + { + 7 => "¡Una semana perfecta! Estás construyendo un hábito real.", + 14 => "¡Dos semanas sin parar! Eres constante de verdad.", + 30 => "¡Un mes entero! Eso ya es una transformación de vida.", + _ => null + }; + } +} +``` + +### 5.2 Cómo se Muestran las Alertas + +``` +Las alertas de bienestar se evalúan en dos momentos: + +1. Al hacer login diario: + → El DashboardController llama a IServicioBienestar.ObtenerAlertasActivas(usuarioId) + → Devuelve una lista de AlertaBienestar + → Se renderizan en el Dashboard como notificaciones destacadas + +2. Al registrar el estado de ánimo (POST /api/estado-animo): + → Se evalúa VerificarAnimoNegativoConsecutivo() inmediatamente + → Si hay alerta, se devuelve en la respuesta JSON como alertaBienestar + +Las alertas NO son bloqueantes. El usuario puede ignorarlas y seguir usando la app. +``` + +--- + +## 6. Seguridad y Autorización + +### 6.1 Hash de Contraseñas + +```csharp +// Usar BCrypt.Net-Next en ServicioAutenticacion.cs + +// Al registrar: +string hashContrasena = BCrypt.Net.BCrypt.HashPassword(dto.Contrasena, workFactor: 12); + +// Al hacer login: +bool esValida = BCrypt.Net.BCrypt.Verify(dto.Contrasena, usuario.ContrasenaHash); + +// NUNCA guardar la contraseña en texto plano. +// NUNCA usar MD5 ni SHA1 sin salt. +``` + +--- + +### 6.2 Validación de Contraseñas + +``` +Requisitos mínimos (validar en el ViewModel y en el servicio): + - Mínimo 8 caracteres + - Al menos 1 letra mayúscula + - Al menos 1 letra minúscula + - Al menos 1 número + - Al menos 1 carácter especial: !@#$%^&* + +Regex: ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$ + +Mensaje de error: "La contraseña debe tener mínimo 8 caracteres, +una mayúscula, una minúscula, un número y un carácter especial." +``` + +--- + +### 6.3 Generación de JWT + +```csharp +// En ServicioAutenticacion.cs + +private string GenerarToken(Usuario usuario) +{ + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier, usuario.Id.ToString()), + new Claim(ClaimTypes.Email, usuario.CorreoElectronico), + new Claim(ClaimTypes.Name, usuario.Nombre), + new Claim(ClaimTypes.Role, usuario.Rol.Nombre), + new Claim("CodigoUnico", usuario.CodigoUnico), + new Claim("CarreraId", usuario.CarreraId.ToString()), + }; + + var clave = new SymmetricSecurityKey( + Encoding.UTF8.GetBytes(_config["Jwt:Clave"])); + var credenciales = new SigningCredentials(clave, SecurityAlgorithms.HmacSha256); + + var token = new JwtSecurityToken( + issuer: _config["Jwt:Emisor"], + audience: _config["Jwt:Audiencia"], + claims: claims, + expires: DateTime.UtcNow.AddMinutes(int.Parse(_config["Jwt:ExpiracionMinutos"])), + signingCredentials: credenciales + ); + + return new JwtSecurityTokenHandler().WriteToken(token); +} +``` + +--- + +### 6.4 Protección de Rutas por Rol + +```csharp +// Controladores MVC — usuario autenticado cualquier rol: +[Authorize] +public class HabitosController : Controller { ... } + +[Authorize] +public class DashboardController : Controller { ... } + +// Controladores MVC — solo Administrador: +[Authorize(Roles = "Administrador")] +public class AdminController : Controller { ... } + +// Controladores API — usuario autenticado: +[ApiController] +[Authorize] +[Route("api/[controller]")] +public class ApiHabitosController : ControllerBase { ... } + +// Acción individual con rol: +[HttpPost("suscripcion/activar/{usuarioId}")] +[Authorize(Roles = "Administrador")] +public async Task ActivarSuscripcion(int usuarioId) { ... } + +// Rutas públicas (sin autenticación): +[AllowAnonymous] +public IActionResult Login() { ... } +``` + +--- + +### 6.5 Protección de Datos Propios + +```csharp +// REGLA: Un usuario solo puede ver y modificar sus propios datos. +// Siempre validar que el recurso pertenece al usuario autenticado. + +// CORRECTO ✅ +public async Task EditarHabito(int id, EditarHabitoViewModel modelo) +{ + var usuarioId = ObtenerUsuarioIdActual(); + var habito = await _servicioHabitos.ObtenerPorId(id); + + if (habito == null) return NotFound(); + if (habito.UsuarioId != usuarioId) return Forbid(); // ← Validación clave + + // ... continuar +} + +// INCORRECTO ❌ — nunca hacer esto (permite ver datos de otros usuarios) +public async Task EditarHabito(int id) +{ + var habito = await _servicioHabitos.ObtenerPorId(id); // sin verificar dueño + return View(habito); +} +``` + +--- + +### 6.6 Generación del Código Único de Usuario + +```csharp +// Clase: Ayudantes/GeneradorCodigo.cs + +public static class GeneradorCodigo +{ + /// + /// Genera un código único en formato EPY-XXXXXXXX (8 caracteres alfanuméricos). + /// Verificar en BD que no exista antes de guardar. + /// + public static string GenerarCodigoUsuario() + { + const string caracteres = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"; // sin 0,O,I,1 para evitar confusión + var random = new Random(); + var codigo = new string( + Enumerable.Range(0, 8) + .Select(_ => caracteres[random.Next(caracteres.Length)]) + .ToArray() + ); + return $"EPY-{codigo}"; + } +} + +// Uso en ServicioAutenticacion.cs al registrar usuario: +string codigoUnico; +do { + codigoUnico = GeneradorCodigo.GenerarCodigoUsuario(); +} while (await _contexto.Usuarios.AnyAsync(u => u.CodigoUnico == codigoUnico)); +// El loop garantiza unicidad +``` + +--- + +## 7. Configuración de Entity Framework Core + +### 7.1 `ContextoAplicacion.cs` — Estructura Base + +```csharp +// Datos/ContextoAplicacion.cs + +public class ContextoAplicacion : DbContext +{ + public ContextoAplicacion(DbContextOptions options) : base(options) { } + + // DbSets — uno por entidad + public DbSet Usuarios { get; set; } + public DbSet Roles { get; set; } + public DbSet Carreras { get; set; } + public DbSet Niveles { get; set; } + public DbSet ProgresosUsuario { get; set; } + public DbSet Personajes { get; set; } + public DbSet ImagenesNivelPersonaje { get; set; } + public DbSet PersonajesUsuario { get; set; } + public DbSet Logros { get; set; } + public DbSet LogrosUsuario { get; set; } + public DbSet Categorias { get; set; } + public DbSet Habitos { get; set; } + public DbSet RegistrosHabito { get; set; } + public DbSet ConfiguracionesPomodoro { get; set; } + public DbSet SesionesPomodoro { get; set; } + public DbSet Misiones { get; set; } + public DbSet EstadosAnimo { get; set; } + public DbSet FrasesMotivacionales { get; set; } + public DbSet TipsPomodoro { get; set; } + public DbSet Temas { get; set; } + public DbSet TemasUsuario { get; set; } + public DbSet Suscripciones { get; set; } + public DbSet TokensRefresh { get; set; } + public DbSet VerificacionesCorreo { get; set; } + public DbSet RecuperacionesContrasena { get; set; } + public DbSet Logs { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + // ── Usuario ────────────────────────────────────────────── + modelBuilder.Entity(e => + { + e.HasIndex(u => u.CorreoElectronico).IsUnique(); + e.HasIndex(u => u.CodigoUnico).IsUnique(); + e.HasIndex(u => u.GoogleId).IsUnique(); + + e.HasOne(u => u.Rol) + .WithMany() + .HasForeignKey(u => u.RolId) + .OnDelete(DeleteBehavior.Restrict); + + e.HasOne(u => u.Carrera) + .WithMany(c => c.Usuarios) + .HasForeignKey(u => u.CarreraId) + .OnDelete(DeleteBehavior.Restrict); + + e.HasOne(u => u.TemaActual) + .WithMany() + .HasForeignKey(u => u.TemaActualId) + .OnDelete(DeleteBehavior.SetNull); + }); + + // ── ProgresoUsuario ─────────────────────────────────────── + modelBuilder.Entity(e => + { + e.HasIndex(p => p.UsuarioId).IsUnique(); + + e.HasOne(p => p.Usuario) + .WithOne(u => u.Progreso) + .HasForeignKey(p => p.UsuarioId) + .OnDelete(DeleteBehavior.Cascade); + + e.HasOne(p => p.NivelActual) + .WithMany(n => n.Progresos) + .HasForeignKey(p => p.NivelActualId) + .OnDelete(DeleteBehavior.Restrict); + }); + + // ── Habito ──────────────────────────────────────────────── + modelBuilder.Entity(e => + { + e.HasOne(h => h.Usuario) + .WithMany(u => u.Habitos) + .HasForeignKey(h => h.UsuarioId) + .OnDelete(DeleteBehavior.Cascade); + + e.HasOne(h => h.Categoria) + .WithMany(c => c.Habitos) + .HasForeignKey(h => h.CategoriaId) + .OnDelete(DeleteBehavior.Restrict); + }); + + // ── RegistroHabito ──────────────────────────────────────── + modelBuilder.Entity(e => + { + e.HasOne(r => r.Habito) + .WithMany(h => h.Registros) + .HasForeignKey(r => r.HabitoId) + .OnDelete(DeleteBehavior.Cascade); + }); + + // ── SesionPomodoro ──────────────────────────────────────── + modelBuilder.Entity(e => + { + e.HasOne(s => s.Usuario) + .WithMany(u => u.SesionesPomodoro) + .HasForeignKey(s => s.UsuarioId) + .OnDelete(DeleteBehavior.Cascade); + + e.HasOne(s => s.Habito) + .WithMany(h => h.SesionesPomodoro) + .HasForeignKey(s => s.HabitoId) + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(false); + + e.HasOne(s => s.Mision) + .WithMany(m => m.SesionesPomodoro) + .HasForeignKey(s => s.MisionId) + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(false); + }); + + // ── Mision ──────────────────────────────────────────────── + modelBuilder.Entity(e => + { + e.HasOne(m => m.Usuario) + .WithMany(u => u.Misiones) + .HasForeignKey(m => m.UsuarioId) + .OnDelete(DeleteBehavior.Cascade); + + e.HasOne(m => m.Categoria) + .WithMany(c => c.Misiones) + .HasForeignKey(m => m.CategoriaId) + .OnDelete(DeleteBehavior.Restrict); + }); + + // ── Personaje / Imágenes ────────────────────────────────── + modelBuilder.Entity(e => + { + e.HasOne(p => p.Carrera) + .WithMany() + .HasForeignKey(p => p.CarreraId) + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(false); + }); + + modelBuilder.Entity(e => + { + e.HasOne(i => i.Personaje) + .WithMany(p => p.Imagenes) + .HasForeignKey(i => i.PersonajeId) + .OnDelete(DeleteBehavior.Cascade); + }); + + // ── Suscripcion ─────────────────────────────────────────── + modelBuilder.Entity(e => + { + e.HasOne(s => s.Usuario) + .WithMany(u => u.Suscripciones) + .HasForeignKey(s => s.UsuarioId) + .OnDelete(DeleteBehavior.Cascade); + + // El admin que activó la suscripción — sin cascade para evitar conflicto + e.HasOne() + .WithMany() + .HasForeignKey(s => s.ActivadaPorAdminId) + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(false); + }); + } +} +``` + +--- + +### 7.2 Registro en `Program.cs` + +```csharp +// Program.cs + +var connectionString = builder.Configuration.GetConnectionString("ConexionPrincipal"); + +builder.Services.AddDbContext(options => + options.UseMySql( + connectionString, + ServerVersion.AutoDetect(connectionString), + mySqlOptions => mySqlOptions.EnableRetryOnFailure() + ) +); + +// Registro de servicios (inyección de dependencias) +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +// JWT +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + ValidateIssuerSigningKey = true, + ValidIssuer = builder.Configuration["Jwt:Emisor"], + ValidAudience = builder.Configuration["Jwt:Audiencia"], + IssuerSigningKey = new SymmetricSecurityKey( + Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Clave"])) + }; + }) + .AddGoogle(options => + { + options.ClientId = builder.Configuration["Google:ClientId"]; + options.ClientSecret = builder.Configuration["Google:ClientSecret"]; + }); + +builder.Services.AddAuthorization(); +builder.Services.AddAutoMapper(typeof(Program)); +builder.Services.AddControllersWithViews(); +``` + +--- + +### 7.3 Comandos de Migración + +```bash +# Crear la primera migración (ejecutar en la terminal del proyecto) +dotnet ef migrations add MigracionInicial + +# Aplicar migraciones a la BD (crea las tablas en MariaDB) +dotnet ef database update + +# Si hay cambios en las entidades, crear nueva migración: +dotnet ef migrations add NombreDescriptivo + +# Ver el SQL que generaría la migración (sin ejecutar): +dotnet ef migrations script +``` + +--- + +*Documento Técnico Complementario — EPYCUS WEB* +*Versión 1.0 — Mayo 2026* +*Leer junto con: EPYCUS_WEB_Documento_Base.md* diff --git a/EPYCUS WEB v0.1.csproj b/EPYCUS WEB v0.1.csproj new file mode 100644 index 0000000..bda54f6 --- /dev/null +++ b/EPYCUS WEB v0.1.csproj @@ -0,0 +1,31 @@ + + + + net10.0 + enable + enable + EPYCUS_WEB_v0._1 + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + diff --git a/EPYCUS WEB v0.1.slnx b/EPYCUS WEB v0.1.slnx new file mode 100644 index 0000000..c15639e --- /dev/null +++ b/EPYCUS WEB v0.1.slnx @@ -0,0 +1,3 @@ + + + diff --git a/Middleware/.gitkeep b/Middleware/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Migrations/20260512134829_InitialMerge.Designer.cs b/Migrations/20260512134829_InitialMerge.Designer.cs new file mode 100644 index 0000000..a6681d2 --- /dev/null +++ b/Migrations/20260512134829_InitialMerge.Designer.cs @@ -0,0 +1,1273 @@ +// +using System; +using EPYCUS_WEB_v0._1.Datos; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace EPYCUS_WEB_v0._1.Migrations +{ + [DbContext(typeof(ContextoAplicacion))] + [Migration("20260512134829_InitialMerge")] + partial class InitialMerge + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Carrera", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Area") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Codigo") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EstaActiva") + .HasColumnType("tinyint(1)"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Carreras"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Categoria", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EstaActiva") + .HasColumnType("tinyint(1)"); + + b.Property("Icono") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Tipo") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Categorias"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ConfiguracionPomodoro", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CiclosAntesDescansoLargo") + .HasColumnType("int"); + + b.Property("FechaActualizacion") + .HasColumnType("datetime(6)"); + + b.Property("SonidoActivo") + .HasColumnType("tinyint(1)"); + + b.Property("TiempoDescansoLargoMin") + .HasColumnType("int"); + + b.Property("TiempoDescansoMin") + .HasColumnType("int"); + + b.Property("TiempoEstudioMin") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId") + .IsUnique(); + + b.ToTable("ConfiguracionesPomodoro"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.EstadoAnimo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Estado") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Fecha") + .HasColumnType("date"); + + b.Property("FechaRegistro") + .HasColumnType("datetime(6)"); + + b.Property("Nota") + .HasColumnType("longtext"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId"); + + b.ToTable("EstadosAnimo"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.FraseMotivacional", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Autor") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EstaActiva") + .HasColumnType("tinyint(1)"); + + b.Property("Frase") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("FrasesMotivacionales"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Habito", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CategoriaId") + .HasColumnType("int"); + + b.Property("ConPomodoro") + .HasColumnType("tinyint(1)"); + + b.Property("Descripcion") + .HasColumnType("longtext"); + + b.Property("DiasSemana") + .HasColumnType("longtext"); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("FechaCreacion") + .HasColumnType("datetime(6)"); + + b.Property("Frecuencia") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RachaActual") + .HasColumnType("int"); + + b.Property("RachaMaxima") + .HasColumnType("int"); + + b.Property("RecordatorioHora") + .HasColumnType("time(6)"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CategoriaId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("Habitos"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ImagenNivelPersonaje", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EsPlaceholder") + .HasColumnType("tinyint(1)"); + + b.Property("ImagenUrl") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NivelNumero") + .HasColumnType("int"); + + b.Property("PersonajeId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PersonajeId"); + + b.ToTable("ImagenesNivelPersonaje"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Accion") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Detalle") + .HasColumnType("longtext"); + + b.Property("DireccionIp") + .HasColumnType("longtext"); + + b.Property("FechaRegistro") + .HasColumnType("datetime(6)"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId"); + + b.ToTable("Logs"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Logro", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CondicionTipo") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CondicionValor") + .HasColumnType("int"); + + b.Property("Descripcion") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("IconoUrl") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("XpRecompensa") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Logros"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.LogroUsuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("FechaObtenido") + .HasColumnType("datetime(6)"); + + b.Property("LogroId") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("LogroId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("LogrosUsuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Mision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CategoriaId") + .HasColumnType("int"); + + b.Property("ConPomodoro") + .HasColumnType("tinyint(1)"); + + b.Property("Descripcion") + .HasColumnType("longtext"); + + b.Property("Estado") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FechaCompletado") + .HasColumnType("datetime(6)"); + + b.Property("FechaCreacion") + .HasColumnType("datetime(6)"); + + b.Property("FechaLimite") + .HasColumnType("date"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NombreCurso") + .HasColumnType("longtext"); + + b.Property("Prioridad") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.Property("XpOtorgado") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CategoriaId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("Misiones"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Nivel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Descripcion") + .HasColumnType("longtext"); + + b.Property("Numero") + .HasColumnType("int"); + + b.Property("Titulo") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("XpRequerido") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Niveles"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Personaje", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CarreraId") + .HasColumnType("int"); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("Genero") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("CarreraId"); + + b.ToTable("Personajes"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.PersonajeUsuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EstaSeleccionado") + .HasColumnType("tinyint(1)"); + + b.Property("FechaObtenido") + .HasColumnType("datetime(6)"); + + b.Property("PersonajeId") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PersonajeId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("PersonajesUsuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ProgresoUsuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DiaDeGraciaUsado") + .HasColumnType("tinyint(1)"); + + b.Property("FechaInicioRacha") + .HasColumnType("datetime(6)"); + + b.Property("FechaUltimaActividad") + .HasColumnType("datetime(6)"); + + b.Property("NivelActualId") + .HasColumnType("int"); + + b.Property("ProductividadDiaria") + .HasColumnType("decimal(65,30)"); + + b.Property("RachaActual") + .HasColumnType("int"); + + b.Property("RachaMaxima") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.Property("XpTotal") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NivelActualId"); + + b.HasIndex("UsuarioId") + .IsUnique(); + + b.ToTable("ProgresosUsuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.RecuperacionContrasena", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ExpiraEn") + .HasColumnType("datetime(6)"); + + b.Property("FechaCreacion") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Usado") + .HasColumnType("tinyint(1)"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId"); + + b.ToTable("RecuperacionesContrasena"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.RegistroHabito", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Estado") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Fecha") + .HasColumnType("date"); + + b.Property("FechaRegistro") + .HasColumnType("datetime(6)"); + + b.Property("HabitoId") + .HasColumnType("int"); + + b.Property("XpOtorgado") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("HabitoId"); + + b.ToTable("RegistrosHabito"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Rol", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.SesionPomodoro", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CiclosCompletados") + .HasColumnType("int"); + + b.Property("FechaFin") + .HasColumnType("datetime(6)"); + + b.Property("FechaInicio") + .HasColumnType("datetime(6)"); + + b.Property("FueCompletada") + .HasColumnType("tinyint(1)"); + + b.Property("HabitoId") + .HasColumnType("int"); + + b.Property("MisionId") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.Property("XpOtorgado") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("HabitoId"); + + b.HasIndex("MisionId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("SesionesPomodoro"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Suscripcion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ActivadaPorAdminId") + .HasColumnType("int"); + + b.Property("EstaActiva") + .HasColumnType("tinyint(1)"); + + b.Property("FechaActivacion") + .HasColumnType("datetime(6)"); + + b.Property("FechaFin") + .HasColumnType("date"); + + b.Property("FechaInicio") + .HasColumnType("date"); + + b.Property("Plan") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PrecioSoles") + .HasColumnType("decimal(65,30)"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ActivadaPorAdminId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("Suscripciones"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Tema", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArchivoCss") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Descripcion") + .HasColumnType("longtext"); + + b.Property("EsPremium") + .HasColumnType("tinyint(1)"); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("ImagenPreviewUrl") + .HasColumnType("longtext"); + + b.Property("Modo") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Precio") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.ToTable("Temas"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.TemaUsuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("FechaObtenido") + .HasColumnType("datetime(6)"); + + b.Property("TemaId") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TemaId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("TemasUsuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.TipPomodoro", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("Tip") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("TipsPomodoro"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.TokenRefresh", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ExpiraEn") + .HasColumnType("datetime(6)"); + + b.Property("FechaCreacion") + .HasColumnType("datetime(6)"); + + b.Property("Revocado") + .HasColumnType("tinyint(1)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId"); + + b.ToTable("TokensRefresh"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AceptoTerminos") + .HasColumnType("tinyint(1)"); + + b.Property("CarreraId") + .HasColumnType("int"); + + b.Property("CodigoUnico") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ContrasenaHash") + .HasColumnType("longtext"); + + b.Property("CorreoElectronico") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("CorreoVerificado") + .HasColumnType("tinyint(1)"); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("FechaNacimiento") + .HasColumnType("datetime(6)"); + + b.Property("FechaRegistro") + .HasColumnType("datetime(6)"); + + b.Property("FotoGoogleUrl") + .HasColumnType("longtext"); + + b.Property("Genero") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("GoogleId") + .HasColumnType("varchar(255)"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RolId") + .HasColumnType("int"); + + b.Property("TemaActualId") + .HasColumnType("int"); + + b.Property("UltimoAcceso") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("CarreraId"); + + b.HasIndex("CodigoUnico") + .IsUnique(); + + b.HasIndex("CorreoElectronico") + .IsUnique(); + + b.HasIndex("GoogleId") + .IsUnique(); + + b.HasIndex("RolId"); + + b.HasIndex("TemaActualId"); + + b.ToTable("Usuarios"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.VerificacionCorreo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ExpiraEn") + .HasColumnType("datetime(6)"); + + b.Property("FechaCreacion") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Usado") + .HasColumnType("tinyint(1)"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId"); + + b.ToTable("VerificacionesCorreo"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ConfiguracionPomodoro", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithOne("ConfiguracionPomodoro") + .HasForeignKey("EPYCUS_WEB_v0._1.Modelos.Entidades.ConfiguracionPomodoro", "UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.EstadoAnimo", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("EstadosAnimo") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Habito", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Categoria", "Categoria") + .WithMany("Habitos") + .HasForeignKey("CategoriaId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("Habitos") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Categoria"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ImagenNivelPersonaje", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Personaje", "Personaje") + .WithMany("Imagenes") + .HasForeignKey("PersonajeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Personaje"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Log", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany() + .HasForeignKey("UsuarioId"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.LogroUsuario", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Logro", "Logro") + .WithMany() + .HasForeignKey("LogroId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("LogrosUsuario") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Logro"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Mision", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Categoria", "Categoria") + .WithMany("Misiones") + .HasForeignKey("CategoriaId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("Misiones") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Categoria"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Personaje", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Carrera", "Carrera") + .WithMany() + .HasForeignKey("CarreraId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Carrera"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.PersonajeUsuario", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Personaje", "Personaje") + .WithMany("PersonajesUsuario") + .HasForeignKey("PersonajeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("PersonajesUsuario") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Personaje"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ProgresoUsuario", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Nivel", "NivelActual") + .WithMany("Progresos") + .HasForeignKey("NivelActualId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithOne("Progreso") + .HasForeignKey("EPYCUS_WEB_v0._1.Modelos.Entidades.ProgresoUsuario", "UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NivelActual"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.RecuperacionContrasena", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany() + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.RegistroHabito", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Habito", "Habito") + .WithMany("Registros") + .HasForeignKey("HabitoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Habito"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.SesionPomodoro", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Habito", "Habito") + .WithMany("SesionesPomodoro") + .HasForeignKey("HabitoId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Mision", "Mision") + .WithMany("SesionesPomodoro") + .HasForeignKey("MisionId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("SesionesPomodoro") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Habito"); + + b.Navigation("Mision"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Suscripcion", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", null) + .WithMany() + .HasForeignKey("ActivadaPorAdminId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("Suscripciones") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.TemaUsuario", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Tema", "Tema") + .WithMany() + .HasForeignKey("TemaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("TemasUsuario") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tema"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.TokenRefresh", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("TokensRefresh") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Carrera", "Carrera") + .WithMany("Usuarios") + .HasForeignKey("CarreraId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Rol", "Rol") + .WithMany() + .HasForeignKey("RolId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Tema", "TemaActual") + .WithMany() + .HasForeignKey("TemaActualId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Carrera"); + + b.Navigation("Rol"); + + b.Navigation("TemaActual"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.VerificacionCorreo", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany() + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Carrera", b => + { + b.Navigation("Usuarios"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Categoria", b => + { + b.Navigation("Habitos"); + + b.Navigation("Misiones"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Habito", b => + { + b.Navigation("Registros"); + + b.Navigation("SesionesPomodoro"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Mision", b => + { + b.Navigation("SesionesPomodoro"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Nivel", b => + { + b.Navigation("Progresos"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Personaje", b => + { + b.Navigation("Imagenes"); + + b.Navigation("PersonajesUsuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", b => + { + b.Navigation("ConfiguracionPomodoro") + .IsRequired(); + + b.Navigation("EstadosAnimo"); + + b.Navigation("Habitos"); + + b.Navigation("LogrosUsuario"); + + b.Navigation("Misiones"); + + b.Navigation("PersonajesUsuario"); + + b.Navigation("Progreso") + .IsRequired(); + + b.Navigation("SesionesPomodoro"); + + b.Navigation("Suscripciones"); + + b.Navigation("TemasUsuario"); + + b.Navigation("TokensRefresh"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Migrations/20260512134829_InitialMerge.cs b/Migrations/20260512134829_InitialMerge.cs new file mode 100644 index 0000000..4b82f82 --- /dev/null +++ b/Migrations/20260512134829_InitialMerge.cs @@ -0,0 +1,980 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace EPYCUS_WEB_v0._1.Migrations +{ + /// + public partial class InitialMerge : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterDatabase() + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Carreras", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Nombre = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Area = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Codigo = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + EstaActiva = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Carreras", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Categorias", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Nombre = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Icono = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Tipo = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + EstaActiva = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Categorias", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "FrasesMotivacionales", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Frase = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Autor = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + EstaActiva = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_FrasesMotivacionales", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Logros", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Nombre = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Descripcion = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + IconoUrl = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + CondicionTipo = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + CondicionValor = table.Column(type: "int", nullable: false), + XpRecompensa = table.Column(type: "int", nullable: false), + EstaActivo = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Logros", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Niveles", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Numero = table.Column(type: "int", nullable: false), + Titulo = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + XpRequerido = table.Column(type: "int", nullable: false), + Descripcion = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_Niveles", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Roles", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Nombre = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_Roles", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Temas", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Nombre = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Descripcion = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Modo = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ArchivoCss = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ImagenPreviewUrl = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + EsPremium = table.Column(type: "tinyint(1)", nullable: false), + Precio = table.Column(type: "decimal(65,30)", nullable: false), + EstaActivo = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Temas", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "TipsPomodoro", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Tip = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + EstaActivo = table.Column(type: "tinyint(1)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TipsPomodoro", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Personajes", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Nombre = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Genero = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + EstaActivo = table.Column(type: "tinyint(1)", nullable: false), + CarreraId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Personajes", x => x.Id); + table.ForeignKey( + name: "FK_Personajes_Carreras_CarreraId", + column: x => x.CarreraId, + principalTable: "Carreras", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Usuarios", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CodigoUnico = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Nombre = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + CorreoElectronico = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ContrasenaHash = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + FechaNacimiento = table.Column(type: "datetime(6)", nullable: false), + Genero = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + CorreoVerificado = table.Column(type: "tinyint(1)", nullable: false), + AceptoTerminos = table.Column(type: "tinyint(1)", nullable: false), + EstaActivo = table.Column(type: "tinyint(1)", nullable: false), + FechaRegistro = table.Column(type: "datetime(6)", nullable: false), + UltimoAcceso = table.Column(type: "datetime(6)", nullable: true), + GoogleId = table.Column(type: "varchar(255)", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + FotoGoogleUrl = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + RolId = table.Column(type: "int", nullable: false), + CarreraId = table.Column(type: "int", nullable: false), + TemaActualId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Usuarios", x => x.Id); + table.ForeignKey( + name: "FK_Usuarios_Carreras_CarreraId", + column: x => x.CarreraId, + principalTable: "Carreras", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Usuarios_Roles_RolId", + column: x => x.RolId, + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Usuarios_Temas_TemaActualId", + column: x => x.TemaActualId, + principalTable: "Temas", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "ImagenesNivelPersonaje", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + NivelNumero = table.Column(type: "int", nullable: false), + ImagenUrl = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + EsPlaceholder = table.Column(type: "tinyint(1)", nullable: false), + PersonajeId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ImagenesNivelPersonaje", x => x.Id); + table.ForeignKey( + name: "FK_ImagenesNivelPersonaje_Personajes_PersonajeId", + column: x => x.PersonajeId, + principalTable: "Personajes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "ConfiguracionesPomodoro", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + TiempoEstudioMin = table.Column(type: "int", nullable: false), + TiempoDescansoMin = table.Column(type: "int", nullable: false), + TiempoDescansoLargoMin = table.Column(type: "int", nullable: false), + CiclosAntesDescansoLargo = table.Column(type: "int", nullable: false), + SonidoActivo = table.Column(type: "tinyint(1)", nullable: false), + FechaActualizacion = table.Column(type: "datetime(6)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ConfiguracionesPomodoro", x => x.Id); + table.ForeignKey( + name: "FK_ConfiguracionesPomodoro_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "EstadosAnimo", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Fecha = table.Column(type: "date", nullable: false), + Estado = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Nota = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + FechaRegistro = table.Column(type: "datetime(6)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_EstadosAnimo", x => x.Id); + table.ForeignKey( + name: "FK_EstadosAnimo_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Habitos", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Nombre = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Descripcion = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Frecuencia = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + DiasSemana = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ConPomodoro = table.Column(type: "tinyint(1)", nullable: false), + RecordatorioHora = table.Column(type: "time(6)", nullable: true), + RachaActual = table.Column(type: "int", nullable: false), + RachaMaxima = table.Column(type: "int", nullable: false), + EstaActivo = table.Column(type: "tinyint(1)", nullable: false), + FechaCreacion = table.Column(type: "datetime(6)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false), + CategoriaId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Habitos", x => x.Id); + table.ForeignKey( + name: "FK_Habitos_Categorias_CategoriaId", + column: x => x.CategoriaId, + principalTable: "Categorias", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Habitos_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "LogrosUsuario", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + FechaObtenido = table.Column(type: "datetime(6)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false), + LogroId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_LogrosUsuario", x => x.Id); + table.ForeignKey( + name: "FK_LogrosUsuario_Logros_LogroId", + column: x => x.LogroId, + principalTable: "Logros", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_LogrosUsuario_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Logs", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Accion = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Detalle = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + DireccionIp = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + FechaRegistro = table.Column(type: "datetime(6)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Logs", x => x.Id); + table.ForeignKey( + name: "FK_Logs_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id"); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Misiones", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Nombre = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Descripcion = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + NombreCurso = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + FechaLimite = table.Column(type: "date", nullable: false), + Prioridad = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Estado = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ConPomodoro = table.Column(type: "tinyint(1)", nullable: false), + XpOtorgado = table.Column(type: "int", nullable: false), + FechaCreacion = table.Column(type: "datetime(6)", nullable: false), + FechaCompletado = table.Column(type: "datetime(6)", nullable: true), + UsuarioId = table.Column(type: "int", nullable: false), + CategoriaId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Misiones", x => x.Id); + table.ForeignKey( + name: "FK_Misiones_Categorias_CategoriaId", + column: x => x.CategoriaId, + principalTable: "Categorias", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Misiones_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "PersonajesUsuario", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + EstaSeleccionado = table.Column(type: "tinyint(1)", nullable: false), + FechaObtenido = table.Column(type: "datetime(6)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false), + PersonajeId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_PersonajesUsuario", x => x.Id); + table.ForeignKey( + name: "FK_PersonajesUsuario_Personajes_PersonajeId", + column: x => x.PersonajeId, + principalTable: "Personajes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PersonajesUsuario_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "ProgresosUsuario", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + XpTotal = table.Column(type: "int", nullable: false), + RachaActual = table.Column(type: "int", nullable: false), + RachaMaxima = table.Column(type: "int", nullable: false), + FechaUltimaActividad = table.Column(type: "datetime(6)", nullable: true), + FechaInicioRacha = table.Column(type: "datetime(6)", nullable: true), + DiaDeGraciaUsado = table.Column(type: "tinyint(1)", nullable: false), + ProductividadDiaria = table.Column(type: "decimal(65,30)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false), + NivelActualId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProgresosUsuario", x => x.Id); + table.ForeignKey( + name: "FK_ProgresosUsuario_Niveles_NivelActualId", + column: x => x.NivelActualId, + principalTable: "Niveles", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_ProgresosUsuario_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "RecuperacionesContrasena", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Token = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ExpiraEn = table.Column(type: "datetime(6)", nullable: false), + Usado = table.Column(type: "tinyint(1)", nullable: false), + FechaCreacion = table.Column(type: "datetime(6)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RecuperacionesContrasena", x => x.Id); + table.ForeignKey( + name: "FK_RecuperacionesContrasena_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Suscripciones", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Plan = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + PrecioSoles = table.Column(type: "decimal(65,30)", nullable: false), + FechaInicio = table.Column(type: "date", nullable: false), + FechaFin = table.Column(type: "date", nullable: false), + EstaActiva = table.Column(type: "tinyint(1)", nullable: false), + ActivadaPorAdminId = table.Column(type: "int", nullable: true), + FechaActivacion = table.Column(type: "datetime(6)", nullable: true), + UsuarioId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Suscripciones", x => x.Id); + table.ForeignKey( + name: "FK_Suscripciones_Usuarios_ActivadaPorAdminId", + column: x => x.ActivadaPorAdminId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "FK_Suscripciones_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "TemasUsuario", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + FechaObtenido = table.Column(type: "datetime(6)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false), + TemaId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TemasUsuario", x => x.Id); + table.ForeignKey( + name: "FK_TemasUsuario_Temas_TemaId", + column: x => x.TemaId, + principalTable: "Temas", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_TemasUsuario_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "TokensRefresh", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Token = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ExpiraEn = table.Column(type: "datetime(6)", nullable: false), + Revocado = table.Column(type: "tinyint(1)", nullable: false), + FechaCreacion = table.Column(type: "datetime(6)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TokensRefresh", x => x.Id); + table.ForeignKey( + name: "FK_TokensRefresh_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "VerificacionesCorreo", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Token = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ExpiraEn = table.Column(type: "datetime(6)", nullable: false), + Usado = table.Column(type: "tinyint(1)", nullable: false), + FechaCreacion = table.Column(type: "datetime(6)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_VerificacionesCorreo", x => x.Id); + table.ForeignKey( + name: "FK_VerificacionesCorreo_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "RegistrosHabito", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Fecha = table.Column(type: "date", nullable: false), + Estado = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + XpOtorgado = table.Column(type: "int", nullable: false), + FechaRegistro = table.Column(type: "datetime(6)", nullable: false), + HabitoId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RegistrosHabito", x => x.Id); + table.ForeignKey( + name: "FK_RegistrosHabito_Habitos_HabitoId", + column: x => x.HabitoId, + principalTable: "Habitos", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "SesionesPomodoro", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + FechaInicio = table.Column(type: "datetime(6)", nullable: false), + FechaFin = table.Column(type: "datetime(6)", nullable: true), + CiclosCompletados = table.Column(type: "int", nullable: false), + XpOtorgado = table.Column(type: "int", nullable: false), + FueCompletada = table.Column(type: "tinyint(1)", nullable: false), + UsuarioId = table.Column(type: "int", nullable: false), + HabitoId = table.Column(type: "int", nullable: true), + MisionId = table.Column(type: "int", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_SesionesPomodoro", x => x.Id); + table.ForeignKey( + name: "FK_SesionesPomodoro_Habitos_HabitoId", + column: x => x.HabitoId, + principalTable: "Habitos", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "FK_SesionesPomodoro_Misiones_MisionId", + column: x => x.MisionId, + principalTable: "Misiones", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "FK_SesionesPomodoro_Usuarios_UsuarioId", + column: x => x.UsuarioId, + principalTable: "Usuarios", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_ConfiguracionesPomodoro_UsuarioId", + table: "ConfiguracionesPomodoro", + column: "UsuarioId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_EstadosAnimo_UsuarioId", + table: "EstadosAnimo", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_Habitos_CategoriaId", + table: "Habitos", + column: "CategoriaId"); + + migrationBuilder.CreateIndex( + name: "IX_Habitos_UsuarioId", + table: "Habitos", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_ImagenesNivelPersonaje_PersonajeId", + table: "ImagenesNivelPersonaje", + column: "PersonajeId"); + + migrationBuilder.CreateIndex( + name: "IX_LogrosUsuario_LogroId", + table: "LogrosUsuario", + column: "LogroId"); + + migrationBuilder.CreateIndex( + name: "IX_LogrosUsuario_UsuarioId", + table: "LogrosUsuario", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_Logs_UsuarioId", + table: "Logs", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_Misiones_CategoriaId", + table: "Misiones", + column: "CategoriaId"); + + migrationBuilder.CreateIndex( + name: "IX_Misiones_UsuarioId", + table: "Misiones", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_Personajes_CarreraId", + table: "Personajes", + column: "CarreraId"); + + migrationBuilder.CreateIndex( + name: "IX_PersonajesUsuario_PersonajeId", + table: "PersonajesUsuario", + column: "PersonajeId"); + + migrationBuilder.CreateIndex( + name: "IX_PersonajesUsuario_UsuarioId", + table: "PersonajesUsuario", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_ProgresosUsuario_NivelActualId", + table: "ProgresosUsuario", + column: "NivelActualId"); + + migrationBuilder.CreateIndex( + name: "IX_ProgresosUsuario_UsuarioId", + table: "ProgresosUsuario", + column: "UsuarioId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_RecuperacionesContrasena_UsuarioId", + table: "RecuperacionesContrasena", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_RegistrosHabito_HabitoId", + table: "RegistrosHabito", + column: "HabitoId"); + + migrationBuilder.CreateIndex( + name: "IX_SesionesPomodoro_HabitoId", + table: "SesionesPomodoro", + column: "HabitoId"); + + migrationBuilder.CreateIndex( + name: "IX_SesionesPomodoro_MisionId", + table: "SesionesPomodoro", + column: "MisionId"); + + migrationBuilder.CreateIndex( + name: "IX_SesionesPomodoro_UsuarioId", + table: "SesionesPomodoro", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_Suscripciones_ActivadaPorAdminId", + table: "Suscripciones", + column: "ActivadaPorAdminId"); + + migrationBuilder.CreateIndex( + name: "IX_Suscripciones_UsuarioId", + table: "Suscripciones", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_TemasUsuario_TemaId", + table: "TemasUsuario", + column: "TemaId"); + + migrationBuilder.CreateIndex( + name: "IX_TemasUsuario_UsuarioId", + table: "TemasUsuario", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_TokensRefresh_UsuarioId", + table: "TokensRefresh", + column: "UsuarioId"); + + migrationBuilder.CreateIndex( + name: "IX_Usuarios_CarreraId", + table: "Usuarios", + column: "CarreraId"); + + migrationBuilder.CreateIndex( + name: "IX_Usuarios_CodigoUnico", + table: "Usuarios", + column: "CodigoUnico", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Usuarios_CorreoElectronico", + table: "Usuarios", + column: "CorreoElectronico", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Usuarios_GoogleId", + table: "Usuarios", + column: "GoogleId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Usuarios_RolId", + table: "Usuarios", + column: "RolId"); + + migrationBuilder.CreateIndex( + name: "IX_Usuarios_TemaActualId", + table: "Usuarios", + column: "TemaActualId"); + + migrationBuilder.CreateIndex( + name: "IX_VerificacionesCorreo_UsuarioId", + table: "VerificacionesCorreo", + column: "UsuarioId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ConfiguracionesPomodoro"); + + migrationBuilder.DropTable( + name: "EstadosAnimo"); + + migrationBuilder.DropTable( + name: "FrasesMotivacionales"); + + migrationBuilder.DropTable( + name: "ImagenesNivelPersonaje"); + + migrationBuilder.DropTable( + name: "LogrosUsuario"); + + migrationBuilder.DropTable( + name: "Logs"); + + migrationBuilder.DropTable( + name: "PersonajesUsuario"); + + migrationBuilder.DropTable( + name: "ProgresosUsuario"); + + migrationBuilder.DropTable( + name: "RecuperacionesContrasena"); + + migrationBuilder.DropTable( + name: "RegistrosHabito"); + + migrationBuilder.DropTable( + name: "SesionesPomodoro"); + + migrationBuilder.DropTable( + name: "Suscripciones"); + + migrationBuilder.DropTable( + name: "TemasUsuario"); + + migrationBuilder.DropTable( + name: "TipsPomodoro"); + + migrationBuilder.DropTable( + name: "TokensRefresh"); + + migrationBuilder.DropTable( + name: "VerificacionesCorreo"); + + migrationBuilder.DropTable( + name: "Logros"); + + migrationBuilder.DropTable( + name: "Personajes"); + + migrationBuilder.DropTable( + name: "Niveles"); + + migrationBuilder.DropTable( + name: "Habitos"); + + migrationBuilder.DropTable( + name: "Misiones"); + + migrationBuilder.DropTable( + name: "Categorias"); + + migrationBuilder.DropTable( + name: "Usuarios"); + + migrationBuilder.DropTable( + name: "Carreras"); + + migrationBuilder.DropTable( + name: "Roles"); + + migrationBuilder.DropTable( + name: "Temas"); + } + } +} diff --git a/Migrations/ContextoAplicacionModelSnapshot.cs b/Migrations/ContextoAplicacionModelSnapshot.cs new file mode 100644 index 0000000..31e198b --- /dev/null +++ b/Migrations/ContextoAplicacionModelSnapshot.cs @@ -0,0 +1,1270 @@ +// +using System; +using EPYCUS_WEB_v0._1.Datos; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace EPYCUS_WEB_v0._1.Migrations +{ + [DbContext(typeof(ContextoAplicacion))] + partial class ContextoAplicacionModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Carrera", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Area") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Codigo") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EstaActiva") + .HasColumnType("tinyint(1)"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Carreras"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Categoria", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EstaActiva") + .HasColumnType("tinyint(1)"); + + b.Property("Icono") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Tipo") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Categorias"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ConfiguracionPomodoro", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CiclosAntesDescansoLargo") + .HasColumnType("int"); + + b.Property("FechaActualizacion") + .HasColumnType("datetime(6)"); + + b.Property("SonidoActivo") + .HasColumnType("tinyint(1)"); + + b.Property("TiempoDescansoLargoMin") + .HasColumnType("int"); + + b.Property("TiempoDescansoMin") + .HasColumnType("int"); + + b.Property("TiempoEstudioMin") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId") + .IsUnique(); + + b.ToTable("ConfiguracionesPomodoro"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.EstadoAnimo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Estado") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Fecha") + .HasColumnType("date"); + + b.Property("FechaRegistro") + .HasColumnType("datetime(6)"); + + b.Property("Nota") + .HasColumnType("longtext"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId"); + + b.ToTable("EstadosAnimo"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.FraseMotivacional", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Autor") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EstaActiva") + .HasColumnType("tinyint(1)"); + + b.Property("Frase") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("FrasesMotivacionales"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Habito", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CategoriaId") + .HasColumnType("int"); + + b.Property("ConPomodoro") + .HasColumnType("tinyint(1)"); + + b.Property("Descripcion") + .HasColumnType("longtext"); + + b.Property("DiasSemana") + .HasColumnType("longtext"); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("FechaCreacion") + .HasColumnType("datetime(6)"); + + b.Property("Frecuencia") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RachaActual") + .HasColumnType("int"); + + b.Property("RachaMaxima") + .HasColumnType("int"); + + b.Property("RecordatorioHora") + .HasColumnType("time(6)"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CategoriaId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("Habitos"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ImagenNivelPersonaje", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EsPlaceholder") + .HasColumnType("tinyint(1)"); + + b.Property("ImagenUrl") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NivelNumero") + .HasColumnType("int"); + + b.Property("PersonajeId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PersonajeId"); + + b.ToTable("ImagenesNivelPersonaje"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Accion") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Detalle") + .HasColumnType("longtext"); + + b.Property("DireccionIp") + .HasColumnType("longtext"); + + b.Property("FechaRegistro") + .HasColumnType("datetime(6)"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId"); + + b.ToTable("Logs"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Logro", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CondicionTipo") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CondicionValor") + .HasColumnType("int"); + + b.Property("Descripcion") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("IconoUrl") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("XpRecompensa") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Logros"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.LogroUsuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("FechaObtenido") + .HasColumnType("datetime(6)"); + + b.Property("LogroId") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("LogroId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("LogrosUsuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Mision", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CategoriaId") + .HasColumnType("int"); + + b.Property("ConPomodoro") + .HasColumnType("tinyint(1)"); + + b.Property("Descripcion") + .HasColumnType("longtext"); + + b.Property("Estado") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FechaCompletado") + .HasColumnType("datetime(6)"); + + b.Property("FechaCreacion") + .HasColumnType("datetime(6)"); + + b.Property("FechaLimite") + .HasColumnType("date"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NombreCurso") + .HasColumnType("longtext"); + + b.Property("Prioridad") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.Property("XpOtorgado") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CategoriaId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("Misiones"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Nivel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Descripcion") + .HasColumnType("longtext"); + + b.Property("Numero") + .HasColumnType("int"); + + b.Property("Titulo") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("XpRequerido") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Niveles"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Personaje", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CarreraId") + .HasColumnType("int"); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("Genero") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("CarreraId"); + + b.ToTable("Personajes"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.PersonajeUsuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EstaSeleccionado") + .HasColumnType("tinyint(1)"); + + b.Property("FechaObtenido") + .HasColumnType("datetime(6)"); + + b.Property("PersonajeId") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PersonajeId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("PersonajesUsuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ProgresoUsuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DiaDeGraciaUsado") + .HasColumnType("tinyint(1)"); + + b.Property("FechaInicioRacha") + .HasColumnType("datetime(6)"); + + b.Property("FechaUltimaActividad") + .HasColumnType("datetime(6)"); + + b.Property("NivelActualId") + .HasColumnType("int"); + + b.Property("ProductividadDiaria") + .HasColumnType("decimal(65,30)"); + + b.Property("RachaActual") + .HasColumnType("int"); + + b.Property("RachaMaxima") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.Property("XpTotal") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NivelActualId"); + + b.HasIndex("UsuarioId") + .IsUnique(); + + b.ToTable("ProgresosUsuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.RecuperacionContrasena", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ExpiraEn") + .HasColumnType("datetime(6)"); + + b.Property("FechaCreacion") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Usado") + .HasColumnType("tinyint(1)"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId"); + + b.ToTable("RecuperacionesContrasena"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.RegistroHabito", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Estado") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Fecha") + .HasColumnType("date"); + + b.Property("FechaRegistro") + .HasColumnType("datetime(6)"); + + b.Property("HabitoId") + .HasColumnType("int"); + + b.Property("XpOtorgado") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("HabitoId"); + + b.ToTable("RegistrosHabito"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Rol", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.SesionPomodoro", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CiclosCompletados") + .HasColumnType("int"); + + b.Property("FechaFin") + .HasColumnType("datetime(6)"); + + b.Property("FechaInicio") + .HasColumnType("datetime(6)"); + + b.Property("FueCompletada") + .HasColumnType("tinyint(1)"); + + b.Property("HabitoId") + .HasColumnType("int"); + + b.Property("MisionId") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.Property("XpOtorgado") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("HabitoId"); + + b.HasIndex("MisionId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("SesionesPomodoro"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Suscripcion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ActivadaPorAdminId") + .HasColumnType("int"); + + b.Property("EstaActiva") + .HasColumnType("tinyint(1)"); + + b.Property("FechaActivacion") + .HasColumnType("datetime(6)"); + + b.Property("FechaFin") + .HasColumnType("date"); + + b.Property("FechaInicio") + .HasColumnType("date"); + + b.Property("Plan") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PrecioSoles") + .HasColumnType("decimal(65,30)"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ActivadaPorAdminId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("Suscripciones"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Tema", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArchivoCss") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Descripcion") + .HasColumnType("longtext"); + + b.Property("EsPremium") + .HasColumnType("tinyint(1)"); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("ImagenPreviewUrl") + .HasColumnType("longtext"); + + b.Property("Modo") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Precio") + .HasColumnType("decimal(65,30)"); + + b.HasKey("Id"); + + b.ToTable("Temas"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.TemaUsuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("FechaObtenido") + .HasColumnType("datetime(6)"); + + b.Property("TemaId") + .HasColumnType("int"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TemaId"); + + b.HasIndex("UsuarioId"); + + b.ToTable("TemasUsuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.TipPomodoro", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("Tip") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("TipsPomodoro"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.TokenRefresh", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ExpiraEn") + .HasColumnType("datetime(6)"); + + b.Property("FechaCreacion") + .HasColumnType("datetime(6)"); + + b.Property("Revocado") + .HasColumnType("tinyint(1)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId"); + + b.ToTable("TokensRefresh"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AceptoTerminos") + .HasColumnType("tinyint(1)"); + + b.Property("CarreraId") + .HasColumnType("int"); + + b.Property("CodigoUnico") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ContrasenaHash") + .HasColumnType("longtext"); + + b.Property("CorreoElectronico") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("CorreoVerificado") + .HasColumnType("tinyint(1)"); + + b.Property("EstaActivo") + .HasColumnType("tinyint(1)"); + + b.Property("FechaNacimiento") + .HasColumnType("datetime(6)"); + + b.Property("FechaRegistro") + .HasColumnType("datetime(6)"); + + b.Property("FotoGoogleUrl") + .HasColumnType("longtext"); + + b.Property("Genero") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("GoogleId") + .HasColumnType("varchar(255)"); + + b.Property("Nombre") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RolId") + .HasColumnType("int"); + + b.Property("TemaActualId") + .HasColumnType("int"); + + b.Property("UltimoAcceso") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("CarreraId"); + + b.HasIndex("CodigoUnico") + .IsUnique(); + + b.HasIndex("CorreoElectronico") + .IsUnique(); + + b.HasIndex("GoogleId") + .IsUnique(); + + b.HasIndex("RolId"); + + b.HasIndex("TemaActualId"); + + b.ToTable("Usuarios"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.VerificacionCorreo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ExpiraEn") + .HasColumnType("datetime(6)"); + + b.Property("FechaCreacion") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Usado") + .HasColumnType("tinyint(1)"); + + b.Property("UsuarioId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UsuarioId"); + + b.ToTable("VerificacionesCorreo"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ConfiguracionPomodoro", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithOne("ConfiguracionPomodoro") + .HasForeignKey("EPYCUS_WEB_v0._1.Modelos.Entidades.ConfiguracionPomodoro", "UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.EstadoAnimo", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("EstadosAnimo") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Habito", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Categoria", "Categoria") + .WithMany("Habitos") + .HasForeignKey("CategoriaId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("Habitos") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Categoria"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ImagenNivelPersonaje", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Personaje", "Personaje") + .WithMany("Imagenes") + .HasForeignKey("PersonajeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Personaje"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Log", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany() + .HasForeignKey("UsuarioId"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.LogroUsuario", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Logro", "Logro") + .WithMany() + .HasForeignKey("LogroId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("LogrosUsuario") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Logro"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Mision", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Categoria", "Categoria") + .WithMany("Misiones") + .HasForeignKey("CategoriaId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("Misiones") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Categoria"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Personaje", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Carrera", "Carrera") + .WithMany() + .HasForeignKey("CarreraId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Carrera"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.PersonajeUsuario", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Personaje", "Personaje") + .WithMany("PersonajesUsuario") + .HasForeignKey("PersonajeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("PersonajesUsuario") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Personaje"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.ProgresoUsuario", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Nivel", "NivelActual") + .WithMany("Progresos") + .HasForeignKey("NivelActualId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithOne("Progreso") + .HasForeignKey("EPYCUS_WEB_v0._1.Modelos.Entidades.ProgresoUsuario", "UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NivelActual"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.RecuperacionContrasena", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany() + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.RegistroHabito", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Habito", "Habito") + .WithMany("Registros") + .HasForeignKey("HabitoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Habito"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.SesionPomodoro", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Habito", "Habito") + .WithMany("SesionesPomodoro") + .HasForeignKey("HabitoId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Mision", "Mision") + .WithMany("SesionesPomodoro") + .HasForeignKey("MisionId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("SesionesPomodoro") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Habito"); + + b.Navigation("Mision"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Suscripcion", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", null) + .WithMany() + .HasForeignKey("ActivadaPorAdminId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("Suscripciones") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.TemaUsuario", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Tema", "Tema") + .WithMany() + .HasForeignKey("TemaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("TemasUsuario") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tema"); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.TokenRefresh", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany("TokensRefresh") + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Carrera", "Carrera") + .WithMany("Usuarios") + .HasForeignKey("CarreraId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Rol", "Rol") + .WithMany() + .HasForeignKey("RolId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Tema", "TemaActual") + .WithMany() + .HasForeignKey("TemaActualId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Carrera"); + + b.Navigation("Rol"); + + b.Navigation("TemaActual"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.VerificacionCorreo", b => + { + b.HasOne("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", "Usuario") + .WithMany() + .HasForeignKey("UsuarioId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Usuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Carrera", b => + { + b.Navigation("Usuarios"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Categoria", b => + { + b.Navigation("Habitos"); + + b.Navigation("Misiones"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Habito", b => + { + b.Navigation("Registros"); + + b.Navigation("SesionesPomodoro"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Mision", b => + { + b.Navigation("SesionesPomodoro"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Nivel", b => + { + b.Navigation("Progresos"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Personaje", b => + { + b.Navigation("Imagenes"); + + b.Navigation("PersonajesUsuario"); + }); + + modelBuilder.Entity("EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario", b => + { + b.Navigation("ConfiguracionPomodoro") + .IsRequired(); + + b.Navigation("EstadosAnimo"); + + b.Navigation("Habitos"); + + b.Navigation("LogrosUsuario"); + + b.Navigation("Misiones"); + + b.Navigation("PersonajesUsuario"); + + b.Navigation("Progreso") + .IsRequired(); + + b.Navigation("SesionesPomodoro"); + + b.Navigation("Suscripciones"); + + b.Navigation("TemasUsuario"); + + b.Navigation("TokensRefresh"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Modelos/Entidades/.gitkeep b/Modelos/Entidades/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Modelos/Entidades/Carrera.cs b/Modelos/Entidades/Carrera.cs new file mode 100644 index 0000000..be95e7b --- /dev/null +++ b/Modelos/Entidades/Carrera.cs @@ -0,0 +1,12 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Carrera + { + public int Id { get; set; } + public string Nombre { get; set; } = string.Empty; + public string Area { get; set; } = string.Empty; + public string Codigo { get; set; } = string.Empty; + public bool EstaActiva { get; set; } = true; + public ICollection Usuarios { get; set; } = new List(); + } +} diff --git a/Modelos/Entidades/Categoria.cs b/Modelos/Entidades/Categoria.cs new file mode 100644 index 0000000..07d908b --- /dev/null +++ b/Modelos/Entidades/Categoria.cs @@ -0,0 +1,13 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Categoria + { + public int Id { get; set; } + public string Nombre { get; set; } = string.Empty; + public string Icono { get; set; } = string.Empty; + public string Tipo { get; set; } = string.Empty; + public bool EstaActiva { get; set; } = true; + public ICollection Habitos { get; set; } = new List(); + public ICollection Misiones { get; set; } = new List(); + } +} diff --git a/Modelos/Entidades/ConfiguracionPomodoro.cs b/Modelos/Entidades/ConfiguracionPomodoro.cs new file mode 100644 index 0000000..46a18dc --- /dev/null +++ b/Modelos/Entidades/ConfiguracionPomodoro.cs @@ -0,0 +1,15 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class ConfiguracionPomodoro + { + public int Id { get; set; } + public int TiempoEstudioMin { get; set; } = 25; + public int TiempoDescansoMin { get; set; } = 5; + public int TiempoDescansoLargoMin { get; set; } = 15; + public int CiclosAntesDescansoLargo { get; set; } = 4; + public bool SonidoActivo { get; set; } = true; + public DateTime FechaActualizacion { get; set; } = DateTime.Now; + public int UsuarioId { get; set; } + public Usuario Usuario { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/EstadoAnimo.cs b/Modelos/Entidades/EstadoAnimo.cs new file mode 100644 index 0000000..f29b5fc --- /dev/null +++ b/Modelos/Entidades/EstadoAnimo.cs @@ -0,0 +1,13 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class EstadoAnimo + { + public int Id { get; set; } + public DateOnly Fecha { get; set; } + public string Estado { get; set; } = string.Empty; + public string? Nota { get; set; } + public DateTime FechaRegistro { get; set; } = DateTime.Now; + public int UsuarioId { get; set; } + public Usuario Usuario { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/FraseMotivacional.cs b/Modelos/Entidades/FraseMotivacional.cs new file mode 100644 index 0000000..363dad5 --- /dev/null +++ b/Modelos/Entidades/FraseMotivacional.cs @@ -0,0 +1,10 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class FraseMotivacional + { + public int Id { get; set; } + public string Frase { get; set; } = string.Empty; + public string Autor { get; set; } = "Anónimo"; + public bool EstaActiva { get; set; } = true; + } +} diff --git a/Modelos/Entidades/Habito.cs b/Modelos/Entidades/Habito.cs new file mode 100644 index 0000000..e643742 --- /dev/null +++ b/Modelos/Entidades/Habito.cs @@ -0,0 +1,23 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Habito + { + public int Id { get; set; } + public string Nombre { get; set; } = string.Empty; + public string? Descripcion { get; set; } + public string Frecuencia { get; set; } = string.Empty; + public string? DiasSemana { get; set; } + public bool ConPomodoro { get; set; } = false; + public TimeSpan? RecordatorioHora { get; set; } + public int RachaActual { get; set; } = 0; + public int RachaMaxima { get; set; } = 0; + public bool EstaActivo { get; set; } = true; + public DateTime FechaCreacion { get; set; } = DateTime.Now; + public int UsuarioId { get; set; } + public int CategoriaId { get; set; } + public Usuario Usuario { get; set; } = null!; + public Categoria Categoria { get; set; } = null!; + public ICollection Registros { get; set; } = new List(); + public ICollection SesionesPomodoro { get; set; } = new List(); + } +} diff --git a/Modelos/Entidades/ImagenNivelPersonaje.cs b/Modelos/Entidades/ImagenNivelPersonaje.cs new file mode 100644 index 0000000..7b72723 --- /dev/null +++ b/Modelos/Entidades/ImagenNivelPersonaje.cs @@ -0,0 +1,12 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class ImagenNivelPersonaje + { + public int Id { get; set; } + public int NivelNumero { get; set; } + public string ImagenUrl { get; set; } = string.Empty; + public bool EsPlaceholder { get; set; } = false; + public int PersonajeId { get; set; } + public Personaje Personaje { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/Log.cs b/Modelos/Entidades/Log.cs new file mode 100644 index 0000000..6eb2962 --- /dev/null +++ b/Modelos/Entidades/Log.cs @@ -0,0 +1,13 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Log + { + public int Id { get; set; } + public string Accion { get; set; } = string.Empty; + public string? Detalle { get; set; } + public string? DireccionIp { get; set; } + public DateTime FechaRegistro { get; set; } = DateTime.Now; + public int? UsuarioId { get; set; } + public Usuario? Usuario { get; set; } + } +} diff --git a/Modelos/Entidades/Logro.cs b/Modelos/Entidades/Logro.cs new file mode 100644 index 0000000..9c01148 --- /dev/null +++ b/Modelos/Entidades/Logro.cs @@ -0,0 +1,14 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Logro + { + public int Id { get; set; } + public string Nombre { get; set; } = string.Empty; + public string Descripcion { get; set; } = string.Empty; + public string IconoUrl { get; set; } = string.Empty; + public string CondicionTipo { get; set; } = string.Empty; + public int CondicionValor { get; set; } + public int XpRecompensa { get; set; } = 0; + public bool EstaActivo { get; set; } = true; + } +} diff --git a/Modelos/Entidades/LogroUsuario.cs b/Modelos/Entidades/LogroUsuario.cs new file mode 100644 index 0000000..de2d25c --- /dev/null +++ b/Modelos/Entidades/LogroUsuario.cs @@ -0,0 +1,12 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class LogroUsuario + { + public int Id { get; set; } + public DateTime FechaObtenido { get; set; } = DateTime.Now; + public int UsuarioId { get; set; } + public int LogroId { get; set; } + public Usuario Usuario { get; set; } = null!; + public Logro Logro { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/Mision.cs b/Modelos/Entidades/Mision.cs new file mode 100644 index 0000000..8aac895 --- /dev/null +++ b/Modelos/Entidades/Mision.cs @@ -0,0 +1,22 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Mision + { + public int Id { get; set; } + public string Nombre { get; set; } = string.Empty; + public string? Descripcion { get; set; } + public string? NombreCurso { get; set; } + public DateOnly FechaLimite { get; set; } + public string Prioridad { get; set; } = "Media"; + public string Estado { get; set; } = "Pendiente"; + public bool ConPomodoro { get; set; } = false; + public int XpOtorgado { get; set; } = 0; + public DateTime FechaCreacion { get; set; } = DateTime.Now; + public DateTime? FechaCompletado { get; set; } + public int UsuarioId { get; set; } + public int CategoriaId { get; set; } + public Usuario Usuario { get; set; } = null!; + public Categoria Categoria { get; set; } = null!; + public ICollection SesionesPomodoro { get; set; } = new List(); + } +} diff --git a/Modelos/Entidades/Nivel.cs b/Modelos/Entidades/Nivel.cs new file mode 100644 index 0000000..ad6aa9e --- /dev/null +++ b/Modelos/Entidades/Nivel.cs @@ -0,0 +1,12 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Nivel + { + public int Id { get; set; } + public int Numero { get; set; } + public string Titulo { get; set; } = string.Empty; + public int XpRequerido { get; set; } + public string? Descripcion { get; set; } + public ICollection Progresos { get; set; } = new List(); + } +} diff --git a/Modelos/Entidades/Personaje.cs b/Modelos/Entidades/Personaje.cs new file mode 100644 index 0000000..c2267a8 --- /dev/null +++ b/Modelos/Entidades/Personaje.cs @@ -0,0 +1,14 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Personaje + { + public int Id { get; set; } + public string Nombre { get; set; } = string.Empty; + public string Genero { get; set; } = string.Empty; + public bool EstaActivo { get; set; } = true; + public int? CarreraId { get; set; } + public Carrera? Carrera { get; set; } + public ICollection Imagenes { get; set; } = new List(); + public ICollection PersonajesUsuario { get; set; } = new List(); + } +} diff --git a/Modelos/Entidades/PersonajeUsuario.cs b/Modelos/Entidades/PersonajeUsuario.cs new file mode 100644 index 0000000..7c1b3ca --- /dev/null +++ b/Modelos/Entidades/PersonajeUsuario.cs @@ -0,0 +1,13 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class PersonajeUsuario + { + public int Id { get; set; } + public bool EstaSeleccionado { get; set; } = false; + public DateTime FechaObtenido { get; set; } = DateTime.Now; + public int UsuarioId { get; set; } + public int PersonajeId { get; set; } + public Usuario Usuario { get; set; } = null!; + public Personaje Personaje { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/ProgresoUsuario.cs b/Modelos/Entidades/ProgresoUsuario.cs new file mode 100644 index 0000000..ce2e837 --- /dev/null +++ b/Modelos/Entidades/ProgresoUsuario.cs @@ -0,0 +1,18 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class ProgresoUsuario + { + public int Id { get; set; } + public int XpTotal { get; set; } = 0; + public int RachaActual { get; set; } = 0; + public int RachaMaxima { get; set; } = 0; + public DateTime? FechaUltimaActividad { get; set; } + public DateTime? FechaInicioRacha { get; set; } + public bool DiaDeGraciaUsado { get; set; } = false; + public decimal ProductividadDiaria { get; set; } = 0; + public int UsuarioId { get; set; } + public int NivelActualId { get; set; } + public Usuario Usuario { get; set; } = null!; + public Nivel NivelActual { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/RecuperacionContrasena.cs b/Modelos/Entidades/RecuperacionContrasena.cs new file mode 100644 index 0000000..cdc43af --- /dev/null +++ b/Modelos/Entidades/RecuperacionContrasena.cs @@ -0,0 +1,13 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class RecuperacionContrasena + { + public int Id { get; set; } + public string Token { get; set; } = string.Empty; + public DateTime ExpiraEn { get; set; } + public bool Usado { get; set; } = false; + public DateTime FechaCreacion { get; set; } = DateTime.Now; + public int UsuarioId { get; set; } + public Usuario Usuario { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/RegistroHabito.cs b/Modelos/Entidades/RegistroHabito.cs new file mode 100644 index 0000000..5cad40d --- /dev/null +++ b/Modelos/Entidades/RegistroHabito.cs @@ -0,0 +1,13 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class RegistroHabito + { + public int Id { get; set; } + public DateOnly Fecha { get; set; } + public string Estado { get; set; } = "Pendiente"; + public int XpOtorgado { get; set; } = 0; + public DateTime FechaRegistro { get; set; } = DateTime.Now; + public int HabitoId { get; set; } + public Habito Habito { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/Rol.cs b/Modelos/Entidades/Rol.cs new file mode 100644 index 0000000..e97b991 --- /dev/null +++ b/Modelos/Entidades/Rol.cs @@ -0,0 +1,8 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Rol + { + public int Id { get; set; } + public string Nombre { get; set; } = string.Empty; + } +} diff --git a/Modelos/Entidades/SesionPomodoro.cs b/Modelos/Entidades/SesionPomodoro.cs new file mode 100644 index 0000000..fda4013 --- /dev/null +++ b/Modelos/Entidades/SesionPomodoro.cs @@ -0,0 +1,18 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class SesionPomodoro + { + public int Id { get; set; } + public DateTime FechaInicio { get; set; } + public DateTime? FechaFin { get; set; } + public int CiclosCompletados { get; set; } = 0; + public int XpOtorgado { get; set; } = 0; + public bool FueCompletada { get; set; } = false; + public int UsuarioId { get; set; } + public int? HabitoId { get; set; } + public int? MisionId { get; set; } + public Usuario Usuario { get; set; } = null!; + public Habito? Habito { get; set; } + public Mision? Mision { get; set; } + } +} diff --git a/Modelos/Entidades/Suscripcion.cs b/Modelos/Entidades/Suscripcion.cs new file mode 100644 index 0000000..f2771c0 --- /dev/null +++ b/Modelos/Entidades/Suscripcion.cs @@ -0,0 +1,16 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Suscripcion + { + public int Id { get; set; } + public string Plan { get; set; } = string.Empty; + public decimal PrecioSoles { get; set; } + public DateOnly FechaInicio { get; set; } + public DateOnly FechaFin { get; set; } + public bool EstaActiva { get; set; } = false; + public int? ActivadaPorAdminId { get; set; } + public DateTime? FechaActivacion { get; set; } + public int UsuarioId { get; set; } + public Usuario Usuario { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/Tema.cs b/Modelos/Entidades/Tema.cs new file mode 100644 index 0000000..bc39ddf --- /dev/null +++ b/Modelos/Entidades/Tema.cs @@ -0,0 +1,15 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Tema + { + public int Id { get; set; } + public string Nombre { get; set; } = string.Empty; + public string? Descripcion { get; set; } + public string Modo { get; set; } = string.Empty; + public string ArchivoCss { get; set; } = string.Empty; + public string? ImagenPreviewUrl { get; set; } + public bool EsPremium { get; set; } = false; + public decimal Precio { get; set; } = 0; + public bool EstaActivo { get; set; } = true; + } +} diff --git a/Modelos/Entidades/TemaUsuario.cs b/Modelos/Entidades/TemaUsuario.cs new file mode 100644 index 0000000..189f27a --- /dev/null +++ b/Modelos/Entidades/TemaUsuario.cs @@ -0,0 +1,12 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class TemaUsuario + { + public int Id { get; set; } + public DateTime FechaObtenido { get; set; } = DateTime.Now; + public int UsuarioId { get; set; } + public int TemaId { get; set; } + public Usuario Usuario { get; set; } = null!; + public Tema Tema { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/TipPomodoro.cs b/Modelos/Entidades/TipPomodoro.cs new file mode 100644 index 0000000..b67d8e9 --- /dev/null +++ b/Modelos/Entidades/TipPomodoro.cs @@ -0,0 +1,9 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class TipPomodoro + { + public int Id { get; set; } + public string Tip { get; set; } = string.Empty; + public bool EstaActivo { get; set; } = true; + } +} diff --git a/Modelos/Entidades/TokenRefresh.cs b/Modelos/Entidades/TokenRefresh.cs new file mode 100644 index 0000000..b327105 --- /dev/null +++ b/Modelos/Entidades/TokenRefresh.cs @@ -0,0 +1,13 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class TokenRefresh + { + public int Id { get; set; } + public string Token { get; set; } = string.Empty; + public DateTime ExpiraEn { get; set; } + public bool Revocado { get; set; } = false; + public DateTime FechaCreacion { get; set; } = DateTime.Now; + public int UsuarioId { get; set; } + public Usuario Usuario { get; set; } = null!; + } +} diff --git a/Modelos/Entidades/Usuario.cs b/Modelos/Entidades/Usuario.cs new file mode 100644 index 0000000..77db1be --- /dev/null +++ b/Modelos/Entidades/Usuario.cs @@ -0,0 +1,37 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class Usuario + { + public int Id { get; set; } + public string CodigoUnico { get; set; } = string.Empty; + public string Nombre { get; set; } = string.Empty; + public string CorreoElectronico { get; set; } = string.Empty; + public string? ContrasenaHash { get; set; } + public DateTime FechaNacimiento { get; set; } + public string Genero { get; set; } = string.Empty; + public bool CorreoVerificado { get; set; } = false; + public bool AceptoTerminos { get; set; } = false; + public bool EstaActivo { get; set; } = true; + public DateTime FechaRegistro { get; set; } = DateTime.UtcNow; + public DateTime? UltimoAcceso { get; set; } + public string? GoogleId { get; set; } + public string? FotoGoogleUrl { get; set; } + public int RolId { get; set; } + public int CarreraId { get; set; } + public int? TemaActualId { get; set; } + public Rol Rol { get; set; } = null!; + public Carrera Carrera { get; set; } = null!; + public Tema? TemaActual { get; set; } + public ProgresoUsuario Progreso { get; set; } = null!; + public ICollection Habitos { get; set; } = new List(); + public ICollection Misiones { get; set; } = new List(); + public ICollection SesionesPomodoro { get; set; } = new List(); + public ConfiguracionPomodoro ConfiguracionPomodoro { get; set; } = null!; + public ICollection PersonajesUsuario { get; set; } = new List(); + public ICollection LogrosUsuario { get; set; } = new List(); + public ICollection EstadosAnimo { get; set; } = new List(); + public ICollection Suscripciones { get; set; } = new List(); + public ICollection TemasUsuario { get; set; } = new List(); + public ICollection TokensRefresh { get; set; } = new List(); + } +} diff --git a/Modelos/Entidades/VerificacionCorreo.cs b/Modelos/Entidades/VerificacionCorreo.cs new file mode 100644 index 0000000..2370c83 --- /dev/null +++ b/Modelos/Entidades/VerificacionCorreo.cs @@ -0,0 +1,13 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Entidades +{ + public class VerificacionCorreo + { + public int Id { get; set; } + public string Token { get; set; } = string.Empty; + public DateTime ExpiraEn { get; set; } + public bool Usado { get; set; } = false; + public DateTime FechaCreacion { get; set; } = DateTime.Now; + public int UsuarioId { get; set; } + public Usuario Usuario { get; set; } = null!; + } +} diff --git a/Modelos/Enums/.gitkeep b/Modelos/Enums/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Modelos/Enums/CondicionLogro.cs b/Modelos/Enums/CondicionLogro.cs new file mode 100644 index 0000000..5e68153 --- /dev/null +++ b/Modelos/Enums/CondicionLogro.cs @@ -0,0 +1,12 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Enums +{ + public enum CondicionLogro + { + HabitosCompletados, + MisionesCompletadas, + RachaDias, + SesionesPomodoro, + XpTotal, + NivelAlcanzado + } +} diff --git a/Modelos/Enums/EstadoAnimoEnum.cs b/Modelos/Enums/EstadoAnimoEnum.cs new file mode 100644 index 0000000..52673ac --- /dev/null +++ b/Modelos/Enums/EstadoAnimoEnum.cs @@ -0,0 +1,11 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Enums +{ + public enum EstadoAnimoEnum + { + Feliz, + Bien, + Neutral, + Cansado, + Estresado + } +} diff --git a/Modelos/Enums/EstadoMision.cs b/Modelos/Enums/EstadoMision.cs new file mode 100644 index 0000000..3ac6bbf --- /dev/null +++ b/Modelos/Enums/EstadoMision.cs @@ -0,0 +1,10 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Enums +{ + public enum EstadoMision + { + Pendiente, + EnProgreso, + Completado, + Fallido + } +} diff --git a/Modelos/Enums/FrecuenciaHabito.cs b/Modelos/Enums/FrecuenciaHabito.cs new file mode 100644 index 0000000..715e7b9 --- /dev/null +++ b/Modelos/Enums/FrecuenciaHabito.cs @@ -0,0 +1,9 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Enums +{ + public enum FrecuenciaHabito + { + Diaria, + Semanal, + Personalizada + } +} diff --git a/Modelos/Enums/PrioridadMision.cs b/Modelos/Enums/PrioridadMision.cs new file mode 100644 index 0000000..3f12d00 --- /dev/null +++ b/Modelos/Enums/PrioridadMision.cs @@ -0,0 +1,9 @@ +namespace EPYCUS_WEB_v0._1.Modelos.Enums +{ + public enum PrioridadMision + { + Baja, + Media, + Alta + } +} diff --git a/Models/ErrorViewModel.cs b/Models/ErrorViewModel.cs new file mode 100644 index 0000000..fa35472 --- /dev/null +++ b/Models/ErrorViewModel.cs @@ -0,0 +1,9 @@ +namespace EPYCUS_WEB_v0._1.Models +{ + public class ErrorViewModel + { + public string? RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + } +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..50e7f9a --- /dev/null +++ b/Program.cs @@ -0,0 +1,114 @@ +using System.Text; +using EPYCUS_WEB_v0._1.Datos; +using EPYCUS_WEB_v0._1.Datos.Semilla; +using EPYCUS_WEB_v0._1.Servicios.Implementaciones; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddDbContext(options => +{ + var cadenaConexion = builder.Configuration.GetConnectionString("ConexionPrincipal"); + options.UseMySql(cadenaConexion, ServerVersion.AutoDetect(cadenaConexion)); +}); + +builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) + .AddJwtBearer(options => + { + options.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + ValidateIssuerSigningKey = true, + ValidIssuer = builder.Configuration["Jwt:Emisor"], + ValidAudience = builder.Configuration["Jwt:Audiencia"], + IssuerSigningKey = new SymmetricSecurityKey( + Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Clave"]!)) + }; + options.Events = new JwtBearerEvents + { + OnMessageReceived = context => + { + var esAdmin = context.Request.Path.StartsWithSegments("/admin"); + var token = esAdmin + ? context.Request.Cookies["admin_jwt_token"] + : context.Request.Cookies["jwt_token"]; + + if (!string.IsNullOrEmpty(token)) + { + context.Token = token; + } + + return Task.CompletedTask; + }, + OnChallenge = context => + { + if (!context.Request.Path.StartsWithSegments("/api")) + { + context.HandleResponse(); + context.Response.Redirect(context.Request.Path.StartsWithSegments("/admin") + ? "/admin/login" + : "/Autenticacion/Login"); + } + + return Task.CompletedTask; + } + }; + }) + .AddGoogle(options => + { + options.ClientId = builder.Configuration["Google:ClientId"]!; + options.ClientSecret = builder.Configuration["Google:ClientSecret"]!; + }); + +builder.Services.AddAuthorization(); +builder.Services.AddControllersWithViews(); + +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); + +// AutoMapper — se activa cuando se creen los perfiles de mapeo +//builder.Services.AddAutoMapper(typeof(Program)); + +var app = builder.Build(); + +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Home/Error"); + app.UseHsts(); +} + +app.UseHttpsRedirection(); +app.UseStaticFiles(); + +app.UseRouting(); + +app.UseAuthentication(); +app.UseAuthorization(); + +app.MapDefaultControllerRoute(); + +using (var scope = app.Services.CreateScope()) +{ + var contexto = scope.ServiceProvider.GetRequiredService(); + + // Aplicar migraciones pendientes + await contexto.Database.MigrateAsync(); + + // Inicializar datos semilla + await DatosSemilla.InicializarAsync(contexto); +} + +app.Run(); diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json new file mode 100644 index 0000000..e4448c6 --- /dev/null +++ b/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5053", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7254;http://localhost:5053", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Servicios/Implementaciones/.gitkeep b/Servicios/Implementaciones/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Servicios/Implementaciones/ServicioAdmin.cs b/Servicios/Implementaciones/ServicioAdmin.cs new file mode 100644 index 0000000..4266471 --- /dev/null +++ b/Servicios/Implementaciones/ServicioAdmin.cs @@ -0,0 +1,119 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.EntityFrameworkCore; + +namespace EPYCUS_WEB_v0._1.Servicios.Implementaciones +{ + public class ServicioAdmin : IServicioAdmin + { + private readonly Datos.ContextoAplicacion _contexto; + + public ServicioAdmin(Datos.ContextoAplicacion contexto) + { + _contexto = contexto; + } + + public async Task> ObtenerTodosUsuarios() + { + return await _contexto.Usuarios + .Include(u => u.Rol) + .Include(u => u.Carrera) + .Include(u => u.Suscripciones) + .ToListAsync(); + } + + public async Task ObtenerUsuarioPorId(int id) + { + return await _contexto.Usuarios + .Include(u => u.Rol) + .Include(u => u.Carrera) + .Include(u => u.Suscripciones) + .FirstOrDefaultAsync(u => u.Id == id); + } + + public async Task ActivarSuscripcion(int usuarioId, int adminId) + { + var usuario = await _contexto.Usuarios + .Include(u => u.Suscripciones) + .FirstOrDefaultAsync(u => u.Id == usuarioId); + + if (usuario == null) + { + return; + } + + var vigente = usuario.Suscripciones.FirstOrDefault(s => s.EstaActiva); + if (vigente != null) + { + vigente.EstaActiva = false; + vigente.FechaFin = DateOnly.FromDateTime(DateTime.Today); + } + + _contexto.Suscripciones.Add(new Suscripcion + { + UsuarioId = usuarioId, + Plan = "Premium", + PrecioSoles = 0, + FechaInicio = DateOnly.FromDateTime(DateTime.Today), + FechaFin = DateOnly.FromDateTime(DateTime.Today.AddYears(1)), + EstaActiva = true, + ActivadaPorAdminId = adminId, + FechaActivacion = DateTime.UtcNow + }); + + await _contexto.SaveChangesAsync(); + } + + public async Task DesactivarSuscripcion(int usuarioId) + { + var suscripcion = await _contexto.Suscripciones + .FirstOrDefaultAsync(s => s.UsuarioId == usuarioId && s.EstaActiva); + + if (suscripcion == null) + { + return; + } + + suscripcion.EstaActiva = false; + suscripcion.FechaFin = DateOnly.FromDateTime(DateTime.Today); + await _contexto.SaveChangesAsync(); + } + + public async Task> ObtenerFrases() + { + return await _contexto.FrasesMotivacionales + .OrderByDescending(f => f.EstaActiva) + .ThenBy(f => f.Frase) + .ToListAsync(); + } + + public async Task CrearFrase(string frase, string autor) + { + if (string.IsNullOrWhiteSpace(frase)) + { + return; + } + + _contexto.FrasesMotivacionales.Add(new FraseMotivacional + { + Frase = frase.Trim(), + Autor = string.IsNullOrWhiteSpace(autor) ? "Anónimo" : autor.Trim(), + EstaActiva = true + }); + + await _contexto.SaveChangesAsync(); + } + + public async Task EliminarFrase(int id) + { + var frase = await _contexto.FrasesMotivacionales.FirstOrDefaultAsync(f => f.Id == id); + if (frase == null) + { + return; + } + + _contexto.FrasesMotivacionales.Remove(frase); + await _contexto.SaveChangesAsync(); + } + } +} diff --git a/Servicios/Implementaciones/ServicioAutenticacion.cs b/Servicios/Implementaciones/ServicioAutenticacion.cs new file mode 100644 index 0000000..258d37f --- /dev/null +++ b/Servicios/Implementaciones/ServicioAutenticacion.cs @@ -0,0 +1,348 @@ +using EPYCUS_WEB_v0._1.Datos; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.ViewModels; +using Microsoft.EntityFrameworkCore; +using Microsoft.IdentityModel.Tokens; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; + +namespace EPYCUS_WEB_v0._1.Servicios.Implementaciones +{ + public class ServicioAutenticacion : IServicioAutenticacion + { + private readonly ContextoAplicacion _contexto; + private readonly IConfiguration _config; + + public ServicioAutenticacion(ContextoAplicacion contexto, IConfiguration config) + { + _contexto = contexto; + _config = config; + } + + public Task<(bool Exito, string Mensaje, string? Token, string? RefreshToken)> RegistrarUsuario(RegistroViewModel modelo) + { + return RegistrarUsuarioInterno(modelo); + } + + public Task<(bool Exito, string Mensaje, string? Token, string? RefreshToken)> RenovarToken(string refreshToken) + { + return RenovarTokenInterno(refreshToken); + } + + private async Task<(bool Exito, string Mensaje, string? Token, string? RefreshToken)> RegistrarUsuarioInterno(RegistroViewModel modelo) + { + var existeCorreo = await _contexto.Usuarios + .AnyAsync(u => u.CorreoElectronico == modelo.CorreoElectronico); + + if (existeCorreo) + { + return (false, "El correo ya está registrado", null, null); + } + + var rolUsuario = await _contexto.Roles.FirstOrDefaultAsync(r => r.Nombre == "Usuario"); + if (rolUsuario == null) + { + return (false, "No existe el rol base de usuario", null, null); + } + + string codigoUnico; + do + { + codigoUnico = Ayudantes.GeneradorCodigo.GenerarCodigoUsuario(); + } while (await _contexto.Usuarios.AnyAsync(u => u.CodigoUnico == codigoUnico)); + + var hash = BCrypt.Net.BCrypt.HashPassword(modelo.Contrasena, workFactor: 12); + + var usuario = new Modelos.Entidades.Usuario + { + CodigoUnico = codigoUnico, + Nombre = modelo.Nombre, + CorreoElectronico = modelo.CorreoElectronico, + ContrasenaHash = hash, + FechaNacimiento = modelo.FechaNacimiento, + Genero = modelo.Genero, + RolId = rolUsuario.Id, + CarreraId = modelo.CarreraId, + CorreoVerificado = false, + AceptoTerminos = modelo.AceptoTerminos, + EstaActivo = true, + FechaRegistro = DateTime.UtcNow + }; + + _contexto.Usuarios.Add(usuario); + await _contexto.SaveChangesAsync(); + + var nivelInicial = await _contexto.Niveles.FirstOrDefaultAsync(n => n.Numero == 0); + if (nivelInicial != null) + { + _contexto.ProgresosUsuario.Add(new Modelos.Entidades.ProgresoUsuario + { + UsuarioId = usuario.Id, + NivelActualId = nivelInicial.Id, + XpTotal = 0, + RachaActual = 0, + RachaMaxima = 0 + }); + } + + _contexto.ConfiguracionesPomodoro.Add(new Modelos.Entidades.ConfiguracionPomodoro + { + UsuarioId = usuario.Id, + TiempoEstudioMin = 25, + TiempoDescansoMin = 5, + TiempoDescansoLargoMin = 15, + CiclosAntesDescansoLargo = 4, + SonidoActivo = true, + FechaActualizacion = DateTime.UtcNow + }); + + await _contexto.SaveChangesAsync(); + + var token = GenerarToken(usuario); + var refreshToken = GenerarRefreshToken(); + + _contexto.TokensRefresh.Add(new Modelos.Entidades.TokenRefresh + { + UsuarioId = usuario.Id, + Token = refreshToken, + ExpiraEn = DateTime.UtcNow.AddDays(ObtenerExpiracionRefreshDias()) + }); + + await _contexto.SaveChangesAsync(); + + return (true, "Registro exitoso", token, refreshToken); + } + + private async Task<(bool Exito, string Mensaje, string? Token, string? RefreshToken)> RenovarTokenInterno(string refreshToken) + { + if (string.IsNullOrWhiteSpace(refreshToken)) + { + return (false, "Token inválido", null, null); + } + + var tokenGuardado = await _contexto.TokensRefresh + .FirstOrDefaultAsync(t => t.Token == refreshToken && !t.Revocado); + + if (tokenGuardado == null || tokenGuardado.ExpiraEn < DateTime.UtcNow) + { + return (false, "Token expirado", null, null); + } + + var usuario = await _contexto.Usuarios + .Include(u => u.Rol) + .FirstOrDefaultAsync(u => u.Id == tokenGuardado.UsuarioId); + + if (usuario == null || !usuario.EstaActivo) + { + return (false, "Usuario inválido", null, null); + } + + tokenGuardado.Revocado = true; + + var nuevoRefresh = GenerarRefreshToken(); + _contexto.TokensRefresh.Add(new Modelos.Entidades.TokenRefresh + { + UsuarioId = usuario.Id, + Token = nuevoRefresh, + ExpiraEn = DateTime.UtcNow.AddDays(ObtenerExpiracionRefreshDias()) + }); + + var token = GenerarToken(usuario); + await _contexto.SaveChangesAsync(); + + return (true, "Token renovado", token, nuevoRefresh); + } + + public async Task<(bool Exito, string Mensaje, string? Token, string? RefreshToken)> Login(string correo, string contrasena) + { + var usuario = await _contexto.Usuarios + .Include(u => u.Rol) + .FirstOrDefaultAsync(u => u.CorreoElectronico == correo); + + if (usuario == null) + { + return (false, "Credenciales incorrectas", null, null); + } + + if (!usuario.EstaActivo) + { + return (false, "La cuenta está desactivada", null, null); + } + + if (string.IsNullOrWhiteSpace(usuario.ContrasenaHash)) + { + return (false, "La cuenta no tiene contraseña, inicia sesión con Google", null, null); + } + + if (!BCrypt.Net.BCrypt.Verify(contrasena, usuario.ContrasenaHash)) + { + return (false, "Credenciales incorrectas", null, null); + } + + var token = GenerarToken(usuario); + var refreshToken = GenerarRefreshToken(); + + usuario.UltimoAcceso = DateTime.UtcNow; + + _contexto.TokensRefresh.Add(new Modelos.Entidades.TokenRefresh + { + UsuarioId = usuario.Id, + Token = refreshToken, + ExpiraEn = DateTime.UtcNow.AddDays(ObtenerExpiracionRefreshDias()) + }); + + await _contexto.SaveChangesAsync(); + + return (true, "Login exitoso", token, refreshToken); + } + + private int ObtenerExpiracionRefreshDias() + { + var expiracion = _config["Jwt:ExpiracionRefreshDias"]; + return int.TryParse(expiracion, out var dias) ? dias : 7; + } + + private string GenerarRefreshToken() + { + return Guid.NewGuid().ToString("N"); + } + + private string GenerarToken(Modelos.Entidades.Usuario usuario) + { + var claims = new[] + { + new Claim(ClaimTypes.NameIdentifier, usuario.Id.ToString()), + new Claim(ClaimTypes.Email, usuario.CorreoElectronico), + new Claim(ClaimTypes.Name, usuario.Nombre), + new Claim(ClaimTypes.Role, usuario.Rol?.Nombre ?? "Usuario"), + new Claim("CodigoUnico", usuario.CodigoUnico), + new Claim("CarreraId", usuario.CarreraId.ToString()) + }; + + var claveStr = _config["Jwt:Clave"]; + if (string.IsNullOrEmpty(claveStr)) + throw new InvalidOperationException("La clave secreta de JWT no está configurada."); + + var clave = new SymmetricSecurityKey(System.Text.Encoding.UTF8.GetBytes(claveStr)); + var credenciales = new SigningCredentials(clave, SecurityAlgorithms.HmacSha256); + + var expiracionStr = _config["Jwt:ExpiracionMinutos"]; + var minutos = int.TryParse(expiracionStr, out int val) ? val : 60; + + var token = new JwtSecurityToken( + issuer: _config["Jwt:Emisor"], + audience: _config["Jwt:Audiencia"], + claims: claims, + expires: DateTime.UtcNow.AddMinutes(minutos), + signingCredentials: credenciales + ); + + return new JwtSecurityTokenHandler().WriteToken(token); + } + + public Task VerificarCorreo(string token) + { + return VerificarCorreoInterno(token); + } + + private async Task VerificarCorreoInterno(string token) + { + var verificacion = await _contexto.VerificacionesCorreo + .FirstOrDefaultAsync(v => v.Token == token && !v.Usado); + + if (verificacion == null || verificacion.ExpiraEn < DateTime.UtcNow) + { + return false; + } + + var usuario = await _contexto.Usuarios.FirstOrDefaultAsync(u => u.Id == verificacion.UsuarioId); + if (usuario == null) + { + return false; + } + + usuario.CorreoVerificado = true; + verificacion.Usado = true; + await _contexto.SaveChangesAsync(); + + return true; + } + + public Task EnviarCorreoRecuperacion(string correo) + { + return EnviarCorreoRecuperacionInterno(correo); + } + + private async Task EnviarCorreoRecuperacionInterno(string correo) + { + var usuario = await _contexto.Usuarios.FirstOrDefaultAsync(u => u.CorreoElectronico == correo); + if (usuario == null) + { + return false; + } + + var token = Guid.NewGuid().ToString("N"); + + _contexto.RecuperacionesContrasena.Add(new Modelos.Entidades.RecuperacionContrasena + { + UsuarioId = usuario.Id, + Token = token, + ExpiraEn = DateTime.UtcNow.AddHours(1), + Usado = false, + FechaCreacion = DateTime.UtcNow + }); + + await _contexto.SaveChangesAsync(); + + return true; + } + + public Task RestablecerContrasena(string token, string nuevaContrasena) + { + return RestablecerContrasenaInterno(token, nuevaContrasena); + } + + private async Task RestablecerContrasenaInterno(string token, string nuevaContrasena) + { + var recuperacion = await _contexto.RecuperacionesContrasena + .FirstOrDefaultAsync(r => r.Token == token && !r.Usado); + + if (recuperacion == null || recuperacion.ExpiraEn < DateTime.UtcNow) + { + return false; + } + + var usuario = await _contexto.Usuarios.FirstOrDefaultAsync(u => u.Id == recuperacion.UsuarioId); + if (usuario == null) + { + return false; + } + + usuario.ContrasenaHash = BCrypt.Net.BCrypt.HashPassword(nuevaContrasena, workFactor: 12); + recuperacion.Usado = true; + + await _contexto.SaveChangesAsync(); + + return true; + } + + public Task CerrarSesion(int usuarioId) + { + return CerrarSesionInterno(usuarioId); + } + + private async Task CerrarSesionInterno(int usuarioId) + { + var tokens = await _contexto.TokensRefresh + .Where(t => t.UsuarioId == usuarioId && !t.Revocado) + .ToListAsync(); + + foreach (var token in tokens) + { + token.Revocado = true; + } + + await _contexto.SaveChangesAsync(); + } + } +} diff --git a/Servicios/Implementaciones/ServicioBienestar.cs b/Servicios/Implementaciones/ServicioBienestar.cs new file mode 100644 index 0000000..801e344 --- /dev/null +++ b/Servicios/Implementaciones/ServicioBienestar.cs @@ -0,0 +1,166 @@ +using EPYCUS_WEB_v0._1.Datos; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.EntityFrameworkCore; + +namespace EPYCUS_WEB_v0._1.Servicios.Implementaciones +{ + public class ServicioBienestar : IServicioBienestar + { + private readonly ContextoAplicacion _contexto; + + public ServicioBienestar(ContextoAplicacion contexto) + { + _contexto = contexto; + } + + public async Task> ObtenerAlertasActivas(int usuarioId) + { + var alertas = new List(); + + var alertaPomodoro = await VerificarUsoExcesivoPomodoro(usuarioId); + if (alertaPomodoro != null) + { + alertas.Add(alertaPomodoro); + } + + var alertaAnimo = await VerificarAnimoNegativoConsecutivo(usuarioId); + if (alertaAnimo != null) + { + alertas.Add(alertaAnimo); + } + + var alertaSueno = await VerificarHabitoSueno(usuarioId); + if (alertaSueno != null) + { + alertas.Add(alertaSueno); + } + + var alertaMisiones = await VerificarSobrecargaMisiones(usuarioId); + if (alertaMisiones != null) + { + alertas.Add(alertaMisiones); + } + + return alertas; + } + + public async Task VerificarUsoExcesivoPomodoro(int usuarioId) + { + var hoy = DateTime.Today; + var ciclosHoy = await _contexto.SesionesPomodoro + .Where(s => s.UsuarioId == usuarioId + && s.FechaInicio.Date == hoy + && s.FueCompletada) + .SumAsync(s => s.CiclosCompletados); + + if (ciclosHoy > 8) + { + return new AlertaBienestar + { + Tipo = "Sobrecarga", + Mensaje = "Llevas más de 8 ciclos Pomodoro hoy. Es momento de una pausa real. Tu cerebro lo necesita.", + Icono = "bi-exclamation-triangle", + EsCritica = true + }; + } + + return null; + } + + public async Task VerificarAnimoNegativoConsecutivo(int usuarioId) + { + var ultimosTresEstados = await _contexto.EstadosAnimo + .Where(e => e.UsuarioId == usuarioId) + .OrderByDescending(e => e.Fecha) + .Take(3) + .Select(e => e.Estado) + .ToListAsync(); + + bool tresNegativosConsecutivos = ultimosTresEstados.Count == 3 + && ultimosTresEstados.All(e => e == "Cansado" || e == "Estresado"); + + if (tresNegativosConsecutivos) + { + return new AlertaBienestar + { + Tipo = "Estres", + Mensaje = "Has registrado estrés o cansancio 3 días seguidos. Considera reducir la carga de hábitos por hoy y priorizar el descanso.", + Icono = "bi-heart-pulse", + EsCritica = true + }; + } + + return null; + } + + private async Task VerificarHabitoSueno(int usuarioId) + { + var hace3dias = DateOnly.FromDateTime(DateTime.Today.AddDays(-3)); + + var tieneHabitoSueno = await _contexto.Habitos + .AnyAsync(h => h.UsuarioId == usuarioId + && h.EstaActivo + && h.Categoria.Nombre == "Sueño"); + + if (!tieneHabitoSueno) + { + return null; + } + + var suenoCumplido = await _contexto.RegistrosHabito + .AnyAsync(r => r.Habito.UsuarioId == usuarioId + && r.Habito.Categoria.Nombre == "Sueño" + && r.Fecha >= hace3dias + && r.Estado == "Completado"); + + if (!suenoCumplido) + { + return new AlertaBienestar + { + Tipo = "Descanso", + Mensaje = "No has registrado tu hábito de sueño en 3 días. El descanso es fundamental para tu rendimiento académico.", + Icono = "bi-moon-stars", + EsCritica = false + }; + } + + return null; + } + + private async Task VerificarSobrecargaMisiones(int usuarioId) + { + var en2dias = DateOnly.FromDateTime(DateTime.Today.AddDays(2)); + var hoy = DateOnly.FromDateTime(DateTime.Today); + + var misionesUrgentes = await _contexto.Misiones + .CountAsync(m => m.UsuarioId == usuarioId + && m.FechaLimite >= hoy + && m.FechaLimite <= en2dias + && (m.Estado == "Pendiente" || m.Estado == "EnProgreso")); + + if (misionesUrgentes >= 3) + { + return new AlertaBienestar + { + Tipo = "Sobrecarga", + Mensaje = $"Tienes {misionesUrgentes} misiones que vencen en los próximos 2 días. Prioriza y divide el trabajo en sesiones Pomodoro.", + Icono = "bi-lightning", + EsCritica = true + }; + } + + return null; + } + + public string? RecomendacionPausaActiva(int ciclosCompletados) + { + return ciclosCompletados switch + { + 2 => "Estira los dedos y mueve las muñecas. 30 segundos.", + 4 => "Párate, camina y mira por la ventana. 5 minutos.", + 6 => "Come algo ligero y toma agua. Tu cerebro necesita glucosa.", + _ => null + }; + } + } +} diff --git a/Servicios/Implementaciones/ServicioCorreo.cs b/Servicios/Implementaciones/ServicioCorreo.cs new file mode 100644 index 0000000..0d7a75f --- /dev/null +++ b/Servicios/Implementaciones/ServicioCorreo.cs @@ -0,0 +1,17 @@ +using EPYCUS_WEB_v0._1.Servicios.Interfaces; + +namespace EPYCUS_WEB_v0._1.Servicios.Implementaciones +{ + public class ServicioCorreo : IServicioCorreo + { + public Task EnviarVerificacion(string correo, string nombre, string token) + { + throw new NotImplementedException(); + } + + public Task EnviarRecuperacion(string correo, string nombre, string token) + { + throw new NotImplementedException(); + } + } +} diff --git a/Servicios/Implementaciones/ServicioGamificacion.cs b/Servicios/Implementaciones/ServicioGamificacion.cs new file mode 100644 index 0000000..3fd69ec --- /dev/null +++ b/Servicios/Implementaciones/ServicioGamificacion.cs @@ -0,0 +1,190 @@ +using EPYCUS_WEB_v0._1.Ayudantes; +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.EntityFrameworkCore; + +namespace EPYCUS_WEB_v0._1.Servicios.Implementaciones +{ + public class ServicioGamificacion : IServicioGamificacion + { + private readonly EPYCUS_WEB_v0._1.Datos.ContextoAplicacion _contexto; + + public ServicioGamificacion(EPYCUS_WEB_v0._1.Datos.ContextoAplicacion contexto) + { + _contexto = contexto; + } + + public async Task<(int XpGanado, bool SubioDeNivel, int NivelNuevo)> SumarXP(int usuarioId, int xp) + { + var progreso = await _contexto.ProgresosUsuario + .Include(p => p.NivelActual) + .FirstOrDefaultAsync(p => p.UsuarioId == usuarioId); + + if (progreso == null) + { + return (0, false, 0); + } + + var xpAnterior = progreso.XpTotal; + progreso.XpTotal += xp; + + var nivelNuevoNumero = CalculadorXP.NivelParaXp(progreso.XpTotal); + var subio = nivelNuevoNumero != progreso.NivelActual.Numero; + + if (subio) + { + var nuevoNivel = await _contexto.Niveles.FirstOrDefaultAsync(n => n.Numero == nivelNuevoNumero); + if (nuevoNivel != null) + { + progreso.NivelActualId = nuevoNivel.Id; + } + } + + await _contexto.SaveChangesAsync(); + + return (progreso.XpTotal - xpAnterior, subio, nivelNuevoNumero); + } + + public async Task VerificarYOtorgarLogros(int usuarioId) + { + var progreso = await _contexto.ProgresosUsuario + .Include(p => p.NivelActual) + .FirstOrDefaultAsync(p => p.UsuarioId == usuarioId); + + if (progreso == null) + { + return; + } + + var logrosActivos = await _contexto.Logros.Where(l => l.EstaActivo).ToListAsync(); + var logrosUsuario = await _contexto.LogrosUsuario.Where(lu => lu.UsuarioId == usuarioId).ToListAsync(); + + foreach (var logro in logrosActivos) + { + var yaTiene = logrosUsuario.Any(lu => lu.LogroId == logro.Id); + if (yaTiene) + { + continue; + } + + var cumplido = logro.CondicionTipo switch + { + "HabitosCompletados" => await _contexto.RegistrosHabito + .CountAsync(r => r.Habito.UsuarioId == usuarioId && r.Estado == "Completado") >= logro.CondicionValor, + "MisionesCompletadas" => await _contexto.Misiones + .CountAsync(m => m.UsuarioId == usuarioId && m.Estado == "Completado") >= logro.CondicionValor, + "RachaDias" => progreso.RachaActual >= logro.CondicionValor, + "SesionesPomodoro" => await _contexto.SesionesPomodoro + .CountAsync(s => s.UsuarioId == usuarioId && s.FueCompletada) >= logro.CondicionValor, + "XpTotal" => progreso.XpTotal >= logro.CondicionValor, + "NivelAlcanzado" => progreso.NivelActual.Numero >= logro.CondicionValor, + _ => false + }; + + if (!cumplido) + { + continue; + } + + _contexto.LogrosUsuario.Add(new LogroUsuario + { + UsuarioId = usuarioId, + LogroId = logro.Id, + FechaObtenido = DateTime.UtcNow + }); + + if (logro.XpRecompensa > 0) + { + progreso.XpTotal += logro.XpRecompensa; + } + } + + await _contexto.SaveChangesAsync(); + } + + public async Task ActualizarRacha(int usuarioId) + { + var progreso = await _contexto.ProgresosUsuario.FirstOrDefaultAsync(p => p.UsuarioId == usuarioId); + if (progreso == null) + { + return; + } + + var hoy = DateOnly.FromDateTime(DateTime.Today); + var fechaUltima = progreso.FechaUltimaActividad.HasValue + ? DateOnly.FromDateTime(progreso.FechaUltimaActividad.Value) + : (DateOnly?)null; + + if (fechaUltima == hoy) + { + return; + } + + if (!fechaUltima.HasValue) + { + progreso.FechaUltimaActividad = DateTime.Today; + progreso.FechaInicioRacha = DateTime.Today; + progreso.RachaActual = 1; + progreso.RachaMaxima = Math.Max(progreso.RachaMaxima, progreso.RachaActual); + await _contexto.SaveChangesAsync(); + return; + } + + var diferencia = hoy.DayNumber - fechaUltima.Value.DayNumber; + + if (diferencia == 1) + { + progreso.RachaActual += 1; + progreso.FechaUltimaActividad = DateTime.Today; + progreso.RachaMaxima = Math.Max(progreso.RachaMaxima, progreso.RachaActual); + progreso.DiaDeGraciaUsado = false; + } + else if (diferencia == 2 && !progreso.DiaDeGraciaUsado) + { + progreso.DiaDeGraciaUsado = true; + } + else if (diferencia > 1) + { + progreso.RachaActual = 0; + progreso.DiaDeGraciaUsado = false; + progreso.FechaInicioRacha = null; + } + + await _contexto.SaveChangesAsync(); + } + + public async Task CalcularProductividadDiaria(int usuarioId) + { + var hoy = DateOnly.FromDateTime(DateTime.Today); + + var habitosProgramadosHoy = await _contexto.Habitos + .Where(h => h.UsuarioId == usuarioId && h.EstaActivo) + .Where(h => EstaProgramadoParaHoy(h, hoy)) + .CountAsync(); + + if (habitosProgramadosHoy == 0) + { + return 0; + } + + var habitosCompletadosHoy = await _contexto.RegistrosHabito + .Where(r => r.Habito.UsuarioId == usuarioId + && r.Fecha == hoy + && r.Estado == "Completado") + .CountAsync(); + + return Math.Round((decimal)habitosCompletadosHoy / habitosProgramadosHoy * 100, 1); + } + + private bool EstaProgramadoParaHoy(Habito habito, DateOnly hoy) + { + return habito.Frecuencia switch + { + "Diaria" => true, + "Semanal" => habito.DiasSemana != null && habito.DiasSemana.Contains(((int)hoy.DayOfWeek).ToString()), + "Personalizada" => habito.DiasSemana != null && habito.DiasSemana.Contains(((int)hoy.DayOfWeek).ToString()), + _ => false + }; + } + } +} diff --git a/Servicios/Implementaciones/ServicioHabitos.cs b/Servicios/Implementaciones/ServicioHabitos.cs new file mode 100644 index 0000000..8217b0a --- /dev/null +++ b/Servicios/Implementaciones/ServicioHabitos.cs @@ -0,0 +1,294 @@ +using System; +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.ViewModels; +using EPYCUS_WEB_v0._1.Datos; +using EPYCUS_WEB_v0._1.Ayudantes; +using Microsoft.EntityFrameworkCore; +using System.Text.Json; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace EPYCUS_WEB_v0._1.Servicios.Implementaciones +{ + public class ServicioHabitos : IServicioHabitos + { + private readonly ContextoAplicacion _context; + private readonly EPYCUS_WEB_v0._1.Servicios.Interfaces.IServicioGamificacion _servicioGamificacion; + + public ServicioHabitos(ContextoAplicacion context, EPYCUS_WEB_v0._1.Servicios.Interfaces.IServicioGamificacion servicioGamificacion) + { + _context = context; + _servicioGamificacion = servicioGamificacion; + } + + public async Task ObtenerDashboard(int usuarioId) + { + var vm = new EPYCUS_WEB_v0._1.ViewModels.HabitosDashboardViewModel(); + + var habitos = await _context.Habitos.Where(h => h.UsuarioId == usuarioId).ToListAsync(); + vm.TotalHabitos = habitos.Count; + + // Conteo registros últimos 7 días + var desde = DateOnly.FromDateTime(DateTime.Now.AddDays(-6)); + var registrosSemana = await (from r in _context.RegistrosHabito + join h in _context.Habitos on r.HabitoId equals h.Id + where r.Fecha >= desde && h.UsuarioId == usuarioId + select r).ToListAsync(); + + vm.CompletadosSemana = registrosSemana.Count(r => r.Estado == "Completado"); + vm.ParcialesSemana = registrosSemana.Count(r => r.Estado == "Parcial"); + vm.OmitidosSemana = registrosSemana.Count(r => r.Estado == "Omitido"); + + // Mejores rachas: top 5 por racha maxima + vm.MejoresRachas = habitos.OrderByDescending(h => h.RachaMaxima) + .Take(5) + .Select(h => (h.Nombre, h.RachaMaxima)) + .ToList(); + + // Distribucion por categoria + vm.DistribucionPorCategoria = habitos + .GroupBy(h => h.CategoriaId) + .Select(g => new { CatId = g.Key, Count = g.Count() }) + .Join(_context.Categorias, + g => g.CatId, + c => c.Id, + (g, c) => new { c.Nombre, g.Count }) + .ToDictionary(x => x.Nombre, x => x.Count); + + // Totales hoy y racha máxima actual entre hábitos + var hoy = DateOnly.FromDateTime(DateTime.Now); + vm.TotalCompletadosHoy = await (from r in _context.RegistrosHabito + join h in _context.Habitos on r.HabitoId equals h.Id + where r.Fecha == hoy && h.UsuarioId == usuarioId && r.Estado == "Completado" + select r).CountAsync(); + + vm.RachaActualMaxima = habitos.Any() ? habitos.Max(h => h.RachaActual) : 0; + + return vm; + } + + public async Task> ObtenerHabitosDeUsuario(int usuarioId) + { + return await _context.Habitos + .Include(h => h.Categoria) + .Where(h => h.UsuarioId == usuarioId) + .ToListAsync(); + } + + public async Task> ObtenerHabitosViewModel(int usuarioId) + { + var habitos = await _context.Habitos + .Include(h => h.Categoria) + .Where(h => h.UsuarioId == usuarioId) + .ToListAsync(); + + return habitos.Select(h => new EPYCUS_WEB_v0._1.ViewModels.HabitoViewModel + { + Id = h.Id, + Nombre = h.Nombre, + Descripcion = h.Descripcion, + Frecuencia = h.Frecuencia, + DiasSemana = string.IsNullOrEmpty(h.DiasSemana) ? null : System.Text.Json.JsonSerializer.Deserialize>(h.DiasSemana), + ConPomodoro = h.ConPomodoro, + RecordatorioHora = h.RecordatorioHora, + RachaActual = h.RachaActual, + RachaMaxima = h.RachaMaxima, + EstaActivo = h.EstaActivo, + FechaCreacion = h.FechaCreacion, + CategoriaId = h.CategoriaId, + CategoriaNombre = h.Categoria?.Nombre ?? string.Empty + }).ToList(); + } + + public async Task ObtenerPorId(int id) + { + return await _context.Habitos + .Include(h => h.Categoria) + .Include(h => h.Registros) + .FirstOrDefaultAsync(h => h.Id == id); + } + + public async Task ObtenerPorIdViewModel(int id) + { + var h = await _context.Habitos + .Include(x => x.Categoria) + .FirstOrDefaultAsync(x => x.Id == id); + + if (h is null) + return null; + + return new EPYCUS_WEB_v0._1.ViewModels.HabitoViewModel + { + Id = h.Id, + Nombre = h.Nombre, + Descripcion = h.Descripcion, + Frecuencia = h.Frecuencia, + DiasSemana = string.IsNullOrEmpty(h.DiasSemana) ? null : System.Text.Json.JsonSerializer.Deserialize>(h.DiasSemana), + ConPomodoro = h.ConPomodoro, + RecordatorioHora = h.RecordatorioHora, + RachaActual = h.RachaActual, + RachaMaxima = h.RachaMaxima, + EstaActivo = h.EstaActivo, + FechaCreacion = h.FechaCreacion, + CategoriaId = h.CategoriaId, + CategoriaNombre = h.Categoria.Nombre + }; + } + + public async Task CrearHabito(CrearHabitoViewModel modelo, int usuarioId) + { + // Validar categoría + var categoria = await _context.Categorias.FirstOrDefaultAsync(c => c.Id == modelo.CategoriaId && c.EstaActiva); + if (categoria is null) + throw new ArgumentException("Categoría no válida"); + + // Normalizar DiasSemana: si viene en formato de texto separado por comas en el formulario + if (modelo.DiasSemana == null) + { + // intentar leer de Request form si existe (cuando el input es string) + // Notar: aquí no se puede acceder a HttpContext, por lo que esperaremos que el controlador convierta correctamente. + } + var habito = new Habito + { + Nombre = modelo.Nombre, + Descripcion = modelo.Descripcion, + CategoriaId = modelo.CategoriaId, + Frecuencia = modelo.Frecuencia, + DiasSemana = modelo.DiasSemana is null ? null : JsonSerializer.Serialize(modelo.DiasSemana), + ConPomodoro = modelo.ConPomodoro, + RecordatorioHora = modelo.RecordatorioHora, + EstaActivo = modelo.EstaActivo, + UsuarioId = usuarioId + }; + + _context.Habitos.Add(habito); + await _context.SaveChangesAsync(); + } + + public async Task> ObtenerCategoriasActivas() + { + return await _context.Categorias.Where(c => c.EstaActiva).ToListAsync(); + } + + public async Task EditarHabito(EditarHabitoViewModel modelo, int usuarioId) + { + var habito = await _context.Habitos.FirstOrDefaultAsync(h => h.Id == modelo.Id && h.UsuarioId == usuarioId); + if (habito is null) + return; + + habito.Nombre = modelo.Nombre; + habito.Descripcion = modelo.Descripcion; + habito.CategoriaId = modelo.CategoriaId; + habito.Frecuencia = modelo.Frecuencia; + habito.DiasSemana = modelo.DiasSemana is null ? null : JsonSerializer.Serialize(modelo.DiasSemana); + habito.ConPomodoro = modelo.ConPomodoro; + habito.RecordatorioHora = modelo.RecordatorioHora; + habito.EstaActivo = modelo.EstaActivo; + + _context.Habitos.Update(habito); + await _context.SaveChangesAsync(); + } + + public async Task EliminarHabito(int id, int usuarioId) + { + var habito = await _context.Habitos.FirstOrDefaultAsync(h => h.Id == id && h.UsuarioId == usuarioId); + if (habito is null) + return; + + _context.Habitos.Remove(habito); + await _context.SaveChangesAsync(); + } + + public async Task<(bool Exito, int XpGanado)> CompletarHabito(int id, int usuarioId) + { + var habito = await _context.Habitos.Include(h => h.Registros).FirstOrDefaultAsync(h => h.Id == id && h.UsuarioId == usuarioId); + if (habito is null) + return (false, 0); + + // Evitar completar dos veces el mismo día + var hoy = DateOnly.FromDateTime(DateTime.Now); + if (habito.Registros.Any(r => r.Fecha == hoy && r.Estado == "Completado")) + return (false, 0); + + int xpGanado = ConstantesGamificacion.XP_BASE_HABITO; + + // Actualizar rachas + habito.RachaActual += 1; + if (habito.RachaActual > habito.RachaMaxima) + habito.RachaMaxima = habito.RachaActual; + + // Bonus por racha semanal + if (habito.RachaActual % ConstantesGamificacion.DIAS_RACHA_BONUS == 0) + { + xpGanado += ConstantesGamificacion.XP_BONUS_RACHA_SEMANAL; + } + + var registro = new RegistroHabito + { + HabitoId = habito.Id, + Fecha = hoy, + Estado = "Completado", + XpOtorgado = xpGanado, + FechaRegistro = DateTime.Now + }; + + _context.RegistrosHabito.Add(registro); + + // Persistir cambios + _context.Habitos.Update(habito); + await _context.SaveChangesAsync(); + + // Llamar al servicio de gamificación: sumar XP calculado (xpGanado) + try + { + await _servicioGamificacion.SumarXP(usuarioId, xpGanado); + } + catch (Exception ex) + { + // Log el error pero no interrumpir el flujo principal + // TODO: Implementar logging apropiado (ILogger) + System.Diagnostics.Debug.WriteLine($"Error al sumar XP para usuario {usuarioId}: {ex.Message}"); + } + + return (true, xpGanado); + } + + public async Task<(bool Exito, string Mensaje)> FallarHabito(int id, int usuarioId) + { + var habito = await _context.Habitos + .Include(h => h.Registros) + .FirstOrDefaultAsync(h => h.Id == id && h.UsuarioId == usuarioId); + + if (habito == null) + { + return (false, "Hábito no encontrado"); + } + + var hoy = DateOnly.FromDateTime(DateTime.Today); + if (habito.Registros.Any(r => r.Fecha == hoy)) + { + return (false, "Ya se registró el estado de hoy"); + } + + // Romper racha + habito.RachaActual = 0; + + // Registrar como fallido + _context.RegistrosHabito.Add(new RegistroHabito + { + HabitoId = habito.Id, + Fecha = hoy, + Estado = "Fallido", + XpOtorgado = 0, + FechaRegistro = DateTime.UtcNow + }); + + _context.Habitos.Update(habito); + await _context.SaveChangesAsync(); + + return (true, "Hábito marcado como fallido"); + } + } +} diff --git a/Servicios/Implementaciones/ServicioMisiones.cs b/Servicios/Implementaciones/ServicioMisiones.cs new file mode 100644 index 0000000..490a556 --- /dev/null +++ b/Servicios/Implementaciones/ServicioMisiones.cs @@ -0,0 +1,128 @@ +using EPYCUS_WEB_v0._1.Datos; +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.ViewModels; +using Microsoft.EntityFrameworkCore; + +// Servicio de Misiones: implementación de la lógica de negocio para CRUD y cambios de estado +// Todas las variables, métodos y comentarios en español según convenciones del proyecto + +namespace EPYCUS_WEB_v0._1.Servicios.Implementaciones +{ + public class ServicioMisiones : IServicioMisiones + { + private readonly ContextoAplicacion _contexto; + private readonly IServicioGamificacion _servicioGamificacion; + + public ServicioMisiones(ContextoAplicacion contexto, IServicioGamificacion servicioGamificacion) + { + _contexto = contexto; + _servicioGamificacion = servicioGamificacion; + } + + public async Task> ObtenerMisionesDeUsuario(int usuarioId) + { + return await _contexto.Misiones + .Include(m => m.Categoria) + .Where(m => m.UsuarioId == usuarioId) + .OrderBy(m => m.Estado == "Completado" ? 1 : 0) + .ThenBy(m => m.FechaLimite) + .ToListAsync(); + } + + public async Task ObtenerPorId(int id) + { + return await _contexto.Misiones + .Include(m => m.Categoria) + .FirstOrDefaultAsync(m => m.Id == id); + } + + public async Task CrearMision(CrearMisionViewModel modelo, int usuarioId) + { + var mision = new Mision + { + Nombre = modelo.Nombre, + Descripcion = modelo.Descripcion, + NombreCurso = modelo.NombreCurso, + FechaLimite = DateOnly.FromDateTime(modelo.FechaLimite), + Prioridad = modelo.Prioridad, + Estado = "Pendiente", + ConPomodoro = modelo.ConPomodoro, + UsuarioId = usuarioId, + CategoriaId = modelo.CategoriaId, + FechaCreacion = DateTime.Now + }; + + _contexto.Misiones.Add(mision); + await _contexto.SaveChangesAsync(); + } + + public async Task EditarMision(EditarMisionViewModel modelo, int usuarioId) + { + var mision = await _contexto.Misiones.FirstOrDefaultAsync(m => m.Id == modelo.Id && m.UsuarioId == usuarioId); + if (mision == null) throw new Exception("Misión no encontrada o no autorizada."); + + if (mision.Estado == "Completado" || mision.Estado == "Fallido") + throw new Exception("No se puede editar una misión que ya está completada o fallida."); + + mision.Nombre = modelo.Nombre; + mision.Descripcion = modelo.Descripcion; + mision.NombreCurso = modelo.NombreCurso; + mision.FechaLimite = DateOnly.FromDateTime(modelo.FechaLimite); + mision.Prioridad = modelo.Prioridad; + mision.ConPomodoro = modelo.ConPomodoro; + mision.CategoriaId = modelo.CategoriaId; + + await _contexto.SaveChangesAsync(); + } + + public async Task EliminarMision(int id, int usuarioId) + { + var mision = await _contexto.Misiones.FirstOrDefaultAsync(m => m.Id == id && m.UsuarioId == usuarioId); + if (mision != null) + { + _contexto.Misiones.Remove(mision); + await _contexto.SaveChangesAsync(); + } + } + + public async Task<(bool Exito, int XpGanado)> CompletarMision(int id, int usuarioId) + { + var mision = await _contexto.Misiones.FirstOrDefaultAsync(m => m.Id == id && m.UsuarioId == usuarioId); + if (mision == null) return (false, 0); + + if (mision.Estado != "Pendiente" && mision.Estado != "EnProgreso") + return (false, 0); + + int xp = mision.Prioridad switch + { + "Alta" => 80, + "Media" => 50, + "Baja" => 30, + _ => 50 + }; + + mision.Estado = "Completado"; + mision.FechaCompletado = DateTime.Now; + mision.XpOtorgado = xp; + + await _contexto.SaveChangesAsync(); + await _servicioGamificacion.SumarXP(usuarioId, xp); + + return (true, xp); + } + + public async Task CambiarEstado(int id, string estado, int usuarioId) + { + var mision = await _contexto.Misiones.FirstOrDefaultAsync(m => m.Id == id && m.UsuarioId == usuarioId); + if (mision == null) return; + + if ((mision.Estado == "Pendiente" && estado == "EnProgreso") || + (mision.Estado == "EnProgreso" && estado == "Pendiente")) + { + mision.Estado = estado; + await _contexto.SaveChangesAsync(); + } + } + } +} diff --git a/Servicios/Implementaciones/ServicioPerfil.cs b/Servicios/Implementaciones/ServicioPerfil.cs new file mode 100644 index 0000000..ee857f7 --- /dev/null +++ b/Servicios/Implementaciones/ServicioPerfil.cs @@ -0,0 +1,29 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.ViewModels; + +namespace EPYCUS_WEB_v0._1.Servicios.Implementaciones +{ + public class ServicioPerfil : IServicioPerfil + { + public Task ObtenerPerfil(int usuarioId) + { + throw new NotImplementedException(); + } + + public Task ActualizarPerfil(PerfilViewModel modelo, int usuarioId) + { + throw new NotImplementedException(); + } + + public Task CambiarPersonaje(int personajeId, int usuarioId) + { + throw new NotImplementedException(); + } + + public Task ObtenerImagenPersonajeActual(int usuarioId) + { + throw new NotImplementedException(); + } + } +} diff --git a/Servicios/Implementaciones/ServicioPomodoro.cs b/Servicios/Implementaciones/ServicioPomodoro.cs new file mode 100644 index 0000000..4e9bf1b --- /dev/null +++ b/Servicios/Implementaciones/ServicioPomodoro.cs @@ -0,0 +1,145 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using EPYCUS_WEB_v0._1.Datos; +using Microsoft.EntityFrameworkCore; +using System.Threading.Tasks; +using System; +using System.Linq; + +namespace EPYCUS_WEB_v0._1.Servicios.Implementaciones +{ + public class ServicioPomodoro : IServicioPomodoro + { + private readonly ContextoAplicacion _context; + private readonly IServicioGamificacion _servicioGamificacion; + private readonly IServicioBienestar _servicioBienestar; + + public ServicioPomodoro(ContextoAplicacion context, IServicioGamificacion servicioGamificacion, IServicioBienestar servicioBienestar) + { + _context = context; + _servicioGamificacion = servicioGamificacion; + _servicioBienestar = servicioBienestar; + } + + public async Task IniciarSesion(int usuarioId, int? habitoId, int? misionId) + { + var sesion = new SesionPomodoro + { + FechaInicio = DateTime.Now, + UsuarioId = usuarioId, + HabitoId = habitoId, + MisionId = misionId, + CiclosCompletados = 0, + XpOtorgado = 0, + FueCompletada = false + }; + + _context.SesionesPomodoro.Add(sesion); + await _context.SaveChangesAsync(); + return sesion; + } + + public async Task<(int XpGanado, bool SugerirDescanso, string? PausaActiva)> RegistrarCiclo(int sesionId, int ciclosCompletados) + { + var sesion = await _context.SesionesPomodoro.FirstOrDefaultAsync(s => s.Id == sesionId); + if (sesion is null) + return (0, false, null); + + sesion.CiclosCompletados = ciclosCompletados; + + // Calcular XP según la especificación: 15 XP por ciclo + int xpGanado = ciclosCompletados * 15; + sesion.XpOtorgado = xpGanado; + + // Obtener configuración del usuario para sugerir descanso largo + var config = await _context.ConfiguracionesPomodoro.FirstOrDefaultAsync(c => c.UsuarioId == sesion.UsuarioId); + if (config is null) + { + config = new ConfiguracionPomodoro { UsuarioId = sesion.UsuarioId }; + } + + bool sugerir = config.CiclosAntesDescansoLargo > 0 && (ciclosCompletados % config.CiclosAntesDescansoLargo == 0); + var pausa = sugerir ? "larga" : "corta"; + + var pausaActiva = _servicioBienestar is Servicios.Implementaciones.ServicioBienestar bienestar + ? bienestar.RecomendacionPausaActiva(ciclosCompletados) + : null; + + _context.SesionesPomodoro.Update(sesion); + await _context.SaveChangesAsync(); + + await _servicioGamificacion.SumarXP(sesion.UsuarioId, 15); + + return (xpGanado, sugerir, pausaActiva ?? pausa); + } + + public async Task FinalizarSesion(int sesionId, int ciclosCompletados) + { + var sesion = await _context.SesionesPomodoro.FirstOrDefaultAsync(s => s.Id == sesionId); + if (sesion is null) return; + + sesion.CiclosCompletados = ciclosCompletados; + sesion.FechaFin = DateTime.Now; + sesion.FueCompletada = true; + + _context.SesionesPomodoro.Update(sesion); + await _context.SaveChangesAsync(); + } + + public async Task CancelarSesion(int sesionId) + { + var sesion = await _context.SesionesPomodoro.FirstOrDefaultAsync(s => s.Id == sesionId); + if (sesion is null) return; + + sesion.FechaFin = DateTime.Now; + sesion.FueCompletada = false; + + _context.SesionesPomodoro.Update(sesion); + await _context.SaveChangesAsync(); + } + + public async Task ObtenerConfiguracion(int usuarioId) + { + var cfg = await _context.ConfiguracionesPomodoro.FirstOrDefaultAsync(c => c.UsuarioId == usuarioId); + if (cfg is null) + { + cfg = new ConfiguracionPomodoro { UsuarioId = usuarioId }; + _context.ConfiguracionesPomodoro.Add(cfg); + await _context.SaveChangesAsync(); + } + return cfg; + } + + public async Task ActualizarConfiguracion(int usuarioId, ConfiguracionPomodoro config) + { + var existente = await _context.ConfiguracionesPomodoro.FirstOrDefaultAsync(c => c.UsuarioId == usuarioId); + if (existente is null) + { + config.UsuarioId = usuarioId; + _context.ConfiguracionesPomodoro.Add(config); + } + else + { + existente.TiempoEstudioMin = config.TiempoEstudioMin; + existente.TiempoDescansoMin = config.TiempoDescansoMin; + existente.TiempoDescansoLargoMin = config.TiempoDescansoLargoMin; + existente.CiclosAntesDescansoLargo = config.CiclosAntesDescansoLargo; + existente.SonidoActivo = config.SonidoActivo; + existente.FechaActualizacion = DateTime.Now; + _context.ConfiguracionesPomodoro.Update(existente); + } + await _context.SaveChangesAsync(); + } + + public async Task ObtenerTipAleatorio() + { + var tip = await _context.TipsPomodoro.Where(t => t.EstaActivo).OrderBy(t => Guid.NewGuid()).Select(t => t.Tip).FirstOrDefaultAsync(); + return tip ?? string.Empty; + } + + public async Task ObtenerSesion(int sesionId) + { + return await _context.SesionesPomodoro.FirstOrDefaultAsync(s => s.Id == sesionId); + } + } +} diff --git a/Servicios/Implementaciones/ServicioProgreso.cs b/Servicios/Implementaciones/ServicioProgreso.cs new file mode 100644 index 0000000..bf675f9 --- /dev/null +++ b/Servicios/Implementaciones/ServicioProgreso.cs @@ -0,0 +1,83 @@ +using EPYCUS_WEB_v0._1.Datos; +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.Servicios.Interfaces; +using Microsoft.EntityFrameworkCore; + +namespace EPYCUS_WEB_v0._1.Servicios.Implementaciones +{ + public class ServicioProgreso : IServicioProgreso + { + private readonly ContextoAplicacion _contexto; + + public ServicioProgreso(ContextoAplicacion contexto) + { + _contexto = contexto; + } + + public async Task ObtenerProgreso(int usuarioId) + { + var progreso = await _contexto.ProgresosUsuario + .Include(p => p.NivelActual) + .FirstOrDefaultAsync(p => p.UsuarioId == usuarioId); + + if (progreso == null) + { + var nivelInicial = await _contexto.Niveles.OrderBy(n => n.Numero).FirstOrDefaultAsync(); + return new ProgresoUsuario + { + UsuarioId = usuarioId, + NivelActual = nivelInicial ?? new Nivel { Numero = 1, Descripcion = "Novato", Titulo = "Principiante" }, + NivelActualId = nivelInicial?.Id ?? 1, + XpTotal = 0, + RachaActual = 0, + RachaMaxima = 0 + }; + } + + return progreso; + } + + public async Task> ObtenerLogrosUsuario(int usuarioId) + { + return await _contexto.LogrosUsuario + .Include(l => l.Logro) + .Where(l => l.UsuarioId == usuarioId) + .ToListAsync(); + } + + public async Task> ObtenerHistorialAnimo(int usuarioId) + { + return await _contexto.EstadosAnimo + .Where(e => e.UsuarioId == usuarioId) + .OrderByDescending(e => e.FechaRegistro) + .Take(7) + .ToListAsync(); + } + + public async Task ObtenerNivelSiguiente(int nivelActualNumero) + { + return await _contexto.Niveles.FirstOrDefaultAsync(n => n.Numero == nivelActualNumero + 1); + } + + public async Task> ObtenerTodosLosLogros() + { + return await _contexto.Logros.Where(l => l.EstaActivo).ToListAsync(); + } + + public async Task ObtenerImagenPersonaje(int usuarioId, int nivelActual) + { + var personajeActivo = await _contexto.PersonajesUsuario + .Where(p => p.UsuarioId == usuarioId) + .FirstOrDefaultAsync(); + + if (personajeActivo == null) return "https://ui-avatars.com/api/?name=User&background=0D8ABC&color=fff&size=200"; + + var img = await _contexto.ImagenesNivelPersonaje + .Where(i => i.PersonajeId == personajeActivo.PersonajeId && i.NivelNumero <= nivelActual) + .OrderByDescending(i => i.NivelNumero) + .FirstOrDefaultAsync(); + + return img?.ImagenUrl ?? "https://ui-avatars.com/api/?name=User&background=0D8ABC&color=fff&size=200"; + } + } +} diff --git a/Servicios/Interfaces/.gitkeep b/Servicios/Interfaces/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Servicios/Interfaces/AlertaBienestar.cs b/Servicios/Interfaces/AlertaBienestar.cs new file mode 100644 index 0000000..1c87cb6 --- /dev/null +++ b/Servicios/Interfaces/AlertaBienestar.cs @@ -0,0 +1,10 @@ +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public class AlertaBienestar + { + public string Tipo { get; set; } = string.Empty; + public string Mensaje { get; set; } = string.Empty; + public string Icono { get; set; } = string.Empty; + public bool EsCritica { get; set; } + } +} diff --git a/Servicios/Interfaces/IServicioAdmin.cs b/Servicios/Interfaces/IServicioAdmin.cs new file mode 100644 index 0000000..d7ca388 --- /dev/null +++ b/Servicios/Interfaces/IServicioAdmin.cs @@ -0,0 +1,15 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; + +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public interface IServicioAdmin + { + Task> ObtenerTodosUsuarios(); + Task ObtenerUsuarioPorId(int id); + Task ActivarSuscripcion(int usuarioId, int adminId); + Task DesactivarSuscripcion(int usuarioId); + Task> ObtenerFrases(); + Task CrearFrase(string frase, string autor); + Task EliminarFrase(int id); + } +} diff --git a/Servicios/Interfaces/IServicioAutenticacion.cs b/Servicios/Interfaces/IServicioAutenticacion.cs new file mode 100644 index 0000000..ccdf877 --- /dev/null +++ b/Servicios/Interfaces/IServicioAutenticacion.cs @@ -0,0 +1,15 @@ +using EPYCUS_WEB_v0._1.ViewModels; + +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public interface IServicioAutenticacion + { + Task<(bool Exito, string Mensaje, string? Token, string? RefreshToken)> RegistrarUsuario(RegistroViewModel modelo); + Task<(bool Exito, string Mensaje, string? Token, string? RefreshToken)> Login(string correo, string contrasena); + Task<(bool Exito, string Mensaje, string? Token, string? RefreshToken)> RenovarToken(string refreshToken); + Task VerificarCorreo(string token); + Task EnviarCorreoRecuperacion(string correo); + Task RestablecerContrasena(string token, string nuevaContrasena); + Task CerrarSesion(int usuarioId); + } +} diff --git a/Servicios/Interfaces/IServicioBienestar.cs b/Servicios/Interfaces/IServicioBienestar.cs new file mode 100644 index 0000000..d8250c2 --- /dev/null +++ b/Servicios/Interfaces/IServicioBienestar.cs @@ -0,0 +1,9 @@ +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public interface IServicioBienestar + { + Task> ObtenerAlertasActivas(int usuarioId); + Task VerificarUsoExcesivoPomodoro(int usuarioId); + Task VerificarAnimoNegativoConsecutivo(int usuarioId); + } +} diff --git a/Servicios/Interfaces/IServicioCorreo.cs b/Servicios/Interfaces/IServicioCorreo.cs new file mode 100644 index 0000000..68b3126 --- /dev/null +++ b/Servicios/Interfaces/IServicioCorreo.cs @@ -0,0 +1,8 @@ +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public interface IServicioCorreo + { + Task EnviarVerificacion(string correo, string nombre, string token); + Task EnviarRecuperacion(string correo, string nombre, string token); + } +} diff --git a/Servicios/Interfaces/IServicioGamificacion.cs b/Servicios/Interfaces/IServicioGamificacion.cs new file mode 100644 index 0000000..abf0bdc --- /dev/null +++ b/Servicios/Interfaces/IServicioGamificacion.cs @@ -0,0 +1,10 @@ +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public interface IServicioGamificacion + { + Task<(int XpGanado, bool SubioDeNivel, int NivelNuevo)> SumarXP(int usuarioId, int xp); + Task VerificarYOtorgarLogros(int usuarioId); + Task ActualizarRacha(int usuarioId); + Task CalcularProductividadDiaria(int usuarioId); + } +} diff --git a/Servicios/Interfaces/IServicioHabitos.cs b/Servicios/Interfaces/IServicioHabitos.cs new file mode 100644 index 0000000..6c195aa --- /dev/null +++ b/Servicios/Interfaces/IServicioHabitos.cs @@ -0,0 +1,20 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.ViewModels; + +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public interface IServicioHabitos + { + Task> ObtenerHabitosDeUsuario(int usuarioId); + Task> ObtenerHabitosViewModel(int usuarioId); + Task> ObtenerCategoriasActivas(); + Task ObtenerPorId(int id); + Task ObtenerPorIdViewModel(int id); + Task CrearHabito(CrearHabitoViewModel modelo, int usuarioId); + Task EditarHabito(EditarHabitoViewModel modelo, int usuarioId); + Task EliminarHabito(int id, int usuarioId); + Task<(bool Exito, int XpGanado)> CompletarHabito(int id, int usuarioId); + Task<(bool Exito, string Mensaje)> FallarHabito(int id, int usuarioId); + Task ObtenerDashboard(int usuarioId); + } +} diff --git a/Servicios/Interfaces/IServicioMisiones.cs b/Servicios/Interfaces/IServicioMisiones.cs new file mode 100644 index 0000000..b0b24a6 --- /dev/null +++ b/Servicios/Interfaces/IServicioMisiones.cs @@ -0,0 +1,16 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.ViewModels; + +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public interface IServicioMisiones + { + Task> ObtenerMisionesDeUsuario(int usuarioId); + Task ObtenerPorId(int id); + Task CrearMision(CrearMisionViewModel modelo, int usuarioId); + Task EditarMision(EditarMisionViewModel modelo, int usuarioId); + Task EliminarMision(int id, int usuarioId); + Task<(bool Exito, int XpGanado)> CompletarMision(int id, int usuarioId); + Task CambiarEstado(int id, string estado, int usuarioId); + } +} diff --git a/Servicios/Interfaces/IServicioPerfil.cs b/Servicios/Interfaces/IServicioPerfil.cs new file mode 100644 index 0000000..fd9c723 --- /dev/null +++ b/Servicios/Interfaces/IServicioPerfil.cs @@ -0,0 +1,13 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; +using EPYCUS_WEB_v0._1.ViewModels; + +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public interface IServicioPerfil + { + Task ObtenerPerfil(int usuarioId); + Task ActualizarPerfil(PerfilViewModel modelo, int usuarioId); + Task CambiarPersonaje(int personajeId, int usuarioId); + Task ObtenerImagenPersonajeActual(int usuarioId); + } +} diff --git a/Servicios/Interfaces/IServicioPomodoro.cs b/Servicios/Interfaces/IServicioPomodoro.cs new file mode 100644 index 0000000..62e1fb9 --- /dev/null +++ b/Servicios/Interfaces/IServicioPomodoro.cs @@ -0,0 +1,16 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; + +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public interface IServicioPomodoro + { + Task IniciarSesion(int usuarioId, int? habitoId, int? misionId); + Task<(int XpGanado, bool SugerirDescanso, string? PausaActiva)> RegistrarCiclo(int sesionId, int ciclosCompletados); + Task FinalizarSesion(int sesionId, int ciclosCompletados); + Task CancelarSesion(int sesionId); + Task ObtenerConfiguracion(int usuarioId); + Task ActualizarConfiguracion(int usuarioId, ConfiguracionPomodoro config); + Task ObtenerTipAleatorio(); + Task ObtenerSesion(int sesionId); + } +} diff --git a/Servicios/Interfaces/IServicioProgreso.cs b/Servicios/Interfaces/IServicioProgreso.cs new file mode 100644 index 0000000..a0308eb --- /dev/null +++ b/Servicios/Interfaces/IServicioProgreso.cs @@ -0,0 +1,14 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; + +namespace EPYCUS_WEB_v0._1.Servicios.Interfaces +{ + public interface IServicioProgreso + { + Task ObtenerProgreso(int usuarioId); + Task> ObtenerLogrosUsuario(int usuarioId); + Task> ObtenerHistorialAnimo(int usuarioId); + Task ObtenerNivelSiguiente(int nivelActualNumero); + Task> ObtenerTodosLosLogros(); + Task ObtenerImagenPersonaje(int usuarioId, int nivelActual); + } +} diff --git a/ViewModels/Admin/AdminDashboardViewModel.cs b/ViewModels/Admin/AdminDashboardViewModel.cs new file mode 100644 index 0000000..bef915f --- /dev/null +++ b/ViewModels/Admin/AdminDashboardViewModel.cs @@ -0,0 +1,10 @@ +namespace EPYCUS_WEB_v0._1.ViewModels.Admin +{ + public class AdminDashboardViewModel + { + public int TotalUsuarios { get; set; } + public int UsuariosActivos { get; set; } + public int SuscripcionesActivas { get; set; } + public int TotalFrases { get; set; } + } +} diff --git a/ViewModels/Admin/AdminLoginViewModel.cs b/ViewModels/Admin/AdminLoginViewModel.cs new file mode 100644 index 0000000..a936656 --- /dev/null +++ b/ViewModels/Admin/AdminLoginViewModel.cs @@ -0,0 +1,20 @@ +using System.ComponentModel.DataAnnotations; + +namespace EPYCUS_WEB_v0._1.ViewModels.Admin +{ + public class AdminLoginViewModel + { + [Required(ErrorMessage = "El correo electrónico es requerido")] + [EmailAddress(ErrorMessage = "El formato del correo no es válido")] + [Display(Name = "Correo Electrónico")] + public string CorreoElectronico { get; set; } = string.Empty; + + [Required(ErrorMessage = "La contraseña es requerida")] + [DataType(DataType.Password)] + [Display(Name = "Contraseña")] + public string Contrasena { get; set; } = string.Empty; + + [Display(Name = "Recordarme")] + public bool Recordarme { get; set; } + } +} diff --git a/ViewModels/Autenticacion/LoginViewModel.cs b/ViewModels/Autenticacion/LoginViewModel.cs new file mode 100644 index 0000000..e91c228 --- /dev/null +++ b/ViewModels/Autenticacion/LoginViewModel.cs @@ -0,0 +1,20 @@ +using System.ComponentModel.DataAnnotations; + +namespace EPYCUS_WEB_v0._1.ViewModels.Autenticacion +{ + public class LoginViewModel + { + [Required(ErrorMessage = "El correo electrónico es requerido")] + [EmailAddress(ErrorMessage = "El formato del correo no es válido")] + [Display(Name = "Correo Electrónico")] + public string CorreoElectronico { get; set; } = string.Empty; + + [Required(ErrorMessage = "La contraseña es requerida")] + [DataType(DataType.Password)] + [Display(Name = "Contraseña")] + public string Contrasena { get; set; } = string.Empty; + + [Display(Name = "Recordarme")] + public bool Recordarme { get; set; } + } +} diff --git a/ViewModels/CrearHabitoViewModel.cs b/ViewModels/CrearHabitoViewModel.cs new file mode 100644 index 0000000..a43d9d6 --- /dev/null +++ b/ViewModels/CrearHabitoViewModel.cs @@ -0,0 +1,36 @@ +namespace EPYCUS_WEB_v0._1.ViewModels +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + + public class CrearHabitoViewModel + { + [Required(ErrorMessage = "El nombre es obligatorio")] + [StringLength(200, ErrorMessage = "El nombre no puede tener más de 200 caracteres")] + public string Nombre { get; set; } = string.Empty; + + [StringLength(500, ErrorMessage = "La descripción no puede tener más de 500 caracteres")] + public string? Descripcion { get; set; } + + [Range(1, int.MaxValue, ErrorMessage = "Seleccione una categoría")] + public int CategoriaId { get; set; } + + [Required(ErrorMessage = "Seleccione la frecuencia")] + [Display(Name = "Frecuencia")] + public string Frecuencia { get; set; } = "Diaria"; // Diaria | Semanal | Personalizada + + [Display(Name = "Días de la semana")] + public List? DiasSemana { get; set; } // 1=Lun ... 7=Dom (se usa cuando Frecuencia = "Semanal" o "Personalizada") + + [Display(Name = "Usar Pomodoro")] + public bool ConPomodoro { get; set; } = false; + + [DataType(DataType.Time)] + [Display(Name = "Hora de recordatorio")] + public TimeSpan? RecordatorioHora { get; set; } + + [Display(Name = "Activo")] + public bool EstaActivo { get; set; } = true; + } +} diff --git a/ViewModels/CrearMisionViewModel.cs b/ViewModels/CrearMisionViewModel.cs new file mode 100644 index 0000000..2ebd05a --- /dev/null +++ b/ViewModels/CrearMisionViewModel.cs @@ -0,0 +1,27 @@ +namespace EPYCUS_WEB_v0._1.ViewModels +{ + public class CrearMisionViewModel + { + [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "El nombre de la misin es obligatorio.")] + [System.ComponentModel.DataAnnotations.MaxLength(200, ErrorMessage = "El nombre no puede exceder 200 caracteres.")] + public string Nombre { get; set; } = string.Empty; + + [System.ComponentModel.DataAnnotations.MaxLength(500, ErrorMessage = "La descripcin no puede exceder 500 caracteres.")] + public string? Descripcion { get; set; } + + [System.ComponentModel.DataAnnotations.MaxLength(150, ErrorMessage = "El nombre del curso no puede exceder 150 caracteres.")] + public string? NombreCurso { get; set; } + + [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "Fecha lmite es obligatoria.")] + [System.ComponentModel.DataAnnotations.DataType(System.ComponentModel.DataAnnotations.DataType.Date)] + public System.DateTime FechaLimite { get; set; } + + [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "Selecciona una prioridad.")] + public string Prioridad { get; set; } = "Media"; // "Baja", "Media", "Alta" + + public bool ConPomodoro { get; set; } = false; + + [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "Selecciona una categora.")] + public int CategoriaId { get; set; } + } +} diff --git a/ViewModels/EditarHabitoViewModel.cs b/ViewModels/EditarHabitoViewModel.cs new file mode 100644 index 0000000..27efb5d --- /dev/null +++ b/ViewModels/EditarHabitoViewModel.cs @@ -0,0 +1,34 @@ +namespace EPYCUS_WEB_v0._1.ViewModels +{ + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + + public class EditarHabitoViewModel + { + [Required] + public int Id { get; set; } + + [Required(ErrorMessage = "El nombre es obligatorio")] + [StringLength(200, ErrorMessage = "El nombre no puede tener más de 200 caracteres")] + public string Nombre { get; set; } = string.Empty; + + [StringLength(500, ErrorMessage = "La descripción no puede tener más de 500 caracteres")] + public string? Descripcion { get; set; } + + [Required(ErrorMessage = "Seleccione una categoría")] + public int CategoriaId { get; set; } + + [Required(ErrorMessage = "Seleccione la frecuencia")] + public string Frecuencia { get; set; } = "Diaria"; + + public List? DiasSemana { get; set; } + + public bool ConPomodoro { get; set; } = false; + + [DataType(DataType.Time)] + public TimeSpan? RecordatorioHora { get; set; } + + public bool EstaActivo { get; set; } = true; + } +} diff --git a/ViewModels/EditarMisionViewModel.cs b/ViewModels/EditarMisionViewModel.cs new file mode 100644 index 0000000..7de7d0e --- /dev/null +++ b/ViewModels/EditarMisionViewModel.cs @@ -0,0 +1,29 @@ +namespace EPYCUS_WEB_v0._1.ViewModels +{ + public class EditarMisionViewModel + { + public int Id { get; set; } + + [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "El nombre de la misin es obligatorio.")] + [System.ComponentModel.DataAnnotations.MaxLength(200, ErrorMessage = "El nombre no puede exceder 200 caracteres.")] + public string Nombre { get; set; } = string.Empty; + + [System.ComponentModel.DataAnnotations.MaxLength(500, ErrorMessage = "La descripcin no puede exceder 500 caracteres.")] + public string? Descripcion { get; set; } + + [System.ComponentModel.DataAnnotations.MaxLength(150, ErrorMessage = "El nombre del curso no puede exceder 150 caracteres.")] + public string? NombreCurso { get; set; } + + [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "Fecha lmite es obligatoria.")] + [System.ComponentModel.DataAnnotations.DataType(System.ComponentModel.DataAnnotations.DataType.Date)] + public System.DateTime FechaLimite { get; set; } + + [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "Selecciona una prioridad.")] + public string Prioridad { get; set; } = "Media"; // "Baja", "Media", "Alta" + + public bool ConPomodoro { get; set; } = false; + + [System.ComponentModel.DataAnnotations.Required(ErrorMessage = "Selecciona una categora.")] + public int CategoriaId { get; set; } + } +} diff --git a/ViewModels/HabitoViewModel.cs b/ViewModels/HabitoViewModel.cs new file mode 100644 index 0000000..2dff3d6 --- /dev/null +++ b/ViewModels/HabitoViewModel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; + +namespace EPYCUS_WEB_v0._1.ViewModels +{ + public class HabitoViewModel + { + public int Id { get; set; } + public string Nombre { get; set; } = string.Empty; + public string? Descripcion { get; set; } + public string Frecuencia { get; set; } = string.Empty; + public List? DiasSemana { get; set; } + public bool ConPomodoro { get; set; } + public TimeSpan? RecordatorioHora { get; set; } + public int RachaActual { get; set; } + public int RachaMaxima { get; set; } + public bool EstaActivo { get; set; } + public DateTime FechaCreacion { get; set; } + public int CategoriaId { get; set; } + public string CategoriaNombre { get; set; } = string.Empty; + } +} diff --git a/ViewModels/HabitosDashboardViewModel.cs b/ViewModels/HabitosDashboardViewModel.cs new file mode 100644 index 0000000..d01f945 --- /dev/null +++ b/ViewModels/HabitosDashboardViewModel.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace EPYCUS_WEB_v0._1.ViewModels +{ + public class HabitosDashboardViewModel + { + public int TotalHabitos { get; set; } + public int CompletadosSemana { get; set; } + public int ParcialesSemana { get; set; } + public int OmitidosSemana { get; set; } + public List<(string Nombre, int Dias)> MejoresRachas { get; set; } = new List<(string, int)>(); + public Dictionary DistribucionPorCategoria { get; set; } = new Dictionary(); + public int TotalCompletadosHoy { get; set; } + public int RachaActualMaxima { get; set; } + } +} diff --git a/ViewModels/HabitosIndexViewModel.cs b/ViewModels/HabitosIndexViewModel.cs new file mode 100644 index 0000000..8ef43d8 --- /dev/null +++ b/ViewModels/HabitosIndexViewModel.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace EPYCUS_WEB_v0._1.ViewModels +{ + public class HabitosIndexViewModel + { + public List Habitos { get; set; } = new List(); + public HabitosDashboardViewModel Dashboard { get; set; } = new HabitosDashboardViewModel(); + } +} diff --git a/ViewModels/HomeDashboardViewModel.cs b/ViewModels/HomeDashboardViewModel.cs new file mode 100644 index 0000000..1071342 --- /dev/null +++ b/ViewModels/HomeDashboardViewModel.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace EPYCUS_WEB_v0._1.ViewModels +{ + public class HomeDashboardViewModel + { + public HabitosDashboardViewModel Estadisticas { get; set; } = new HabitosDashboardViewModel(); + public List HabitosHoy { get; set; } = new List(); + public string FraseMotivacional { get; set; } = string.Empty; + public string AutorFrase { get; set; } = string.Empty; + public bool EstaAutenticado { get; set; } = false; + public string NombreUsuario { get; set; } = string.Empty; + } +} diff --git a/ViewModels/PerfilViewModel.cs b/ViewModels/PerfilViewModel.cs new file mode 100644 index 0000000..039bfe4 --- /dev/null +++ b/ViewModels/PerfilViewModel.cs @@ -0,0 +1,6 @@ +namespace EPYCUS_WEB_v0._1.ViewModels +{ + public class PerfilViewModel + { + } +} diff --git a/ViewModels/PomodoroIndexViewModel.cs b/ViewModels/PomodoroIndexViewModel.cs new file mode 100644 index 0000000..a13e86b --- /dev/null +++ b/ViewModels/PomodoroIndexViewModel.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using EPYCUS_WEB_v0._1.Modelos.Entidades; + +namespace EPYCUS_WEB_v0._1.ViewModels +{ + public class PomodoroIndexViewModel + { + public ConfiguracionPomodoro Configuracion { get; set; } = new ConfiguracionPomodoro(); + public EstadisticasPomodoroHoy EstadisticasHoy { get; set; } = new EstadisticasPomodoroHoy(); + public List TareasEnfoque { get; set; } = new List(); + public List HistorialHoy { get; set; } = new List(); + } + + public class EstadisticasPomodoroHoy + { + public int CiclosCompletados { get; set; } + public int MinutosEnfocados { get; set; } + public int XpGanado { get; set; } + public int MisionesCompletadas { get; set; } + } + + public class TareaPomodoro + { + public int Id { get; set; } + public string Nombre { get; set; } = string.Empty; + public string CategoriaNombre { get; set; } = string.Empty; + public string Tipo { get; set; } = string.Empty; // "Habito" o "Mision" + } +} diff --git a/ViewModels/ProgresoViewModel.cs b/ViewModels/ProgresoViewModel.cs new file mode 100644 index 0000000..53b9343 --- /dev/null +++ b/ViewModels/ProgresoViewModel.cs @@ -0,0 +1,16 @@ +using EPYCUS_WEB_v0._1.Modelos.Entidades; + +namespace EPYCUS_WEB_v0._1.ViewModels +{ + public class ProgresoViewModel + { + public ProgresoUsuario Progreso { get; set; } = null!; + public Nivel? NivelSiguiente { get; set; } + public int XpParaSiguienteNivel => NivelSiguiente != null ? NivelSiguiente.XpRequerido - Progreso.NivelActual.XpRequerido : 0; + public int XpEnNivelActual => Progreso.XpTotal - Progreso.NivelActual.XpRequerido; + public int PorcentajeNivel => XpParaSiguienteNivel > 0 ? (int)((double)XpEnNivelActual / XpParaSiguienteNivel * 100) : 100; + public List TodosLosLogros { get; set; } = new List(); + public List LogrosDesbloqueadosIds { get; set; } = new List(); + public string ImagenPersonajeUrl { get; set; } = "/img/personajes/generico/masculino/placeholder.png"; + } +} diff --git a/ViewModels/RegistroViewModel.cs b/ViewModels/RegistroViewModel.cs new file mode 100644 index 0000000..6cd4b00 --- /dev/null +++ b/ViewModels/RegistroViewModel.cs @@ -0,0 +1,39 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace EPYCUS_WEB_v0._1.ViewModels +{ + public class RegistroViewModel + { + [Required(ErrorMessage = "El nombre es obligatorio")] + [StringLength(150, ErrorMessage = "El nombre no puede exceder 150 caracteres")] + public string Nombre { get; set; } = string.Empty; + + [Required(ErrorMessage = "El correo electrónico es requerido")] + [EmailAddress(ErrorMessage = "El formato del correo no es válido")] + public string CorreoElectronico { get; set; } = string.Empty; + + [Required(ErrorMessage = "La contraseña es requerida")] + [RegularExpression("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*]).{8,}$", ErrorMessage = "La contraseña debe tener mínimo 8 caracteres, una mayúscula, una minúscula, un número y un carácter especial.")] + [DataType(DataType.Password)] + public string Contrasena { get; set; } = string.Empty; + + [Required(ErrorMessage = "Confirma la contraseña")] + [Compare(nameof(Contrasena), ErrorMessage = "Las contraseñas no coinciden")] + [DataType(DataType.Password)] + public string ConfirmarContrasena { get; set; } = string.Empty; + + [Required(ErrorMessage = "La fecha de nacimiento es obligatoria")] + [DataType(DataType.Date)] + public DateTime FechaNacimiento { get; set; } + + [Required(ErrorMessage = "Seleccione un género")] + public string Genero { get; set; } = string.Empty; + + [Required(ErrorMessage = "Seleccione una carrera")] + public int CarreraId { get; set; } + + [Range(typeof(bool), "true", "true", ErrorMessage = "Debe aceptar los términos")] + public bool AceptoTerminos { get; set; } + } +} diff --git a/Views/Admin/DetalleUsuario.cshtml b/Views/Admin/DetalleUsuario.cshtml new file mode 100644 index 0000000..0499c05 --- /dev/null +++ b/Views/Admin/DetalleUsuario.cshtml @@ -0,0 +1,80 @@ +@model EPYCUS_WEB_v0._1.Modelos.Entidades.Usuario + +@{ + ViewData["Title"] = "Detalle de usuario"; + Layout = "_LayoutAdmin"; +} + +
+

Detalle de usuario

+

Información general y suscripción.

+
+ +
+
+
+
+
@Model.Nombre
+

@Model.CorreoElectronico

+
+ @Model.Rol?.Nombre +
+
+
+
+
+
+
+
Carrera
+
@Model.Carrera?.Nombre
+
+
+
Estado
+
@(Model.EstaActivo ? "Activo" : "Inactivo")
+
+
+
Registro
+
@Model.FechaRegistro.ToString("dd/MM/yyyy")
+
+
+
Último acceso
+
@(Model.UltimoAcceso?.ToString("dd/MM/yyyy") ?? "Sin registros")
+
+
+
+ +
+
Suscripción
+ @{ + var suscripcionActiva = Model.Suscripciones.Any(s => s.EstaActiva); + } + @if (suscripcionActiva) + { + Premium activa + } + else + { + Gratis + } +
+ @if (suscripcionActiva) + { +
+ @Html.AntiForgeryToken() + + +
+ } + else + { +
+ @Html.AntiForgeryToken() + + +
+ } + Volver +
+
+
+
diff --git a/Views/Admin/Frases.cshtml b/Views/Admin/Frases.cshtml new file mode 100644 index 0000000..9a62baa --- /dev/null +++ b/Views/Admin/Frases.cshtml @@ -0,0 +1,84 @@ +@model IEnumerable + +@{ + ViewData["Title"] = "Frases motivacionales"; + Layout = "_LayoutAdmin"; +} + +
+

Frases motivacionales

+

Gestiona las frases que se muestran en el sistema.

+
+ +@if (TempData["Exito"] != null) +{ +
+ +
+
Acción completada
+
@TempData["Exito"]
+
+
+} + +
+
+
+
Nueva frase
+
+ @Html.AntiForgeryToken() +
+ + +
+
+ + +
+ +
+
+
+
+
+
+ + + + + + + + + + + @foreach (var frase in Model) + { + + + + + + + } + +
FraseAutorEstado
@frase.Frase@frase.Autor + @if (frase.EstaActiva) + { + Activa + } + else + { + Inactiva + } + +
+ @Html.AntiForgeryToken() + + +
+
+
+
+
+
diff --git a/Views/Admin/Index.cshtml b/Views/Admin/Index.cshtml new file mode 100644 index 0000000..240eed2 --- /dev/null +++ b/Views/Admin/Index.cshtml @@ -0,0 +1,67 @@ +@model EPYCUS_WEB_v0._1.ViewModels.Admin.AdminDashboardViewModel + +@{ + ViewData["Title"] = "Panel Admin"; + Layout = "_LayoutAdmin"; +} + +
+

Panel administrativo

+

Supervisa la actividad general del sistema.

+
+ +
+
+
+
+
+
+
Usuarios totales
+
@Model.TotalUsuarios
+
+
+
+
+
+
+
+
+
+
Usuarios activos
+
@Model.UsuariosActivos
+
+
+
+
+
+
+
+
+
+
Suscripciones activas
+
@Model.SuscripcionesActivas
+
+
+
+
+
+
+
+
+
+
Frases motivacionales
+
@Model.TotalFrases
+
+
+
+
+
+ +
+
Acciones rápidas
+

Accede rápidamente a los módulos principales del panel.

+ +
diff --git a/Views/Admin/Login.cshtml b/Views/Admin/Login.cshtml new file mode 100644 index 0000000..945eaa9 --- /dev/null +++ b/Views/Admin/Login.cshtml @@ -0,0 +1,43 @@ +@model EPYCUS_WEB_v0._1.ViewModels.Admin.AdminLoginViewModel + +@{ + ViewData["Title"] = "Login Admin"; + Layout = "_LayoutAuth"; +} + +
+
+
+ +
+

Acceso Administrador

+

Área restringida para personal autorizado.

+
+ +
+
+ +
+ + + +
+ +
+ + + +
+ +
+ + +
+ + +
+
+ +@section Scripts { + +} diff --git a/Views/Admin/Usuarios.cshtml b/Views/Admin/Usuarios.cshtml new file mode 100644 index 0000000..58053d7 --- /dev/null +++ b/Views/Admin/Usuarios.cshtml @@ -0,0 +1,91 @@ +@model IEnumerable + +@{ + ViewData["Title"] = "Usuarios"; + Layout = "_LayoutAdmin"; +} + +
+

Usuarios

+

Gestiona estados y suscripciones.

+
+ +@if (TempData["Exito"] != null) +{ +
+ +
+
Acción completada
+
@TempData["Exito"]
+
+
+} + +
+
+ + + + + + + + + + + + + @foreach (var usuario in Model) + { + var suscripcionActiva = usuario.Suscripciones.Any(s => s.EstaActiva); + + + + + + + + + } + +
NombreCorreoRolEstadoSuscripción
@usuario.Nombre@usuario.CorreoElectronico@usuario.Rol?.Nombre + @if (usuario.EstaActivo) + { + Activo + } + else + { + Inactivo + } + + @if (suscripcionActiva) + { + Premium + } + else + { + Gratis + } + +
+ Ver + @if (suscripcionActiva) + { +
+ @Html.AntiForgeryToken() + + +
+ } + else + { +
+ @Html.AntiForgeryToken() + + +
+ } +
+
+
+
diff --git a/Views/Autenticacion/Login.cshtml b/Views/Autenticacion/Login.cshtml new file mode 100644 index 0000000..3c7d5b0 --- /dev/null +++ b/Views/Autenticacion/Login.cshtml @@ -0,0 +1,66 @@ +@model EPYCUS_WEB_v0._1.ViewModels.Autenticacion.LoginViewModel + +@{ + ViewData["Title"] = "Iniciar Sesión"; + Layout = "_LayoutAuth"; +} + +
+
+
+ +
+

Bienvenido a Epycus

+

Tu viaje hacia la excelencia profesional comienza aquí

+
+ +
+ + +
+ +
+ + + + +
+ +
+ +
+ +
+ + + + +
+ +
+ +
+ + +
+ + + +
+

¿Aún no tienes una cuenta? Regístrate ahora

+
+ + +
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} +} diff --git a/Views/Autenticacion/Registro.cshtml b/Views/Autenticacion/Registro.cshtml new file mode 100644 index 0000000..3a25465 --- /dev/null +++ b/Views/Autenticacion/Registro.cshtml @@ -0,0 +1,88 @@ +@model EPYCUS_WEB_v0._1.ViewModels.RegistroViewModel + +@{ + ViewData["Title"] = "Crear cuenta"; + Layout = "_LayoutAuth"; +} + +
+
+
+ +
+

Crear cuenta

+

Empieza tu camino con Epycus.

+
+ +
+ @Html.AntiForgeryToken() +
+ +
+ + + +
+ +
+ + + +
+ +
+
+ + + +
+
+ + + +
+
+ +
+
+ + + +
+
+ + + +
+
+ +
+ + + +
+ +
+ + + +
+ + +
+
+ +@section Scripts { + +} diff --git a/Views/Habitos/Crear.cshtml b/Views/Habitos/Crear.cshtml new file mode 100644 index 0000000..5ae77d3 --- /dev/null +++ b/Views/Habitos/Crear.cshtml @@ -0,0 +1,78 @@ +@model EPYCUS_WEB_v0._1.ViewModels.CrearHabitoViewModel + +@{ + ViewData["Title"] = "Crear hábito"; +} + +
+

Crear hábito

+

Define un hábito claro y fácil de cumplir.

+
+ +
+ @Html.AntiForgeryToken() +
+
+ + + +
+ +
+ + + +
+ +
+ + @{ var categorias = ViewBag.Categorias as List ?? new List(); } + + +
+ +
+ + +
+ +
+ + +
Usa 1=Lun, 2=Mar, 3=Mié, 4=Jue, 5=Vie, 6=Sáb, 0=Dom.
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + Cancelar +
+
+ +@section Scripts { + +} diff --git a/Views/Habitos/Editar.cshtml b/Views/Habitos/Editar.cshtml new file mode 100644 index 0000000..31cddae --- /dev/null +++ b/Views/Habitos/Editar.cshtml @@ -0,0 +1,85 @@ +@model EPYCUS_WEB_v0._1.ViewModels.EditarHabitoViewModel + +@{ + ViewData["Title"] = "Editar hábito"; +} + +
+

Editar hábito

+

Ajusta tu hábito para mantener la constancia.

+
+ +
+ + +
+ + + +
+ +
+ + + +
+ +
+ + @{ var categorias = ViewBag.Categorias as List ?? new List(); } + + +
+ +
+ + +
+ +
+ + +
Usa 1=Lun, 2=Mar, 3=Mié, 4=Jue, 5=Vie, 6=Sáb, 0=Dom.
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + Cancelar +
+
+ +@section Scripts { + +} diff --git a/Views/Habitos/Index.cshtml b/Views/Habitos/Index.cshtml new file mode 100644 index 0000000..69198c4 --- /dev/null +++ b/Views/Habitos/Index.cshtml @@ -0,0 +1,482 @@ +@model EPYCUS_WEB_v0._1.ViewModels.HabitosIndexViewModel + +@{ + ViewData["Title"] = "Hábitos"; +} + +
+

Hábitos

+

Pequeñas acciones diarias, grandes cambios.

+
+ + +
+
+ + +
+
+
+
+ +
+
+

@Model.Dashboard.TotalHabitos

+

Total hábitos

+
+
+
+
+
+
+ +
+
+

@Model.Dashboard.TotalCompletadosHoy

+

Completados hoy

+
+
+
+
+
+
+ +
+
+

@Model.Dashboard.RachaActualMaxima

+

Racha actual
¡Sigue así!

+
+
+
+
+
+
+ +
+
+ @{ + int totalSemana = Model.Dashboard.CompletadosSemana + Model.Dashboard.ParcialesSemana + Model.Dashboard.OmitidosSemana; + int porcExito = totalSemana == 0 ? 0 : (int)Math.Round((double)Model.Dashboard.CompletadosSemana / totalSemana * 100); + } +

@porcExito%

+

Tasa de éxito
Últimos 7 días

+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+ + +
+ Lun + Mar + Mié + Jue + Vie + Sáb + Dom + Hoy +
+ + @if (Model?.Habitos == null || !Model.Habitos.Any()) + { +
No hay hábitos todavía. ¡Empieza creando uno nuevo!
+ } + else + { + @foreach (var h in Model.Habitos) + { +
+
+ + +
+
+
@h.Nombre
+ @h.CategoriaNombre +
+
+
@h.Frecuencia
+
@h.RachaActual días
+
+ + +
+ +
+
+
+
+
+
+
+ + +
+ +
+ + +
+
+ } + } +
+
+ +
+
Tip diario
+
Los hábitos pequeños y constantes generan grandes resultados.
+
+
+
+ + +
+ +
+ + +
+ + +
+
+
Resumen semanal
+ +
+ +
+
+
+
+
+ @porcExito% + Éxito
semanal
+
+
+
+
+
+
    +
  • + Completados + @Model.Dashboard.CompletadosSemana +
  • +
  • + Parciales + @Model.Dashboard.ParcialesSemana +
  • +
  • + Omitidos + @Model.Dashboard.OmitidosSemana +
  • +
  • + Total hábitos: @Model.Dashboard.TotalHabitos +
  • +
+
+
+
+ + +
+
Mejores rachas
+
    + @foreach (var r in Model.Dashboard.MejoresRachas) + { +
  • + @r.Nombre + @r.Dias días +
  • + } +
+ Ver todas las rachas +
+ + +
+
Distribución por categoría
+ +
+
+ +
+
+
+
    + @foreach (var kv in Model.Dashboard.DistribucionPorCategoria) + { +
  • + @kv.Key + @kv.Value +
  • + } +
+
+
+
+ @Model.Dashboard.TotalHabitos hábitos en total +
+
+
+
+ + + + +@section Scripts { + + + +} diff --git a/Views/Home/Index.cshtml b/Views/Home/Index.cshtml new file mode 100644 index 0000000..d22367b --- /dev/null +++ b/Views/Home/Index.cshtml @@ -0,0 +1,254 @@ +@model EPYCUS_WEB_v0._1.ViewModels.HomeDashboardViewModel + +@{ + ViewData["Title"] = "Inicio"; +} + +@if (Model != null && Model.EstaAutenticado) +{ +
+

+ ¡Hola, @Model.NombreUsuario! +

+ @if (!string.IsNullOrEmpty(Model.FraseMotivacional)) + { +

+ "@Model.FraseMotivacional" - @Model.AutorFrase +

+ } +
+ + +
+
+
+
+ +
+
+

@Model.Estadisticas.TotalHabitos

+

Hábitos activos

+
+
+
+
+
+
+ +
+
+

@Model.Estadisticas.TotalCompletadosHoy

+

Completados hoy

+
+
+
+
+
+
+ +
+
+

@Model.Estadisticas.RachaActualMaxima

+

Mejor racha actual

+
+
+
+
+ +
+ +
+
+
+
Tus hábitos para hoy
+ Ver todos +
+ + @if (Model.HabitosHoy == null || !Model.HabitosHoy.Any()) + { +
+ No tienes hábitos programados para hoy. ¡Disfruta tu día! +
+ } + else + { + @foreach (var h in Model.HabitosHoy) + { +
+
+ +
+
+
@h.Nombre
+ @h.CategoriaNombre +
+
+
@h.RachaActual días
+
+
+ +
+
+ } + } +
+
+ + +
+
+
Distribución por categoría
+
+ +
+
+ Mantén un equilibrio en tus hábitos para un mejor estilo de vida. +
+
+
+
+ + @section Scripts { + + + } +} +else +{ +
+
+
+

Bienvenido a Epycus

+

Organiza tus hábitos, misiones y sesiones Pomodoro con un sistema visual diseñado para motivarte cada día.

+ +
+
+
+ +
Tu progreso visible
+

Mide tu avance con indicadores claros y celebra cada logro.

+
+
+
+
+} diff --git a/Views/Home/Privacy.cshtml b/Views/Home/Privacy.cshtml new file mode 100644 index 0000000..63f7d4d --- /dev/null +++ b/Views/Home/Privacy.cshtml @@ -0,0 +1,14 @@ +@{ + ViewData["Title"] = "Política de Privacidad"; +} + +
+

Política de Privacidad

+

En Epycus protegemos tus datos personales y solo usamos la información necesaria para mejorar tu experiencia.

+
+
    +
  • Guardamos tus datos de autenticación de forma segura.
  • +
  • Tu progreso y hábitos solo son visibles para ti.
  • +
  • Puedes solicitar la eliminación de tu cuenta cuando lo necesites.
  • +
+
diff --git a/Views/Misiones/Crear.cshtml b/Views/Misiones/Crear.cshtml new file mode 100644 index 0000000..5cab893 --- /dev/null +++ b/Views/Misiones/Crear.cshtml @@ -0,0 +1,74 @@ +@model EPYCUS_WEB_v0._1.ViewModels.CrearMisionViewModel + +@{ + ViewData["Title"] = "Crear Misión"; +} + +
+

Nueva misión

+

Define una misión concreta y alcanza tus objetivos.

+
+ +
+
+
+ +
+ + + +
+ +
+ + + +
+ +
+
+ + + +
+
+ + + +
+
+ +
+
+ + + +
+
+ + + +
+
+ +
+ + +
+ +
+ + Cancelar +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} +} diff --git a/Views/Misiones/Editar.cshtml b/Views/Misiones/Editar.cshtml new file mode 100644 index 0000000..e1bc0e2 --- /dev/null +++ b/Views/Misiones/Editar.cshtml @@ -0,0 +1,75 @@ +@model EPYCUS_WEB_v0._1.ViewModels.EditarMisionViewModel + +@{ + ViewData["Title"] = "Editar Misión"; +} + +
+

Editar misión

+

Ajusta los detalles y mantén el rumbo.

+
+ +
+
+
+ + +
+ + + +
+ +
+ + + +
+ +
+
+ + + +
+
+ + + +
+
+ +
+
+ + + +
+
+ + + +
+
+ +
+ + +
+ +
+ + Cancelar +
+
+
+ +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} +} diff --git a/Views/Misiones/Index.cshtml b/Views/Misiones/Index.cshtml new file mode 100644 index 0000000..67e36a5 --- /dev/null +++ b/Views/Misiones/Index.cshtml @@ -0,0 +1,92 @@ +@model IEnumerable + +@{ + ViewData["Title"] = "Misiones"; +} + +
+

Misiones

+

Enfoca tu energía en objetivos claros y medibles.

+ Nueva misión +
+ + @if (TempData["Exito"] != null) + { +
+ +
+
Acción completada
+
@TempData["Exito"]
+
+
+ } + @if (TempData["Error"] != null) + { +
+ +
+
Ocurrió un problema
+
@TempData["Error"]
+
+
+ } + +
+ @foreach (var mision in Model) + { + var colorPrioridad = mision.Prioridad switch + { + "Alta" => "danger", + "Media" => "warning", + "Baja" => "success", + _ => "secondary" + }; + + var badgeEstado = mision.Estado switch + { + "Pendiente" => "bg-secondary", + "EnProgreso" => "bg-primary", + "Completado" => "bg-success", + "Fallido" => "bg-danger", + _ => "bg-light" + }; + +
+
+
+ @mision.Estado + @mision.Prioridad +
+
@mision.Nombre
+

@mision.Categoria?.Nombre

+

@mision.Descripcion

+
+ + Límite: @mision.FechaLimite.ToString("dd/MM/yyyy") +
+
+ @if (mision.Estado == "Pendiente") + { +
+ + + +
+ } + else if (mision.Estado == "EnProgreso") + { +
+ + +
+ } + + @if (mision.Estado != "Completado" && mision.Estado != "Fallido") + { + Editar + } +
+
+
+ } +
diff --git a/Views/Pomodoro/Configuracion.cshtml b/Views/Pomodoro/Configuracion.cshtml new file mode 100644 index 0000000..f65e7c7 --- /dev/null +++ b/Views/Pomodoro/Configuracion.cshtml @@ -0,0 +1,42 @@ +@model EPYCUS_WEB_v0._1.Modelos.Entidades.ConfiguracionPomodoro + +@{ + ViewData["Title"] = "Configuración Pomodoro"; +} + +
+

Configuración Pomodoro

+

Personaliza tus ciclos para trabajar con mayor enfoque.

+
+ +
+ @Html.AntiForgeryToken() +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+ +
+ + Volver +
+
diff --git a/Views/Pomodoro/Index.cshtml b/Views/Pomodoro/Index.cshtml new file mode 100644 index 0000000..855b591 --- /dev/null +++ b/Views/Pomodoro/Index.cshtml @@ -0,0 +1,464 @@ +@model EPYCUS_WEB_v0._1.ViewModels.PomodoroIndexViewModel + +@{ + ViewData["Title"] = "Pomodoro"; +} + +
+

Pomodoro

+

Enfócate, mantén la concentración y conquista tus metas.

+
+ +
+ +
+
+ + +
+
+ Enfoque +
+
+ Descanso corto +
+
+ Descanso largo +
+
+ + +
+
+ +
🍅
+
25:00
+
Tiempo de enfoque
+
+
+ + +
+ + +
+ + +
+
+ +
+ 1 +
+ + +
+
+
+
+ + +
+
+ + +
+
+ +
+
+ + +
+ + +
+
+
Resumen de hoy
+
+ +
+
+
+ +

@(Model?.EstadisticasHoy.CiclosCompletados ?? 0)

+ Ciclos completados +
+
+
+
+ +

@(Model?.EstadisticasHoy.MinutosEnfocados ?? 0)

+ Minutos enfocados +
+
+
+
+ +

@(Model?.EstadisticasHoy.XpGanado ?? 0)

+ XP Ganado +
+
+
+
+ +

@(Model?.EstadisticasHoy.MisionesCompletadas ?? 0)

+ Misiones Completadas +
+
+
+
+ + +
+
+
Tareas de enfoque
+ Selecciona una para enfocarte +
+ +
+ @if (Model != null && Model.TareasEnfoque != null && Model.TareasEnfoque.Any()) + { + foreach (var tarea in Model.TareasEnfoque) + { + string iconClass = tarea.Tipo == "Habito" ? "bi-journal-check" : "bi-bullseye"; + string colorClass = tarea.Tipo == "Habito" ? "text-primary" : "text-danger"; + +
+
+
+ @tarea.Nombre + @tarea.CategoriaNombre +
+
+ } + } + else + { +
+ No tienes hábitos ni misiones marcados para usar Pomodoro. Puedes activarlos editándolos en sus respectivas pantallas. +
+ } +
+ +
+ Consejo: Una tarea por ciclo. Concéntrate al 100%. +
+
+ + +
+
+
Historial de hoy
+
+ +
+ @if (Model != null && Model.HistorialHoy != null && Model.HistorialHoy.Any()) + { + foreach (var sesion in Model.HistorialHoy) + { + bool esEnfoque = sesion.XpOtorgado > 0; + string tipo = esEnfoque ? "Enfoque" : "Descanso"; + string tiempoTxt = $"{(sesion.FechaFin.HasValue ? (sesion.FechaFin.Value - sesion.FechaInicio).Minutes : 0)} min"; + string iconClass = esEnfoque ? "bi-check-circle text-success" : "bi-cup-hot text-warning"; + string badgeClass = esEnfoque ? "bg-success" : "bg-warning text-dark"; + string badgeText = esEnfoque ? "Completado" : "Descanso"; + +
+ +
+
+ @tipo @tiempoTxt +
+ @badgeText +
+
+ } + } + else + { +
Aún no hay sesiones registradas hoy.
+ } +
+
+ +
+
+ +@section Scripts { + +} diff --git a/Views/Progreso/Index.cshtml b/Views/Progreso/Index.cshtml new file mode 100644 index 0000000..69e86ba --- /dev/null +++ b/Views/Progreso/Index.cshtml @@ -0,0 +1,125 @@ +@model EPYCUS_WEB_v0._1.ViewModels.ProgresoViewModel + +@{ + ViewData["Title"] = "Mi Progreso"; +} + +
+
+

Mi Progreso

+
+ +
+ +
+
+
+ Personaje +
+

@Model.Progreso.NivelActual.Titulo

+

Nivel @Model.Progreso.NivelActual.Numero

+ +
+
+ XP Actual: @Model.XpEnNivelActual + @if (Model.NivelSiguiente != null) + { + @Model.XpParaSiguienteNivel XP para Nivel @Model.NivelSiguiente.Numero + } + else + { + Nivel Máximo + } +
+
+
+
+

XP Total Histórico: @Model.Progreso.XpTotal

+
+
+
+ + +
+
+
+
+
+ +
+

@Model.Progreso.RachaActual Días

+

Racha Actual

+
+
+
+
+
+ +
+

@Model.Progreso.RachaMaxima Días

+

Racha Máxima Histórica

+
+
+
+
+
+

¿Sabías qué?

+

Mantener tu racha diaria multiplica la cantidad de experiencia (XP) que ganas al completar tareas y hábitos.

+
+ +
+
+
+
+
+ + +

Mis Logros

+ +
+ @if (Model.TodosLosLogros.Count == 0) + { +
+
+ +
Aún no hay logros disponibles en el sistema
+
+
+ } + else + { + @foreach (var logro in Model.TodosLosLogros) + { + var desbloqueado = Model.LogrosDesbloqueadosIds.Contains(logro.Id); + +
+
+
+ @if (!string.IsNullOrEmpty(logro.IconoUrl)) + { + @logro.Nombre + } + else + { + + } +
+
+
+
@logro.Nombre
+ @if (desbloqueado) + { + + } +
+

@logro.Descripcion

+
+ +@logro.XpRecompensa XP +
+
+
+
+ } + } +
+
diff --git a/Views/Shared/Error.cshtml b/Views/Shared/Error.cshtml new file mode 100644 index 0000000..2c0364b --- /dev/null +++ b/Views/Shared/Error.cshtml @@ -0,0 +1,22 @@ +@model ErrorViewModel +@{ + ViewData["Title"] = "Error"; +} + +
+
+ +
+

Ocurrió un error

+

Algo no salió como esperábamos. Intenta nuevamente en unos minutos.

+
+
+ + @if (Model.ShowRequestId) + { +
ID de solicitud: @Model.RequestId
+ } + +
+ Volver al inicio +
diff --git a/Views/Shared/_Layout.cshtml b/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000..611812b --- /dev/null +++ b/Views/Shared/_Layout.cshtml @@ -0,0 +1,115 @@ + + + + + + @ViewData["Title"] - Epycus + + + + + + + + +
+ @{ + var currentController = ViewContext.RouteData.Values["controller"]?.ToString() ?? string.Empty; + var currentAction = ViewContext.RouteData.Values["action"]?.ToString() ?? string.Empty; + } + +
+
+ @RenderBody() +
+
+
+ + + + + @await RenderSectionAsync("Scripts", required: false) + + diff --git a/Views/Shared/_Layout.cshtml.css b/Views/Shared/_Layout.cshtml.css new file mode 100644 index 0000000..c187c02 --- /dev/null +++ b/Views/Shared/_Layout.cshtml.css @@ -0,0 +1,48 @@ +/* Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification +for details on configuring this project to bundle and minify static web assets. */ + +a.navbar-brand { + white-space: normal; + text-align: center; + word-break: break-all; +} + +a { + color: #0077cc; +} + +.btn-primary { + color: #fff; + background-color: #1b6ec2; + border-color: #1861ac; +} + +.nav-pills .nav-link.active, .nav-pills .show > .nav-link { + color: #fff; + background-color: #1b6ec2; + border-color: #1861ac; +} + +.border-top { + border-top: 1px solid #e5e5e5; +} +.border-bottom { + border-bottom: 1px solid #e5e5e5; +} + +.box-shadow { + box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); +} + +button.accept-policy { + font-size: 1rem; + line-height: inherit; +} + +.footer { + position: absolute; + bottom: 0; + width: 100%; + white-space: nowrap; + line-height: 60px; +} diff --git a/Views/Shared/_LayoutAdmin.cshtml b/Views/Shared/_LayoutAdmin.cshtml new file mode 100644 index 0000000..91d00d0 --- /dev/null +++ b/Views/Shared/_LayoutAdmin.cshtml @@ -0,0 +1,61 @@ + + + + + + @ViewData["Title"] - Epycus + + + + + + + +
+ +
+
+ @RenderBody() +
+
+
+ + + + @await RenderSectionAsync("Scripts", required: false) + + diff --git a/Views/Shared/_LayoutAuth.cshtml b/Views/Shared/_LayoutAuth.cshtml new file mode 100644 index 0000000..5d2c0e4 --- /dev/null +++ b/Views/Shared/_LayoutAuth.cshtml @@ -0,0 +1,91 @@ + + + + + + @ViewData["Title"] - Epycus + + + + + + + + +
+
+
+ +
+
+
+ +
+

Epycus

+

Tu progreso profesional en un solo lugar.

+
+ @RenderBody() +
+
+ + + + + @await RenderSectionAsync("Scripts", required: false) + + diff --git a/Views/Shared/_ValidationScriptsPartial.cshtml b/Views/Shared/_ValidationScriptsPartial.cshtml new file mode 100644 index 0000000..5d1f685 --- /dev/null +++ b/Views/Shared/_ValidationScriptsPartial.cshtml @@ -0,0 +1,2 @@ + + diff --git a/Views/_ViewImports.cshtml b/Views/_ViewImports.cshtml new file mode 100644 index 0000000..5083548 --- /dev/null +++ b/Views/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using EPYCUS_WEB_v0._1 +@using EPYCUS_WEB_v0._1.Models +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/Views/_ViewStart.cshtml b/Views/_ViewStart.cshtml new file mode 100644 index 0000000..a5f1004 --- /dev/null +++ b/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/appsettings.Example.json b/appsettings.Example.json new file mode 100644 index 0000000..51b66b3 --- /dev/null +++ b/appsettings.Example.json @@ -0,0 +1,27 @@ +{ + "ConnectionStrings": { + "ConexionPrincipal": "Server=localhost;Port=3306;Database=epycus_db;User=root;Password=YOUR_DB_PASSWORD_HERE;" + }, + "Jwt": { + "Clave": "YOUR_SUPER_SECRET_JWT_KEY_HERE_AT_LEAST_32_CHARACTERS_LONG!", + "Emisor": "EpycusWeb", + "Audiencia": "EpycusUsuarios", + "ExpiracionMinutos": 60, + "ExpiracionRefreshDias": 7 + }, + "Google": { + "ClientId": "YOUR_GOOGLE_CLIENT_ID_HERE.apps.googleusercontent.com", + "ClientSecret": "YOUR_GOOGLE_CLIENT_SECRET_HERE" + }, + "Correo": { + "Servidor": "smtp.gmail.com", + "Puerto": 587, + "Usuario": "your-email@gmail.com", + "Contrasena": "YOUR_GMAIL_APP_PASSWORD_HERE", + "NombreRemitente": "Epycus App" + }, + "App": { + "UrlBase": "https://localhost:7000", + "Version": "1.0.0" + } +} diff --git a/appsettings.json b/appsettings.json new file mode 100644 index 0000000..30eaeee --- /dev/null +++ b/appsettings.json @@ -0,0 +1,27 @@ +{ + "ConnectionStrings": { + "ConexionPrincipal": "Server=localhost;Port=3306;Database=epycus_db;User=root;Password=YOUR_DB_PASSWORD;" + }, + "Jwt": { + "Clave": "CHANGE_THIS_TO_YOUR_SECRET_KEY_AT_LEAST_32_CHARS", + "Emisor": "EpycusWeb", + "Audiencia": "EpycusUsuarios", + "ExpiracionMinutos": 60, + "ExpiracionRefreshDias": 7 + }, + "Google": { + "ClientId": "YOUR_GOOGLE_CLIENT_ID", + "ClientSecret": "YOUR_GOOGLE_CLIENT_SECRET" + }, + "Correo": { + "Servidor": "smtp.gmail.com", + "Puerto": 587, + "Usuario": "your-email@gmail.com", + "Contrasena": "YOUR_GMAIL_APP_PASSWORD", + "NombreRemitente": "Epycus App" + }, + "App": { + "UrlBase": "https://localhost:7000", + "Version": "1.0.0" + } +} diff --git a/wwwroot/css/site.css b/wwwroot/css/site.css new file mode 100644 index 0000000..27d5333 --- /dev/null +++ b/wwwroot/css/site.css @@ -0,0 +1,759 @@ +body { + font-family: "Inter", sans-serif; + background: var(--ep-fondo); + color: var(--ep-texto); + min-height: 100vh; + line-height: 1.6; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: var(--ep-superficie-2); +} + +::-webkit-scrollbar-thumb { + background: var(--ep-borde); + border-radius: 999px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--ep-texto-apagado); +} + +a { + color: var(--ep-primario); + text-decoration: none; + transition: color 0.2s ease; +} + +a:hover { + color: var(--ep-primario-hover); +} + +button, +input, +select, +textarea { + font-family: inherit; +} + +button:focus-visible, +a:focus-visible, +input:focus-visible, +select:focus-visible, +textarea:focus-visible { + outline: 2px solid var(--ep-neon); + outline-offset: 2px; +} + +.ep-card { + background: var(--ep-superficie); + border: 1px solid var(--ep-borde); + border-radius: var(--ep-radio); + box-shadow: var(--ep-sombra); + padding: 1.5rem; + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.ep-card:hover { + transform: translateY(-2px); + box-shadow: 0 12px 30px rgba(0,0,0,0.15); +} + +.ep-card-neon { + background: var(--ep-superficie); + border: 1px solid var(--ep-neon-borde); + border-radius: var(--ep-radio); + box-shadow: var(--ep-sombra-neon); + padding: 1.5rem; +} + +.ep-barra-xp { + background: var(--ep-barra-xp-fondo); + border-radius: var(--ep-radio-sm); + height: 8px; + overflow: hidden; +} + +.ep-barra-xp-relleno { + background: var(--ep-barra-xp-relleno); + height: 100%; + transition: width 0.3s ease; +} + +.ep-badge-nivel { + background: var(--ep-nivel); + color: #fff; + border-radius: 999px; + padding: 0.25rem 0.75rem; + font-weight: 600; + font-size: 0.85rem; +} + +.ep-badge-xp { + background: var(--ep-xp-suave); + color: var(--ep-xp); + border-radius: 999px; + padding: 0.25rem 0.75rem; + font-weight: 600; + font-size: 0.85rem; +} + +.ep-badge-racha { + background: var(--ep-racha-suave); + color: var(--ep-racha); + border-radius: 999px; + padding: 0.25rem 0.75rem; + font-weight: 600; + font-size: 0.85rem; +} + +.btn-ep { + background: var(--ep-primario); + color: #fff; + border: none; + border-radius: var(--ep-radio-sm); + padding: 0.6rem 1.2rem; + font-weight: 600; + box-shadow: var(--ep-sombra-primario); + transition: background 0.2s ease, transform 0.2s ease; +} + +.btn-ep:hover { + background: var(--ep-primario-hover); + color: #fff; + transform: translateY(-1px); +} + +.btn-ep:focus-visible, +.btn-ep-outline:focus-visible, +.ep-boton-icono:focus-visible { + box-shadow: 0 0 0 0.2rem var(--ep-neon-suave); +} + +.btn-ep:active { + transform: translateY(0); +} + +.btn-ep:disabled, +.btn-ep-outline:disabled { + opacity: 0.6; + cursor: not-allowed; + box-shadow: none; +} + +.btn-ep-outline { + background: transparent; + color: var(--ep-primario); + border: 1px solid var(--ep-primario); + border-radius: var(--ep-radio-sm); + padding: 0.6rem 1.2rem; + font-weight: 600; + transition: background 0.2s ease, color 0.2s ease; +} + +.btn-ep-outline:hover { + background: var(--ep-primario); + color: #fff; +} + +.ep-input { + background: var(--ep-superficie); + border: 1px solid var(--ep-borde); + border-radius: var(--ep-radio-sm); + color: var(--ep-texto); + padding: 0.6rem 0.9rem; + transition: border-color 0.2s ease, box-shadow 0.2s ease; +} + +.ep-input:focus { + border-color: var(--ep-primario); + box-shadow: 0 0 0 0.15rem var(--ep-neon-suave); +} + +.ep-input::placeholder { + color: var(--ep-texto-apagado); +} + +.ep-input:disabled { + background: var(--ep-superficie-2); + color: var(--ep-texto-apagado); +} + +.ep-sidebar { + background: var(--ep-nav-fondo); + min-height: 100vh; + width: 260px; + padding: 1.5rem 1rem; + position: fixed; + top: 0; + left: 0; + border-right: 1px solid var(--ep-borde); +} + +.ep-sidebar .ep-nav-item { + font-weight: 500; +} + +.ep-nav-item { + color: var(--ep-nav-texto); + border-radius: var(--ep-radio-sm); + padding: 0.65rem 0.9rem; + display: flex; + align-items: center; + gap: 0.75rem; + text-decoration: none; + transition: background 0.2s ease, color 0.2s ease; +} + +.ep-nav-item i { + font-size: 1.1rem; +} + +.ep-nav-item:hover { + background: var(--ep-nav-item-hover); + color: var(--ep-nav-texto-activo); +} + +.ep-nav-item.activo { + background: var(--ep-nav-item-activo); + color: var(--ep-nav-texto-activo); + font-weight: 600; +} + +.ep-contenido { + margin-left: 260px; + padding: 2rem; +} + +.ep-contenido .container, +.ep-contenido .container-fluid { + max-width: 1200px; +} + +.ep-contenido h1, +.ep-contenido h2, +.ep-contenido h3 { + color: var(--ep-texto); + letter-spacing: -0.02em; +} + +.ep-contenido p { + color: var(--ep-texto-secundario); +} + +.ep-estado-completado { + color: var(--ep-exito); + font-weight: 600; +} + +.ep-estado-pendiente { + color: var(--ep-advertencia); + font-weight: 600; +} + +.ep-estado-fallido { + color: var(--ep-peligro); + font-weight: 600; +} + +.ep-texto-gradiente { + background: linear-gradient(90deg, var(--ep-primario), var(--ep-acento)); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.ep-separador { + border-bottom: 1px solid var(--ep-borde); + margin: 1.5rem 0; +} + +.ep-boton-icono { + width: 40px; + height: 40px; + border-radius: 50%; + border: 1px solid var(--ep-borde); + background: var(--ep-superficie); + color: var(--ep-texto); + display: inline-flex; + align-items: center; + justify-content: center; + transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease; +} + +.ep-boton-icono:hover { + background: var(--ep-superficie-2); + border-color: var(--ep-primario); + color: var(--ep-primario); +} + +.ep-alerta { + border-radius: var(--ep-radio); + padding: 1rem 1.25rem; + border: 1px solid var(--ep-borde); + background: var(--ep-superficie); + display: flex; + gap: 0.75rem; + align-items: flex-start; +} + +.ep-alerta-icono { + font-size: 1.5rem; + color: var(--ep-info); +} + +.ep-alerta-titulo { + font-weight: 600; + margin-bottom: 0.25rem; +} + +.ep-tabla { + width: 100%; + border-collapse: collapse; + border: 1px solid var(--ep-borde); + border-radius: var(--ep-radio); + overflow: hidden; +} + +.ep-tabla th, +.ep-tabla td { + padding: 0.85rem 1rem; + border-bottom: 1px solid var(--ep-borde); +} + +.ep-tabla th { + background: var(--ep-superficie-2); + color: var(--ep-texto-secundario); + font-weight: 600; + text-align: left; +} + +.ep-tabla tr:hover { + background: var(--ep-superficie-2); +} + +@media (max-width: 768px) { + .ep-sidebar { + position: static; + width: 100%; + min-height: auto; + } + + .ep-contenido { + margin-left: 0; + padding: 1.5rem; + } + + .ep-card { + padding: 1.25rem; + } + + .ep-contenido .container, + .ep-contenido .container-fluid { + max-width: 100%; + } +} + +/* --- Habits Dashboard Redesign --- */ + +.ep-header-title { + font-weight: 700; + font-size: 2rem; + margin-bottom: 0.2rem; +} + +.ep-header-subtitle { + color: var(--ep-texto-secundario); + font-size: 0.95rem; +} + +.ep-summary-card { + display: flex; + align-items: center; + gap: 1rem; + padding: 1.25rem; + border-radius: var(--ep-radio); + background: var(--ep-superficie); + border: 1px solid var(--ep-borde); + height: 100%; +} + +.ep-summary-icon { + width: 48px; + height: 48px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; +} + +.ep-summary-icon.icon-purple { + background: rgba(167, 139, 250, 0.15); + color: #A78BFA; +} + +.ep-summary-icon.icon-green { + background: rgba(16, 185, 129, 0.15); + color: #10B981; +} + +.ep-summary-icon.icon-orange { + background: rgba(249, 115, 22, 0.15); + color: #F97316; +} + +.ep-summary-icon.icon-blue { + background: rgba(59, 130, 246, 0.15); + color: #3B82F6; +} + +.ep-summary-value { + font-size: 1.5rem; + font-weight: 700; + margin-bottom: 0; + line-height: 1; +} + +.ep-summary-label { + color: var(--ep-texto-secundario); + font-size: 0.85rem; + margin-bottom: 0; + margin-top: 0.25rem; +} + +.ep-habit-card { + display: flex; + align-items: center; + background: var(--ep-superficie); + border: 1px solid var(--ep-borde); + border-radius: var(--ep-radio); + padding: 1rem 1.25rem; + margin-bottom: 0.75rem; + transition: transform 0.2s; +} + +.ep-habit-card:hover { + border-color: var(--ep-neon-borde); +} + +.ep-habit-icon { + width: 48px; + height: 48px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; + margin-right: 1rem; +} + +/* Day Checkboxes */ +.ep-day-check { + width: 24px; + height: 24px; + border-radius: 50%; + border: 2px solid var(--ep-borde); + display: inline-flex; + align-items: center; + justify-content: center; + color: transparent; + font-size: 0.8rem; + cursor: pointer; + transition: all 0.2s; +} + +.ep-day-check.checked { + background: var(--ep-primario); + border-color: var(--ep-primario); + color: #fff; +} + +.ep-day-check.disabled { + border-color: var(--ep-superficie-2); + background: var(--ep-superficie-2); + cursor: not-allowed; +} + +.ep-tabs { + border-bottom: 1px solid var(--ep-borde); + margin-bottom: 1rem; +} + +.ep-tab { + color: var(--ep-texto-secundario); + text-decoration: none; + padding: 0.5rem 1rem; + display: inline-block; + border-bottom: 2px solid transparent; + font-weight: 500; +} + +.ep-tab.active { + color: var(--ep-primario); + border-bottom-color: var(--ep-primario); +} + +.ep-tab:hover { + color: var(--ep-texto); +} + +/* Simple CSS Donut */ +.ep-donut-wrapper { + position: relative; + width: 120px; + height: 120px; + margin: 0 auto; +} + +.ep-donut { + width: 100%; + height: 100%; + border-radius: 50%; + background: conic-gradient( + var(--ep-exito) 0% 70%, + var(--ep-advertencia) 70% 85%, + var(--ep-peligro) 85% 100% + ); + display: flex; + align-items: center; + justify-content: center; +} + +.ep-donut-inner { + width: 90px; + height: 90px; + background: var(--ep-superficie); + border-radius: 50%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.ep-donut-val { + font-size: 1.5rem; + font-weight: 700; + line-height: 1; +} + +.ep-donut-label { + font-size: 0.75rem; + color: var(--ep-texto-secundario); +} + +.ep-sidebar-btn { + width: 100%; + text-align: center; + padding: 0.75rem; + border-radius: var(--ep-radio-sm); + font-weight: 600; + margin-bottom: 0.75rem; + display: block; + text-decoration: none; +} + +.ep-btn-purple { + background: var(--ep-acento); + color: #fff; + border: none; +} + +.ep-btn-purple:hover { + background: #4F46E5; + color: #fff; +} + +.ep-btn-white { + background: var(--ep-texto); + color: var(--ep-acento); + border: none; +} + +.ep-btn-white:hover { + background: #E2E8F0; + color: var(--ep-acento); +} + +/* --- Pomodoro UI --- */ +.ep-pomodoro-timer-wrapper { + position: relative; + width: 280px; + height: 280px; + margin: 2rem auto; +} + +.ep-pomodoro-ring { + width: 100%; + height: 100%; + border-radius: 50%; + border: 12px solid var(--ep-superficie-2); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + position: relative; + transition: all 0.3s ease; +} + +.ep-pomodoro-ring.active { + border-color: var(--ep-acento); + box-shadow: 0 0 20px rgba(167, 139, 250, 0.4); +} + +.ep-pomodoro-ring.descanso { + border-color: var(--ep-exito); + box-shadow: 0 0 20px rgba(16, 185, 129, 0.4); +} + +.ep-pomodoro-time { + font-size: 4.5rem; + font-weight: 700; + line-height: 1; + color: var(--ep-texto); +} + +.ep-pomodoro-label { + font-size: 0.9rem; + color: var(--ep-texto-secundario); + margin-top: 0.5rem; + background: var(--ep-superficie-2); + padding: 0.25rem 1rem; + border-radius: var(--ep-radio-sm); +} + +.ep-pomodoro-tabs { + display: flex; + justify-content: center; + gap: 1rem; + background: var(--ep-superficie-2); + padding: 0.5rem; + border-radius: var(--ep-radio); + width: fit-content; + margin: 0 auto; +} + +.ep-pomodoro-tab { + padding: 0.5rem 1.5rem; + border-radius: var(--ep-radio-sm); + color: var(--ep-texto-secundario); + cursor: pointer; + font-weight: 500; + transition: all 0.2s; + display: flex; + align-items: center; + gap: 0.5rem; +} + +.ep-pomodoro-tab:hover { + color: var(--ep-texto); +} + +.ep-pomodoro-tab.active { + background: var(--ep-superficie); + color: var(--ep-acento); + box-shadow: 0 2px 4px rgba(0,0,0,0.2); +} + +.ep-pomodoro-tab.active.descanso { + color: var(--ep-exito); +} + +.ep-pomodoro-controls { + display: flex; + justify-content: center; + align-items: center; + gap: 1rem; + margin-top: 2rem; +} + +.ep-btn-play { + background: var(--ep-acento); + color: #fff; + border: none; + padding: 1rem 3rem; + font-size: 1.25rem; + font-weight: 600; + border-radius: var(--ep-radio); + transition: background 0.2s; +} + +.ep-btn-play:hover { + background: #4F46E5; +} + +.ep-btn-play.descanso { + background: var(--ep-exito); +} + +.ep-btn-play.descanso:hover { + background: #059669; +} + +.ep-btn-icon { + width: 54px; + height: 54px; + border-radius: var(--ep-radio); + border: 1px solid var(--ep-borde); + background: transparent; + color: var(--ep-texto-secundario); + display: flex; + align-items: center; + justify-content: center; + font-size: 1.25rem; + transition: all 0.2s; +} + +.ep-btn-icon:hover { + background: var(--ep-superficie-2); + color: var(--ep-texto); +} + +.ep-task-item { + display: flex; + align-items: center; + padding: 0.75rem 0; + border-bottom: 1px solid var(--ep-borde); +} + +.ep-task-item:last-child { + border-bottom: none; +} + +.ep-task-check { + width: 20px; + height: 20px; + border-radius: 50%; + border: 2px solid var(--ep-borde); + margin-right: 1rem; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + color: transparent; + font-size: 0.75rem; +} + +.ep-task-check.checked { + background: var(--ep-primario); + border-color: var(--ep-primario); + color: #fff; +} + +.ep-task-tag { + font-size: 0.75rem; + padding: 0.15rem 0.5rem; + border-radius: 12px; + background: rgba(167, 139, 250, 0.15); + color: #A78BFA; + margin-left: 0.5rem; +} diff --git a/wwwroot/css/temas/.gitkeep b/wwwroot/css/temas/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/wwwroot/css/temas/tema-noche-epica.css b/wwwroot/css/temas/tema-noche-epica.css new file mode 100644 index 0000000..ff572f6 --- /dev/null +++ b/wwwroot/css/temas/tema-noche-epica.css @@ -0,0 +1,37 @@ +:root { + --ep-fondo: #070B14; + --ep-superficie: #0E1420; + --ep-superficie-2: #141B2D; + --ep-borde: #1E293B; + --ep-primario: #3B82F6; + --ep-primario-hover: #2563EB; + --ep-acento: #6366F1; + --ep-neon: #00D4FF; + --ep-neon-suave: rgba(0,212,255,0.12); + --ep-neon-borde: rgba(0,212,255,0.30); + --ep-texto: #F1F5F9; + --ep-texto-secundario: #94A3B8; + --ep-texto-apagado: #475569; + --ep-exito: #10B981; + --ep-advertencia: #F59E0B; + --ep-peligro: #EF4444; + --ep-info: #38BDF8; + --ep-xp: #FACC15; + --ep-xp-suave: rgba(250,204,21,0.15); + --ep-racha: #F97316; + --ep-racha-suave: rgba(249,115,22,0.15); + --ep-nivel: #A78BFA; + --ep-barra-xp-fondo: #1E293B; + --ep-barra-xp-relleno: linear-gradient(90deg,#3B82F6,#00D4FF); + --ep-nav-fondo: #0A0F1E; + --ep-nav-item-hover: rgba(59,130,246,0.15); + --ep-nav-item-activo: rgba(59,130,246,0.25); + --ep-nav-texto: #94A3B8; + --ep-nav-texto-activo: #00D4FF; + --ep-sombra: 0 4px 24px rgba(0,0,0,0.60); + --ep-sombra-neon: 0 0 20px rgba(0,212,255,0.20); + --ep-sombra-primario: 0 4px 15px rgba(59,130,246,0.30); + --ep-radio: 12px; + --ep-radio-sm: 8px; + --ep-radio-lg: 20px; +} diff --git a/wwwroot/css/temas/tema-sakura.css b/wwwroot/css/temas/tema-sakura.css new file mode 100644 index 0000000..b4b7159 --- /dev/null +++ b/wwwroot/css/temas/tema-sakura.css @@ -0,0 +1,37 @@ +:root { + --ep-fondo: #FDF4FF; + --ep-superficie: #FFFFFF; + --ep-superficie-2: #F5E6FF; + --ep-borde: #E9D5FF; + --ep-primario: #A855F7; + --ep-primario-hover: #9333EA; + --ep-acento: #EC4899; + --ep-neon: #C084FC; + --ep-neon-suave: rgba(192,132,252,0.12); + --ep-neon-borde: rgba(192,132,252,0.40); + --ep-texto: #1E1B4B; + --ep-texto-secundario: #6B7280; + --ep-texto-apagado: #9CA3AF; + --ep-exito: #059669; + --ep-advertencia: #D97706; + --ep-peligro: #DC2626; + --ep-info: #7C3AED; + --ep-xp: #F59E0B; + --ep-xp-suave: rgba(245,158,11,0.12); + --ep-racha: #F97316; + --ep-racha-suave: rgba(249,115,22,0.10); + --ep-nivel: #A855F7; + --ep-barra-xp-fondo: #E9D5FF; + --ep-barra-xp-relleno: linear-gradient(90deg,#A855F7,#EC4899); + --ep-nav-fondo: #FFFFFF; + --ep-nav-item-hover: rgba(168,85,247,0.08); + --ep-nav-item-activo: rgba(168,85,247,0.15); + --ep-nav-texto: #6B7280; + --ep-nav-texto-activo: #A855F7; + --ep-sombra: 0 4px 24px rgba(168,85,247,0.10); + --ep-sombra-neon: 0 0 20px rgba(192,132,252,0.15); + --ep-sombra-primario: 0 4px 15px rgba(168,85,247,0.20); + --ep-radio: 12px; + --ep-radio-sm: 8px; + --ep-radio-lg: 20px; +} diff --git a/wwwroot/favicon.ico b/wwwroot/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..63e859b476eff5055e0e557aaa151ca8223fbeef GIT binary patch literal 5430 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 * { + box-sizing: border-box; + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-right: calc(var(--bs-gutter-x) * 0.5); + padding-left: calc(var(--bs-gutter-x) * 0.5); + margin-top: var(--bs-gutter-y); +} + +.col { + flex: 1 0 0%; +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto; +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100%; +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50%; +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.33333333%; +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25%; +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20%; +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.66666667%; +} + +.col-auto { + flex: 0 0 auto; + width: auto; +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333%; +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667%; +} + +.col-3 { + flex: 0 0 auto; + width: 25%; +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333%; +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667%; +} + +.col-6 { + flex: 0 0 auto; + width: 50%; +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333%; +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667%; +} + +.col-9 { + flex: 0 0 auto; + width: 75%; +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333%; +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667%; +} + +.col-12 { + flex: 0 0 auto; + width: 100%; +} + +.offset-1 { + margin-left: 8.33333333%; +} + +.offset-2 { + margin-left: 16.66666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.33333333%; +} + +.offset-5 { + margin-left: 41.66666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.33333333%; +} + +.offset-8 { + margin-left: 66.66666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.33333333%; +} + +.offset-11 { + margin-left: 91.66666667%; +} + +.g-0, +.gx-0 { + --bs-gutter-x: 0; +} + +.g-0, +.gy-0 { + --bs-gutter-y: 0; +} + +.g-1, +.gx-1 { + --bs-gutter-x: 0.25rem; +} + +.g-1, +.gy-1 { + --bs-gutter-y: 0.25rem; +} + +.g-2, +.gx-2 { + --bs-gutter-x: 0.5rem; +} + +.g-2, +.gy-2 { + --bs-gutter-y: 0.5rem; +} + +.g-3, +.gx-3 { + --bs-gutter-x: 1rem; +} + +.g-3, +.gy-3 { + --bs-gutter-y: 1rem; +} + +.g-4, +.gx-4 { + --bs-gutter-x: 1.5rem; +} + +.g-4, +.gy-4 { + --bs-gutter-y: 1.5rem; +} + +.g-5, +.gx-5 { + --bs-gutter-x: 3rem; +} + +.g-5, +.gy-5 { + --bs-gutter-y: 3rem; +} + +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0%; + } + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-sm-auto { + flex: 0 0 auto; + width: auto; + } + .col-sm-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-sm-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-sm-3 { + flex: 0 0 auto; + width: 25%; + } + .col-sm-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-sm-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-sm-6 { + flex: 0 0 auto; + width: 50%; + } + .col-sm-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-sm-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-sm-9 { + flex: 0 0 auto; + width: 75%; + } + .col-sm-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-sm-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-sm-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-sm-0 { + margin-left: 0; + } + .offset-sm-1 { + margin-left: 8.33333333%; + } + .offset-sm-2 { + margin-left: 16.66666667%; + } + .offset-sm-3 { + margin-left: 25%; + } + .offset-sm-4 { + margin-left: 33.33333333%; + } + .offset-sm-5 { + margin-left: 41.66666667%; + } + .offset-sm-6 { + margin-left: 50%; + } + .offset-sm-7 { + margin-left: 58.33333333%; + } + .offset-sm-8 { + margin-left: 66.66666667%; + } + .offset-sm-9 { + margin-left: 75%; + } + .offset-sm-10 { + margin-left: 83.33333333%; + } + .offset-sm-11 { + margin-left: 91.66666667%; + } + .g-sm-0, + .gx-sm-0 { + --bs-gutter-x: 0; + } + .g-sm-0, + .gy-sm-0 { + --bs-gutter-y: 0; + } + .g-sm-1, + .gx-sm-1 { + --bs-gutter-x: 0.25rem; + } + .g-sm-1, + .gy-sm-1 { + --bs-gutter-y: 0.25rem; + } + .g-sm-2, + .gx-sm-2 { + --bs-gutter-x: 0.5rem; + } + .g-sm-2, + .gy-sm-2 { + --bs-gutter-y: 0.5rem; + } + .g-sm-3, + .gx-sm-3 { + --bs-gutter-x: 1rem; + } + .g-sm-3, + .gy-sm-3 { + --bs-gutter-y: 1rem; + } + .g-sm-4, + .gx-sm-4 { + --bs-gutter-x: 1.5rem; + } + .g-sm-4, + .gy-sm-4 { + --bs-gutter-y: 1.5rem; + } + .g-sm-5, + .gx-sm-5 { + --bs-gutter-x: 3rem; + } + .g-sm-5, + .gy-sm-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 768px) { + .col-md { + flex: 1 0 0%; + } + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-md-auto { + flex: 0 0 auto; + width: auto; + } + .col-md-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-md-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-md-3 { + flex: 0 0 auto; + width: 25%; + } + .col-md-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-md-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-md-6 { + flex: 0 0 auto; + width: 50%; + } + .col-md-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-md-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-md-9 { + flex: 0 0 auto; + width: 75%; + } + .col-md-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-md-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-md-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-md-0 { + margin-left: 0; + } + .offset-md-1 { + margin-left: 8.33333333%; + } + .offset-md-2 { + margin-left: 16.66666667%; + } + .offset-md-3 { + margin-left: 25%; + } + .offset-md-4 { + margin-left: 33.33333333%; + } + .offset-md-5 { + margin-left: 41.66666667%; + } + .offset-md-6 { + margin-left: 50%; + } + .offset-md-7 { + margin-left: 58.33333333%; + } + .offset-md-8 { + margin-left: 66.66666667%; + } + .offset-md-9 { + margin-left: 75%; + } + .offset-md-10 { + margin-left: 83.33333333%; + } + .offset-md-11 { + margin-left: 91.66666667%; + } + .g-md-0, + .gx-md-0 { + --bs-gutter-x: 0; + } + .g-md-0, + .gy-md-0 { + --bs-gutter-y: 0; + } + .g-md-1, + .gx-md-1 { + --bs-gutter-x: 0.25rem; + } + .g-md-1, + .gy-md-1 { + --bs-gutter-y: 0.25rem; + } + .g-md-2, + .gx-md-2 { + --bs-gutter-x: 0.5rem; + } + .g-md-2, + .gy-md-2 { + --bs-gutter-y: 0.5rem; + } + .g-md-3, + .gx-md-3 { + --bs-gutter-x: 1rem; + } + .g-md-3, + .gy-md-3 { + --bs-gutter-y: 1rem; + } + .g-md-4, + .gx-md-4 { + --bs-gutter-x: 1.5rem; + } + .g-md-4, + .gy-md-4 { + --bs-gutter-y: 1.5rem; + } + .g-md-5, + .gx-md-5 { + --bs-gutter-x: 3rem; + } + .g-md-5, + .gy-md-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0%; + } + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-lg-auto { + flex: 0 0 auto; + width: auto; + } + .col-lg-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-lg-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-lg-3 { + flex: 0 0 auto; + width: 25%; + } + .col-lg-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-lg-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-lg-6 { + flex: 0 0 auto; + width: 50%; + } + .col-lg-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-lg-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-lg-9 { + flex: 0 0 auto; + width: 75%; + } + .col-lg-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-lg-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-lg-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-lg-0 { + margin-left: 0; + } + .offset-lg-1 { + margin-left: 8.33333333%; + } + .offset-lg-2 { + margin-left: 16.66666667%; + } + .offset-lg-3 { + margin-left: 25%; + } + .offset-lg-4 { + margin-left: 33.33333333%; + } + .offset-lg-5 { + margin-left: 41.66666667%; + } + .offset-lg-6 { + margin-left: 50%; + } + .offset-lg-7 { + margin-left: 58.33333333%; + } + .offset-lg-8 { + margin-left: 66.66666667%; + } + .offset-lg-9 { + margin-left: 75%; + } + .offset-lg-10 { + margin-left: 83.33333333%; + } + .offset-lg-11 { + margin-left: 91.66666667%; + } + .g-lg-0, + .gx-lg-0 { + --bs-gutter-x: 0; + } + .g-lg-0, + .gy-lg-0 { + --bs-gutter-y: 0; + } + .g-lg-1, + .gx-lg-1 { + --bs-gutter-x: 0.25rem; + } + .g-lg-1, + .gy-lg-1 { + --bs-gutter-y: 0.25rem; + } + .g-lg-2, + .gx-lg-2 { + --bs-gutter-x: 0.5rem; + } + .g-lg-2, + .gy-lg-2 { + --bs-gutter-y: 0.5rem; + } + .g-lg-3, + .gx-lg-3 { + --bs-gutter-x: 1rem; + } + .g-lg-3, + .gy-lg-3 { + --bs-gutter-y: 1rem; + } + .g-lg-4, + .gx-lg-4 { + --bs-gutter-x: 1.5rem; + } + .g-lg-4, + .gy-lg-4 { + --bs-gutter-y: 1.5rem; + } + .g-lg-5, + .gx-lg-5 { + --bs-gutter-x: 3rem; + } + .g-lg-5, + .gy-lg-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0%; + } + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xl-auto { + flex: 0 0 auto; + width: auto; + } + .col-xl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-xl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xl-3 { + flex: 0 0 auto; + width: 25%; + } + .col-xl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-xl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-xl-6 { + flex: 0 0 auto; + width: 50%; + } + .col-xl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-xl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-xl-9 { + flex: 0 0 auto; + width: 75%; + } + .col-xl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-xl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-xl-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-xl-0 { + margin-left: 0; + } + .offset-xl-1 { + margin-left: 8.33333333%; + } + .offset-xl-2 { + margin-left: 16.66666667%; + } + .offset-xl-3 { + margin-left: 25%; + } + .offset-xl-4 { + margin-left: 33.33333333%; + } + .offset-xl-5 { + margin-left: 41.66666667%; + } + .offset-xl-6 { + margin-left: 50%; + } + .offset-xl-7 { + margin-left: 58.33333333%; + } + .offset-xl-8 { + margin-left: 66.66666667%; + } + .offset-xl-9 { + margin-left: 75%; + } + .offset-xl-10 { + margin-left: 83.33333333%; + } + .offset-xl-11 { + margin-left: 91.66666667%; + } + .g-xl-0, + .gx-xl-0 { + --bs-gutter-x: 0; + } + .g-xl-0, + .gy-xl-0 { + --bs-gutter-y: 0; + } + .g-xl-1, + .gx-xl-1 { + --bs-gutter-x: 0.25rem; + } + .g-xl-1, + .gy-xl-1 { + --bs-gutter-y: 0.25rem; + } + .g-xl-2, + .gx-xl-2 { + --bs-gutter-x: 0.5rem; + } + .g-xl-2, + .gy-xl-2 { + --bs-gutter-y: 0.5rem; + } + .g-xl-3, + .gx-xl-3 { + --bs-gutter-x: 1rem; + } + .g-xl-3, + .gy-xl-3 { + --bs-gutter-y: 1rem; + } + .g-xl-4, + .gx-xl-4 { + --bs-gutter-x: 1.5rem; + } + .g-xl-4, + .gy-xl-4 { + --bs-gutter-y: 1.5rem; + } + .g-xl-5, + .gx-xl-5 { + --bs-gutter-x: 3rem; + } + .g-xl-5, + .gy-xl-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0%; + } + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xxl-auto { + flex: 0 0 auto; + width: auto; + } + .col-xxl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-xxl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xxl-3 { + flex: 0 0 auto; + width: 25%; + } + .col-xxl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-xxl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-xxl-6 { + flex: 0 0 auto; + width: 50%; + } + .col-xxl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-xxl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-xxl-9 { + flex: 0 0 auto; + width: 75%; + } + .col-xxl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-xxl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-xxl-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-xxl-0 { + margin-left: 0; + } + .offset-xxl-1 { + margin-left: 8.33333333%; + } + .offset-xxl-2 { + margin-left: 16.66666667%; + } + .offset-xxl-3 { + margin-left: 25%; + } + .offset-xxl-4 { + margin-left: 33.33333333%; + } + .offset-xxl-5 { + margin-left: 41.66666667%; + } + .offset-xxl-6 { + margin-left: 50%; + } + .offset-xxl-7 { + margin-left: 58.33333333%; + } + .offset-xxl-8 { + margin-left: 66.66666667%; + } + .offset-xxl-9 { + margin-left: 75%; + } + .offset-xxl-10 { + margin-left: 83.33333333%; + } + .offset-xxl-11 { + margin-left: 91.66666667%; + } + .g-xxl-0, + .gx-xxl-0 { + --bs-gutter-x: 0; + } + .g-xxl-0, + .gy-xxl-0 { + --bs-gutter-y: 0; + } + .g-xxl-1, + .gx-xxl-1 { + --bs-gutter-x: 0.25rem; + } + .g-xxl-1, + .gy-xxl-1 { + --bs-gutter-y: 0.25rem; + } + .g-xxl-2, + .gx-xxl-2 { + --bs-gutter-x: 0.5rem; + } + .g-xxl-2, + .gy-xxl-2 { + --bs-gutter-y: 0.5rem; + } + .g-xxl-3, + .gx-xxl-3 { + --bs-gutter-x: 1rem; + } + .g-xxl-3, + .gy-xxl-3 { + --bs-gutter-y: 1rem; + } + .g-xxl-4, + .gx-xxl-4 { + --bs-gutter-x: 1.5rem; + } + .g-xxl-4, + .gy-xxl-4 { + --bs-gutter-y: 1.5rem; + } + .g-xxl-5, + .gx-xxl-5 { + --bs-gutter-x: 3rem; + } + .g-xxl-5, + .gy-xxl-5 { + --bs-gutter-y: 3rem; + } +} +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-grid { + display: grid !important; +} + +.d-inline-grid { + display: inline-grid !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: flex !important; +} + +.d-inline-flex { + display: inline-flex !important; +} + +.d-none { + display: none !important; +} + +.flex-fill { + flex: 1 1 auto !important; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-row-reverse { + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + flex-direction: column-reverse !important; +} + +.flex-grow-0 { + flex-grow: 0 !important; +} + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.flex-shrink-0 { + flex-shrink: 0 !important; +} + +.flex-shrink-1 { + flex-shrink: 1 !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + justify-content: flex-start !important; +} + +.justify-content-end { + justify-content: flex-end !important; +} + +.justify-content-center { + justify-content: center !important; +} + +.justify-content-between { + justify-content: space-between !important; +} + +.justify-content-around { + justify-content: space-around !important; +} + +.justify-content-evenly { + justify-content: space-evenly !important; +} + +.align-items-start { + align-items: flex-start !important; +} + +.align-items-end { + align-items: flex-end !important; +} + +.align-items-center { + align-items: center !important; +} + +.align-items-baseline { + align-items: baseline !important; +} + +.align-items-stretch { + align-items: stretch !important; +} + +.align-content-start { + align-content: flex-start !important; +} + +.align-content-end { + align-content: flex-end !important; +} + +.align-content-center { + align-content: center !important; +} + +.align-content-between { + align-content: space-between !important; +} + +.align-content-around { + align-content: space-around !important; +} + +.align-content-stretch { + align-content: stretch !important; +} + +.align-self-auto { + align-self: auto !important; +} + +.align-self-start { + align-self: flex-start !important; +} + +.align-self-end { + align-self: flex-end !important; +} + +.align-self-center { + align-self: center !important; +} + +.align-self-baseline { + align-self: baseline !important; +} + +.align-self-stretch { + align-self: stretch !important; +} + +.order-first { + order: -1 !important; +} + +.order-0 { + order: 0 !important; +} + +.order-1 { + order: 1 !important; +} + +.order-2 { + order: 2 !important; +} + +.order-3 { + order: 3 !important; +} + +.order-4 { + order: 4 !important; +} + +.order-5 { + order: 5 !important; +} + +.order-last { + order: 6 !important; +} + +.m-0 { + margin: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mx-0 { + margin-right: 0 !important; + margin-left: 0 !important; +} + +.mx-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; +} + +.mx-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; +} + +.mx-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; +} + +.mx-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; +} + +.mx-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; +} + +.mx-auto { + margin-right: auto !important; + margin-left: auto !important; +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.my-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; +} + +.my-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important; +} + +.mt-0 { + margin-top: 0 !important; +} + +.mt-1 { + margin-top: 0.25rem !important; +} + +.mt-2 { + margin-top: 0.5rem !important; +} + +.mt-3 { + margin-top: 1rem !important; +} + +.mt-4 { + margin-top: 1.5rem !important; +} + +.mt-5 { + margin-top: 3rem !important; +} + +.mt-auto { + margin-top: auto !important; +} + +.me-0 { + margin-right: 0 !important; +} + +.me-1 { + margin-right: 0.25rem !important; +} + +.me-2 { + margin-right: 0.5rem !important; +} + +.me-3 { + margin-right: 1rem !important; +} + +.me-4 { + margin-right: 1.5rem !important; +} + +.me-5 { + margin-right: 3rem !important; +} + +.me-auto { + margin-right: auto !important; +} + +.mb-0 { + margin-bottom: 0 !important; +} + +.mb-1 { + margin-bottom: 0.25rem !important; +} + +.mb-2 { + margin-bottom: 0.5rem !important; +} + +.mb-3 { + margin-bottom: 1rem !important; +} + +.mb-4 { + margin-bottom: 1.5rem !important; +} + +.mb-5 { + margin-bottom: 3rem !important; +} + +.mb-auto { + margin-bottom: auto !important; +} + +.ms-0 { + margin-left: 0 !important; +} + +.ms-1 { + margin-left: 0.25rem !important; +} + +.ms-2 { + margin-left: 0.5rem !important; +} + +.ms-3 { + margin-left: 1rem !important; +} + +.ms-4 { + margin-left: 1.5rem !important; +} + +.ms-5 { + margin-left: 3rem !important; +} + +.ms-auto { + margin-left: auto !important; +} + +.p-0 { + padding: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.px-0 { + padding-right: 0 !important; + padding-left: 0 !important; +} + +.px-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; +} + +.px-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; +} + +.px-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; +} + +.px-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; +} + +.px-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.py-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; +} + +.py-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; +} + +.pt-0 { + padding-top: 0 !important; +} + +.pt-1 { + padding-top: 0.25rem !important; +} + +.pt-2 { + padding-top: 0.5rem !important; +} + +.pt-3 { + padding-top: 1rem !important; +} + +.pt-4 { + padding-top: 1.5rem !important; +} + +.pt-5 { + padding-top: 3rem !important; +} + +.pe-0 { + padding-right: 0 !important; +} + +.pe-1 { + padding-right: 0.25rem !important; +} + +.pe-2 { + padding-right: 0.5rem !important; +} + +.pe-3 { + padding-right: 1rem !important; +} + +.pe-4 { + padding-right: 1.5rem !important; +} + +.pe-5 { + padding-right: 3rem !important; +} + +.pb-0 { + padding-bottom: 0 !important; +} + +.pb-1 { + padding-bottom: 0.25rem !important; +} + +.pb-2 { + padding-bottom: 0.5rem !important; +} + +.pb-3 { + padding-bottom: 1rem !important; +} + +.pb-4 { + padding-bottom: 1.5rem !important; +} + +.pb-5 { + padding-bottom: 3rem !important; +} + +.ps-0 { + padding-left: 0 !important; +} + +.ps-1 { + padding-left: 0.25rem !important; +} + +.ps-2 { + padding-left: 0.5rem !important; +} + +.ps-3 { + padding-left: 1rem !important; +} + +.ps-4 { + padding-left: 1.5rem !important; +} + +.ps-5 { + padding-left: 3rem !important; +} + +@media (min-width: 576px) { + .d-sm-inline { + display: inline !important; + } + .d-sm-inline-block { + display: inline-block !important; + } + .d-sm-block { + display: block !important; + } + .d-sm-grid { + display: grid !important; + } + .d-sm-inline-grid { + display: inline-grid !important; + } + .d-sm-table { + display: table !important; + } + .d-sm-table-row { + display: table-row !important; + } + .d-sm-table-cell { + display: table-cell !important; + } + .d-sm-flex { + display: flex !important; + } + .d-sm-inline-flex { + display: inline-flex !important; + } + .d-sm-none { + display: none !important; + } + .flex-sm-fill { + flex: 1 1 auto !important; + } + .flex-sm-row { + flex-direction: row !important; + } + .flex-sm-column { + flex-direction: column !important; + } + .flex-sm-row-reverse { + flex-direction: row-reverse !important; + } + .flex-sm-column-reverse { + flex-direction: column-reverse !important; + } + .flex-sm-grow-0 { + flex-grow: 0 !important; + } + .flex-sm-grow-1 { + flex-grow: 1 !important; + } + .flex-sm-shrink-0 { + flex-shrink: 0 !important; + } + .flex-sm-shrink-1 { + flex-shrink: 1 !important; + } + .flex-sm-wrap { + flex-wrap: wrap !important; + } + .flex-sm-nowrap { + flex-wrap: nowrap !important; + } + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-sm-start { + justify-content: flex-start !important; + } + .justify-content-sm-end { + justify-content: flex-end !important; + } + .justify-content-sm-center { + justify-content: center !important; + } + .justify-content-sm-between { + justify-content: space-between !important; + } + .justify-content-sm-around { + justify-content: space-around !important; + } + .justify-content-sm-evenly { + justify-content: space-evenly !important; + } + .align-items-sm-start { + align-items: flex-start !important; + } + .align-items-sm-end { + align-items: flex-end !important; + } + .align-items-sm-center { + align-items: center !important; + } + .align-items-sm-baseline { + align-items: baseline !important; + } + .align-items-sm-stretch { + align-items: stretch !important; + } + .align-content-sm-start { + align-content: flex-start !important; + } + .align-content-sm-end { + align-content: flex-end !important; + } + .align-content-sm-center { + align-content: center !important; + } + .align-content-sm-between { + align-content: space-between !important; + } + .align-content-sm-around { + align-content: space-around !important; + } + .align-content-sm-stretch { + align-content: stretch !important; + } + .align-self-sm-auto { + align-self: auto !important; + } + .align-self-sm-start { + align-self: flex-start !important; + } + .align-self-sm-end { + align-self: flex-end !important; + } + .align-self-sm-center { + align-self: center !important; + } + .align-self-sm-baseline { + align-self: baseline !important; + } + .align-self-sm-stretch { + align-self: stretch !important; + } + .order-sm-first { + order: -1 !important; + } + .order-sm-0 { + order: 0 !important; + } + .order-sm-1 { + order: 1 !important; + } + .order-sm-2 { + order: 2 !important; + } + .order-sm-3 { + order: 3 !important; + } + .order-sm-4 { + order: 4 !important; + } + .order-sm-5 { + order: 5 !important; + } + .order-sm-last { + order: 6 !important; + } + .m-sm-0 { + margin: 0 !important; + } + .m-sm-1 { + margin: 0.25rem !important; + } + .m-sm-2 { + margin: 0.5rem !important; + } + .m-sm-3 { + margin: 1rem !important; + } + .m-sm-4 { + margin: 1.5rem !important; + } + .m-sm-5 { + margin: 3rem !important; + } + .m-sm-auto { + margin: auto !important; + } + .mx-sm-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-sm-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-sm-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-sm-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-sm-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-sm-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-sm-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-sm-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-sm-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-sm-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-sm-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-sm-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-sm-0 { + margin-top: 0 !important; + } + .mt-sm-1 { + margin-top: 0.25rem !important; + } + .mt-sm-2 { + margin-top: 0.5rem !important; + } + .mt-sm-3 { + margin-top: 1rem !important; + } + .mt-sm-4 { + margin-top: 1.5rem !important; + } + .mt-sm-5 { + margin-top: 3rem !important; + } + .mt-sm-auto { + margin-top: auto !important; + } + .me-sm-0 { + margin-right: 0 !important; + } + .me-sm-1 { + margin-right: 0.25rem !important; + } + .me-sm-2 { + margin-right: 0.5rem !important; + } + .me-sm-3 { + margin-right: 1rem !important; + } + .me-sm-4 { + margin-right: 1.5rem !important; + } + .me-sm-5 { + margin-right: 3rem !important; + } + .me-sm-auto { + margin-right: auto !important; + } + .mb-sm-0 { + margin-bottom: 0 !important; + } + .mb-sm-1 { + margin-bottom: 0.25rem !important; + } + .mb-sm-2 { + margin-bottom: 0.5rem !important; + } + .mb-sm-3 { + margin-bottom: 1rem !important; + } + .mb-sm-4 { + margin-bottom: 1.5rem !important; + } + .mb-sm-5 { + margin-bottom: 3rem !important; + } + .mb-sm-auto { + margin-bottom: auto !important; + } + .ms-sm-0 { + margin-left: 0 !important; + } + .ms-sm-1 { + margin-left: 0.25rem !important; + } + .ms-sm-2 { + margin-left: 0.5rem !important; + } + .ms-sm-3 { + margin-left: 1rem !important; + } + .ms-sm-4 { + margin-left: 1.5rem !important; + } + .ms-sm-5 { + margin-left: 3rem !important; + } + .ms-sm-auto { + margin-left: auto !important; + } + .p-sm-0 { + padding: 0 !important; + } + .p-sm-1 { + padding: 0.25rem !important; + } + .p-sm-2 { + padding: 0.5rem !important; + } + .p-sm-3 { + padding: 1rem !important; + } + .p-sm-4 { + padding: 1.5rem !important; + } + .p-sm-5 { + padding: 3rem !important; + } + .px-sm-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-sm-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-sm-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-sm-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-sm-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-sm-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-sm-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-sm-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-sm-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-sm-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-sm-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-sm-0 { + padding-top: 0 !important; + } + .pt-sm-1 { + padding-top: 0.25rem !important; + } + .pt-sm-2 { + padding-top: 0.5rem !important; + } + .pt-sm-3 { + padding-top: 1rem !important; + } + .pt-sm-4 { + padding-top: 1.5rem !important; + } + .pt-sm-5 { + padding-top: 3rem !important; + } + .pe-sm-0 { + padding-right: 0 !important; + } + .pe-sm-1 { + padding-right: 0.25rem !important; + } + .pe-sm-2 { + padding-right: 0.5rem !important; + } + .pe-sm-3 { + padding-right: 1rem !important; + } + .pe-sm-4 { + padding-right: 1.5rem !important; + } + .pe-sm-5 { + padding-right: 3rem !important; + } + .pb-sm-0 { + padding-bottom: 0 !important; + } + .pb-sm-1 { + padding-bottom: 0.25rem !important; + } + .pb-sm-2 { + padding-bottom: 0.5rem !important; + } + .pb-sm-3 { + padding-bottom: 1rem !important; + } + .pb-sm-4 { + padding-bottom: 1.5rem !important; + } + .pb-sm-5 { + padding-bottom: 3rem !important; + } + .ps-sm-0 { + padding-left: 0 !important; + } + .ps-sm-1 { + padding-left: 0.25rem !important; + } + .ps-sm-2 { + padding-left: 0.5rem !important; + } + .ps-sm-3 { + padding-left: 1rem !important; + } + .ps-sm-4 { + padding-left: 1.5rem !important; + } + .ps-sm-5 { + padding-left: 3rem !important; + } +} +@media (min-width: 768px) { + .d-md-inline { + display: inline !important; + } + .d-md-inline-block { + display: inline-block !important; + } + .d-md-block { + display: block !important; + } + .d-md-grid { + display: grid !important; + } + .d-md-inline-grid { + display: inline-grid !important; + } + .d-md-table { + display: table !important; + } + .d-md-table-row { + display: table-row !important; + } + .d-md-table-cell { + display: table-cell !important; + } + .d-md-flex { + display: flex !important; + } + .d-md-inline-flex { + display: inline-flex !important; + } + .d-md-none { + display: none !important; + } + .flex-md-fill { + flex: 1 1 auto !important; + } + .flex-md-row { + flex-direction: row !important; + } + .flex-md-column { + flex-direction: column !important; + } + .flex-md-row-reverse { + flex-direction: row-reverse !important; + } + .flex-md-column-reverse { + flex-direction: column-reverse !important; + } + .flex-md-grow-0 { + flex-grow: 0 !important; + } + .flex-md-grow-1 { + flex-grow: 1 !important; + } + .flex-md-shrink-0 { + flex-shrink: 0 !important; + } + .flex-md-shrink-1 { + flex-shrink: 1 !important; + } + .flex-md-wrap { + flex-wrap: wrap !important; + } + .flex-md-nowrap { + flex-wrap: nowrap !important; + } + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-md-start { + justify-content: flex-start !important; + } + .justify-content-md-end { + justify-content: flex-end !important; + } + .justify-content-md-center { + justify-content: center !important; + } + .justify-content-md-between { + justify-content: space-between !important; + } + .justify-content-md-around { + justify-content: space-around !important; + } + .justify-content-md-evenly { + justify-content: space-evenly !important; + } + .align-items-md-start { + align-items: flex-start !important; + } + .align-items-md-end { + align-items: flex-end !important; + } + .align-items-md-center { + align-items: center !important; + } + .align-items-md-baseline { + align-items: baseline !important; + } + .align-items-md-stretch { + align-items: stretch !important; + } + .align-content-md-start { + align-content: flex-start !important; + } + .align-content-md-end { + align-content: flex-end !important; + } + .align-content-md-center { + align-content: center !important; + } + .align-content-md-between { + align-content: space-between !important; + } + .align-content-md-around { + align-content: space-around !important; + } + .align-content-md-stretch { + align-content: stretch !important; + } + .align-self-md-auto { + align-self: auto !important; + } + .align-self-md-start { + align-self: flex-start !important; + } + .align-self-md-end { + align-self: flex-end !important; + } + .align-self-md-center { + align-self: center !important; + } + .align-self-md-baseline { + align-self: baseline !important; + } + .align-self-md-stretch { + align-self: stretch !important; + } + .order-md-first { + order: -1 !important; + } + .order-md-0 { + order: 0 !important; + } + .order-md-1 { + order: 1 !important; + } + .order-md-2 { + order: 2 !important; + } + .order-md-3 { + order: 3 !important; + } + .order-md-4 { + order: 4 !important; + } + .order-md-5 { + order: 5 !important; + } + .order-md-last { + order: 6 !important; + } + .m-md-0 { + margin: 0 !important; + } + .m-md-1 { + margin: 0.25rem !important; + } + .m-md-2 { + margin: 0.5rem !important; + } + .m-md-3 { + margin: 1rem !important; + } + .m-md-4 { + margin: 1.5rem !important; + } + .m-md-5 { + margin: 3rem !important; + } + .m-md-auto { + margin: auto !important; + } + .mx-md-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-md-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-md-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-md-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-md-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-md-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-md-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-md-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-md-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-md-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-md-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-md-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-md-0 { + margin-top: 0 !important; + } + .mt-md-1 { + margin-top: 0.25rem !important; + } + .mt-md-2 { + margin-top: 0.5rem !important; + } + .mt-md-3 { + margin-top: 1rem !important; + } + .mt-md-4 { + margin-top: 1.5rem !important; + } + .mt-md-5 { + margin-top: 3rem !important; + } + .mt-md-auto { + margin-top: auto !important; + } + .me-md-0 { + margin-right: 0 !important; + } + .me-md-1 { + margin-right: 0.25rem !important; + } + .me-md-2 { + margin-right: 0.5rem !important; + } + .me-md-3 { + margin-right: 1rem !important; + } + .me-md-4 { + margin-right: 1.5rem !important; + } + .me-md-5 { + margin-right: 3rem !important; + } + .me-md-auto { + margin-right: auto !important; + } + .mb-md-0 { + margin-bottom: 0 !important; + } + .mb-md-1 { + margin-bottom: 0.25rem !important; + } + .mb-md-2 { + margin-bottom: 0.5rem !important; + } + .mb-md-3 { + margin-bottom: 1rem !important; + } + .mb-md-4 { + margin-bottom: 1.5rem !important; + } + .mb-md-5 { + margin-bottom: 3rem !important; + } + .mb-md-auto { + margin-bottom: auto !important; + } + .ms-md-0 { + margin-left: 0 !important; + } + .ms-md-1 { + margin-left: 0.25rem !important; + } + .ms-md-2 { + margin-left: 0.5rem !important; + } + .ms-md-3 { + margin-left: 1rem !important; + } + .ms-md-4 { + margin-left: 1.5rem !important; + } + .ms-md-5 { + margin-left: 3rem !important; + } + .ms-md-auto { + margin-left: auto !important; + } + .p-md-0 { + padding: 0 !important; + } + .p-md-1 { + padding: 0.25rem !important; + } + .p-md-2 { + padding: 0.5rem !important; + } + .p-md-3 { + padding: 1rem !important; + } + .p-md-4 { + padding: 1.5rem !important; + } + .p-md-5 { + padding: 3rem !important; + } + .px-md-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-md-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-md-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-md-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-md-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-md-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-md-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-md-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-md-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-md-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-md-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-md-0 { + padding-top: 0 !important; + } + .pt-md-1 { + padding-top: 0.25rem !important; + } + .pt-md-2 { + padding-top: 0.5rem !important; + } + .pt-md-3 { + padding-top: 1rem !important; + } + .pt-md-4 { + padding-top: 1.5rem !important; + } + .pt-md-5 { + padding-top: 3rem !important; + } + .pe-md-0 { + padding-right: 0 !important; + } + .pe-md-1 { + padding-right: 0.25rem !important; + } + .pe-md-2 { + padding-right: 0.5rem !important; + } + .pe-md-3 { + padding-right: 1rem !important; + } + .pe-md-4 { + padding-right: 1.5rem !important; + } + .pe-md-5 { + padding-right: 3rem !important; + } + .pb-md-0 { + padding-bottom: 0 !important; + } + .pb-md-1 { + padding-bottom: 0.25rem !important; + } + .pb-md-2 { + padding-bottom: 0.5rem !important; + } + .pb-md-3 { + padding-bottom: 1rem !important; + } + .pb-md-4 { + padding-bottom: 1.5rem !important; + } + .pb-md-5 { + padding-bottom: 3rem !important; + } + .ps-md-0 { + padding-left: 0 !important; + } + .ps-md-1 { + padding-left: 0.25rem !important; + } + .ps-md-2 { + padding-left: 0.5rem !important; + } + .ps-md-3 { + padding-left: 1rem !important; + } + .ps-md-4 { + padding-left: 1.5rem !important; + } + .ps-md-5 { + padding-left: 3rem !important; + } +} +@media (min-width: 992px) { + .d-lg-inline { + display: inline !important; + } + .d-lg-inline-block { + display: inline-block !important; + } + .d-lg-block { + display: block !important; + } + .d-lg-grid { + display: grid !important; + } + .d-lg-inline-grid { + display: inline-grid !important; + } + .d-lg-table { + display: table !important; + } + .d-lg-table-row { + display: table-row !important; + } + .d-lg-table-cell { + display: table-cell !important; + } + .d-lg-flex { + display: flex !important; + } + .d-lg-inline-flex { + display: inline-flex !important; + } + .d-lg-none { + display: none !important; + } + .flex-lg-fill { + flex: 1 1 auto !important; + } + .flex-lg-row { + flex-direction: row !important; + } + .flex-lg-column { + flex-direction: column !important; + } + .flex-lg-row-reverse { + flex-direction: row-reverse !important; + } + .flex-lg-column-reverse { + flex-direction: column-reverse !important; + } + .flex-lg-grow-0 { + flex-grow: 0 !important; + } + .flex-lg-grow-1 { + flex-grow: 1 !important; + } + .flex-lg-shrink-0 { + flex-shrink: 0 !important; + } + .flex-lg-shrink-1 { + flex-shrink: 1 !important; + } + .flex-lg-wrap { + flex-wrap: wrap !important; + } + .flex-lg-nowrap { + flex-wrap: nowrap !important; + } + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-lg-start { + justify-content: flex-start !important; + } + .justify-content-lg-end { + justify-content: flex-end !important; + } + .justify-content-lg-center { + justify-content: center !important; + } + .justify-content-lg-between { + justify-content: space-between !important; + } + .justify-content-lg-around { + justify-content: space-around !important; + } + .justify-content-lg-evenly { + justify-content: space-evenly !important; + } + .align-items-lg-start { + align-items: flex-start !important; + } + .align-items-lg-end { + align-items: flex-end !important; + } + .align-items-lg-center { + align-items: center !important; + } + .align-items-lg-baseline { + align-items: baseline !important; + } + .align-items-lg-stretch { + align-items: stretch !important; + } + .align-content-lg-start { + align-content: flex-start !important; + } + .align-content-lg-end { + align-content: flex-end !important; + } + .align-content-lg-center { + align-content: center !important; + } + .align-content-lg-between { + align-content: space-between !important; + } + .align-content-lg-around { + align-content: space-around !important; + } + .align-content-lg-stretch { + align-content: stretch !important; + } + .align-self-lg-auto { + align-self: auto !important; + } + .align-self-lg-start { + align-self: flex-start !important; + } + .align-self-lg-end { + align-self: flex-end !important; + } + .align-self-lg-center { + align-self: center !important; + } + .align-self-lg-baseline { + align-self: baseline !important; + } + .align-self-lg-stretch { + align-self: stretch !important; + } + .order-lg-first { + order: -1 !important; + } + .order-lg-0 { + order: 0 !important; + } + .order-lg-1 { + order: 1 !important; + } + .order-lg-2 { + order: 2 !important; + } + .order-lg-3 { + order: 3 !important; + } + .order-lg-4 { + order: 4 !important; + } + .order-lg-5 { + order: 5 !important; + } + .order-lg-last { + order: 6 !important; + } + .m-lg-0 { + margin: 0 !important; + } + .m-lg-1 { + margin: 0.25rem !important; + } + .m-lg-2 { + margin: 0.5rem !important; + } + .m-lg-3 { + margin: 1rem !important; + } + .m-lg-4 { + margin: 1.5rem !important; + } + .m-lg-5 { + margin: 3rem !important; + } + .m-lg-auto { + margin: auto !important; + } + .mx-lg-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-lg-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-lg-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-lg-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-lg-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-lg-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-lg-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-lg-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-lg-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-lg-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-lg-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-lg-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-lg-0 { + margin-top: 0 !important; + } + .mt-lg-1 { + margin-top: 0.25rem !important; + } + .mt-lg-2 { + margin-top: 0.5rem !important; + } + .mt-lg-3 { + margin-top: 1rem !important; + } + .mt-lg-4 { + margin-top: 1.5rem !important; + } + .mt-lg-5 { + margin-top: 3rem !important; + } + .mt-lg-auto { + margin-top: auto !important; + } + .me-lg-0 { + margin-right: 0 !important; + } + .me-lg-1 { + margin-right: 0.25rem !important; + } + .me-lg-2 { + margin-right: 0.5rem !important; + } + .me-lg-3 { + margin-right: 1rem !important; + } + .me-lg-4 { + margin-right: 1.5rem !important; + } + .me-lg-5 { + margin-right: 3rem !important; + } + .me-lg-auto { + margin-right: auto !important; + } + .mb-lg-0 { + margin-bottom: 0 !important; + } + .mb-lg-1 { + margin-bottom: 0.25rem !important; + } + .mb-lg-2 { + margin-bottom: 0.5rem !important; + } + .mb-lg-3 { + margin-bottom: 1rem !important; + } + .mb-lg-4 { + margin-bottom: 1.5rem !important; + } + .mb-lg-5 { + margin-bottom: 3rem !important; + } + .mb-lg-auto { + margin-bottom: auto !important; + } + .ms-lg-0 { + margin-left: 0 !important; + } + .ms-lg-1 { + margin-left: 0.25rem !important; + } + .ms-lg-2 { + margin-left: 0.5rem !important; + } + .ms-lg-3 { + margin-left: 1rem !important; + } + .ms-lg-4 { + margin-left: 1.5rem !important; + } + .ms-lg-5 { + margin-left: 3rem !important; + } + .ms-lg-auto { + margin-left: auto !important; + } + .p-lg-0 { + padding: 0 !important; + } + .p-lg-1 { + padding: 0.25rem !important; + } + .p-lg-2 { + padding: 0.5rem !important; + } + .p-lg-3 { + padding: 1rem !important; + } + .p-lg-4 { + padding: 1.5rem !important; + } + .p-lg-5 { + padding: 3rem !important; + } + .px-lg-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-lg-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-lg-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-lg-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-lg-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-lg-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-lg-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-lg-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-lg-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-lg-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-lg-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-lg-0 { + padding-top: 0 !important; + } + .pt-lg-1 { + padding-top: 0.25rem !important; + } + .pt-lg-2 { + padding-top: 0.5rem !important; + } + .pt-lg-3 { + padding-top: 1rem !important; + } + .pt-lg-4 { + padding-top: 1.5rem !important; + } + .pt-lg-5 { + padding-top: 3rem !important; + } + .pe-lg-0 { + padding-right: 0 !important; + } + .pe-lg-1 { + padding-right: 0.25rem !important; + } + .pe-lg-2 { + padding-right: 0.5rem !important; + } + .pe-lg-3 { + padding-right: 1rem !important; + } + .pe-lg-4 { + padding-right: 1.5rem !important; + } + .pe-lg-5 { + padding-right: 3rem !important; + } + .pb-lg-0 { + padding-bottom: 0 !important; + } + .pb-lg-1 { + padding-bottom: 0.25rem !important; + } + .pb-lg-2 { + padding-bottom: 0.5rem !important; + } + .pb-lg-3 { + padding-bottom: 1rem !important; + } + .pb-lg-4 { + padding-bottom: 1.5rem !important; + } + .pb-lg-5 { + padding-bottom: 3rem !important; + } + .ps-lg-0 { + padding-left: 0 !important; + } + .ps-lg-1 { + padding-left: 0.25rem !important; + } + .ps-lg-2 { + padding-left: 0.5rem !important; + } + .ps-lg-3 { + padding-left: 1rem !important; + } + .ps-lg-4 { + padding-left: 1.5rem !important; + } + .ps-lg-5 { + padding-left: 3rem !important; + } +} +@media (min-width: 1200px) { + .d-xl-inline { + display: inline !important; + } + .d-xl-inline-block { + display: inline-block !important; + } + .d-xl-block { + display: block !important; + } + .d-xl-grid { + display: grid !important; + } + .d-xl-inline-grid { + display: inline-grid !important; + } + .d-xl-table { + display: table !important; + } + .d-xl-table-row { + display: table-row !important; + } + .d-xl-table-cell { + display: table-cell !important; + } + .d-xl-flex { + display: flex !important; + } + .d-xl-inline-flex { + display: inline-flex !important; + } + .d-xl-none { + display: none !important; + } + .flex-xl-fill { + flex: 1 1 auto !important; + } + .flex-xl-row { + flex-direction: row !important; + } + .flex-xl-column { + flex-direction: column !important; + } + .flex-xl-row-reverse { + flex-direction: row-reverse !important; + } + .flex-xl-column-reverse { + flex-direction: column-reverse !important; + } + .flex-xl-grow-0 { + flex-grow: 0 !important; + } + .flex-xl-grow-1 { + flex-grow: 1 !important; + } + .flex-xl-shrink-0 { + flex-shrink: 0 !important; + } + .flex-xl-shrink-1 { + flex-shrink: 1 !important; + } + .flex-xl-wrap { + flex-wrap: wrap !important; + } + .flex-xl-nowrap { + flex-wrap: nowrap !important; + } + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-xl-start { + justify-content: flex-start !important; + } + .justify-content-xl-end { + justify-content: flex-end !important; + } + .justify-content-xl-center { + justify-content: center !important; + } + .justify-content-xl-between { + justify-content: space-between !important; + } + .justify-content-xl-around { + justify-content: space-around !important; + } + .justify-content-xl-evenly { + justify-content: space-evenly !important; + } + .align-items-xl-start { + align-items: flex-start !important; + } + .align-items-xl-end { + align-items: flex-end !important; + } + .align-items-xl-center { + align-items: center !important; + } + .align-items-xl-baseline { + align-items: baseline !important; + } + .align-items-xl-stretch { + align-items: stretch !important; + } + .align-content-xl-start { + align-content: flex-start !important; + } + .align-content-xl-end { + align-content: flex-end !important; + } + .align-content-xl-center { + align-content: center !important; + } + .align-content-xl-between { + align-content: space-between !important; + } + .align-content-xl-around { + align-content: space-around !important; + } + .align-content-xl-stretch { + align-content: stretch !important; + } + .align-self-xl-auto { + align-self: auto !important; + } + .align-self-xl-start { + align-self: flex-start !important; + } + .align-self-xl-end { + align-self: flex-end !important; + } + .align-self-xl-center { + align-self: center !important; + } + .align-self-xl-baseline { + align-self: baseline !important; + } + .align-self-xl-stretch { + align-self: stretch !important; + } + .order-xl-first { + order: -1 !important; + } + .order-xl-0 { + order: 0 !important; + } + .order-xl-1 { + order: 1 !important; + } + .order-xl-2 { + order: 2 !important; + } + .order-xl-3 { + order: 3 !important; + } + .order-xl-4 { + order: 4 !important; + } + .order-xl-5 { + order: 5 !important; + } + .order-xl-last { + order: 6 !important; + } + .m-xl-0 { + margin: 0 !important; + } + .m-xl-1 { + margin: 0.25rem !important; + } + .m-xl-2 { + margin: 0.5rem !important; + } + .m-xl-3 { + margin: 1rem !important; + } + .m-xl-4 { + margin: 1.5rem !important; + } + .m-xl-5 { + margin: 3rem !important; + } + .m-xl-auto { + margin: auto !important; + } + .mx-xl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-xl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-xl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-xl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-xl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-xl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-xl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-xl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-xl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-xl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-xl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-xl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-xl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-xl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-xl-0 { + margin-top: 0 !important; + } + .mt-xl-1 { + margin-top: 0.25rem !important; + } + .mt-xl-2 { + margin-top: 0.5rem !important; + } + .mt-xl-3 { + margin-top: 1rem !important; + } + .mt-xl-4 { + margin-top: 1.5rem !important; + } + .mt-xl-5 { + margin-top: 3rem !important; + } + .mt-xl-auto { + margin-top: auto !important; + } + .me-xl-0 { + margin-right: 0 !important; + } + .me-xl-1 { + margin-right: 0.25rem !important; + } + .me-xl-2 { + margin-right: 0.5rem !important; + } + .me-xl-3 { + margin-right: 1rem !important; + } + .me-xl-4 { + margin-right: 1.5rem !important; + } + .me-xl-5 { + margin-right: 3rem !important; + } + .me-xl-auto { + margin-right: auto !important; + } + .mb-xl-0 { + margin-bottom: 0 !important; + } + .mb-xl-1 { + margin-bottom: 0.25rem !important; + } + .mb-xl-2 { + margin-bottom: 0.5rem !important; + } + .mb-xl-3 { + margin-bottom: 1rem !important; + } + .mb-xl-4 { + margin-bottom: 1.5rem !important; + } + .mb-xl-5 { + margin-bottom: 3rem !important; + } + .mb-xl-auto { + margin-bottom: auto !important; + } + .ms-xl-0 { + margin-left: 0 !important; + } + .ms-xl-1 { + margin-left: 0.25rem !important; + } + .ms-xl-2 { + margin-left: 0.5rem !important; + } + .ms-xl-3 { + margin-left: 1rem !important; + } + .ms-xl-4 { + margin-left: 1.5rem !important; + } + .ms-xl-5 { + margin-left: 3rem !important; + } + .ms-xl-auto { + margin-left: auto !important; + } + .p-xl-0 { + padding: 0 !important; + } + .p-xl-1 { + padding: 0.25rem !important; + } + .p-xl-2 { + padding: 0.5rem !important; + } + .p-xl-3 { + padding: 1rem !important; + } + .p-xl-4 { + padding: 1.5rem !important; + } + .p-xl-5 { + padding: 3rem !important; + } + .px-xl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-xl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-xl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-xl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-xl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-xl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-xl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-xl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-xl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-xl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-xl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-xl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-xl-0 { + padding-top: 0 !important; + } + .pt-xl-1 { + padding-top: 0.25rem !important; + } + .pt-xl-2 { + padding-top: 0.5rem !important; + } + .pt-xl-3 { + padding-top: 1rem !important; + } + .pt-xl-4 { + padding-top: 1.5rem !important; + } + .pt-xl-5 { + padding-top: 3rem !important; + } + .pe-xl-0 { + padding-right: 0 !important; + } + .pe-xl-1 { + padding-right: 0.25rem !important; + } + .pe-xl-2 { + padding-right: 0.5rem !important; + } + .pe-xl-3 { + padding-right: 1rem !important; + } + .pe-xl-4 { + padding-right: 1.5rem !important; + } + .pe-xl-5 { + padding-right: 3rem !important; + } + .pb-xl-0 { + padding-bottom: 0 !important; + } + .pb-xl-1 { + padding-bottom: 0.25rem !important; + } + .pb-xl-2 { + padding-bottom: 0.5rem !important; + } + .pb-xl-3 { + padding-bottom: 1rem !important; + } + .pb-xl-4 { + padding-bottom: 1.5rem !important; + } + .pb-xl-5 { + padding-bottom: 3rem !important; + } + .ps-xl-0 { + padding-left: 0 !important; + } + .ps-xl-1 { + padding-left: 0.25rem !important; + } + .ps-xl-2 { + padding-left: 0.5rem !important; + } + .ps-xl-3 { + padding-left: 1rem !important; + } + .ps-xl-4 { + padding-left: 1.5rem !important; + } + .ps-xl-5 { + padding-left: 3rem !important; + } +} +@media (min-width: 1400px) { + .d-xxl-inline { + display: inline !important; + } + .d-xxl-inline-block { + display: inline-block !important; + } + .d-xxl-block { + display: block !important; + } + .d-xxl-grid { + display: grid !important; + } + .d-xxl-inline-grid { + display: inline-grid !important; + } + .d-xxl-table { + display: table !important; + } + .d-xxl-table-row { + display: table-row !important; + } + .d-xxl-table-cell { + display: table-cell !important; + } + .d-xxl-flex { + display: flex !important; + } + .d-xxl-inline-flex { + display: inline-flex !important; + } + .d-xxl-none { + display: none !important; + } + .flex-xxl-fill { + flex: 1 1 auto !important; + } + .flex-xxl-row { + flex-direction: row !important; + } + .flex-xxl-column { + flex-direction: column !important; + } + .flex-xxl-row-reverse { + flex-direction: row-reverse !important; + } + .flex-xxl-column-reverse { + flex-direction: column-reverse !important; + } + .flex-xxl-grow-0 { + flex-grow: 0 !important; + } + .flex-xxl-grow-1 { + flex-grow: 1 !important; + } + .flex-xxl-shrink-0 { + flex-shrink: 0 !important; + } + .flex-xxl-shrink-1 { + flex-shrink: 1 !important; + } + .flex-xxl-wrap { + flex-wrap: wrap !important; + } + .flex-xxl-nowrap { + flex-wrap: nowrap !important; + } + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-xxl-start { + justify-content: flex-start !important; + } + .justify-content-xxl-end { + justify-content: flex-end !important; + } + .justify-content-xxl-center { + justify-content: center !important; + } + .justify-content-xxl-between { + justify-content: space-between !important; + } + .justify-content-xxl-around { + justify-content: space-around !important; + } + .justify-content-xxl-evenly { + justify-content: space-evenly !important; + } + .align-items-xxl-start { + align-items: flex-start !important; + } + .align-items-xxl-end { + align-items: flex-end !important; + } + .align-items-xxl-center { + align-items: center !important; + } + .align-items-xxl-baseline { + align-items: baseline !important; + } + .align-items-xxl-stretch { + align-items: stretch !important; + } + .align-content-xxl-start { + align-content: flex-start !important; + } + .align-content-xxl-end { + align-content: flex-end !important; + } + .align-content-xxl-center { + align-content: center !important; + } + .align-content-xxl-between { + align-content: space-between !important; + } + .align-content-xxl-around { + align-content: space-around !important; + } + .align-content-xxl-stretch { + align-content: stretch !important; + } + .align-self-xxl-auto { + align-self: auto !important; + } + .align-self-xxl-start { + align-self: flex-start !important; + } + .align-self-xxl-end { + align-self: flex-end !important; + } + .align-self-xxl-center { + align-self: center !important; + } + .align-self-xxl-baseline { + align-self: baseline !important; + } + .align-self-xxl-stretch { + align-self: stretch !important; + } + .order-xxl-first { + order: -1 !important; + } + .order-xxl-0 { + order: 0 !important; + } + .order-xxl-1 { + order: 1 !important; + } + .order-xxl-2 { + order: 2 !important; + } + .order-xxl-3 { + order: 3 !important; + } + .order-xxl-4 { + order: 4 !important; + } + .order-xxl-5 { + order: 5 !important; + } + .order-xxl-last { + order: 6 !important; + } + .m-xxl-0 { + margin: 0 !important; + } + .m-xxl-1 { + margin: 0.25rem !important; + } + .m-xxl-2 { + margin: 0.5rem !important; + } + .m-xxl-3 { + margin: 1rem !important; + } + .m-xxl-4 { + margin: 1.5rem !important; + } + .m-xxl-5 { + margin: 3rem !important; + } + .m-xxl-auto { + margin: auto !important; + } + .mx-xxl-0 { + margin-right: 0 !important; + margin-left: 0 !important; + } + .mx-xxl-1 { + margin-right: 0.25rem !important; + margin-left: 0.25rem !important; + } + .mx-xxl-2 { + margin-right: 0.5rem !important; + margin-left: 0.5rem !important; + } + .mx-xxl-3 { + margin-right: 1rem !important; + margin-left: 1rem !important; + } + .mx-xxl-4 { + margin-right: 1.5rem !important; + margin-left: 1.5rem !important; + } + .mx-xxl-5 { + margin-right: 3rem !important; + margin-left: 3rem !important; + } + .mx-xxl-auto { + margin-right: auto !important; + margin-left: auto !important; + } + .my-xxl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-xxl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-xxl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-xxl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-xxl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-xxl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-xxl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-xxl-0 { + margin-top: 0 !important; + } + .mt-xxl-1 { + margin-top: 0.25rem !important; + } + .mt-xxl-2 { + margin-top: 0.5rem !important; + } + .mt-xxl-3 { + margin-top: 1rem !important; + } + .mt-xxl-4 { + margin-top: 1.5rem !important; + } + .mt-xxl-5 { + margin-top: 3rem !important; + } + .mt-xxl-auto { + margin-top: auto !important; + } + .me-xxl-0 { + margin-right: 0 !important; + } + .me-xxl-1 { + margin-right: 0.25rem !important; + } + .me-xxl-2 { + margin-right: 0.5rem !important; + } + .me-xxl-3 { + margin-right: 1rem !important; + } + .me-xxl-4 { + margin-right: 1.5rem !important; + } + .me-xxl-5 { + margin-right: 3rem !important; + } + .me-xxl-auto { + margin-right: auto !important; + } + .mb-xxl-0 { + margin-bottom: 0 !important; + } + .mb-xxl-1 { + margin-bottom: 0.25rem !important; + } + .mb-xxl-2 { + margin-bottom: 0.5rem !important; + } + .mb-xxl-3 { + margin-bottom: 1rem !important; + } + .mb-xxl-4 { + margin-bottom: 1.5rem !important; + } + .mb-xxl-5 { + margin-bottom: 3rem !important; + } + .mb-xxl-auto { + margin-bottom: auto !important; + } + .ms-xxl-0 { + margin-left: 0 !important; + } + .ms-xxl-1 { + margin-left: 0.25rem !important; + } + .ms-xxl-2 { + margin-left: 0.5rem !important; + } + .ms-xxl-3 { + margin-left: 1rem !important; + } + .ms-xxl-4 { + margin-left: 1.5rem !important; + } + .ms-xxl-5 { + margin-left: 3rem !important; + } + .ms-xxl-auto { + margin-left: auto !important; + } + .p-xxl-0 { + padding: 0 !important; + } + .p-xxl-1 { + padding: 0.25rem !important; + } + .p-xxl-2 { + padding: 0.5rem !important; + } + .p-xxl-3 { + padding: 1rem !important; + } + .p-xxl-4 { + padding: 1.5rem !important; + } + .p-xxl-5 { + padding: 3rem !important; + } + .px-xxl-0 { + padding-right: 0 !important; + padding-left: 0 !important; + } + .px-xxl-1 { + padding-right: 0.25rem !important; + padding-left: 0.25rem !important; + } + .px-xxl-2 { + padding-right: 0.5rem !important; + padding-left: 0.5rem !important; + } + .px-xxl-3 { + padding-right: 1rem !important; + padding-left: 1rem !important; + } + .px-xxl-4 { + padding-right: 1.5rem !important; + padding-left: 1.5rem !important; + } + .px-xxl-5 { + padding-right: 3rem !important; + padding-left: 3rem !important; + } + .py-xxl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-xxl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-xxl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-xxl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-xxl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-xxl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-xxl-0 { + padding-top: 0 !important; + } + .pt-xxl-1 { + padding-top: 0.25rem !important; + } + .pt-xxl-2 { + padding-top: 0.5rem !important; + } + .pt-xxl-3 { + padding-top: 1rem !important; + } + .pt-xxl-4 { + padding-top: 1.5rem !important; + } + .pt-xxl-5 { + padding-top: 3rem !important; + } + .pe-xxl-0 { + padding-right: 0 !important; + } + .pe-xxl-1 { + padding-right: 0.25rem !important; + } + .pe-xxl-2 { + padding-right: 0.5rem !important; + } + .pe-xxl-3 { + padding-right: 1rem !important; + } + .pe-xxl-4 { + padding-right: 1.5rem !important; + } + .pe-xxl-5 { + padding-right: 3rem !important; + } + .pb-xxl-0 { + padding-bottom: 0 !important; + } + .pb-xxl-1 { + padding-bottom: 0.25rem !important; + } + .pb-xxl-2 { + padding-bottom: 0.5rem !important; + } + .pb-xxl-3 { + padding-bottom: 1rem !important; + } + .pb-xxl-4 { + padding-bottom: 1.5rem !important; + } + .pb-xxl-5 { + padding-bottom: 3rem !important; + } + .ps-xxl-0 { + padding-left: 0 !important; + } + .ps-xxl-1 { + padding-left: 0.25rem !important; + } + .ps-xxl-2 { + padding-left: 0.5rem !important; + } + .ps-xxl-3 { + padding-left: 1rem !important; + } + .ps-xxl-4 { + padding-left: 1.5rem !important; + } + .ps-xxl-5 { + padding-left: 3rem !important; + } +} +@media print { + .d-print-inline { + display: inline !important; + } + .d-print-inline-block { + display: inline-block !important; + } + .d-print-block { + display: block !important; + } + .d-print-grid { + display: grid !important; + } + .d-print-inline-grid { + display: inline-grid !important; + } + .d-print-table { + display: table !important; + } + .d-print-table-row { + display: table-row !important; + } + .d-print-table-cell { + display: table-cell !important; + } + .d-print-flex { + display: flex !important; + } + .d-print-inline-flex { + display: inline-flex !important; + } + .d-print-none { + display: none !important; + } +} + +/*# sourceMappingURL=bootstrap-grid.css.map */ \ No newline at end of file diff --git a/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map new file mode 100644 index 0000000..ce99ec1 --- /dev/null +++ b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/mixins/_banner.scss","../../scss/_containers.scss","../../scss/mixins/_container.scss","bootstrap-grid.css","../../scss/mixins/_breakpoints.scss","../../scss/_variables.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_utilities.scss","../../scss/utilities/_api.scss"],"names":[],"mappings":"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EE,mBAAA;EJ6+BR;EI1+BM;;IAEE,mBAAA;EJ4+BR;AACF;AKpiCQ;EAOI,0BAAA;ALgiCZ;;AKviCQ;EAOI,gCAAA;ALoiCZ;;AK3iCQ;EAOI,yBAAA;ALwiCZ;;AK/iCQ;EAOI,wBAAA;AL4iCZ;;AKnjCQ;EAOI,+BAAA;ALgjCZ;;AKvjCQ;EAOI,yBAAA;ALojCZ;;AK3jCQ;EAOI,6BAAA;ALwjCZ;;AK/jCQ;EAOI,8BAAA;AL4jCZ;;AKnkCQ;EAOI,wBAAA;ALgkCZ;;AKvkCQ;EAOI,+BAAA;ALokCZ;;AK3kCQ;EAOI,wBAAA;ALwkCZ;;AK/kCQ;EAOI,yBAAA;AL4kCZ;;AKnlCQ;EAOI,8BAAA;ALglCZ;;AKvlCQ;EAOI,iCAAA;ALolCZ;;AK3lCQ;EAOI,sCAAA;ALwlCZ;;AK/lCQ;EAOI,yCAAA;AL4lCZ;;AKnmCQ;EAOI,uBAAA;ALgmCZ;;AKvmCQ;EAOI,uBAAA;ALomCZ;;AK3mCQ;EAOI,yBAAA;ALwmCZ;;AK/mCQ;EAOI,yBAAA;AL4mCZ;;AKnnCQ;EAOI,0BAAA;ALgnCZ;;AKvnCQ;EAOI,4BAAA;ALonCZ;;AK3nCQ;EAOI,kCAAA;ALwnCZ;;AK/nCQ;EAOI,sCAAA;AL4nCZ;;AKnoCQ;EAOI,oCAAA;ALgoCZ;;AKvoCQ;EAOI,kCAAA;ALooCZ;;AK3oCQ;EAOI,yCAAA;ALwoCZ;;AK/oCQ;EAOI,wCAAA;AL4oCZ;;AKnpCQ;EAOI,wCAAA;ALgpCZ;;AKvpCQ;EAOI,kCAAA;ALopCZ;;AK3pCQ;EAOI,gCAAA;ALwpCZ;;AK/pCQ;EAOI,8BAAA;AL4pCZ;;AKnqCQ;EAOI,gCAAA;ALgqCZ;;AKvqCQ;EAOI,+BAAA;ALoqCZ;;AK3qCQ;EAOI,oCAAA;ALwqCZ;;AK/qCQ;EAOI,kCAAA;AL4qCZ;;AKnrCQ;EAOI,gCAAA;ALgrCZ;;AKvrCQ;EAOI,uCAAA;ALorCZ;;AK3rCQ;EAOI,sCAAA;ALwrCZ;;AK/rCQ;EAOI,iCAAA;AL4rCZ;;AKnsCQ;EAOI,2BAAA;ALgsCZ;;AKvsCQ;EAOI,iCAAA;ALosCZ;;AK3sCQ;EAOI,+BAAA;ALwsCZ;;AK/sCQ;EAOI,6BAAA;AL4sCZ;;AKntCQ;EA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;AL8iDZ;;AKrjDQ;EAOI,4BAAA;ALkjDZ;;AKzjDQ;EAOI,2BAAA;ALsjDZ;;AK7jDQ;EAOI,iCAAA;AL0jDZ;;AKjkDQ;EAOI,gCAAA;AL8jDZ;;AKrkDQ;EAOI,8BAAA;ALkkDZ;;AKzkDQ;EAOI,gCAAA;ALskDZ;;AK7kDQ;EAOI,8BAAA;AL0kDZ;;AKjlDQ;EAOI,4BAAA;AL8kDZ;;AKrlDQ;EAOI,kCAAA;ALklDZ;;AKzlDQ;EAOI,iCAAA;ALslDZ;;AK7lDQ;EAOI,+BAAA;AL0lDZ;;AKjmDQ;EAOI,iCAAA;AL8lDZ;;AKrmDQ;EAOI,+BAAA;ALkmDZ;;AKzmDQ;EAOI,0BAAA;ALsmDZ;;AK7mDQ;EAOI,gCAAA;AL0mDZ;;AKjnDQ;EAOI,+BAAA;AL8mDZ;;AKrnDQ;EAOI,6BAAA;ALknDZ;;AKznDQ;EAOI,+BAAA;ALsnDZ;;AK7nDQ;EAOI,6BAAA;AL0nDZ;;ACpoDI;EIGI;IAOI,0BAAA;EL+nDV;EKtoDM;IAOI,gCAAA;ELkoDV;EKzoDM;IAOI,yBAAA;ELqoDV;EK5oDM;IAOI,wBAAA;ELwoDV;EK/oDM;IAOI,+BAAA;EL2oDV;EKlpDM;IAOI,yBAAA;EL8oDV;EKrpDM;IAOI,6BAAA;ELipDV;EKxpDM;IAOI,8BAAA;ELopDV;EK3pDM;IAOI,wBAAA;ELupDV;EK9pDM;IAOI,+BAAA;EL0pDV;EKjqDM;IAOI,wBAAA;EL6pDV;EKpqDM;IAOI,yBAAA;ELgqDV;EKvqDM;IAOI,8BAAA;ELmqDV;EK1qDM;IAOI,iCAAA;ELsqDV;EK7qDM;IAOI,sCAAA;ELyqDV;EKhrDM;IAOI,yCAAA;EL4qDV;EKnrDM;IAOI,uBAAA;EL+qDV;EKtrDM;IAOI,uBAAA;ELkrDV;EKzrDM;IAOI,yBAAA;ELqrDV;EK5rDM;IAOI,yBAAA;ELwrDV;EK/rDM;IAOI,0BAAA;EL2rDV;EKlsDM;IAOI,4BAAA;EL8rDV;EKrsDM;IAOI,kCAAA;ELisDV;EKxsDM;IAOI,sCAAA;ELosDV;EK3sDM;IAOI,oCAAA;ELusDV;EK9sDM;IAOI,kCAAA;EL0sDV;EKjtDM;IAOI,yCAAA;EL6sDV;EKptDM;IAOI,wCAAA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nEV;EK/nEM;IAOI,yCAAA;EL2nEV;EKloEM;IAOI,uBAAA;EL8nEV;EKroEM;IAOI,uBAAA;ELioEV;EKxoEM;IAOI,yBAAA;ELooEV;EK3oEM;IAOI,yBAAA;ELuoEV;EK9oEM;IAOI,0BAAA;EL0oEV;EKjpEM;IAOI,4BAAA;EL6oEV;EKppEM;IAOI,kCAAA;ELgpEV;EKvpEM;IAOI,sCAAA;ELmpEV;EK1pEM;IAOI,oCAAA;ELspEV;EK7pEM;IAOI,kCAAA;ELypEV;EKhqEM;IAOI,yCAAA;EL4pEV;EKnqEM;IAOI,wCAAA;EL+pEV;EKtqEM;IAOI,wCAAA;ELkqEV;EKzqEM;IAOI,kCAAA;ELqqEV;EK5qEM;IAOI,gCAAA;ELwqEV;EK/qEM;IAOI,8BAAA;EL2qEV;EKlrEM;IAOI,gCAAA;EL8qEV;EKrrEM;IAOI,+BAAA;ELirEV;EKxrEM;IAOI,oCAAA;ELorEV;EK3rEM;IAOI,kCAAA;ELurEV;EK9rEM;IAOI,gCAAA;EL0rEV;EKjsEM;IAOI,uCAAA;EL6rEV;EKpsEM;IAOI,sCAAA;ELgsEV;EKvsEM;IAOI,iCAAA;ELmsEV;EK1sEM;IAOI,2BAAA;ELssEV;EK7sEM;IAOI,iCAAA;ELysEV;EKhtEM;IAOI,+BAAA;EL4sEV;EKntEM;IAOI,6BAAA;EL+sEV;EKttEM;IAOI,+BAAA;ELktEV;EKztEM;IAOI,8BAAA;ELqtEV;EK5tEM;IAOI,oBAAA;ELwtEV;EK/tEM;IAOI,mBAAA;EL2tEV;EKluEM;IAOI,mBAAA;EL8tEV;EKruEM;IAOI,mBAAA;ELiuEV;EKxuEM;IAOI,mBAAA;ELouEV;EK3uEM;IAOI,mBAAA;ELuuEV;EK9uEM;IAOI,mBAAA;EL0uEV;EKjvEM;IAOI,mBAAA;EL6uEV;EKpvEM;IAOI,oBAAA;ELgvEV;EKvvEM;IAOI,0BAAA;ELmvEV;EK1vEM;IAOI,yBAAA;ELsvEV;EK7vEM;IAOI,uBAAA;ELyvEV;EKhwEM;IAOI,yBAAA;EL4vEV;EKnwEM;IAOI,uBAAA;EL+vEV;EKtwEM;IAOI,uBAAA;ELkwEV;EKzwEM;IAOI,0BAAA;IAAA,yBAAA;ELswEV;EK7wEM;IAO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EKviFM;IAOI,yBAAA;ELmiFV;EK1iFM;IAOI,wBAAA;ELsiFV;EK7iFM;IAOI,+BAAA;ELyiFV;EKhjFM;IAOI,yBAAA;EL4iFV;EKnjFM;IAOI,6BAAA;EL+iFV;EKtjFM;IAOI,8BAAA;ELkjFV;EKzjFM;IAOI,wBAAA;ELqjFV;EK5jFM;IAOI,+BAAA;ELwjFV;EK/jFM;IAOI,wBAAA;EL2jFV;EKlkFM;IAOI,yBAAA;EL8jFV;EKrkFM;IAOI,8BAAA;ELikFV;EKxkFM;IAOI,iCAAA;ELokFV;EK3kFM;IAOI,sCAAA;ELukFV;EK9kFM;IAOI,yCAAA;EL0kFV;EKjlFM;IAOI,uBAAA;EL6kFV;EKplFM;IAOI,uBAAA;ELglFV;EKvlFM;IAOI,yBAAA;ELmlFV;EK1lFM;IAOI,yBAAA;ELslFV;EK7lFM;IAOI,0BAAA;ELylFV;EKhmFM;IAOI,4BAAA;EL4lFV;EKnmFM;IAOI,kCAAA;EL+lFV;EKtmFM;IAOI,sCAAA;ELkmFV;EKzmFM;IAOI,oCAAA;ELqmFV;EK5mFM;IAOI,kCAAA;ELwmFV;EK/mFM;IAOI,yCAAA;EL2mFV;EKlnFM;IAOI,wCAAA;EL8mFV;EKrnFM;IAOI,wCAAA;ELinFV;EKxnFM;IAOI,kCAAA;ELonFV;EK3nFM;IAOI,gCAAA;ELunFV;EK9nFM;IAOI,8BAAA;EL0nFV;EKjoFM;IAOI,gCAAA;EL6nFV;EKpoFM;IAOI,+BAAA;ELgoFV;EKvoFM;IAOI,oCAAA;ELmoFV;EK1oFM;IAOI,kCAAA;ELsoFV;EK7oFM;IAOI,gCAAA;ELyoFV;EKhpFM;IAOI,uCAAA;EL4oFV;EKnpFM;IAOI,sCAAA;EL+oFV;EKtpFM;IAOI,iCAAA;ELkpFV;EKzpFM;IAOI,2BAAA;ELqpFV;EK5pFM;IAOI,iCAAA;ELwpFV;EK/pFM;IAOI,+BAAA;EL2pFV;EKlqFM;IAOI,6BAAA;EL8pFV;EKrqFM;IAOI,+BAAA;ELiqFV;EKxqFM;IAOI,8BAAA;ELoqFV;EK3qFM;IAOI,oBAAA;ELuqFV;EK9qFM;IAOI,mBAAA;EL0qFV;EKjrFM;IAOI,mBAAA;EL6qFV;EKprFM;IAOI,mBAAA;ELgrFV;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AAA;ELy8FV;EKh9FM;IAOI,iCAAA;EL48FV;EKn9FM;IAOI,+BAAA;EL+8FV;EKt9FM;IAOI,iCAAA;ELk9FV;EKz9FM;IAOI,+BAAA;ELq9FV;EK59FM;IAOI,0BAAA;ELw9FV;EK/9FM;IAOI,gCAAA;EL29FV;EKl+FM;IAOI,+BAAA;EL89FV;EKr+FM;IAOI,6BAAA;ELi+FV;EKx+FM;IAOI,+BAAA;ELo+FV;EK3+FM;IAOI,6BAAA;ELu+FV;AACF;ACl/FI;EIGI;IAOI,0BAAA;EL4+FV;EKn/FM;IAOI,gCAAA;EL++FV;EKt/FM;IAOI,yBAAA;ELk/FV;EKz/FM;IAOI,wBAAA;ELq/FV;EK5/FM;IAOI,+BAAA;ELw/FV;EK//FM;IAOI,yBAAA;EL2/FV;EKlgGM;IAOI,6BAAA;EL8/FV;EKrgGM;IAOI,8BAAA;ELigGV;EKxgGM;IAOI,wBAAA;ELogGV;EK3gGM;IAOI,+BAAA;ELugGV;EK9gGM;IAOI,wBAAA;EL0gGV;EKjhGM;IAOI,yBAAA;EL6gGV;EKphGM;IAOI,8BAAA;ELghGV;EKvhGM;IAOI,iCAAA;ELmhGV;EK1hGM;IAOI,sCAAA;ELshGV;EK7hGM;IAOI,yCAAA;ELyhGV;EKhiGM;IAOI,uBAAA;EL4hGV;EKniGM;IAOI,uBAAA;EL+hGV;EKtiGM;IAOI,yBAAA;ELkiGV;EKziGM;IAOI,yBAAA;ELqiGV;EK5iGM;IAOI,0BAAA;ELwiGV;EK/iGM;IAOI,4BAAA;EL2iGV;EKljGM;IAOI,kCAAA;EL8iGV;EKrjGM;IAOI,sCAAA;ELijGV;EKxjGM;IAOI,oCAAA;ELojGV;EK3jGM;IAOI,kCAAA;ELujGV;EK9jGM;IAOI,yCAAA;EL0jGV;EKjkGM;IAOI,wCAAA;EL6jGV;EKpkGM;IAOI,wCAAA;ELgkGV;EKvkGM;IAOI,kCAAA;ELmkGV;EK1kGM;IAOI,gCAAA;ELskGV;EK7kGM;IAOI,8BAAA;ELykGV;EKhlGM;IAOI,gCAAA;EL4kGV;EKnlGM;IAOI,+BAAA;EL+kGV;EKtlGM;IAOI,oCAAA;ELklGV;EKzlGM;IAOI,kCAAA;ELqlGV;EK5lGM;IAOI,gCAAA;ELwlGV;EK/l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ELi3GV;EKx3GM;IAOI,+BAAA;ELo3GV;EK33GM;IAOI,8BAAA;ELu3GV;EK93GM;IAOI,4BAAA;EL03GV;EKj4GM;IAOI,8BAAA;EL63GV;EKp4GM;IAOI,4BAAA;ELg4GV;EKv4GM;IAOI,2BAAA;ELm4GV;EK14GM;IAOI,iCAAA;ELs4GV;EK74GM;IAOI,gCAAA;ELy4GV;EKh5GM;IAOI,8BAAA;EL44GV;EKn5GM;IAOI,gCAAA;EL+4GV;EKt5GM;IAOI,8BAAA;ELk5GV;EKz5GM;IAOI,4BAAA;ELq5GV;EK55GM;IAOI,kCAAA;ELw5GV;EK/5GM;IAOI,iCAAA;EL25GV;EKl6GM;IAOI,+BAAA;EL85GV;EKr6GM;IAOI,iCAAA;ELi6GV;EKx6GM;IAOI,+BAAA;ELo6GV;EK36GM;IAOI,0BAAA;ELu6GV;EK96GM;IAOI,gCAAA;EL06GV;EKj7GM;IAOI,+BAAA;EL66GV;EKp7GM;IAOI,6BAAA;ELg7GV;EKv7GM;IAOI,+BAAA;ELm7GV;EK17GM;IAOI,6BAAA;ELs7GV;AACF;ACj8GI;EIGI;IAOI,0BAAA;EL27GV;EKl8GM;IAOI,gCAAA;EL87GV;EKr8GM;IAOI,yBAAA;ELi8GV;EKx8GM;IAOI,wBAAA;ELo8GV;EK38GM;IAOI,+BAAA;ELu8GV;EK98GM;IAOI,yBAAA;EL08GV;EKj9GM;IAOI,6BAAA;EL68GV;EKp9GM;IAOI,8BAAA;ELg9GV;EKv9GM;IAOI,wBAAA;ELm9GV;EK19GM;IAOI,+BAAA;ELs9GV;EK79GM;IAOI,wBAAA;ELy9GV;EKh+GM;IAOI,yBAAA;EL49GV;EKn+GM;IAOI,8BAAA;EL+9GV;EKt+GM;IAOI,iCAAA;ELk+GV;EKz+GM;IAOI,sCAAA;ELq+GV;EK5+GM;IAOI,yCAAA;ELw+GV;EK/+GM;IAOI,uBAAA;EL2+GV;EKl/GM;IAOI,uBAAA;EL8+GV;EKr/GM;IAOI,yBAAA;ELi/GV;EKx/GM;IAOI,yBAAA;ELo/GV;EK3/GM;IAOI,0BAAA;ELu/GV;EK9/GM;IAOI,4BAAA;EL0/GV;EKjgHM;IAOI,kCAAA;EL6/GV;EKpgHM;IAOI,sCAAA;ELggHV;EKvgHM;I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","file":"bootstrap-grid.css","sourcesContent":["@mixin bsBanner($file) {\n /*!\n * Bootstrap #{$file} v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-container-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n","// Container mixins\n\n@mixin make-container($gutter: $container-padding-x) {\n --#{$prefix}gutter-x: #{$gutter};\n --#{$prefix}gutter-y: 0;\n width: 100%;\n padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n margin-right: auto;\n margin-left: auto;\n}\n","/*!\n * Bootstrap Grid v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n --bs-gutter-x: 1.5rem;\n --bs-gutter-y: 0;\n width: 100%;\n padding-right: calc(var(--bs-gutter-x) * 0.5);\n padding-left: calc(var(--bs-gutter-x) * 0.5);\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container-sm, .container {\n max-width: 540px;\n }\n}\n@media (min-width: 768px) {\n .container-md, .container-sm, .container {\n max-width: 720px;\n }\n}\n@media (min-width: 992px) {\n .container-lg, .container-md, .container-sm, .container {\n max-width: 960px;\n }\n}\n@media (min-width: 1200px) {\n .container-xl, .container-lg, .container-md, .container-sm, .container {\n max-width: 1140px;\n }\n}\n@media (min-width: 1400px) {\n .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n max-width: 1320px;\n }\n}\n:root {\n --bs-breakpoint-xs: 0;\n --bs-breakpoint-sm: 576px;\n --bs-breakpoint-md: 768px;\n --bs-breakpoint-lg: 992px;\n --bs-breakpoint-xl: 1200px;\n --bs-breakpoint-xxl: 1400px;\n}\n\n.row {\n --bs-gutter-x: 1.5rem;\n --bs-gutter-y: 0;\n display: flex;\n flex-wrap: wrap;\n margin-top: calc(-1 * var(--bs-gutter-y));\n margin-right: calc(-0.5 * var(--bs-gutter-x));\n margin-left: calc(-0.5 * var(--bs-gutter-x));\n}\n.row > * {\n box-sizing: border-box;\n flex-shrink: 0;\n width: 100%;\n max-width: 100%;\n padding-right: calc(var(--bs-gutter-x) * 0.5);\n padding-left: calc(var(--bs-gutter-x) * 0.5);\n margin-top: var(--bs-gutter-y);\n}\n\n.col {\n flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n flex: 0 0 auto;\n width: auto;\n}\n\n.row-cols-1 > * {\n flex: 0 0 auto;\n width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 auto;\n width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 auto;\n width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 auto;\n width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n}\n\n.col-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n}\n\n.col-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n}\n\n.col-3 {\n flex: 0 0 auto;\n width: 25%;\n}\n\n.col-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n}\n\n.col-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n}\n\n.col-6 {\n flex: 0 0 auto;\n width: 50%;\n}\n\n.col-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n}\n\n.col-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n}\n\n.col-9 {\n flex: 0 0 auto;\n width: 75%;\n}\n\n.col-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n}\n\n.col-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n}\n\n.col-12 {\n flex: 0 0 auto;\n width: 100%;\n}\n\n.offset-1 {\n margin-left: 8.33333333%;\n}\n\n.offset-2 {\n margin-left: 16.66666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.33333333%;\n}\n\n.offset-5 {\n margin-left: 41.66666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.33333333%;\n}\n\n.offset-8 {\n margin-left: 66.66666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.33333333%;\n}\n\n.offset-11 {\n margin-left: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex: 1 0 0%;\n }\n .row-cols-sm-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-sm-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-sm-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-sm-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-sm-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-sm-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-sm-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-sm-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-sm-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-sm-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.33333333%;\n }\n .offset-sm-2 {\n margin-left: 16.66666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.33333333%;\n }\n .offset-sm-5 {\n margin-left: 41.66666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.33333333%;\n }\n .offset-sm-8 {\n margin-left: 66.66666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.33333333%;\n }\n .offset-sm-11 {\n margin-left: 91.66666667%;\n }\n .g-sm-0,\n .gx-sm-0 {\n --bs-gutter-x: 0;\n }\n .g-sm-0,\n .gy-sm-0 {\n --bs-gutter-y: 0;\n }\n .g-sm-1,\n .gx-sm-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-sm-1,\n .gy-sm-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-sm-2,\n .gx-sm-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-sm-2,\n .gy-sm-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-sm-3,\n .gx-sm-3 {\n --bs-gutter-x: 1rem;\n }\n .g-sm-3,\n .gy-sm-3 {\n --bs-gutter-y: 1rem;\n }\n .g-sm-4,\n .gx-sm-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-sm-4,\n .gy-sm-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-sm-5,\n .gx-sm-5 {\n --bs-gutter-x: 3rem;\n }\n .g-sm-5,\n .gy-sm-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 768px) {\n .col-md {\n flex: 1 0 0%;\n }\n .row-cols-md-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-md-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-md-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-md-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-md-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-md-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-md-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-md-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-md-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-md-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-md-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-md-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-md-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-md-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.33333333%;\n }\n .offset-md-2 {\n margin-left: 16.66666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.33333333%;\n }\n .offset-md-5 {\n margin-left: 41.66666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.33333333%;\n }\n .offset-md-8 {\n margin-left: 66.66666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.33333333%;\n }\n .offset-md-11 {\n margin-left: 91.66666667%;\n }\n .g-md-0,\n .gx-md-0 {\n --bs-gutter-x: 0;\n }\n .g-md-0,\n .gy-md-0 {\n --bs-gutter-y: 0;\n }\n .g-md-1,\n .gx-md-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-md-1,\n .gy-md-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-md-2,\n .gx-md-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-md-2,\n .gy-md-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-md-3,\n .gx-md-3 {\n --bs-gutter-x: 1rem;\n }\n .g-md-3,\n .gy-md-3 {\n --bs-gutter-y: 1rem;\n }\n .g-md-4,\n .gx-md-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-md-4,\n .gy-md-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-md-5,\n .gx-md-5 {\n --bs-gutter-x: 3rem;\n }\n .g-md-5,\n .gy-md-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 992px) {\n .col-lg {\n flex: 1 0 0%;\n }\n .row-cols-lg-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-lg-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-lg-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-lg-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-lg-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-lg-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-lg-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-lg-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-lg-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-lg-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.33333333%;\n }\n .offset-lg-2 {\n margin-left: 16.66666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.33333333%;\n }\n .offset-lg-5 {\n margin-left: 41.66666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.33333333%;\n }\n .offset-lg-8 {\n margin-left: 66.66666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.33333333%;\n }\n .offset-lg-11 {\n margin-left: 91.66666667%;\n }\n .g-lg-0,\n .gx-lg-0 {\n --bs-gutter-x: 0;\n }\n .g-lg-0,\n .gy-lg-0 {\n --bs-gutter-y: 0;\n }\n .g-lg-1,\n .gx-lg-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-lg-1,\n .gy-lg-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-lg-2,\n .gx-lg-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-lg-2,\n .gy-lg-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-lg-3,\n .gx-lg-3 {\n --bs-gutter-x: 1rem;\n }\n .g-lg-3,\n .gy-lg-3 {\n --bs-gutter-y: 1rem;\n }\n .g-lg-4,\n .gx-lg-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-lg-4,\n .gy-lg-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-lg-5,\n .gx-lg-5 {\n --bs-gutter-x: 3rem;\n }\n .g-lg-5,\n .gy-lg-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 1200px) {\n .col-xl {\n flex: 1 0 0%;\n }\n .row-cols-xl-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-xl-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-xl-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xl-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-xl-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-xl-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-xl-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-xl-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-xl-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-xl-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.33333333%;\n }\n .offset-xl-2 {\n margin-left: 16.66666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.33333333%;\n }\n .offset-xl-5 {\n margin-left: 41.66666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.33333333%;\n }\n .offset-xl-8 {\n margin-left: 66.66666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.33333333%;\n }\n .offset-xl-11 {\n margin-left: 91.66666667%;\n }\n .g-xl-0,\n .gx-xl-0 {\n --bs-gutter-x: 0;\n }\n .g-xl-0,\n .gy-xl-0 {\n --bs-gutter-y: 0;\n }\n .g-xl-1,\n .gx-xl-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-xl-1,\n .gy-xl-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-xl-2,\n .gx-xl-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-xl-2,\n .gy-xl-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-xl-3,\n .gx-xl-3 {\n --bs-gutter-x: 1rem;\n }\n .g-xl-3,\n .gy-xl-3 {\n --bs-gutter-y: 1rem;\n }\n .g-xl-4,\n .gx-xl-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-xl-4,\n .gy-xl-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-xl-5,\n .gx-xl-5 {\n --bs-gutter-x: 3rem;\n }\n .g-xl-5,\n .gy-xl-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 1400px) {\n .col-xxl {\n flex: 1 0 0%;\n }\n .row-cols-xxl-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-xxl-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-xxl-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-xxl-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-xxl-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-xxl-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-xxl-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xxl-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-xxl-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-xxl-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xxl-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-xxl-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-xxl-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-xxl-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-xxl-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-xxl-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-xxl-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-xxl-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-xxl-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-xxl-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-xxl-0 {\n margin-left: 0;\n }\n .offset-xxl-1 {\n margin-left: 8.33333333%;\n }\n .offset-xxl-2 {\n margin-left: 16.66666667%;\n }\n .offset-xxl-3 {\n margin-left: 25%;\n }\n .offset-xxl-4 {\n margin-left: 33.33333333%;\n }\n .offset-xxl-5 {\n margin-left: 41.66666667%;\n }\n .offset-xxl-6 {\n margin-left: 50%;\n }\n .offset-xxl-7 {\n margin-left: 58.33333333%;\n }\n .offset-xxl-8 {\n margin-left: 66.66666667%;\n }\n .offset-xxl-9 {\n margin-left: 75%;\n }\n .offset-xxl-10 {\n margin-left: 83.33333333%;\n }\n .offset-xxl-11 {\n margin-left: 91.66666667%;\n }\n .g-xxl-0,\n .gx-xxl-0 {\n --bs-gutter-x: 0;\n }\n .g-xxl-0,\n .gy-xxl-0 {\n --bs-gutter-y: 0;\n }\n .g-xxl-1,\n .gx-xxl-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-xxl-1,\n .gy-xxl-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-xxl-2,\n .gx-xxl-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-xxl-2,\n .gy-xxl-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-xxl-3,\n .gx-xxl-3 {\n --bs-gutter-x: 1rem;\n }\n .g-xxl-3,\n .gy-xxl-3 {\n --bs-gutter-y: 1rem;\n }\n .g-xxl-4,\n .gx-xxl-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-xxl-4,\n .gy-xxl-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-xxl-5,\n .gx-xxl-5 {\n --bs-gutter-x: 3rem;\n }\n .g-xxl-5,\n .gy-xxl-5 {\n --bs-gutter-y: 3rem;\n }\n}\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-grid {\n display: grid !important;\n}\n\n.d-inline-grid {\n display: inline-grid !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n.d-none {\n display: none !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n justify-content: space-evenly !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n.order-first {\n order: -1 !important;\n}\n\n.order-0 {\n order: 0 !important;\n}\n\n.order-1 {\n order: 1 !important;\n}\n\n.order-2 {\n order: 2 !important;\n}\n\n.order-3 {\n order: 3 !important;\n}\n\n.order-4 {\n order: 4 !important;\n}\n\n.order-5 {\n order: 5 !important;\n}\n\n.order-last {\n order: 6 !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mx-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n}\n\n.mx-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n}\n\n.mx-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n}\n\n.mx-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n}\n\n.mx-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n}\n\n.mx-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n}\n\n.my-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n}\n\n.my-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n}\n\n.my-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n}\n\n.my-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n}\n\n.mt-0 {\n margin-top: 0 !important;\n}\n\n.mt-1 {\n margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n margin-top: 1rem !important;\n}\n\n.mt-4 {\n margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n margin-top: 3rem !important;\n}\n\n.mt-auto {\n margin-top: auto !important;\n}\n\n.me-0 {\n margin-right: 0 !important;\n}\n\n.me-1 {\n margin-right: 0.25rem !important;\n}\n\n.me-2 {\n margin-right: 0.5rem !important;\n}\n\n.me-3 {\n margin-right: 1rem !important;\n}\n\n.me-4 {\n margin-right: 1.5rem !important;\n}\n\n.me-5 {\n margin-right: 3rem !important;\n}\n\n.me-auto {\n margin-right: auto !important;\n}\n\n.mb-0 {\n margin-bottom: 0 !important;\n}\n\n.mb-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n margin-bottom: auto !important;\n}\n\n.ms-0 {\n margin-left: 0 !important;\n}\n\n.ms-1 {\n margin-left: 0.25rem !important;\n}\n\n.ms-2 {\n margin-left: 0.5rem !important;\n}\n\n.ms-3 {\n margin-left: 1rem !important;\n}\n\n.ms-4 {\n margin-left: 1.5rem !important;\n}\n\n.ms-5 {\n margin-left: 3rem !important;\n}\n\n.ms-auto {\n margin-left: auto !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.px-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n}\n\n.px-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n}\n\n.px-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n}\n\n.px-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n}\n\n.px-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n}\n\n.px-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n}\n\n.py-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n}\n\n.py-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n}\n\n.py-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n padding-top: 0 !important;\n}\n\n.pt-1 {\n padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n padding-top: 1rem !important;\n}\n\n.pt-4 {\n padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n padding-top: 3rem !important;\n}\n\n.pe-0 {\n padding-right: 0 !important;\n}\n\n.pe-1 {\n padding-right: 0.25rem !important;\n}\n\n.pe-2 {\n padding-right: 0.5rem !important;\n}\n\n.pe-3 {\n padding-right: 1rem !important;\n}\n\n.pe-4 {\n padding-right: 1.5rem !important;\n}\n\n.pe-5 {\n padding-right: 3rem !important;\n}\n\n.pb-0 {\n padding-bottom: 0 !important;\n}\n\n.pb-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n padding-left: 0 !important;\n}\n\n.ps-1 {\n padding-left: 0.25rem !important;\n}\n\n.ps-2 {\n padding-left: 0.5rem !important;\n}\n\n.ps-3 {\n padding-left: 1rem !important;\n}\n\n.ps-4 {\n padding-left: 1.5rem !important;\n}\n\n.ps-5 {\n padding-left: 3rem !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-grid {\n display: grid !important;\n }\n .d-sm-inline-grid {\n display: inline-grid !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n .d-sm-none {\n display: none !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .justify-content-sm-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n .order-sm-first {\n order: -1 !important;\n }\n .order-sm-0 {\n order: 0 !important;\n }\n .order-sm-1 {\n order: 1 !important;\n }\n .order-sm-2 {\n order: 2 !important;\n }\n .order-sm-3 {\n order: 3 !important;\n }\n .order-sm-4 {\n order: 4 !important;\n }\n .order-sm-5 {\n order: 5 !important;\n }\n .order-sm-last {\n order: 6 !important;\n }\n .m-sm-0 {\n margin: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mx-sm-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-sm-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-sm-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-sm-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-sm-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-sm-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-sm-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-sm-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-sm-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-sm-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-sm-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-sm-0 {\n margin-top: 0 !important;\n }\n .mt-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mt-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mt-sm-3 {\n margin-top: 1rem !important;\n }\n .mt-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mt-sm-5 {\n margin-top: 3rem !important;\n }\n .mt-sm-auto {\n margin-top: auto !important;\n }\n .me-sm-0 {\n margin-right: 0 !important;\n }\n .me-sm-1 {\n margin-right: 0.25rem !important;\n }\n .me-sm-2 {\n margin-right: 0.5rem !important;\n }\n .me-sm-3 {\n margin-right: 1rem !important;\n }\n .me-sm-4 {\n margin-right: 1.5rem !important;\n }\n .me-sm-5 {\n margin-right: 3rem !important;\n }\n .me-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-0 {\n margin-bottom: 0 !important;\n }\n .mb-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-sm-3 {\n margin-bottom: 1rem !important;\n }\n .mb-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-sm-5 {\n margin-bottom: 3rem !important;\n }\n .mb-sm-auto {\n margin-bottom: auto !important;\n }\n .ms-sm-0 {\n margin-left: 0 !important;\n }\n .ms-sm-1 {\n margin-left: 0.25rem !important;\n }\n .ms-sm-2 {\n margin-left: 0.5rem !important;\n }\n .ms-sm-3 {\n margin-left: 1rem !important;\n }\n .ms-sm-4 {\n margin-left: 1.5rem !important;\n }\n .ms-sm-5 {\n margin-left: 3rem !important;\n }\n .ms-sm-auto {\n margin-left: auto !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .px-sm-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-sm-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-sm-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-sm-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-sm-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-sm-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-sm-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-sm-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-sm-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-sm-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-sm-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-sm-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-sm-0 {\n padding-top: 0 !important;\n }\n .pt-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pt-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pt-sm-3 {\n padding-top: 1rem !important;\n }\n .pt-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pt-sm-5 {\n padding-top: 3rem !important;\n }\n .pe-sm-0 {\n padding-right: 0 !important;\n }\n .pe-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pe-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pe-sm-3 {\n padding-right: 1rem !important;\n }\n .pe-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pe-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-0 {\n padding-bottom: 0 !important;\n }\n .pb-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pb-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-sm-5 {\n padding-bottom: 3rem !important;\n }\n .ps-sm-0 {\n padding-left: 0 !important;\n }\n .ps-sm-1 {\n padding-left: 0.25rem !important;\n }\n .ps-sm-2 {\n padding-left: 0.5rem !important;\n }\n .ps-sm-3 {\n padding-left: 1rem !important;\n }\n .ps-sm-4 {\n padding-left: 1.5rem !important;\n }\n .ps-sm-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 768px) {\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-grid {\n display: grid !important;\n }\n .d-md-inline-grid {\n display: inline-grid !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n .d-md-none {\n display: none !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .justify-content-md-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n .order-md-first {\n order: -1 !important;\n }\n .order-md-0 {\n order: 0 !important;\n }\n .order-md-1 {\n order: 1 !important;\n }\n .order-md-2 {\n order: 2 !important;\n }\n .order-md-3 {\n order: 3 !important;\n }\n .order-md-4 {\n order: 4 !important;\n }\n .order-md-5 {\n order: 5 !important;\n }\n .order-md-last {\n order: 6 !important;\n }\n .m-md-0 {\n margin: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mx-md-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-md-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-md-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-md-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-md-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-md-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-md-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-md-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-md-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-md-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-md-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-md-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-md-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-md-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-md-0 {\n margin-top: 0 !important;\n }\n .mt-md-1 {\n margin-top: 0.25rem !important;\n }\n .mt-md-2 {\n margin-top: 0.5rem !important;\n }\n .mt-md-3 {\n margin-top: 1rem !important;\n }\n .mt-md-4 {\n margin-top: 1.5rem !important;\n }\n .mt-md-5 {\n margin-top: 3rem !important;\n }\n .mt-md-auto {\n margin-top: auto !important;\n }\n .me-md-0 {\n margin-right: 0 !important;\n }\n .me-md-1 {\n margin-right: 0.25rem !important;\n }\n .me-md-2 {\n margin-right: 0.5rem !important;\n }\n .me-md-3 {\n margin-right: 1rem !important;\n }\n .me-md-4 {\n margin-right: 1.5rem !important;\n }\n .me-md-5 {\n margin-right: 3rem !important;\n }\n .me-md-auto {\n margin-right: auto !important;\n }\n .mb-md-0 {\n margin-bottom: 0 !important;\n }\n .mb-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-md-3 {\n margin-bottom: 1rem !important;\n }\n .mb-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-md-5 {\n margin-bottom: 3rem !important;\n }\n .mb-md-auto {\n margin-bottom: auto !important;\n }\n .ms-md-0 {\n margin-left: 0 !important;\n }\n .ms-md-1 {\n margin-left: 0.25rem !important;\n }\n .ms-md-2 {\n margin-left: 0.5rem !important;\n }\n .ms-md-3 {\n margin-left: 1rem !important;\n }\n .ms-md-4 {\n margin-left: 1.5rem !important;\n }\n .ms-md-5 {\n margin-left: 3rem !important;\n }\n .ms-md-auto {\n margin-left: auto !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .px-md-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-md-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-md-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-md-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-md-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-md-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-md-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-md-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-md-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-md-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-md-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-md-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-md-0 {\n padding-top: 0 !important;\n }\n .pt-md-1 {\n padding-top: 0.25rem !important;\n }\n .pt-md-2 {\n padding-top: 0.5rem !important;\n }\n .pt-md-3 {\n padding-top: 1rem !important;\n }\n .pt-md-4 {\n padding-top: 1.5rem !important;\n }\n .pt-md-5 {\n padding-top: 3rem !important;\n }\n .pe-md-0 {\n padding-right: 0 !important;\n }\n .pe-md-1 {\n padding-right: 0.25rem !important;\n }\n .pe-md-2 {\n padding-right: 0.5rem !important;\n }\n .pe-md-3 {\n padding-right: 1rem !important;\n }\n .pe-md-4 {\n padding-right: 1.5rem !important;\n }\n .pe-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-0 {\n padding-bottom: 0 !important;\n }\n .pb-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-md-3 {\n padding-bottom: 1rem !important;\n }\n .pb-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-md-5 {\n padding-bottom: 3rem !important;\n }\n .ps-md-0 {\n padding-left: 0 !important;\n }\n .ps-md-1 {\n padding-left: 0.25rem !important;\n }\n .ps-md-2 {\n padding-left: 0.5rem !important;\n }\n .ps-md-3 {\n padding-left: 1rem !important;\n }\n .ps-md-4 {\n padding-left: 1.5rem !important;\n }\n .ps-md-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 992px) {\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-grid {\n display: grid !important;\n }\n .d-lg-inline-grid {\n display: inline-grid !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n .d-lg-none {\n display: none !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .justify-content-lg-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n .order-lg-first {\n order: -1 !important;\n }\n .order-lg-0 {\n order: 0 !important;\n }\n .order-lg-1 {\n order: 1 !important;\n }\n .order-lg-2 {\n order: 2 !important;\n }\n .order-lg-3 {\n order: 3 !important;\n }\n .order-lg-4 {\n order: 4 !important;\n }\n .order-lg-5 {\n order: 5 !important;\n }\n .order-lg-last {\n order: 6 !important;\n }\n .m-lg-0 {\n margin: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mx-lg-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-lg-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-lg-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-lg-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-lg-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-lg-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-lg-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-lg-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-lg-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-lg-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-lg-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-lg-0 {\n margin-top: 0 !important;\n }\n .mt-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mt-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mt-lg-3 {\n margin-top: 1rem !important;\n }\n .mt-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mt-lg-5 {\n margin-top: 3rem !important;\n }\n .mt-lg-auto {\n margin-top: auto !important;\n }\n .me-lg-0 {\n margin-right: 0 !important;\n }\n .me-lg-1 {\n margin-right: 0.25rem !important;\n }\n .me-lg-2 {\n margin-right: 0.5rem !important;\n }\n .me-lg-3 {\n margin-right: 1rem !important;\n }\n .me-lg-4 {\n margin-right: 1.5rem !important;\n }\n .me-lg-5 {\n margin-right: 3rem !important;\n }\n .me-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-0 {\n margin-bottom: 0 !important;\n }\n .mb-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-lg-3 {\n margin-bottom: 1rem !important;\n }\n .mb-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-lg-5 {\n margin-bottom: 3rem !important;\n }\n .mb-lg-auto {\n margin-bottom: auto !important;\n }\n .ms-lg-0 {\n margin-left: 0 !important;\n }\n .ms-lg-1 {\n margin-left: 0.25rem !important;\n }\n .ms-lg-2 {\n margin-left: 0.5rem !important;\n }\n .ms-lg-3 {\n margin-left: 1rem !important;\n }\n .ms-lg-4 {\n margin-left: 1.5rem !important;\n }\n .ms-lg-5 {\n margin-left: 3rem !important;\n }\n .ms-lg-auto {\n margin-left: auto !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .px-lg-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-lg-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-lg-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-lg-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-lg-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-lg-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-lg-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-lg-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-lg-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-lg-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-lg-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-lg-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-lg-0 {\n padding-top: 0 !important;\n }\n .pt-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pt-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pt-lg-3 {\n padding-top: 1rem !important;\n }\n .pt-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pt-lg-5 {\n padding-top: 3rem !important;\n }\n .pe-lg-0 {\n padding-right: 0 !important;\n }\n .pe-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pe-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pe-lg-3 {\n padding-right: 1rem !important;\n }\n .pe-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pe-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-0 {\n padding-bottom: 0 !important;\n }\n .pb-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pb-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-lg-5 {\n padding-bottom: 3rem !important;\n }\n .ps-lg-0 {\n padding-left: 0 !important;\n }\n .ps-lg-1 {\n padding-left: 0.25rem !important;\n }\n .ps-lg-2 {\n padding-left: 0.5rem !important;\n }\n .ps-lg-3 {\n padding-left: 1rem !important;\n }\n .ps-lg-4 {\n padding-left: 1.5rem !important;\n }\n .ps-lg-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 1200px) {\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-grid {\n display: grid !important;\n }\n .d-xl-inline-grid {\n display: inline-grid !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n .d-xl-none {\n display: none !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .justify-content-xl-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n .order-xl-first {\n order: -1 !important;\n }\n .order-xl-0 {\n order: 0 !important;\n }\n .order-xl-1 {\n order: 1 !important;\n }\n .order-xl-2 {\n order: 2 !important;\n }\n .order-xl-3 {\n order: 3 !important;\n }\n .order-xl-4 {\n order: 4 !important;\n }\n .order-xl-5 {\n order: 5 !important;\n }\n .order-xl-last {\n order: 6 !important;\n }\n .m-xl-0 {\n margin: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mx-xl-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-xl-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-xl-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-xl-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-xl-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-xl-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-xl-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-xl-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-xl-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-xl-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-xl-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-xl-0 {\n margin-top: 0 !important;\n }\n .mt-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mt-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mt-xl-3 {\n margin-top: 1rem !important;\n }\n .mt-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mt-xl-5 {\n margin-top: 3rem !important;\n }\n .mt-xl-auto {\n margin-top: auto !important;\n }\n .me-xl-0 {\n margin-right: 0 !important;\n }\n .me-xl-1 {\n margin-right: 0.25rem !important;\n }\n .me-xl-2 {\n margin-right: 0.5rem !important;\n }\n .me-xl-3 {\n margin-right: 1rem !important;\n }\n .me-xl-4 {\n margin-right: 1.5rem !important;\n }\n .me-xl-5 {\n margin-right: 3rem !important;\n }\n .me-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-0 {\n margin-bottom: 0 !important;\n }\n .mb-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-xl-3 {\n margin-bottom: 1rem !important;\n }\n .mb-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-xl-5 {\n margin-bottom: 3rem !important;\n }\n .mb-xl-auto {\n margin-bottom: auto !important;\n }\n .ms-xl-0 {\n margin-left: 0 !important;\n }\n .ms-xl-1 {\n margin-left: 0.25rem !important;\n }\n .ms-xl-2 {\n margin-left: 0.5rem !important;\n }\n .ms-xl-3 {\n margin-left: 1rem !important;\n }\n .ms-xl-4 {\n margin-left: 1.5rem !important;\n }\n .ms-xl-5 {\n margin-left: 3rem !important;\n }\n .ms-xl-auto {\n margin-left: auto !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .px-xl-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-xl-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-xl-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-xl-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-xl-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-xl-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-xl-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-xl-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-xl-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-xl-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-xl-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-xl-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-xl-0 {\n padding-top: 0 !important;\n }\n .pt-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pt-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pt-xl-3 {\n padding-top: 1rem !important;\n }\n .pt-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pt-xl-5 {\n padding-top: 3rem !important;\n }\n .pe-xl-0 {\n padding-right: 0 !important;\n }\n .pe-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pe-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pe-xl-3 {\n padding-right: 1rem !important;\n }\n .pe-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pe-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-0 {\n padding-bottom: 0 !important;\n }\n .pb-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pb-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-xl-5 {\n padding-bottom: 3rem !important;\n }\n .ps-xl-0 {\n padding-left: 0 !important;\n }\n .ps-xl-1 {\n padding-left: 0.25rem !important;\n }\n .ps-xl-2 {\n padding-left: 0.5rem !important;\n }\n .ps-xl-3 {\n padding-left: 1rem !important;\n }\n .ps-xl-4 {\n padding-left: 1.5rem !important;\n }\n .ps-xl-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 1400px) {\n .d-xxl-inline {\n display: inline !important;\n }\n .d-xxl-inline-block {\n display: inline-block !important;\n }\n .d-xxl-block {\n display: block !important;\n }\n .d-xxl-grid {\n display: grid !important;\n }\n .d-xxl-inline-grid {\n display: inline-grid !important;\n }\n .d-xxl-table {\n display: table !important;\n }\n .d-xxl-table-row {\n display: table-row !important;\n }\n .d-xxl-table-cell {\n display: table-cell !important;\n }\n .d-xxl-flex {\n display: flex !important;\n }\n .d-xxl-inline-flex {\n display: inline-flex !important;\n }\n .d-xxl-none {\n display: none !important;\n }\n .flex-xxl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xxl-row {\n flex-direction: row !important;\n }\n .flex-xxl-column {\n flex-direction: column !important;\n }\n .flex-xxl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xxl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xxl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xxl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xxl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xxl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-xxl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xxl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xxl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xxl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xxl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xxl-center {\n justify-content: center !important;\n }\n .justify-content-xxl-between {\n justify-content: space-between !important;\n }\n .justify-content-xxl-around {\n justify-content: space-around !important;\n }\n .justify-content-xxl-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-xxl-start {\n align-items: flex-start !important;\n }\n .align-items-xxl-end {\n align-items: flex-end !important;\n }\n .align-items-xxl-center {\n align-items: center !important;\n }\n .align-items-xxl-baseline {\n align-items: baseline !important;\n }\n .align-items-xxl-stretch {\n align-items: stretch !important;\n }\n .align-content-xxl-start {\n align-content: flex-start !important;\n }\n .align-content-xxl-end {\n align-content: flex-end !important;\n }\n .align-content-xxl-center {\n align-content: center !important;\n }\n .align-content-xxl-between {\n align-content: space-between !important;\n }\n .align-content-xxl-around {\n align-content: space-around !important;\n }\n .align-content-xxl-stretch {\n align-content: stretch !important;\n }\n .align-self-xxl-auto {\n align-self: auto !important;\n }\n .align-self-xxl-start {\n align-self: flex-start !important;\n }\n .align-self-xxl-end {\n align-self: flex-end !important;\n }\n .align-self-xxl-center {\n align-self: center !important;\n }\n .align-self-xxl-baseline {\n align-self: baseline !important;\n }\n .align-self-xxl-stretch {\n align-self: stretch !important;\n }\n .order-xxl-first {\n order: -1 !important;\n }\n .order-xxl-0 {\n order: 0 !important;\n }\n .order-xxl-1 {\n order: 1 !important;\n }\n .order-xxl-2 {\n order: 2 !important;\n }\n .order-xxl-3 {\n order: 3 !important;\n }\n .order-xxl-4 {\n order: 4 !important;\n }\n .order-xxl-5 {\n order: 5 !important;\n }\n .order-xxl-last {\n order: 6 !important;\n }\n .m-xxl-0 {\n margin: 0 !important;\n }\n .m-xxl-1 {\n margin: 0.25rem !important;\n }\n .m-xxl-2 {\n margin: 0.5rem !important;\n }\n .m-xxl-3 {\n margin: 1rem !important;\n }\n .m-xxl-4 {\n margin: 1.5rem !important;\n }\n .m-xxl-5 {\n margin: 3rem !important;\n }\n .m-xxl-auto {\n margin: auto !important;\n }\n .mx-xxl-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-xxl-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-xxl-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-xxl-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-xxl-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-xxl-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-xxl-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-xxl-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-xxl-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-xxl-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-xxl-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-xxl-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-xxl-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-xxl-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-xxl-0 {\n margin-top: 0 !important;\n }\n .mt-xxl-1 {\n margin-top: 0.25rem !important;\n }\n .mt-xxl-2 {\n margin-top: 0.5rem !important;\n }\n .mt-xxl-3 {\n margin-top: 1rem !important;\n }\n .mt-xxl-4 {\n margin-top: 1.5rem !important;\n }\n .mt-xxl-5 {\n margin-top: 3rem !important;\n }\n .mt-xxl-auto {\n margin-top: auto !important;\n }\n .me-xxl-0 {\n margin-right: 0 !important;\n }\n .me-xxl-1 {\n margin-right: 0.25rem !important;\n }\n .me-xxl-2 {\n margin-right: 0.5rem !important;\n }\n .me-xxl-3 {\n margin-right: 1rem !important;\n }\n .me-xxl-4 {\n margin-right: 1.5rem !important;\n }\n .me-xxl-5 {\n margin-right: 3rem !important;\n }\n .me-xxl-auto {\n margin-right: auto !important;\n }\n .mb-xxl-0 {\n margin-bottom: 0 !important;\n }\n .mb-xxl-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-xxl-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-xxl-3 {\n margin-bottom: 1rem !important;\n }\n .mb-xxl-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-xxl-5 {\n margin-bottom: 3rem !important;\n }\n .mb-xxl-auto {\n margin-bottom: auto !important;\n }\n .ms-xxl-0 {\n margin-left: 0 !important;\n }\n .ms-xxl-1 {\n margin-left: 0.25rem !important;\n }\n .ms-xxl-2 {\n margin-left: 0.5rem !important;\n }\n .ms-xxl-3 {\n margin-left: 1rem !important;\n }\n .ms-xxl-4 {\n margin-left: 1.5rem !important;\n }\n .ms-xxl-5 {\n margin-left: 3rem !important;\n }\n .ms-xxl-auto {\n margin-left: auto !important;\n }\n .p-xxl-0 {\n padding: 0 !important;\n }\n .p-xxl-1 {\n padding: 0.25rem !important;\n }\n .p-xxl-2 {\n padding: 0.5rem !important;\n }\n .p-xxl-3 {\n padding: 1rem !important;\n }\n .p-xxl-4 {\n padding: 1.5rem !important;\n }\n .p-xxl-5 {\n padding: 3rem !important;\n }\n .px-xxl-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-xxl-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-xxl-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-xxl-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-xxl-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-xxl-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-xxl-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-xxl-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-xxl-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-xxl-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-xxl-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-xxl-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-xxl-0 {\n padding-top: 0 !important;\n }\n .pt-xxl-1 {\n padding-top: 0.25rem !important;\n }\n .pt-xxl-2 {\n padding-top: 0.5rem !important;\n }\n .pt-xxl-3 {\n padding-top: 1rem !important;\n }\n .pt-xxl-4 {\n padding-top: 1.5rem !important;\n }\n .pt-xxl-5 {\n padding-top: 3rem !important;\n }\n .pe-xxl-0 {\n padding-right: 0 !important;\n }\n .pe-xxl-1 {\n padding-right: 0.25rem !important;\n }\n .pe-xxl-2 {\n padding-right: 0.5rem !important;\n }\n .pe-xxl-3 {\n padding-right: 1rem !important;\n }\n .pe-xxl-4 {\n padding-right: 1.5rem !important;\n }\n .pe-xxl-5 {\n padding-right: 3rem !important;\n }\n .pb-xxl-0 {\n padding-bottom: 0 !important;\n }\n .pb-xxl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-xxl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-xxl-3 {\n padding-bottom: 1rem !important;\n }\n .pb-xxl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-xxl-5 {\n padding-bottom: 3rem !important;\n }\n .ps-xxl-0 {\n padding-left: 0 !important;\n }\n .ps-xxl-1 {\n padding-left: 0.25rem !important;\n }\n .ps-xxl-2 {\n padding-left: 0.5rem !important;\n }\n .ps-xxl-3 {\n padding-left: 1rem !important;\n }\n .ps-xxl-4 {\n padding-left: 1.5rem !important;\n }\n .ps-xxl-5 {\n padding-left: 3rem !important;\n }\n}\n@media print {\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-grid {\n display: grid !important;\n }\n .d-print-inline-grid {\n display: inline-grid !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n .d-print-none {\n display: none !important;\n }\n}\n\n/*# sourceMappingURL=bootstrap-grid.css.map */\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl xxl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @if not $n {\n @error \"breakpoint `#{$name}` not found in `#{$breakpoints}`\";\n }\n @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width.\n// The maximum value is reduced by 0.02px to work around the limitations of\n// `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $max: map-get($breakpoints, $name);\n @return if($max and $max > 0, $max - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $next: breakpoint-next($name, $breakpoints);\n $max: breakpoint-max($next, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($next, $breakpoints) {\n @content;\n }\n }\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n// scss-docs-start gray-color-variables\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n// scss-docs-end gray-color-variables\n\n// fusv-disable\n// scss-docs-start gray-colors-map\n$grays: (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n) !default;\n// scss-docs-end gray-colors-map\n// fusv-enable\n\n// scss-docs-start color-variables\n$blue: #0d6efd !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #d63384 !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #198754 !default;\n$teal: #20c997 !default;\n$cyan: #0dcaf0 !default;\n// scss-docs-end color-variables\n\n// scss-docs-start colors-map\n$colors: (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"black\": $black,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n) !default;\n// scss-docs-end colors-map\n\n// The contrast ratio to reach against white, to determine if color changes from \"light\" to \"dark\". Acceptable values for WCAG 2.0 are 3, 4.5 and 7.\n// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast\n$min-contrast-ratio: 4.5 !default;\n\n// Customize the light and dark text colors for use in our color contrast function.\n$color-contrast-dark: $black !default;\n$color-contrast-light: $white !default;\n\n// fusv-disable\n$blue-100: tint-color($blue, 80%) !default;\n$blue-200: tint-color($blue, 60%) !default;\n$blue-300: tint-color($blue, 40%) !default;\n$blue-400: tint-color($blue, 20%) !default;\n$blue-500: $blue !default;\n$blue-600: shade-color($blue, 20%) !default;\n$blue-700: shade-color($blue, 40%) !default;\n$blue-800: shade-color($blue, 60%) !default;\n$blue-900: shade-color($blue, 80%) !default;\n\n$indigo-100: tint-color($indigo, 80%) !default;\n$indigo-200: tint-color($indigo, 60%) !default;\n$indigo-300: tint-color($indigo, 40%) !default;\n$indigo-400: tint-color($indigo, 20%) !default;\n$indigo-500: $indigo !default;\n$indigo-600: shade-color($indigo, 20%) !default;\n$indigo-700: shade-color($indigo, 40%) !default;\n$indigo-800: shade-color($indigo, 60%) !default;\n$indigo-900: shade-color($indigo, 80%) !default;\n\n$purple-100: tint-color($purple, 80%) !default;\n$purple-200: tint-color($purple, 60%) !default;\n$purple-300: tint-color($purple, 40%) !default;\n$purple-400: tint-color($purple, 20%) !default;\n$purple-500: $purple !default;\n$purple-600: shade-color($purple, 20%) !default;\n$purple-700: shade-color($purple, 40%) !default;\n$purple-800: shade-color($purple, 60%) !default;\n$purple-900: shade-color($purple, 80%) !default;\n\n$pink-100: tint-color($pink, 80%) !default;\n$pink-200: tint-color($pink, 60%) !default;\n$pink-300: tint-color($pink, 40%) !default;\n$pink-400: tint-color($pink, 20%) !default;\n$pink-500: $pink !default;\n$pink-600: shade-color($pink, 20%) !default;\n$pink-700: shade-color($pink, 40%) !default;\n$pink-800: shade-color($pink, 60%) !default;\n$pink-900: shade-color($pink, 80%) !default;\n\n$red-100: tint-color($red, 80%) !default;\n$red-200: tint-color($red, 60%) !default;\n$red-300: tint-color($red, 40%) !default;\n$red-400: tint-color($red, 20%) !default;\n$red-500: $red !default;\n$red-600: shade-color($red, 20%) !default;\n$red-700: shade-color($red, 40%) !default;\n$red-800: shade-color($red, 60%) !default;\n$red-900: shade-color($red, 80%) !default;\n\n$orange-100: tint-color($orange, 80%) !default;\n$orange-200: tint-color($orange, 60%) !default;\n$orange-300: tint-color($orange, 40%) !default;\n$orange-400: tint-color($orange, 20%) !default;\n$orange-500: $orange !default;\n$orange-600: shade-color($orange, 20%) !default;\n$orange-700: shade-color($orange, 40%) !default;\n$orange-800: shade-color($orange, 60%) !default;\n$orange-900: shade-color($orange, 80%) !default;\n\n$yellow-100: tint-color($yellow, 80%) !default;\n$yellow-200: tint-color($yellow, 60%) !default;\n$yellow-300: tint-color($yellow, 40%) !default;\n$yellow-400: tint-color($yellow, 20%) !default;\n$yellow-500: $yellow !default;\n$yellow-600: shade-color($yellow, 20%) !default;\n$yellow-700: shade-color($yellow, 40%) !default;\n$yellow-800: shade-color($yellow, 60%) !default;\n$yellow-900: shade-color($yellow, 80%) !default;\n\n$green-100: tint-color($green, 80%) !default;\n$green-200: tint-color($green, 60%) !default;\n$green-300: tint-color($green, 40%) !default;\n$green-400: tint-color($green, 20%) !default;\n$green-500: $green !default;\n$green-600: shade-color($green, 20%) !default;\n$green-700: shade-color($green, 40%) !default;\n$green-800: shade-color($green, 60%) !default;\n$green-900: shade-color($green, 80%) !default;\n\n$teal-100: tint-color($teal, 80%) !default;\n$teal-200: tint-color($teal, 60%) !default;\n$teal-300: tint-color($teal, 40%) !default;\n$teal-400: tint-color($teal, 20%) !default;\n$teal-500: $teal !default;\n$teal-600: shade-color($teal, 20%) !default;\n$teal-700: shade-color($teal, 40%) !default;\n$teal-800: shade-color($teal, 60%) !default;\n$teal-900: shade-color($teal, 80%) !default;\n\n$cyan-100: tint-color($cyan, 80%) !default;\n$cyan-200: tint-color($cyan, 60%) !default;\n$cyan-300: tint-color($cyan, 40%) !default;\n$cyan-400: tint-color($cyan, 20%) !default;\n$cyan-500: $cyan !default;\n$cyan-600: shade-color($cyan, 20%) !default;\n$cyan-700: shade-color($cyan, 40%) !default;\n$cyan-800: shade-color($cyan, 60%) !default;\n$cyan-900: shade-color($cyan, 80%) !default;\n\n$blues: (\n \"blue-100\": $blue-100,\n \"blue-200\": $blue-200,\n \"blue-300\": $blue-300,\n \"blue-400\": $blue-400,\n \"blue-500\": $blue-500,\n \"blue-600\": $blue-600,\n \"blue-700\": $blue-700,\n \"blue-800\": $blue-800,\n \"blue-900\": $blue-900\n) !default;\n\n$indigos: (\n \"indigo-100\": $indigo-100,\n \"indigo-200\": $indigo-200,\n \"indigo-300\": $indigo-300,\n \"indigo-400\": $indigo-400,\n \"indigo-500\": $indigo-500,\n \"indigo-600\": $indigo-600,\n \"indigo-700\": $indigo-700,\n \"indigo-800\": $indigo-800,\n \"indigo-900\": $indigo-900\n) !default;\n\n$purples: (\n \"purple-100\": $purple-100,\n \"purple-200\": $purple-200,\n \"purple-300\": $purple-300,\n \"purple-400\": $purple-400,\n \"purple-500\": $purple-500,\n \"purple-600\": $purple-600,\n \"purple-700\": $purple-700,\n \"purple-800\": $purple-800,\n \"purple-900\": $purple-900\n) !default;\n\n$pinks: (\n \"pink-100\": $pink-100,\n \"pink-200\": $pink-200,\n \"pink-300\": $pink-300,\n \"pink-400\": $pink-400,\n \"pink-500\": $pink-500,\n \"pink-600\": $pink-600,\n \"pink-700\": $pink-700,\n \"pink-800\": $pink-800,\n \"pink-900\": $pink-900\n) !default;\n\n$reds: (\n \"red-100\": $red-100,\n \"red-200\": $red-200,\n \"red-300\": $red-300,\n \"red-400\": $red-400,\n \"red-500\": $red-500,\n \"red-600\": $red-600,\n \"red-700\": $red-700,\n \"red-800\": $red-800,\n \"red-900\": $red-900\n) !default;\n\n$oranges: (\n \"orange-100\": $orange-100,\n \"orange-200\": $orange-200,\n \"orange-300\": $orange-300,\n \"orange-400\": $orange-400,\n \"orange-500\": $orange-500,\n \"orange-600\": $orange-600,\n \"orange-700\": $orange-700,\n \"orange-800\": $orange-800,\n \"orange-900\": $orange-900\n) !default;\n\n$yellows: (\n \"yellow-100\": $yellow-100,\n \"yellow-200\": $yellow-200,\n \"yellow-300\": $yellow-300,\n \"yellow-400\": $yellow-400,\n \"yellow-500\": $yellow-500,\n \"yellow-600\": $yellow-600,\n \"yellow-700\": $yellow-700,\n \"yellow-800\": $yellow-800,\n \"yellow-900\": $yellow-900\n) !default;\n\n$greens: (\n \"green-100\": $green-100,\n \"green-200\": $green-200,\n \"green-300\": $green-300,\n \"green-400\": $green-400,\n \"green-500\": $green-500,\n \"green-600\": $green-600,\n \"green-700\": $green-700,\n \"green-800\": $green-800,\n \"green-900\": $green-900\n) !default;\n\n$teals: (\n \"teal-100\": $teal-100,\n \"teal-200\": $teal-200,\n \"teal-300\": $teal-300,\n \"teal-400\": $teal-400,\n \"teal-500\": $teal-500,\n \"teal-600\": $teal-600,\n \"teal-700\": $teal-700,\n \"teal-800\": $teal-800,\n \"teal-900\": $teal-900\n) !default;\n\n$cyans: (\n \"cyan-100\": $cyan-100,\n \"cyan-200\": $cyan-200,\n \"cyan-300\": $cyan-300,\n \"cyan-400\": $cyan-400,\n \"cyan-500\": $cyan-500,\n \"cyan-600\": $cyan-600,\n \"cyan-700\": $cyan-700,\n \"cyan-800\": $cyan-800,\n \"cyan-900\": $cyan-900\n) !default;\n// fusv-enable\n\n// scss-docs-start theme-color-variables\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-900 !default;\n// scss-docs-end theme-color-variables\n\n// scss-docs-start theme-colors-map\n$theme-colors: (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n) !default;\n// scss-docs-end theme-colors-map\n\n// scss-docs-start theme-text-variables\n$primary-text-emphasis: shade-color($primary, 60%) !default;\n$secondary-text-emphasis: shade-color($secondary, 60%) !default;\n$success-text-emphasis: shade-color($success, 60%) !default;\n$info-text-emphasis: shade-color($info, 60%) !default;\n$warning-text-emphasis: shade-color($warning, 60%) !default;\n$danger-text-emphasis: shade-color($danger, 60%) !default;\n$light-text-emphasis: $gray-700 !default;\n$dark-text-emphasis: $gray-700 !default;\n// scss-docs-end theme-text-variables\n\n// scss-docs-start theme-bg-subtle-variables\n$primary-bg-subtle: tint-color($primary, 80%) !default;\n$secondary-bg-subtle: tint-color($secondary, 80%) !default;\n$success-bg-subtle: tint-color($success, 80%) !default;\n$info-bg-subtle: tint-color($info, 80%) !default;\n$warning-bg-subtle: tint-color($warning, 80%) !default;\n$danger-bg-subtle: tint-color($danger, 80%) !default;\n$light-bg-subtle: mix($gray-100, $white) !default;\n$dark-bg-subtle: $gray-400 !default;\n// scss-docs-end theme-bg-subtle-variables\n\n// scss-docs-start theme-border-subtle-variables\n$primary-border-subtle: tint-color($primary, 60%) !default;\n$secondary-border-subtle: tint-color($secondary, 60%) !default;\n$success-border-subtle: tint-color($success, 60%) !default;\n$info-border-subtle: tint-color($info, 60%) !default;\n$warning-border-subtle: tint-color($warning, 60%) !default;\n$danger-border-subtle: tint-color($danger, 60%) !default;\n$light-border-subtle: $gray-200 !default;\n$dark-border-subtle: $gray-500 !default;\n// scss-docs-end theme-border-subtle-variables\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n (\"<\", \"%3c\"),\n (\">\", \"%3e\"),\n (\"#\", \"%23\"),\n (\"(\", \"%28\"),\n (\")\", \"%29\"),\n) !default;\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-reduced-motion: true !default;\n$enable-smooth-scroll: true !default;\n$enable-grid-classes: true !default;\n$enable-container-classes: true !default;\n$enable-cssgrid: false !default;\n$enable-button-pointers: true !default;\n$enable-rfs: true !default;\n$enable-validation-icons: true !default;\n$enable-negative-margins: false !default;\n$enable-deprecation-messages: true !default;\n$enable-important-utilities: true !default;\n\n$enable-dark-mode: true !default;\n$color-mode-type: data !default; // `data` or `media-query`\n\n// Prefix for :root CSS variables\n\n$variable-prefix: bs- !default; // Deprecated in v5.2.0 for the shorter `$prefix`\n$prefix: $variable-prefix !default;\n\n// Gradient\n//\n// The gradient which is added to components if `$enable-gradients` is `true`\n// This gradient is also added to elements with `.bg-gradient`\n// scss-docs-start variable-gradient\n$gradient: linear-gradient(180deg, rgba($white, .15), rgba($white, 0)) !default;\n// scss-docs-end variable-gradient\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n// scss-docs-start spacer-variables-maps\n$spacer: 1rem !default;\n$spacers: (\n 0: 0,\n 1: $spacer * .25,\n 2: $spacer * .5,\n 3: $spacer,\n 4: $spacer * 1.5,\n 5: $spacer * 3,\n) !default;\n// scss-docs-end spacer-variables-maps\n\n// Position\n//\n// Define the edge positioning anchors of the position utilities.\n\n// scss-docs-start position-map\n$position-values: (\n 0: 0,\n 50: 50%,\n 100: 100%\n) !default;\n// scss-docs-end position-map\n\n// Body\n//\n// Settings for the `` element.\n\n$body-text-align: null !default;\n$body-color: $gray-900 !default;\n$body-bg: $white !default;\n\n$body-secondary-color: rgba($body-color, .75) !default;\n$body-secondary-bg: $gray-200 !default;\n\n$body-tertiary-color: rgba($body-color, .5) !default;\n$body-tertiary-bg: $gray-100 !default;\n\n$body-emphasis-color: $black !default;\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: $primary !default;\n$link-decoration: underline !default;\n$link-shade-percentage: 20% !default;\n$link-hover-color: shift-color($link-color, $link-shade-percentage) !default;\n$link-hover-decoration: null !default;\n\n$stretched-link-pseudo-element: after !default;\n$stretched-link-z-index: 1 !default;\n\n// Icon links\n// scss-docs-start icon-link-variables\n$icon-link-gap: .375rem !default;\n$icon-link-underline-offset: .25em !default;\n$icon-link-icon-size: 1em !default;\n$icon-link-icon-transition: .2s ease-in-out transform !default;\n$icon-link-icon-transform: translate3d(.25em, 0, 0) !default;\n// scss-docs-end icon-link-variables\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n// scss-docs-start grid-breakpoints\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px,\n xxl: 1400px\n) !default;\n// scss-docs-end grid-breakpoints\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n// scss-docs-start container-max-widths\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px,\n xxl: 1320px\n) !default;\n// scss-docs-end container-max-widths\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 1.5rem !default;\n$grid-row-columns: 6 !default;\n\n// Container padding\n\n$container-padding-x: $grid-gutter-width !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n// scss-docs-start border-variables\n$border-width: 1px !default;\n$border-widths: (\n 1: 1px,\n 2: 2px,\n 3: 3px,\n 4: 4px,\n 5: 5px\n) !default;\n$border-style: solid !default;\n$border-color: $gray-300 !default;\n$border-color-translucent: rgba($black, .175) !default;\n// scss-docs-end border-variables\n\n// scss-docs-start border-radius-variables\n$border-radius: .375rem !default;\n$border-radius-sm: .25rem !default;\n$border-radius-lg: .5rem !default;\n$border-radius-xl: 1rem !default;\n$border-radius-xxl: 2rem !default;\n$border-radius-pill: 50rem !default;\n// scss-docs-end border-radius-variables\n// fusv-disable\n$border-radius-2xl: $border-radius-xxl !default; // Deprecated in v5.3.0\n// fusv-enable\n\n// scss-docs-start box-shadow-variables\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n$box-shadow-inset: inset 0 1px 2px rgba($black, .075) !default;\n// scss-docs-end box-shadow-variables\n\n$component-active-color: $white !default;\n$component-active-bg: $primary !default;\n\n// scss-docs-start focus-ring-variables\n$focus-ring-width: .25rem !default;\n$focus-ring-opacity: .25 !default;\n$focus-ring-color: rgba($primary, $focus-ring-opacity) !default;\n$focus-ring-blur: 0 !default;\n$focus-ring-box-shadow: 0 0 $focus-ring-blur $focus-ring-width $focus-ring-color !default;\n// scss-docs-end focus-ring-variables\n\n// scss-docs-start caret-variables\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n// scss-docs-end caret-variables\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n// scss-docs-start collapse-transition\n$transition-collapse: height .35s ease !default;\n$transition-collapse-width: width .35s ease !default;\n// scss-docs-end collapse-transition\n\n// stylelint-disable function-disallowed-list\n// scss-docs-start aspect-ratios\n$aspect-ratios: (\n \"1x1\": 100%,\n \"4x3\": calc(3 / 4 * 100%),\n \"16x9\": calc(9 / 16 * 100%),\n \"21x9\": calc(9 / 21 * 100%)\n) !default;\n// scss-docs-end aspect-ratios\n// stylelint-enable function-disallowed-list\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// scss-docs-start font-variables\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", \"Liberation Sans\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n// stylelint-enable value-keyword-case\n$font-family-base: var(--#{$prefix}font-sans-serif) !default;\n$font-family-code: var(--#{$prefix}font-monospace) !default;\n\n// $font-size-root affects the value of `rem`, which is used for as well font sizes, paddings, and margins\n// $font-size-base affects the font size of the body text\n$font-size-root: null !default;\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-sm: $font-size-base * .875 !default;\n$font-size-lg: $font-size-base * 1.25 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-medium: 500 !default;\n$font-weight-semibold: 600 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n\n$line-height-base: 1.5 !default;\n$line-height-sm: 1.25 !default;\n$line-height-lg: 2 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n// scss-docs-end font-variables\n\n// scss-docs-start font-sizes\n$font-sizes: (\n 1: $h1-font-size,\n 2: $h2-font-size,\n 3: $h3-font-size,\n 4: $h4-font-size,\n 5: $h5-font-size,\n 6: $h6-font-size\n) !default;\n// scss-docs-end font-sizes\n\n// scss-docs-start headings-variables\n$headings-margin-bottom: $spacer * .5 !default;\n$headings-font-family: null !default;\n$headings-font-style: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: inherit !default;\n// scss-docs-end headings-variables\n\n// scss-docs-start display-headings\n$display-font-sizes: (\n 1: 5rem,\n 2: 4.5rem,\n 3: 4rem,\n 4: 3.5rem,\n 5: 3rem,\n 6: 2.5rem\n) !default;\n\n$display-font-family: null !default;\n$display-font-style: null !default;\n$display-font-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n// scss-docs-end display-headings\n\n// scss-docs-start type-variables\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: .875em !default;\n\n$sub-sup-font-size: .75em !default;\n\n// fusv-disable\n$text-muted: var(--#{$prefix}secondary-color) !default; // Deprecated in 5.3.0\n// fusv-enable\n\n$initialism-font-size: $small-font-size !default;\n\n$blockquote-margin-y: $spacer !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n$blockquote-footer-color: $gray-600 !default;\n$blockquote-footer-font-size: $small-font-size !default;\n\n$hr-margin-y: $spacer !default;\n$hr-color: inherit !default;\n\n// fusv-disable\n$hr-bg-color: null !default; // Deprecated in v5.2.0\n$hr-height: null !default; // Deprecated in v5.2.0\n// fusv-enable\n\n$hr-border-color: null !default; // Allows for inherited colors\n$hr-border-width: var(--#{$prefix}border-width) !default;\n$hr-opacity: .25 !default;\n\n// scss-docs-start vr-variables\n$vr-border-width: var(--#{$prefix}border-width) !default;\n// scss-docs-end vr-variables\n\n$legend-margin-bottom: .5rem !default;\n$legend-font-size: 1.5rem !default;\n$legend-font-weight: null !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-padding: .1875em !default;\n$mark-color: $body-color !default;\n$mark-bg: $yellow-100 !default;\n// scss-docs-end type-variables\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n// scss-docs-start table-variables\n$table-cell-padding-y: .5rem !default;\n$table-cell-padding-x: .5rem !default;\n$table-cell-padding-y-sm: .25rem !default;\n$table-cell-padding-x-sm: .25rem !default;\n\n$table-cell-vertical-align: top !default;\n\n$table-color: var(--#{$prefix}emphasis-color) !default;\n$table-bg: var(--#{$prefix}body-bg) !default;\n$table-accent-bg: transparent !default;\n\n$table-th-font-weight: null !default;\n\n$table-striped-color: $table-color !default;\n$table-striped-bg-factor: .05 !default;\n$table-striped-bg: rgba(var(--#{$prefix}emphasis-color-rgb), $table-striped-bg-factor) !default;\n\n$table-active-color: $table-color !default;\n$table-active-bg-factor: .1 !default;\n$table-active-bg: rgba(var(--#{$prefix}emphasis-color-rgb), $table-active-bg-factor) !default;\n\n$table-hover-color: $table-color !default;\n$table-hover-bg-factor: .075 !default;\n$table-hover-bg: rgba(var(--#{$prefix}emphasis-color-rgb), $table-hover-bg-factor) !default;\n\n$table-border-factor: .2 !default;\n$table-border-width: var(--#{$prefix}border-width) !default;\n$table-border-color: var(--#{$prefix}border-color) !default;\n\n$table-striped-order: odd !default;\n$table-striped-columns-order: even !default;\n\n$table-group-separator-color: currentcolor !default;\n\n$table-caption-color: var(--#{$prefix}secondary-color) !default;\n\n$table-bg-scale: -80% !default;\n// scss-docs-end table-variables\n\n// scss-docs-start table-loop\n$table-variants: (\n \"primary\": shift-color($primary, $table-bg-scale),\n \"secondary\": shift-color($secondary, $table-bg-scale),\n \"success\": shift-color($success, $table-bg-scale),\n \"info\": shift-color($info, $table-bg-scale),\n \"warning\": shift-color($warning, $table-bg-scale),\n \"danger\": shift-color($danger, $table-bg-scale),\n \"light\": $light,\n \"dark\": $dark,\n) !default;\n// scss-docs-end table-loop\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n// scss-docs-start input-btn-variables\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: $focus-ring-width !default;\n$input-btn-focus-color-opacity: $focus-ring-opacity !default;\n$input-btn-focus-color: $focus-ring-color !default;\n$input-btn-focus-blur: $focus-ring-blur !default;\n$input-btn-focus-box-shadow: $focus-ring-box-shadow !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n\n$input-btn-border-width: var(--#{$prefix}border-width) !default;\n// scss-docs-end input-btn-variables\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n// scss-docs-start btn-variables\n$btn-color: var(--#{$prefix}body-color) !default;\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-color: var(--#{$prefix}link-color) !default;\n$btn-link-hover-color: var(--#{$prefix}link-hover-color) !default;\n$btn-link-disabled-color: $gray-600 !default;\n$btn-link-focus-shadow-rgb: to-rgb(mix(color-contrast($link-color), $link-color, 15%)) !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: var(--#{$prefix}border-radius) !default;\n$btn-border-radius-sm: var(--#{$prefix}border-radius-sm) !default;\n$btn-border-radius-lg: var(--#{$prefix}border-radius-lg) !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$btn-hover-bg-shade-amount: 15% !default;\n$btn-hover-bg-tint-amount: 15% !default;\n$btn-hover-border-shade-amount: 20% !default;\n$btn-hover-border-tint-amount: 10% !default;\n$btn-active-bg-shade-amount: 20% !default;\n$btn-active-bg-tint-amount: 20% !default;\n$btn-active-border-shade-amount: 25% !default;\n$btn-active-border-tint-amount: 10% !default;\n// scss-docs-end btn-variables\n\n\n// Forms\n\n// scss-docs-start form-text-variables\n$form-text-margin-top: .25rem !default;\n$form-text-font-size: $small-font-size !default;\n$form-text-font-style: null !default;\n$form-text-font-weight: null !default;\n$form-text-color: var(--#{$prefix}secondary-color) !default;\n// scss-docs-end form-text-variables\n\n// scss-docs-start form-label-variables\n$form-label-margin-bottom: .5rem !default;\n$form-label-font-size: null !default;\n$form-label-font-style: null !default;\n$form-label-font-weight: null !default;\n$form-label-color: null !default;\n// scss-docs-end form-label-variables\n\n// scss-docs-start form-input-variables\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n\n$input-bg: var(--#{$prefix}body-bg) !default;\n$input-disabled-color: null !default;\n$input-disabled-bg: var(--#{$prefix}secondary-bg) !default;\n$input-disabled-border-color: null !default;\n\n$input-color: var(--#{$prefix}body-color) !default;\n$input-border-color: var(--#{$prefix}border-color) !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: var(--#{$prefix}box-shadow-inset) !default;\n\n$input-border-radius: var(--#{$prefix}border-radius) !default;\n$input-border-radius-sm: var(--#{$prefix}border-radius-sm) !default;\n$input-border-radius-lg: var(--#{$prefix}border-radius-lg) !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: tint-color($component-active-bg, 50%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: var(--#{$prefix}secondary-color) !default;\n$input-plaintext-color: var(--#{$prefix}body-color) !default;\n\n$input-height-border: calc(#{$input-border-width} * 2) !default; // stylelint-disable-line function-disallowed-list\n\n$input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y * .5) !default;\n\n$input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm: add($input-line-height * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg: add($input-line-height * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-color-width: 3rem !default;\n// scss-docs-end form-input-variables\n\n// scss-docs-start form-check-variables\n$form-check-input-width: 1em !default;\n$form-check-min-height: $font-size-base * $line-height-base !default;\n$form-check-padding-start: $form-check-input-width + .5em !default;\n$form-check-margin-bottom: .125rem !default;\n$form-check-label-color: null !default;\n$form-check-label-cursor: null !default;\n$form-check-transition: null !default;\n\n$form-check-input-active-filter: brightness(90%) !default;\n\n$form-check-input-bg: $input-bg !default;\n$form-check-input-border: var(--#{$prefix}border-width) solid var(--#{$prefix}border-color) !default;\n$form-check-input-border-radius: .25em !default;\n$form-check-radio-border-radius: 50% !default;\n$form-check-input-focus-border: $input-focus-border-color !default;\n$form-check-input-focus-box-shadow: $focus-ring-box-shadow !default;\n\n$form-check-input-checked-color: $component-active-color !default;\n$form-check-input-checked-bg-color: $component-active-bg !default;\n$form-check-input-checked-border-color: $form-check-input-checked-bg-color !default;\n$form-check-input-checked-bg-image: url(\"data:image/svg+xml,\") !default;\n$form-check-radio-checked-bg-image: url(\"data:image/svg+xml,\") !default;\n\n$form-check-input-indeterminate-color: $component-active-color !default;\n$form-check-input-indeterminate-bg-color: $component-active-bg !default;\n$form-check-input-indeterminate-border-color: $form-check-input-indeterminate-bg-color !default;\n$form-check-input-indeterminate-bg-image: url(\"data:image/svg+xml,\") !default;\n\n$form-check-input-disabled-opacity: .5 !default;\n$form-check-label-disabled-opacity: $form-check-input-disabled-opacity !default;\n$form-check-btn-check-disabled-opacity: $btn-disabled-opacity !default;\n\n$form-check-inline-margin-end: 1rem !default;\n// scss-docs-end form-check-variables\n\n// scss-docs-start form-switch-variables\n$form-switch-color: rgba($black, .25) !default;\n$form-switch-width: 2em !default;\n$form-switch-padding-start: $form-switch-width + .5em !default;\n$form-switch-bg-image: url(\"data:image/svg+xml,\") !default;\n$form-switch-border-radius: $form-switch-width !default;\n$form-switch-transition: background-position .15s ease-in-out !default;\n\n$form-switch-focus-color: $input-focus-border-color !default;\n$form-switch-focus-bg-image: url(\"data:image/svg+xml,\") !default;\n\n$form-switch-checked-color: $component-active-color !default;\n$form-switch-checked-bg-image: url(\"data:image/svg+xml,\") !default;\n$form-switch-checked-bg-position: right center !default;\n// scss-docs-end form-switch-variables\n\n// scss-docs-start input-group-variables\n$input-group-addon-padding-y: $input-padding-y !default;\n$input-group-addon-padding-x: $input-padding-x !default;\n$input-group-addon-font-weight: $input-font-weight !default;\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: var(--#{$prefix}tertiary-bg) !default;\n$input-group-addon-border-color: $input-border-color !default;\n// scss-docs-end input-group-variables\n\n// scss-docs-start form-select-variables\n$form-select-padding-y: $input-padding-y !default;\n$form-select-padding-x: $input-padding-x !default;\n$form-select-font-family: $input-font-family !default;\n$form-select-font-size: $input-font-size !default;\n$form-select-indicator-padding: $form-select-padding-x * 3 !default; // Extra padding for background-image\n$form-select-font-weight: $input-font-weight !default;\n$form-select-line-height: $input-line-height !default;\n$form-select-color: $input-color !default;\n$form-select-bg: $input-bg !default;\n$form-select-disabled-color: null !default;\n$form-select-disabled-bg: $input-disabled-bg !default;\n$form-select-disabled-border-color: $input-disabled-border-color !default;\n$form-select-bg-position: right $form-select-padding-x center !default;\n$form-select-bg-size: 16px 12px !default; // In pixels because image dimensions\n$form-select-indicator-color: $gray-800 !default;\n$form-select-indicator: url(\"data:image/svg+xml,\") !default;\n\n$form-select-feedback-icon-padding-end: $form-select-padding-x * 2.5 + $form-select-indicator-padding !default;\n$form-select-feedback-icon-position: center right $form-select-indicator-padding !default;\n$form-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$form-select-border-width: $input-border-width !default;\n$form-select-border-color: $input-border-color !default;\n$form-select-border-radius: $input-border-radius !default;\n$form-select-box-shadow: var(--#{$prefix}box-shadow-inset) !default;\n\n$form-select-focus-border-color: $input-focus-border-color !default;\n$form-select-focus-width: $input-focus-width !default;\n$form-select-focus-box-shadow: 0 0 0 $form-select-focus-width $input-btn-focus-color !default;\n\n$form-select-padding-y-sm: $input-padding-y-sm !default;\n$form-select-padding-x-sm: $input-padding-x-sm !default;\n$form-select-font-size-sm: $input-font-size-sm !default;\n$form-select-border-radius-sm: $input-border-radius-sm !default;\n\n$form-select-padding-y-lg: $input-padding-y-lg !default;\n$form-select-padding-x-lg: $input-padding-x-lg !default;\n$form-select-font-size-lg: $input-font-size-lg !default;\n$form-select-border-radius-lg: $input-border-radius-lg !default;\n\n$form-select-transition: $input-transition !default;\n// scss-docs-end form-select-variables\n\n// scss-docs-start form-range-variables\n$form-range-track-width: 100% !default;\n$form-range-track-height: .5rem !default;\n$form-range-track-cursor: pointer !default;\n$form-range-track-bg: var(--#{$prefix}secondary-bg) !default;\n$form-range-track-border-radius: 1rem !default;\n$form-range-track-box-shadow: var(--#{$prefix}box-shadow-inset) !default;\n\n$form-range-thumb-width: 1rem !default;\n$form-range-thumb-height: $form-range-thumb-width !default;\n$form-range-thumb-bg: $component-active-bg !default;\n$form-range-thumb-border: 0 !default;\n$form-range-thumb-border-radius: 1rem !default;\n$form-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$form-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$form-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in Edge\n$form-range-thumb-active-bg: tint-color($component-active-bg, 70%) !default;\n$form-range-thumb-disabled-bg: var(--#{$prefix}secondary-color) !default;\n$form-range-thumb-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n// scss-docs-end form-range-variables\n\n// scss-docs-start form-file-variables\n$form-file-button-color: $input-color !default;\n$form-file-button-bg: var(--#{$prefix}tertiary-bg) !default;\n$form-file-button-hover-bg: var(--#{$prefix}secondary-bg) !default;\n// scss-docs-end form-file-variables\n\n// scss-docs-start form-floating-variables\n$form-floating-height: add(3.5rem, $input-height-border) !default;\n$form-floating-line-height: 1.25 !default;\n$form-floating-padding-x: $input-padding-x !default;\n$form-floating-padding-y: 1rem !default;\n$form-floating-input-padding-t: 1.625rem !default;\n$form-floating-input-padding-b: .625rem !default;\n$form-floating-label-height: 1.5em !default;\n$form-floating-label-opacity: .65 !default;\n$form-floating-label-transform: scale(.85) translateY(-.5rem) translateX(.15rem) !default;\n$form-floating-label-disabled-color: $gray-600 !default;\n$form-floating-transition: opacity .1s ease-in-out, transform .1s ease-in-out !default;\n// scss-docs-end form-floating-variables\n\n// Form validation\n\n// scss-docs-start form-feedback-variables\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $form-text-font-size !default;\n$form-feedback-font-style: $form-text-font-style !default;\n$form-feedback-valid-color: $success !default;\n$form-feedback-invalid-color: $danger !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: url(\"data:image/svg+xml,\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: url(\"data:image/svg+xml,\") !default;\n// scss-docs-end form-feedback-variables\n\n// scss-docs-start form-validation-colors\n$form-valid-color: $form-feedback-valid-color !default;\n$form-valid-border-color: $form-feedback-valid-color !default;\n$form-invalid-color: $form-feedback-invalid-color !default;\n$form-invalid-border-color: $form-feedback-invalid-color !default;\n// scss-docs-end form-validation-colors\n\n// scss-docs-start form-validation-states\n$form-validation-states: (\n \"valid\": (\n \"color\": var(--#{$prefix}form-valid-color),\n \"icon\": $form-feedback-icon-valid,\n \"tooltip-color\": #fff,\n \"tooltip-bg-color\": var(--#{$prefix}success),\n \"focus-box-shadow\": 0 0 $input-btn-focus-blur $input-focus-width rgba(var(--#{$prefix}success-rgb), $input-btn-focus-color-opacity),\n \"border-color\": var(--#{$prefix}form-valid-border-color),\n ),\n \"invalid\": (\n \"color\": var(--#{$prefix}form-invalid-color),\n \"icon\": $form-feedback-icon-invalid,\n \"tooltip-color\": #fff,\n \"tooltip-bg-color\": var(--#{$prefix}danger),\n \"focus-box-shadow\": 0 0 $input-btn-focus-blur $input-focus-width rgba(var(--#{$prefix}danger-rgb), $input-btn-focus-color-opacity),\n \"border-color\": var(--#{$prefix}form-invalid-border-color),\n )\n) !default;\n// scss-docs-end form-validation-states\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n// scss-docs-start zindex-stack\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-offcanvas-backdrop: 1040 !default;\n$zindex-offcanvas: 1045 !default;\n$zindex-modal-backdrop: 1050 !default;\n$zindex-modal: 1055 !default;\n$zindex-popover: 1070 !default;\n$zindex-tooltip: 1080 !default;\n$zindex-toast: 1090 !default;\n// scss-docs-end zindex-stack\n\n// scss-docs-start zindex-levels-map\n$zindex-levels: (\n n1: -1,\n 0: 0,\n 1: 1,\n 2: 2,\n 3: 3\n) !default;\n// scss-docs-end zindex-levels-map\n\n\n// Navs\n\n// scss-docs-start nav-variables\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-font-size: null !default;\n$nav-link-font-weight: null !default;\n$nav-link-color: var(--#{$prefix}link-color) !default;\n$nav-link-hover-color: var(--#{$prefix}link-hover-color) !default;\n$nav-link-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out !default;\n$nav-link-disabled-color: var(--#{$prefix}secondary-color) !default;\n$nav-link-focus-box-shadow: $focus-ring-box-shadow !default;\n\n$nav-tabs-border-color: var(--#{$prefix}border-color) !default;\n$nav-tabs-border-width: var(--#{$prefix}border-width) !default;\n$nav-tabs-border-radius: var(--#{$prefix}border-radius) !default;\n$nav-tabs-link-hover-border-color: var(--#{$prefix}secondary-bg) var(--#{$prefix}secondary-bg) $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: var(--#{$prefix}emphasis-color) !default;\n$nav-tabs-link-active-bg: var(--#{$prefix}body-bg) !default;\n$nav-tabs-link-active-border-color: var(--#{$prefix}border-color) var(--#{$prefix}border-color) $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: var(--#{$prefix}border-radius) !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-underline-gap: 1rem !default;\n$nav-underline-border-width: .125rem !default;\n$nav-underline-link-active-color: var(--#{$prefix}emphasis-color) !default;\n// scss-docs-end nav-variables\n\n\n// Navbar\n\n// scss-docs-start navbar-variables\n$navbar-padding-y: $spacer * .5 !default;\n$navbar-padding-x: null !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) * .5 !default;\n$navbar-brand-margin-end: 1rem !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n$navbar-toggler-focus-width: $btn-focus-width !default;\n$navbar-toggler-transition: box-shadow .15s ease-in-out !default;\n\n$navbar-light-color: rgba(var(--#{$prefix}emphasis-color-rgb), .65) !default;\n$navbar-light-hover-color: rgba(var(--#{$prefix}emphasis-color-rgb), .8) !default;\n$navbar-light-active-color: rgba(var(--#{$prefix}emphasis-color-rgb), 1) !default;\n$navbar-light-disabled-color: rgba(var(--#{$prefix}emphasis-color-rgb), .3) !default;\n$navbar-light-icon-color: rgba($body-color, .75) !default;\n$navbar-light-toggler-icon-bg: url(\"data:image/svg+xml,\") !default;\n$navbar-light-toggler-border-color: rgba(var(--#{$prefix}emphasis-color-rgb), .15) !default;\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n// scss-docs-end navbar-variables\n\n// scss-docs-start navbar-dark-variables\n$navbar-dark-color: rgba($white, .55) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-icon-color: $navbar-dark-color !default;\n$navbar-dark-toggler-icon-bg: url(\"data:image/svg+xml,\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n// scss-docs-end navbar-dark-variables\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n// scss-docs-start dropdown-variables\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-x: 0 !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-color: var(--#{$prefix}body-color) !default;\n$dropdown-bg: var(--#{$prefix}body-bg) !default;\n$dropdown-border-color: var(--#{$prefix}border-color-translucent) !default;\n$dropdown-border-radius: var(--#{$prefix}border-radius) !default;\n$dropdown-border-width: var(--#{$prefix}border-width) !default;\n$dropdown-inner-border-radius: calc(#{$dropdown-border-radius} - #{$dropdown-border-width}) !default; // stylelint-disable-line function-disallowed-list\n$dropdown-divider-bg: $dropdown-border-color !default;\n$dropdown-divider-margin-y: $spacer * .5 !default;\n$dropdown-box-shadow: var(--#{$prefix}box-shadow) !default;\n\n$dropdown-link-color: var(--#{$prefix}body-color) !default;\n$dropdown-link-hover-color: $dropdown-link-color !default;\n$dropdown-link-hover-bg: var(--#{$prefix}tertiary-bg) !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: var(--#{$prefix}tertiary-color) !default;\n\n$dropdown-item-padding-y: $spacer * .25 !default;\n$dropdown-item-padding-x: $spacer !default;\n\n$dropdown-header-color: $gray-600 !default;\n$dropdown-header-padding-x: $dropdown-item-padding-x !default;\n$dropdown-header-padding-y: $dropdown-padding-y !default;\n// fusv-disable\n$dropdown-header-padding: $dropdown-header-padding-y $dropdown-header-padding-x !default; // Deprecated in v5.2.0\n// fusv-enable\n// scss-docs-end dropdown-variables\n\n// scss-docs-start dropdown-dark-variables\n$dropdown-dark-color: $gray-300 !default;\n$dropdown-dark-bg: $gray-800 !default;\n$dropdown-dark-border-color: $dropdown-border-color !default;\n$dropdown-dark-divider-bg: $dropdown-divider-bg !default;\n$dropdown-dark-box-shadow: null !default;\n$dropdown-dark-link-color: $dropdown-dark-color !default;\n$dropdown-dark-link-hover-color: $white !default;\n$dropdown-dark-link-hover-bg: rgba($white, .15) !default;\n$dropdown-dark-link-active-color: $dropdown-link-active-color !default;\n$dropdown-dark-link-active-bg: $dropdown-link-active-bg !default;\n$dropdown-dark-link-disabled-color: $gray-500 !default;\n$dropdown-dark-header-color: $gray-500 !default;\n// scss-docs-end dropdown-dark-variables\n\n\n// Pagination\n\n// scss-docs-start pagination-variables\n$pagination-padding-y: .375rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n\n$pagination-font-size: $font-size-base !default;\n\n$pagination-color: var(--#{$prefix}link-color) !default;\n$pagination-bg: var(--#{$prefix}body-bg) !default;\n$pagination-border-radius: var(--#{$prefix}border-radius) !default;\n$pagination-border-width: var(--#{$prefix}border-width) !default;\n$pagination-margin-start: calc(#{$pagination-border-width} * -1) !default; // stylelint-disable-line function-disallowed-list\n$pagination-border-color: var(--#{$prefix}border-color) !default;\n\n$pagination-focus-color: var(--#{$prefix}link-hover-color) !default;\n$pagination-focus-bg: var(--#{$prefix}secondary-bg) !default;\n$pagination-focus-box-shadow: $focus-ring-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: var(--#{$prefix}link-hover-color) !default;\n$pagination-hover-bg: var(--#{$prefix}tertiary-bg) !default;\n$pagination-hover-border-color: var(--#{$prefix}border-color) !default; // Todo in v6: remove this?\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $component-active-bg !default;\n\n$pagination-disabled-color: var(--#{$prefix}secondary-color) !default;\n$pagination-disabled-bg: var(--#{$prefix}secondary-bg) !default;\n$pagination-disabled-border-color: var(--#{$prefix}border-color) !default;\n\n$pagination-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$pagination-border-radius-sm: var(--#{$prefix}border-radius-sm) !default;\n$pagination-border-radius-lg: var(--#{$prefix}border-radius-lg) !default;\n// scss-docs-end pagination-variables\n\n\n// Placeholders\n\n// scss-docs-start placeholders\n$placeholder-opacity-max: .5 !default;\n$placeholder-opacity-min: .2 !default;\n// scss-docs-end placeholders\n\n// Cards\n\n// scss-docs-start card-variables\n$card-spacer-y: $spacer !default;\n$card-spacer-x: $spacer !default;\n$card-title-spacer-y: $spacer * .5 !default;\n$card-title-color: null !default;\n$card-subtitle-color: null !default;\n$card-border-width: var(--#{$prefix}border-width) !default;\n$card-border-color: var(--#{$prefix}border-color-translucent) !default;\n$card-border-radius: var(--#{$prefix}border-radius) !default;\n$card-box-shadow: null !default;\n$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;\n$card-cap-padding-y: $card-spacer-y * .5 !default;\n$card-cap-padding-x: $card-spacer-x !default;\n$card-cap-bg: rgba(var(--#{$prefix}body-color-rgb), .03) !default;\n$card-cap-color: null !default;\n$card-height: null !default;\n$card-color: null !default;\n$card-bg: var(--#{$prefix}body-bg) !default;\n$card-img-overlay-padding: $spacer !default;\n$card-group-margin: $grid-gutter-width * .5 !default;\n// scss-docs-end card-variables\n\n// Accordion\n\n// scss-docs-start accordion-variables\n$accordion-padding-y: 1rem !default;\n$accordion-padding-x: 1.25rem !default;\n$accordion-color: var(--#{$prefix}body-color) !default;\n$accordion-bg: var(--#{$prefix}body-bg) !default;\n$accordion-border-width: var(--#{$prefix}border-width) !default;\n$accordion-border-color: var(--#{$prefix}border-color) !default;\n$accordion-border-radius: var(--#{$prefix}border-radius) !default;\n$accordion-inner-border-radius: subtract($accordion-border-radius, $accordion-border-width) !default;\n\n$accordion-body-padding-y: $accordion-padding-y !default;\n$accordion-body-padding-x: $accordion-padding-x !default;\n\n$accordion-button-padding-y: $accordion-padding-y !default;\n$accordion-button-padding-x: $accordion-padding-x !default;\n$accordion-button-color: var(--#{$prefix}body-color) !default;\n$accordion-button-bg: var(--#{$prefix}accordion-bg) !default;\n$accordion-transition: $btn-transition, border-radius .15s ease !default;\n$accordion-button-active-bg: var(--#{$prefix}primary-bg-subtle) !default;\n$accordion-button-active-color: var(--#{$prefix}primary-text-emphasis) !default;\n\n// fusv-disable\n$accordion-button-focus-border-color: $input-focus-border-color !default; // Deprecated in v5.3.3\n// fusv-enable\n$accordion-button-focus-box-shadow: $btn-focus-box-shadow !default;\n\n$accordion-icon-width: 1.25rem !default;\n$accordion-icon-color: $body-color !default;\n$accordion-icon-active-color: $primary-text-emphasis !default;\n$accordion-icon-transition: transform .2s ease-in-out !default;\n$accordion-icon-transform: rotate(-180deg) !default;\n\n$accordion-button-icon: url(\"data:image/svg+xml,\") !default;\n$accordion-button-active-icon: url(\"data:image/svg+xml,\") !default;\n// scss-docs-end accordion-variables\n\n// Tooltips\n\n// scss-docs-start tooltip-variables\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: var(--#{$prefix}body-bg) !default;\n$tooltip-bg: var(--#{$prefix}emphasis-color) !default;\n$tooltip-border-radius: var(--#{$prefix}border-radius) !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: $spacer * .25 !default;\n$tooltip-padding-x: $spacer * .5 !default;\n$tooltip-margin: null !default; // TODO: remove this in v6\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n// fusv-disable\n$tooltip-arrow-color: null !default; // Deprecated in Bootstrap 5.2.0 for CSS variables\n// fusv-enable\n// scss-docs-end tooltip-variables\n\n// Form tooltips must come after regular tooltips\n// scss-docs-start tooltip-feedback-variables\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: null !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n// scss-docs-end tooltip-feedback-variables\n\n\n// Popovers\n\n// scss-docs-start popover-variables\n$popover-font-size: $font-size-sm !default;\n$popover-bg: var(--#{$prefix}body-bg) !default;\n$popover-max-width: 276px !default;\n$popover-border-width: var(--#{$prefix}border-width) !default;\n$popover-border-color: var(--#{$prefix}border-color-translucent) !default;\n$popover-border-radius: var(--#{$prefix}border-radius-lg) !default;\n$popover-inner-border-radius: calc(#{$popover-border-radius} - #{$popover-border-width}) !default; // stylelint-disable-line function-disallowed-list\n$popover-box-shadow: var(--#{$prefix}box-shadow) !default;\n\n$popover-header-font-size: $font-size-base !default;\n$popover-header-bg: var(--#{$prefix}secondary-bg) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: $spacer !default;\n\n$popover-body-color: var(--#{$prefix}body-color) !default;\n$popover-body-padding-y: $spacer !default;\n$popover-body-padding-x: $spacer !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n// scss-docs-end popover-variables\n\n// fusv-disable\n// Deprecated in Bootstrap 5.2.0 for CSS variables\n$popover-arrow-color: $popover-bg !default;\n$popover-arrow-outer-color: var(--#{$prefix}border-color-translucent) !default;\n// fusv-enable\n\n\n// Toasts\n\n// scss-docs-start toast-variables\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .5rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba(var(--#{$prefix}body-bg-rgb), .85) !default;\n$toast-border-width: var(--#{$prefix}border-width) !default;\n$toast-border-color: var(--#{$prefix}border-color-translucent) !default;\n$toast-border-radius: var(--#{$prefix}border-radius) !default;\n$toast-box-shadow: var(--#{$prefix}box-shadow) !default;\n$toast-spacing: $container-padding-x !default;\n\n$toast-header-color: var(--#{$prefix}secondary-color) !default;\n$toast-header-background-color: rgba(var(--#{$prefix}body-bg-rgb), .85) !default;\n$toast-header-border-color: $toast-border-color !default;\n// scss-docs-end toast-variables\n\n\n// Badges\n\n// scss-docs-start badge-variables\n$badge-font-size: .75em !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-color: $white !default;\n$badge-padding-y: .35em !default;\n$badge-padding-x: .65em !default;\n$badge-border-radius: var(--#{$prefix}border-radius) !default;\n// scss-docs-end badge-variables\n\n\n// Modals\n\n// scss-docs-start modal-variables\n$modal-inner-padding: $spacer !default;\n\n$modal-footer-margin-between: .5rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-color: null !default;\n$modal-content-bg: var(--#{$prefix}body-bg) !default;\n$modal-content-border-color: var(--#{$prefix}border-color-translucent) !default;\n$modal-content-border-width: var(--#{$prefix}border-width) !default;\n$modal-content-border-radius: var(--#{$prefix}border-radius-lg) !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs: var(--#{$prefix}box-shadow-sm) !default;\n$modal-content-box-shadow-sm-up: var(--#{$prefix}box-shadow) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n\n$modal-header-border-color: var(--#{$prefix}border-color) !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-header-padding-y: $modal-inner-padding !default;\n$modal-header-padding-x: $modal-inner-padding !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-footer-bg: null !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n\n$modal-sm: 300px !default;\n$modal-md: 500px !default;\n$modal-lg: 800px !default;\n$modal-xl: 1140px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n$modal-scale-transform: scale(1.02) !default;\n// scss-docs-end modal-variables\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n// scss-docs-start alert-variables\n$alert-padding-y: $spacer !default;\n$alert-padding-x: $spacer !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: var(--#{$prefix}border-radius) !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: var(--#{$prefix}border-width) !default;\n$alert-dismissible-padding-r: $alert-padding-x * 3 !default; // 3x covers width of x plus default padding on either side\n// scss-docs-end alert-variables\n\n// fusv-disable\n$alert-bg-scale: -80% !default; // Deprecated in v5.2.0, to be removed in v6\n$alert-border-scale: -70% !default; // Deprecated in v5.2.0, to be removed in v6\n$alert-color-scale: 40% !default; // Deprecated in v5.2.0, to be removed in v6\n// fusv-enable\n\n// Progress bars\n\n// scss-docs-start progress-variables\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n$progress-bg: var(--#{$prefix}secondary-bg) !default;\n$progress-border-radius: var(--#{$prefix}border-radius) !default;\n$progress-box-shadow: var(--#{$prefix}box-shadow-inset) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: $primary !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n// scss-docs-end progress-variables\n\n\n// List group\n\n// scss-docs-start list-group-variables\n$list-group-color: var(--#{$prefix}body-color) !default;\n$list-group-bg: var(--#{$prefix}body-bg) !default;\n$list-group-border-color: var(--#{$prefix}border-color) !default;\n$list-group-border-width: var(--#{$prefix}border-width) !default;\n$list-group-border-radius: var(--#{$prefix}border-radius) !default;\n\n$list-group-item-padding-y: $spacer * .5 !default;\n$list-group-item-padding-x: $spacer !default;\n// fusv-disable\n$list-group-item-bg-scale: -80% !default; // Deprecated in v5.3.0\n$list-group-item-color-scale: 40% !default; // Deprecated in v5.3.0\n// fusv-enable\n\n$list-group-hover-bg: var(--#{$prefix}tertiary-bg) !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: var(--#{$prefix}secondary-color) !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: var(--#{$prefix}secondary-color) !default;\n$list-group-action-hover-color: var(--#{$prefix}emphasis-color) !default;\n\n$list-group-action-active-color: var(--#{$prefix}body-color) !default;\n$list-group-action-active-bg: var(--#{$prefix}secondary-bg) !default;\n// scss-docs-end list-group-variables\n\n\n// Image thumbnails\n\n// scss-docs-start thumbnail-variables\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: var(--#{$prefix}body-bg) !default;\n$thumbnail-border-width: var(--#{$prefix}border-width) !default;\n$thumbnail-border-color: var(--#{$prefix}border-color) !default;\n$thumbnail-border-radius: var(--#{$prefix}border-radius) !default;\n$thumbnail-box-shadow: var(--#{$prefix}box-shadow-sm) !default;\n// scss-docs-end thumbnail-variables\n\n\n// Figures\n\n// scss-docs-start figure-variables\n$figure-caption-font-size: $small-font-size !default;\n$figure-caption-color: var(--#{$prefix}secondary-color) !default;\n// scss-docs-end figure-variables\n\n\n// Breadcrumbs\n\n// scss-docs-start breadcrumb-variables\n$breadcrumb-font-size: null !default;\n$breadcrumb-padding-y: 0 !default;\n$breadcrumb-padding-x: 0 !default;\n$breadcrumb-item-padding-x: .5rem !default;\n$breadcrumb-margin-bottom: 1rem !default;\n$breadcrumb-bg: null !default;\n$breadcrumb-divider-color: var(--#{$prefix}secondary-color) !default;\n$breadcrumb-active-color: var(--#{$prefix}secondary-color) !default;\n$breadcrumb-divider: quote(\"/\") !default;\n$breadcrumb-divider-flipped: $breadcrumb-divider !default;\n$breadcrumb-border-radius: null !default;\n// scss-docs-end breadcrumb-variables\n\n// Carousel\n\n// scss-docs-start carousel-variables\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-opacity: .5 !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-active-opacity: 1 !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n$carousel-caption-padding-y: 1.25rem !default;\n$carousel-caption-spacer: 1.25rem !default;\n\n$carousel-control-icon-width: 2rem !default;\n\n$carousel-control-prev-icon-bg: url(\"data:image/svg+xml,\") !default;\n$carousel-control-next-icon-bg: url(\"data:image/svg+xml,\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n// scss-docs-end carousel-variables\n\n// scss-docs-start carousel-dark-variables\n$carousel-dark-indicator-active-bg: $black !default;\n$carousel-dark-caption-color: $black !default;\n$carousel-dark-control-icon-filter: invert(1) grayscale(100) !default;\n// scss-docs-end carousel-dark-variables\n\n\n// Spinners\n\n// scss-docs-start spinner-variables\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-vertical-align: -.125em !default;\n$spinner-border-width: .25em !default;\n$spinner-animation-speed: .75s !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n// scss-docs-end spinner-variables\n\n\n// Close\n\n// scss-docs-start close-variables\n$btn-close-width: 1em !default;\n$btn-close-height: $btn-close-width !default;\n$btn-close-padding-x: .25em !default;\n$btn-close-padding-y: $btn-close-padding-x !default;\n$btn-close-color: $black !default;\n$btn-close-bg: url(\"data:image/svg+xml,\") !default;\n$btn-close-focus-shadow: $focus-ring-box-shadow !default;\n$btn-close-opacity: .5 !default;\n$btn-close-hover-opacity: .75 !default;\n$btn-close-focus-opacity: 1 !default;\n$btn-close-disabled-opacity: .25 !default;\n$btn-close-white-filter: invert(1) grayscale(100%) brightness(200%) !default;\n// scss-docs-end close-variables\n\n\n// Offcanvas\n\n// scss-docs-start offcanvas-variables\n$offcanvas-padding-y: $modal-inner-padding !default;\n$offcanvas-padding-x: $modal-inner-padding !default;\n$offcanvas-horizontal-width: 400px !default;\n$offcanvas-vertical-height: 30vh !default;\n$offcanvas-transition-duration: .3s !default;\n$offcanvas-border-color: $modal-content-border-color !default;\n$offcanvas-border-width: $modal-content-border-width !default;\n$offcanvas-title-line-height: $modal-title-line-height !default;\n$offcanvas-bg-color: var(--#{$prefix}body-bg) !default;\n$offcanvas-color: var(--#{$prefix}body-color) !default;\n$offcanvas-box-shadow: $modal-content-box-shadow-xs !default;\n$offcanvas-backdrop-bg: $modal-backdrop-bg !default;\n$offcanvas-backdrop-opacity: $modal-backdrop-opacity !default;\n// scss-docs-end offcanvas-variables\n\n// Code\n\n$code-font-size: $small-font-size !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .1875rem !default;\n$kbd-padding-x: .375rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: var(--#{$prefix}body-bg) !default;\n$kbd-bg: var(--#{$prefix}body-color) !default;\n$nested-kbd-font-weight: null !default; // Deprecated in v5.2.0, removing in v6\n\n$pre-color: null !default;\n\n@import \"variables-dark\"; // TODO: can be removed safely in v6, only here to avoid breaking changes in v5.3\n","// Row\n//\n// Rows contain your columns.\n\n:root {\n @each $name, $value in $grid-breakpoints {\n --#{$prefix}breakpoint-#{$name}: #{$value};\n }\n}\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n\n > * {\n @include make-col-ready();\n }\n }\n}\n\n@if $enable-cssgrid {\n .grid {\n display: grid;\n grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr);\n grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr);\n gap: var(--#{$prefix}gap, #{$grid-gutter-width});\n\n @include make-cssgrid();\n }\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-row($gutter: $grid-gutter-width) {\n --#{$prefix}gutter-x: #{$gutter};\n --#{$prefix}gutter-y: 0;\n display: flex;\n flex-wrap: wrap;\n // TODO: Revisit calc order after https://github.com/react-bootstrap/react-bootstrap/issues/6039 is fixed\n margin-top: calc(-1 * var(--#{$prefix}gutter-y)); // stylelint-disable-line function-disallowed-list\n margin-right: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n margin-left: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n}\n\n@mixin make-col-ready() {\n // Add box sizing if only the grid is loaded\n box-sizing: if(variable-exists(include-column-box-sizing) and $include-column-box-sizing, border-box, null);\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we set the width\n // later on to override this initial width.\n flex-shrink: 0;\n width: 100%;\n max-width: 100%; // Prevent `.col-auto`, `.col` (& responsive variants) from breaking out the grid\n padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n margin-top: var(--#{$prefix}gutter-y);\n}\n\n@mixin make-col($size: false, $columns: $grid-columns) {\n @if $size {\n flex: 0 0 auto;\n width: percentage(divide($size, $columns));\n\n } @else {\n flex: 1 1 0;\n max-width: 100%;\n }\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: divide($size, $columns);\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// number of columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 auto;\n width: percentage(divide(1, $count));\n }\n}\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex: 1 0 0%; // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n }\n\n .row-cols#{$infix}-auto > * {\n @include make-col-auto();\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n\n // Gutters\n //\n // Make use of `.g-*`, `.gx-*` or `.gy-*` utilities to change spacing between the columns.\n @each $key, $value in $gutters {\n .g#{$infix}-#{$key},\n .gx#{$infix}-#{$key} {\n --#{$prefix}gutter-x: #{$value};\n }\n\n .g#{$infix}-#{$key},\n .gy#{$infix}-#{$key} {\n --#{$prefix}gutter-y: #{$value};\n }\n }\n }\n }\n}\n\n@mixin make-cssgrid($columns: $grid-columns, $breakpoints: $grid-breakpoints) {\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .g-col#{$infix}-#{$i} {\n grid-column: auto / span $i;\n }\n }\n\n // Start with `1` because `0` is an invalid value.\n // Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible.\n @for $i from 1 through ($columns - 1) {\n .g-start#{$infix}-#{$i} {\n grid-column-start: $i;\n }\n }\n }\n }\n }\n}\n","// Utility generator\n// Used to generate utilities & print utilities\n@mixin generate-utility($utility, $infix: \"\", $is-rfs-media-query: false) {\n $values: map-get($utility, values);\n\n // If the values are a list or string, convert it into a map\n @if type-of($values) == \"string\" or type-of(nth($values, 1)) != \"list\" {\n $values: zip($values, $values);\n }\n\n @each $key, $value in $values {\n $properties: map-get($utility, property);\n\n // Multiple properties are possible, for example with vertical or horizontal margins or paddings\n @if type-of($properties) == \"string\" {\n $properties: append((), $properties);\n }\n\n // Use custom class if present\n $property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1));\n $property-class: if($property-class == null, \"\", $property-class);\n\n // Use custom CSS variable name if present, otherwise default to `class`\n $css-variable-name: if(map-has-key($utility, css-variable-name), map-get($utility, css-variable-name), map-get($utility, class));\n\n // State params to generate pseudo-classes\n $state: if(map-has-key($utility, state), map-get($utility, state), ());\n\n $infix: if($property-class == \"\" and str-slice($infix, 1, 1) == \"-\", str-slice($infix, 2), $infix);\n\n // Don't prefix if value key is null (e.g. with shadow class)\n $property-class-modifier: if($key, if($property-class == \"\" and $infix == \"\", \"\", \"-\") + $key, \"\");\n\n @if map-get($utility, rfs) {\n // Inside the media query\n @if $is-rfs-media-query {\n $val: rfs-value($value);\n\n // Do not render anything if fluid and non fluid values are the same\n $value: if($val == rfs-fluid-value($value), null, $val);\n }\n @else {\n $value: rfs-fluid-value($value);\n }\n }\n\n $is-css-var: map-get($utility, css-var);\n $is-local-vars: map-get($utility, local-vars);\n $is-rtl: map-get($utility, rtl);\n\n @if $value != null {\n @if $is-rtl == false {\n /* rtl:begin:remove */\n }\n\n @if $is-css-var {\n .#{$property-class + $infix + $property-class-modifier} {\n --#{$prefix}#{$css-variable-name}: #{$value};\n }\n\n @each $pseudo in $state {\n .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n --#{$prefix}#{$css-variable-name}: #{$value};\n }\n }\n } @else {\n .#{$property-class + $infix + $property-class-modifier} {\n @each $property in $properties {\n @if $is-local-vars {\n @each $local-var, $variable in $is-local-vars {\n --#{$prefix}#{$local-var}: #{$variable};\n }\n }\n #{$property}: $value if($enable-important-utilities, !important, null);\n }\n }\n\n @each $pseudo in $state {\n .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n @each $property in $properties {\n @if $is-local-vars {\n @each $local-var, $variable in $is-local-vars {\n --#{$prefix}#{$local-var}: #{$variable};\n }\n }\n #{$property}: $value if($enable-important-utilities, !important, null);\n }\n }\n }\n }\n\n @if $is-rtl == false {\n /* rtl:end:remove */\n }\n }\n }\n}\n","// Loop over each breakpoint\n@each $breakpoint in map-keys($grid-breakpoints) {\n\n // Generate media query if needed\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n // Loop over each utility property\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Only proceed if responsive media queries are enabled or if it's the base media query\n @if type-of($utility) == \"map\" and (map-get($utility, responsive) or $infix == \"\") {\n @include generate-utility($utility, $infix);\n }\n }\n }\n}\n\n// RFS rescaling\n@media (min-width: $rfs-mq-value) {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) {\n // Loop over each utility property\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Only proceed if responsive media queries are enabled or if it's the base media query\n @if type-of($utility) == \"map\" and map-get($utility, rfs) and (map-get($utility, responsive) or $infix == \"\") {\n @include generate-utility($utility, $infix, true);\n }\n }\n }\n }\n}\n\n\n// Print utilities\n@media print {\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Then check if the utility needs print styles\n @if type-of($utility) == \"map\" and map-get($utility, print) == true {\n @include generate-utility($utility, \"-print\");\n }\n }\n}\n"]} \ No newline at end of file diff --git a/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css new file mode 100644 index 0000000..49b843b --- /dev/null +++ b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap Grid v5.3.3 (https://getbootstrap.com/) + * Copyright 2011-2024 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}@media (min-width:576px){.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}}@media (min-width:768px){.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}}@media (min-width:992px){.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}}@media (min-width:1200px){.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}}@media (min-width:1400px){.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} +/*# sourceMappingURL=bootstrap-grid.min.css.map */ \ No newline at end of file diff --git a/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map new file mode 100644 index 0000000..a0db8b5 --- /dev/null +++ b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/mixins/_banner.scss","../../scss/_containers.scss","dist/css/bootstrap-grid.css","../../scss/mixins/_container.scss","../../scss/mixins/_breakpoints.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_utilities.scss","../../scss/utilities/_api.scss"],"names":[],"mappings":"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","sourcesContent":["@mixin bsBanner($file) {\n /*!\n * Bootstrap #{$file} v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-container-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n","/*!\n * Bootstrap Grid v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n --bs-gutter-x: 1.5rem;\n --bs-gutter-y: 0;\n width: 100%;\n padding-right: calc(var(--bs-gutter-x) * 0.5);\n padding-left: calc(var(--bs-gutter-x) * 0.5);\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container-sm, .container {\n max-width: 540px;\n }\n}\n@media (min-width: 768px) {\n .container-md, .container-sm, .container {\n max-width: 720px;\n }\n}\n@media (min-width: 992px) {\n .container-lg, .container-md, .container-sm, .container {\n max-width: 960px;\n }\n}\n@media (min-width: 1200px) {\n .container-xl, .container-lg, .container-md, .container-sm, .container {\n max-width: 1140px;\n }\n}\n@media (min-width: 1400px) {\n .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n max-width: 1320px;\n }\n}\n:root {\n --bs-breakpoint-xs: 0;\n --bs-breakpoint-sm: 576px;\n --bs-breakpoint-md: 768px;\n --bs-breakpoint-lg: 992px;\n --bs-breakpoint-xl: 1200px;\n --bs-breakpoint-xxl: 1400px;\n}\n\n.row {\n --bs-gutter-x: 1.5rem;\n --bs-gutter-y: 0;\n display: flex;\n flex-wrap: wrap;\n margin-top: calc(-1 * var(--bs-gutter-y));\n margin-right: calc(-0.5 * var(--bs-gutter-x));\n margin-left: calc(-0.5 * var(--bs-gutter-x));\n}\n.row > * {\n box-sizing: border-box;\n flex-shrink: 0;\n width: 100%;\n max-width: 100%;\n padding-right: calc(var(--bs-gutter-x) * 0.5);\n padding-left: calc(var(--bs-gutter-x) * 0.5);\n margin-top: var(--bs-gutter-y);\n}\n\n.col {\n flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n flex: 0 0 auto;\n width: auto;\n}\n\n.row-cols-1 > * {\n flex: 0 0 auto;\n width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 auto;\n width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 auto;\n width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 auto;\n width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n}\n\n.col-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n}\n\n.col-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n}\n\n.col-3 {\n flex: 0 0 auto;\n width: 25%;\n}\n\n.col-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n}\n\n.col-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n}\n\n.col-6 {\n flex: 0 0 auto;\n width: 50%;\n}\n\n.col-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n}\n\n.col-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n}\n\n.col-9 {\n flex: 0 0 auto;\n width: 75%;\n}\n\n.col-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n}\n\n.col-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n}\n\n.col-12 {\n flex: 0 0 auto;\n width: 100%;\n}\n\n.offset-1 {\n margin-left: 8.33333333%;\n}\n\n.offset-2 {\n margin-left: 16.66666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.33333333%;\n}\n\n.offset-5 {\n margin-left: 41.66666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.33333333%;\n}\n\n.offset-8 {\n margin-left: 66.66666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.33333333%;\n}\n\n.offset-11 {\n margin-left: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex: 1 0 0%;\n }\n .row-cols-sm-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-sm-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-sm-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-sm-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-sm-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-sm-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-sm-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-sm-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-sm-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-sm-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.33333333%;\n }\n .offset-sm-2 {\n margin-left: 16.66666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.33333333%;\n }\n .offset-sm-5 {\n margin-left: 41.66666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.33333333%;\n }\n .offset-sm-8 {\n margin-left: 66.66666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.33333333%;\n }\n .offset-sm-11 {\n margin-left: 91.66666667%;\n }\n .g-sm-0,\n .gx-sm-0 {\n --bs-gutter-x: 0;\n }\n .g-sm-0,\n .gy-sm-0 {\n --bs-gutter-y: 0;\n }\n .g-sm-1,\n .gx-sm-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-sm-1,\n .gy-sm-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-sm-2,\n .gx-sm-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-sm-2,\n .gy-sm-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-sm-3,\n .gx-sm-3 {\n --bs-gutter-x: 1rem;\n }\n .g-sm-3,\n .gy-sm-3 {\n --bs-gutter-y: 1rem;\n }\n .g-sm-4,\n .gx-sm-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-sm-4,\n .gy-sm-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-sm-5,\n .gx-sm-5 {\n --bs-gutter-x: 3rem;\n }\n .g-sm-5,\n .gy-sm-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 768px) {\n .col-md {\n flex: 1 0 0%;\n }\n .row-cols-md-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-md-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-md-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-md-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-md-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-md-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-md-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-md-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-md-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-md-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-md-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-md-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-md-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-md-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.33333333%;\n }\n .offset-md-2 {\n margin-left: 16.66666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.33333333%;\n }\n .offset-md-5 {\n margin-left: 41.66666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.33333333%;\n }\n .offset-md-8 {\n margin-left: 66.66666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.33333333%;\n }\n .offset-md-11 {\n margin-left: 91.66666667%;\n }\n .g-md-0,\n .gx-md-0 {\n --bs-gutter-x: 0;\n }\n .g-md-0,\n .gy-md-0 {\n --bs-gutter-y: 0;\n }\n .g-md-1,\n .gx-md-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-md-1,\n .gy-md-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-md-2,\n .gx-md-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-md-2,\n .gy-md-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-md-3,\n .gx-md-3 {\n --bs-gutter-x: 1rem;\n }\n .g-md-3,\n .gy-md-3 {\n --bs-gutter-y: 1rem;\n }\n .g-md-4,\n .gx-md-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-md-4,\n .gy-md-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-md-5,\n .gx-md-5 {\n --bs-gutter-x: 3rem;\n }\n .g-md-5,\n .gy-md-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 992px) {\n .col-lg {\n flex: 1 0 0%;\n }\n .row-cols-lg-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-lg-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-lg-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-lg-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-lg-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-lg-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-lg-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-lg-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-lg-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-lg-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.33333333%;\n }\n .offset-lg-2 {\n margin-left: 16.66666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.33333333%;\n }\n .offset-lg-5 {\n margin-left: 41.66666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.33333333%;\n }\n .offset-lg-8 {\n margin-left: 66.66666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.33333333%;\n }\n .offset-lg-11 {\n margin-left: 91.66666667%;\n }\n .g-lg-0,\n .gx-lg-0 {\n --bs-gutter-x: 0;\n }\n .g-lg-0,\n .gy-lg-0 {\n --bs-gutter-y: 0;\n }\n .g-lg-1,\n .gx-lg-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-lg-1,\n .gy-lg-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-lg-2,\n .gx-lg-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-lg-2,\n .gy-lg-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-lg-3,\n .gx-lg-3 {\n --bs-gutter-x: 1rem;\n }\n .g-lg-3,\n .gy-lg-3 {\n --bs-gutter-y: 1rem;\n }\n .g-lg-4,\n .gx-lg-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-lg-4,\n .gy-lg-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-lg-5,\n .gx-lg-5 {\n --bs-gutter-x: 3rem;\n }\n .g-lg-5,\n .gy-lg-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 1200px) {\n .col-xl {\n flex: 1 0 0%;\n }\n .row-cols-xl-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-xl-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-xl-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xl-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-xl-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-xl-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-xl-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-xl-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-xl-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-xl-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.33333333%;\n }\n .offset-xl-2 {\n margin-left: 16.66666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.33333333%;\n }\n .offset-xl-5 {\n margin-left: 41.66666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.33333333%;\n }\n .offset-xl-8 {\n margin-left: 66.66666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.33333333%;\n }\n .offset-xl-11 {\n margin-left: 91.66666667%;\n }\n .g-xl-0,\n .gx-xl-0 {\n --bs-gutter-x: 0;\n }\n .g-xl-0,\n .gy-xl-0 {\n --bs-gutter-y: 0;\n }\n .g-xl-1,\n .gx-xl-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-xl-1,\n .gy-xl-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-xl-2,\n .gx-xl-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-xl-2,\n .gy-xl-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-xl-3,\n .gx-xl-3 {\n --bs-gutter-x: 1rem;\n }\n .g-xl-3,\n .gy-xl-3 {\n --bs-gutter-y: 1rem;\n }\n .g-xl-4,\n .gx-xl-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-xl-4,\n .gy-xl-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-xl-5,\n .gx-xl-5 {\n --bs-gutter-x: 3rem;\n }\n .g-xl-5,\n .gy-xl-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 1400px) {\n .col-xxl {\n flex: 1 0 0%;\n }\n .row-cols-xxl-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-xxl-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-xxl-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-xxl-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-xxl-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-xxl-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-xxl-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xxl-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-xxl-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-xxl-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xxl-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-xxl-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-xxl-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-xxl-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-xxl-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-xxl-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-xxl-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-xxl-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-xxl-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-xxl-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-xxl-0 {\n margin-left: 0;\n }\n .offset-xxl-1 {\n margin-left: 8.33333333%;\n }\n .offset-xxl-2 {\n margin-left: 16.66666667%;\n }\n .offset-xxl-3 {\n margin-left: 25%;\n }\n .offset-xxl-4 {\n margin-left: 33.33333333%;\n }\n .offset-xxl-5 {\n margin-left: 41.66666667%;\n }\n .offset-xxl-6 {\n margin-left: 50%;\n }\n .offset-xxl-7 {\n margin-left: 58.33333333%;\n }\n .offset-xxl-8 {\n margin-left: 66.66666667%;\n }\n .offset-xxl-9 {\n margin-left: 75%;\n }\n .offset-xxl-10 {\n margin-left: 83.33333333%;\n }\n .offset-xxl-11 {\n margin-left: 91.66666667%;\n }\n .g-xxl-0,\n .gx-xxl-0 {\n --bs-gutter-x: 0;\n }\n .g-xxl-0,\n .gy-xxl-0 {\n --bs-gutter-y: 0;\n }\n .g-xxl-1,\n .gx-xxl-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-xxl-1,\n .gy-xxl-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-xxl-2,\n .gx-xxl-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-xxl-2,\n .gy-xxl-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-xxl-3,\n .gx-xxl-3 {\n --bs-gutter-x: 1rem;\n }\n .g-xxl-3,\n .gy-xxl-3 {\n --bs-gutter-y: 1rem;\n }\n .g-xxl-4,\n .gx-xxl-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-xxl-4,\n .gy-xxl-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-xxl-5,\n .gx-xxl-5 {\n --bs-gutter-x: 3rem;\n }\n .g-xxl-5,\n .gy-xxl-5 {\n --bs-gutter-y: 3rem;\n }\n}\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-grid {\n display: grid !important;\n}\n\n.d-inline-grid {\n display: inline-grid !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n.d-none {\n display: none !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n justify-content: space-evenly !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n.order-first {\n order: -1 !important;\n}\n\n.order-0 {\n order: 0 !important;\n}\n\n.order-1 {\n order: 1 !important;\n}\n\n.order-2 {\n order: 2 !important;\n}\n\n.order-3 {\n order: 3 !important;\n}\n\n.order-4 {\n order: 4 !important;\n}\n\n.order-5 {\n order: 5 !important;\n}\n\n.order-last {\n order: 6 !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mx-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n}\n\n.mx-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n}\n\n.mx-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n}\n\n.mx-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n}\n\n.mx-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n}\n\n.mx-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n}\n\n.my-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n}\n\n.my-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n}\n\n.my-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n}\n\n.my-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n}\n\n.mt-0 {\n margin-top: 0 !important;\n}\n\n.mt-1 {\n margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n margin-top: 1rem !important;\n}\n\n.mt-4 {\n margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n margin-top: 3rem !important;\n}\n\n.mt-auto {\n margin-top: auto !important;\n}\n\n.me-0 {\n margin-right: 0 !important;\n}\n\n.me-1 {\n margin-right: 0.25rem !important;\n}\n\n.me-2 {\n margin-right: 0.5rem !important;\n}\n\n.me-3 {\n margin-right: 1rem !important;\n}\n\n.me-4 {\n margin-right: 1.5rem !important;\n}\n\n.me-5 {\n margin-right: 3rem !important;\n}\n\n.me-auto {\n margin-right: auto !important;\n}\n\n.mb-0 {\n margin-bottom: 0 !important;\n}\n\n.mb-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n margin-bottom: auto !important;\n}\n\n.ms-0 {\n margin-left: 0 !important;\n}\n\n.ms-1 {\n margin-left: 0.25rem !important;\n}\n\n.ms-2 {\n margin-left: 0.5rem !important;\n}\n\n.ms-3 {\n margin-left: 1rem !important;\n}\n\n.ms-4 {\n margin-left: 1.5rem !important;\n}\n\n.ms-5 {\n margin-left: 3rem !important;\n}\n\n.ms-auto {\n margin-left: auto !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.px-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n}\n\n.px-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n}\n\n.px-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n}\n\n.px-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n}\n\n.px-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n}\n\n.px-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n}\n\n.py-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n}\n\n.py-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n}\n\n.py-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n padding-top: 0 !important;\n}\n\n.pt-1 {\n padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n padding-top: 1rem !important;\n}\n\n.pt-4 {\n padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n padding-top: 3rem !important;\n}\n\n.pe-0 {\n padding-right: 0 !important;\n}\n\n.pe-1 {\n padding-right: 0.25rem !important;\n}\n\n.pe-2 {\n padding-right: 0.5rem !important;\n}\n\n.pe-3 {\n padding-right: 1rem !important;\n}\n\n.pe-4 {\n padding-right: 1.5rem !important;\n}\n\n.pe-5 {\n padding-right: 3rem !important;\n}\n\n.pb-0 {\n padding-bottom: 0 !important;\n}\n\n.pb-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n padding-left: 0 !important;\n}\n\n.ps-1 {\n padding-left: 0.25rem !important;\n}\n\n.ps-2 {\n padding-left: 0.5rem !important;\n}\n\n.ps-3 {\n padding-left: 1rem !important;\n}\n\n.ps-4 {\n padding-left: 1.5rem !important;\n}\n\n.ps-5 {\n padding-left: 3rem !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-grid {\n display: grid !important;\n }\n .d-sm-inline-grid {\n display: inline-grid !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n .d-sm-none {\n display: none !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .justify-content-sm-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n .order-sm-first {\n order: -1 !important;\n }\n .order-sm-0 {\n order: 0 !important;\n }\n .order-sm-1 {\n order: 1 !important;\n }\n .order-sm-2 {\n order: 2 !important;\n }\n .order-sm-3 {\n order: 3 !important;\n }\n .order-sm-4 {\n order: 4 !important;\n }\n .order-sm-5 {\n order: 5 !important;\n }\n .order-sm-last {\n order: 6 !important;\n }\n .m-sm-0 {\n margin: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mx-sm-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-sm-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-sm-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-sm-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-sm-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-sm-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-sm-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-sm-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-sm-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-sm-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-sm-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-sm-0 {\n margin-top: 0 !important;\n }\n .mt-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mt-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mt-sm-3 {\n margin-top: 1rem !important;\n }\n .mt-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mt-sm-5 {\n margin-top: 3rem !important;\n }\n .mt-sm-auto {\n margin-top: auto !important;\n }\n .me-sm-0 {\n margin-right: 0 !important;\n }\n .me-sm-1 {\n margin-right: 0.25rem !important;\n }\n .me-sm-2 {\n margin-right: 0.5rem !important;\n }\n .me-sm-3 {\n margin-right: 1rem !important;\n }\n .me-sm-4 {\n margin-right: 1.5rem !important;\n }\n .me-sm-5 {\n margin-right: 3rem !important;\n }\n .me-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-0 {\n margin-bottom: 0 !important;\n }\n .mb-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-sm-3 {\n margin-bottom: 1rem !important;\n }\n .mb-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-sm-5 {\n margin-bottom: 3rem !important;\n }\n .mb-sm-auto {\n margin-bottom: auto !important;\n }\n .ms-sm-0 {\n margin-left: 0 !important;\n }\n .ms-sm-1 {\n margin-left: 0.25rem !important;\n }\n .ms-sm-2 {\n margin-left: 0.5rem !important;\n }\n .ms-sm-3 {\n margin-left: 1rem !important;\n }\n .ms-sm-4 {\n margin-left: 1.5rem !important;\n }\n .ms-sm-5 {\n margin-left: 3rem !important;\n }\n .ms-sm-auto {\n margin-left: auto !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .px-sm-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-sm-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-sm-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-sm-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-sm-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-sm-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-sm-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-sm-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-sm-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-sm-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-sm-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-sm-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-sm-0 {\n padding-top: 0 !important;\n }\n .pt-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pt-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pt-sm-3 {\n padding-top: 1rem !important;\n }\n .pt-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pt-sm-5 {\n padding-top: 3rem !important;\n }\n .pe-sm-0 {\n padding-right: 0 !important;\n }\n .pe-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pe-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pe-sm-3 {\n padding-right: 1rem !important;\n }\n .pe-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pe-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-0 {\n padding-bottom: 0 !important;\n }\n .pb-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pb-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-sm-5 {\n padding-bottom: 3rem !important;\n }\n .ps-sm-0 {\n padding-left: 0 !important;\n }\n .ps-sm-1 {\n padding-left: 0.25rem !important;\n }\n .ps-sm-2 {\n padding-left: 0.5rem !important;\n }\n .ps-sm-3 {\n padding-left: 1rem !important;\n }\n .ps-sm-4 {\n padding-left: 1.5rem !important;\n }\n .ps-sm-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 768px) {\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-grid {\n display: grid !important;\n }\n .d-md-inline-grid {\n display: inline-grid !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n .d-md-none {\n display: none !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .justify-content-md-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n .order-md-first {\n order: -1 !important;\n }\n .order-md-0 {\n order: 0 !important;\n }\n .order-md-1 {\n order: 1 !important;\n }\n .order-md-2 {\n order: 2 !important;\n }\n .order-md-3 {\n order: 3 !important;\n }\n .order-md-4 {\n order: 4 !important;\n }\n .order-md-5 {\n order: 5 !important;\n }\n .order-md-last {\n order: 6 !important;\n }\n .m-md-0 {\n margin: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mx-md-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-md-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-md-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-md-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-md-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-md-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-md-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-md-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-md-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-md-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-md-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-md-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-md-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-md-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-md-0 {\n margin-top: 0 !important;\n }\n .mt-md-1 {\n margin-top: 0.25rem !important;\n }\n .mt-md-2 {\n margin-top: 0.5rem !important;\n }\n .mt-md-3 {\n margin-top: 1rem !important;\n }\n .mt-md-4 {\n margin-top: 1.5rem !important;\n }\n .mt-md-5 {\n margin-top: 3rem !important;\n }\n .mt-md-auto {\n margin-top: auto !important;\n }\n .me-md-0 {\n margin-right: 0 !important;\n }\n .me-md-1 {\n margin-right: 0.25rem !important;\n }\n .me-md-2 {\n margin-right: 0.5rem !important;\n }\n .me-md-3 {\n margin-right: 1rem !important;\n }\n .me-md-4 {\n margin-right: 1.5rem !important;\n }\n .me-md-5 {\n margin-right: 3rem !important;\n }\n .me-md-auto {\n margin-right: auto !important;\n }\n .mb-md-0 {\n margin-bottom: 0 !important;\n }\n .mb-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-md-3 {\n margin-bottom: 1rem !important;\n }\n .mb-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-md-5 {\n margin-bottom: 3rem !important;\n }\n .mb-md-auto {\n margin-bottom: auto !important;\n }\n .ms-md-0 {\n margin-left: 0 !important;\n }\n .ms-md-1 {\n margin-left: 0.25rem !important;\n }\n .ms-md-2 {\n margin-left: 0.5rem !important;\n }\n .ms-md-3 {\n margin-left: 1rem !important;\n }\n .ms-md-4 {\n margin-left: 1.5rem !important;\n }\n .ms-md-5 {\n margin-left: 3rem !important;\n }\n .ms-md-auto {\n margin-left: auto !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .px-md-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-md-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-md-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-md-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-md-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-md-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-md-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-md-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-md-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-md-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-md-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-md-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-md-0 {\n padding-top: 0 !important;\n }\n .pt-md-1 {\n padding-top: 0.25rem !important;\n }\n .pt-md-2 {\n padding-top: 0.5rem !important;\n }\n .pt-md-3 {\n padding-top: 1rem !important;\n }\n .pt-md-4 {\n padding-top: 1.5rem !important;\n }\n .pt-md-5 {\n padding-top: 3rem !important;\n }\n .pe-md-0 {\n padding-right: 0 !important;\n }\n .pe-md-1 {\n padding-right: 0.25rem !important;\n }\n .pe-md-2 {\n padding-right: 0.5rem !important;\n }\n .pe-md-3 {\n padding-right: 1rem !important;\n }\n .pe-md-4 {\n padding-right: 1.5rem !important;\n }\n .pe-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-0 {\n padding-bottom: 0 !important;\n }\n .pb-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-md-3 {\n padding-bottom: 1rem !important;\n }\n .pb-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-md-5 {\n padding-bottom: 3rem !important;\n }\n .ps-md-0 {\n padding-left: 0 !important;\n }\n .ps-md-1 {\n padding-left: 0.25rem !important;\n }\n .ps-md-2 {\n padding-left: 0.5rem !important;\n }\n .ps-md-3 {\n padding-left: 1rem !important;\n }\n .ps-md-4 {\n padding-left: 1.5rem !important;\n }\n .ps-md-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 992px) {\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-grid {\n display: grid !important;\n }\n .d-lg-inline-grid {\n display: inline-grid !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n .d-lg-none {\n display: none !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .justify-content-lg-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n .order-lg-first {\n order: -1 !important;\n }\n .order-lg-0 {\n order: 0 !important;\n }\n .order-lg-1 {\n order: 1 !important;\n }\n .order-lg-2 {\n order: 2 !important;\n }\n .order-lg-3 {\n order: 3 !important;\n }\n .order-lg-4 {\n order: 4 !important;\n }\n .order-lg-5 {\n order: 5 !important;\n }\n .order-lg-last {\n order: 6 !important;\n }\n .m-lg-0 {\n margin: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mx-lg-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-lg-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-lg-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-lg-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-lg-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-lg-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-lg-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-lg-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-lg-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-lg-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-lg-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-lg-0 {\n margin-top: 0 !important;\n }\n .mt-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mt-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mt-lg-3 {\n margin-top: 1rem !important;\n }\n .mt-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mt-lg-5 {\n margin-top: 3rem !important;\n }\n .mt-lg-auto {\n margin-top: auto !important;\n }\n .me-lg-0 {\n margin-right: 0 !important;\n }\n .me-lg-1 {\n margin-right: 0.25rem !important;\n }\n .me-lg-2 {\n margin-right: 0.5rem !important;\n }\n .me-lg-3 {\n margin-right: 1rem !important;\n }\n .me-lg-4 {\n margin-right: 1.5rem !important;\n }\n .me-lg-5 {\n margin-right: 3rem !important;\n }\n .me-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-0 {\n margin-bottom: 0 !important;\n }\n .mb-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-lg-3 {\n margin-bottom: 1rem !important;\n }\n .mb-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-lg-5 {\n margin-bottom: 3rem !important;\n }\n .mb-lg-auto {\n margin-bottom: auto !important;\n }\n .ms-lg-0 {\n margin-left: 0 !important;\n }\n .ms-lg-1 {\n margin-left: 0.25rem !important;\n }\n .ms-lg-2 {\n margin-left: 0.5rem !important;\n }\n .ms-lg-3 {\n margin-left: 1rem !important;\n }\n .ms-lg-4 {\n margin-left: 1.5rem !important;\n }\n .ms-lg-5 {\n margin-left: 3rem !important;\n }\n .ms-lg-auto {\n margin-left: auto !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .px-lg-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-lg-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-lg-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-lg-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-lg-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-lg-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-lg-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-lg-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-lg-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-lg-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-lg-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-lg-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-lg-0 {\n padding-top: 0 !important;\n }\n .pt-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pt-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pt-lg-3 {\n padding-top: 1rem !important;\n }\n .pt-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pt-lg-5 {\n padding-top: 3rem !important;\n }\n .pe-lg-0 {\n padding-right: 0 !important;\n }\n .pe-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pe-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pe-lg-3 {\n padding-right: 1rem !important;\n }\n .pe-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pe-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-0 {\n padding-bottom: 0 !important;\n }\n .pb-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pb-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-lg-5 {\n padding-bottom: 3rem !important;\n }\n .ps-lg-0 {\n padding-left: 0 !important;\n }\n .ps-lg-1 {\n padding-left: 0.25rem !important;\n }\n .ps-lg-2 {\n padding-left: 0.5rem !important;\n }\n .ps-lg-3 {\n padding-left: 1rem !important;\n }\n .ps-lg-4 {\n padding-left: 1.5rem !important;\n }\n .ps-lg-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 1200px) {\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-grid {\n display: grid !important;\n }\n .d-xl-inline-grid {\n display: inline-grid !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n .d-xl-none {\n display: none !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .justify-content-xl-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n .order-xl-first {\n order: -1 !important;\n }\n .order-xl-0 {\n order: 0 !important;\n }\n .order-xl-1 {\n order: 1 !important;\n }\n .order-xl-2 {\n order: 2 !important;\n }\n .order-xl-3 {\n order: 3 !important;\n }\n .order-xl-4 {\n order: 4 !important;\n }\n .order-xl-5 {\n order: 5 !important;\n }\n .order-xl-last {\n order: 6 !important;\n }\n .m-xl-0 {\n margin: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mx-xl-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-xl-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-xl-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-xl-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-xl-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-xl-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-xl-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-xl-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-xl-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-xl-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-xl-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-xl-0 {\n margin-top: 0 !important;\n }\n .mt-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mt-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mt-xl-3 {\n margin-top: 1rem !important;\n }\n .mt-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mt-xl-5 {\n margin-top: 3rem !important;\n }\n .mt-xl-auto {\n margin-top: auto !important;\n }\n .me-xl-0 {\n margin-right: 0 !important;\n }\n .me-xl-1 {\n margin-right: 0.25rem !important;\n }\n .me-xl-2 {\n margin-right: 0.5rem !important;\n }\n .me-xl-3 {\n margin-right: 1rem !important;\n }\n .me-xl-4 {\n margin-right: 1.5rem !important;\n }\n .me-xl-5 {\n margin-right: 3rem !important;\n }\n .me-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-0 {\n margin-bottom: 0 !important;\n }\n .mb-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-xl-3 {\n margin-bottom: 1rem !important;\n }\n .mb-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-xl-5 {\n margin-bottom: 3rem !important;\n }\n .mb-xl-auto {\n margin-bottom: auto !important;\n }\n .ms-xl-0 {\n margin-left: 0 !important;\n }\n .ms-xl-1 {\n margin-left: 0.25rem !important;\n }\n .ms-xl-2 {\n margin-left: 0.5rem !important;\n }\n .ms-xl-3 {\n margin-left: 1rem !important;\n }\n .ms-xl-4 {\n margin-left: 1.5rem !important;\n }\n .ms-xl-5 {\n margin-left: 3rem !important;\n }\n .ms-xl-auto {\n margin-left: auto !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .px-xl-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-xl-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-xl-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-xl-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-xl-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-xl-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-xl-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-xl-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-xl-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-xl-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-xl-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-xl-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-xl-0 {\n padding-top: 0 !important;\n }\n .pt-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pt-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pt-xl-3 {\n padding-top: 1rem !important;\n }\n .pt-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pt-xl-5 {\n padding-top: 3rem !important;\n }\n .pe-xl-0 {\n padding-right: 0 !important;\n }\n .pe-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pe-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pe-xl-3 {\n padding-right: 1rem !important;\n }\n .pe-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pe-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-0 {\n padding-bottom: 0 !important;\n }\n .pb-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pb-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-xl-5 {\n padding-bottom: 3rem !important;\n }\n .ps-xl-0 {\n padding-left: 0 !important;\n }\n .ps-xl-1 {\n padding-left: 0.25rem !important;\n }\n .ps-xl-2 {\n padding-left: 0.5rem !important;\n }\n .ps-xl-3 {\n padding-left: 1rem !important;\n }\n .ps-xl-4 {\n padding-left: 1.5rem !important;\n }\n .ps-xl-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 1400px) {\n .d-xxl-inline {\n display: inline !important;\n }\n .d-xxl-inline-block {\n display: inline-block !important;\n }\n .d-xxl-block {\n display: block !important;\n }\n .d-xxl-grid {\n display: grid !important;\n }\n .d-xxl-inline-grid {\n display: inline-grid !important;\n }\n .d-xxl-table {\n display: table !important;\n }\n .d-xxl-table-row {\n display: table-row !important;\n }\n .d-xxl-table-cell {\n display: table-cell !important;\n }\n .d-xxl-flex {\n display: flex !important;\n }\n .d-xxl-inline-flex {\n display: inline-flex !important;\n }\n .d-xxl-none {\n display: none !important;\n }\n .flex-xxl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xxl-row {\n flex-direction: row !important;\n }\n .flex-xxl-column {\n flex-direction: column !important;\n }\n .flex-xxl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xxl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xxl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xxl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xxl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xxl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-xxl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xxl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xxl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xxl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xxl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xxl-center {\n justify-content: center !important;\n }\n .justify-content-xxl-between {\n justify-content: space-between !important;\n }\n .justify-content-xxl-around {\n justify-content: space-around !important;\n }\n .justify-content-xxl-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-xxl-start {\n align-items: flex-start !important;\n }\n .align-items-xxl-end {\n align-items: flex-end !important;\n }\n .align-items-xxl-center {\n align-items: center !important;\n }\n .align-items-xxl-baseline {\n align-items: baseline !important;\n }\n .align-items-xxl-stretch {\n align-items: stretch !important;\n }\n .align-content-xxl-start {\n align-content: flex-start !important;\n }\n .align-content-xxl-end {\n align-content: flex-end !important;\n }\n .align-content-xxl-center {\n align-content: center !important;\n }\n .align-content-xxl-between {\n align-content: space-between !important;\n }\n .align-content-xxl-around {\n align-content: space-around !important;\n }\n .align-content-xxl-stretch {\n align-content: stretch !important;\n }\n .align-self-xxl-auto {\n align-self: auto !important;\n }\n .align-self-xxl-start {\n align-self: flex-start !important;\n }\n .align-self-xxl-end {\n align-self: flex-end !important;\n }\n .align-self-xxl-center {\n align-self: center !important;\n }\n .align-self-xxl-baseline {\n align-self: baseline !important;\n }\n .align-self-xxl-stretch {\n align-self: stretch !important;\n }\n .order-xxl-first {\n order: -1 !important;\n }\n .order-xxl-0 {\n order: 0 !important;\n }\n .order-xxl-1 {\n order: 1 !important;\n }\n .order-xxl-2 {\n order: 2 !important;\n }\n .order-xxl-3 {\n order: 3 !important;\n }\n .order-xxl-4 {\n order: 4 !important;\n }\n .order-xxl-5 {\n order: 5 !important;\n }\n .order-xxl-last {\n order: 6 !important;\n }\n .m-xxl-0 {\n margin: 0 !important;\n }\n .m-xxl-1 {\n margin: 0.25rem !important;\n }\n .m-xxl-2 {\n margin: 0.5rem !important;\n }\n .m-xxl-3 {\n margin: 1rem !important;\n }\n .m-xxl-4 {\n margin: 1.5rem !important;\n }\n .m-xxl-5 {\n margin: 3rem !important;\n }\n .m-xxl-auto {\n margin: auto !important;\n }\n .mx-xxl-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-xxl-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-xxl-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-xxl-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-xxl-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-xxl-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-xxl-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-xxl-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-xxl-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-xxl-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-xxl-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-xxl-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-xxl-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-xxl-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-xxl-0 {\n margin-top: 0 !important;\n }\n .mt-xxl-1 {\n margin-top: 0.25rem !important;\n }\n .mt-xxl-2 {\n margin-top: 0.5rem !important;\n }\n .mt-xxl-3 {\n margin-top: 1rem !important;\n }\n .mt-xxl-4 {\n margin-top: 1.5rem !important;\n }\n .mt-xxl-5 {\n margin-top: 3rem !important;\n }\n .mt-xxl-auto {\n margin-top: auto !important;\n }\n .me-xxl-0 {\n margin-right: 0 !important;\n }\n .me-xxl-1 {\n margin-right: 0.25rem !important;\n }\n .me-xxl-2 {\n margin-right: 0.5rem !important;\n }\n .me-xxl-3 {\n margin-right: 1rem !important;\n }\n .me-xxl-4 {\n margin-right: 1.5rem !important;\n }\n .me-xxl-5 {\n margin-right: 3rem !important;\n }\n .me-xxl-auto {\n margin-right: auto !important;\n }\n .mb-xxl-0 {\n margin-bottom: 0 !important;\n }\n .mb-xxl-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-xxl-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-xxl-3 {\n margin-bottom: 1rem !important;\n }\n .mb-xxl-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-xxl-5 {\n margin-bottom: 3rem !important;\n }\n .mb-xxl-auto {\n margin-bottom: auto !important;\n }\n .ms-xxl-0 {\n margin-left: 0 !important;\n }\n .ms-xxl-1 {\n margin-left: 0.25rem !important;\n }\n .ms-xxl-2 {\n margin-left: 0.5rem !important;\n }\n .ms-xxl-3 {\n margin-left: 1rem !important;\n }\n .ms-xxl-4 {\n margin-left: 1.5rem !important;\n }\n .ms-xxl-5 {\n margin-left: 3rem !important;\n }\n .ms-xxl-auto {\n margin-left: auto !important;\n }\n .p-xxl-0 {\n padding: 0 !important;\n }\n .p-xxl-1 {\n padding: 0.25rem !important;\n }\n .p-xxl-2 {\n padding: 0.5rem !important;\n }\n .p-xxl-3 {\n padding: 1rem !important;\n }\n .p-xxl-4 {\n padding: 1.5rem !important;\n }\n .p-xxl-5 {\n padding: 3rem !important;\n }\n .px-xxl-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-xxl-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-xxl-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-xxl-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-xxl-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-xxl-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-xxl-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-xxl-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-xxl-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-xxl-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-xxl-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-xxl-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-xxl-0 {\n padding-top: 0 !important;\n }\n .pt-xxl-1 {\n padding-top: 0.25rem !important;\n }\n .pt-xxl-2 {\n padding-top: 0.5rem !important;\n }\n .pt-xxl-3 {\n padding-top: 1rem !important;\n }\n .pt-xxl-4 {\n padding-top: 1.5rem !important;\n }\n .pt-xxl-5 {\n padding-top: 3rem !important;\n }\n .pe-xxl-0 {\n padding-right: 0 !important;\n }\n .pe-xxl-1 {\n padding-right: 0.25rem !important;\n }\n .pe-xxl-2 {\n padding-right: 0.5rem !important;\n }\n .pe-xxl-3 {\n padding-right: 1rem !important;\n }\n .pe-xxl-4 {\n padding-right: 1.5rem !important;\n }\n .pe-xxl-5 {\n padding-right: 3rem !important;\n }\n .pb-xxl-0 {\n padding-bottom: 0 !important;\n }\n .pb-xxl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-xxl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-xxl-3 {\n padding-bottom: 1rem !important;\n }\n .pb-xxl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-xxl-5 {\n padding-bottom: 3rem !important;\n }\n .ps-xxl-0 {\n padding-left: 0 !important;\n }\n .ps-xxl-1 {\n padding-left: 0.25rem !important;\n }\n .ps-xxl-2 {\n padding-left: 0.5rem !important;\n }\n .ps-xxl-3 {\n padding-left: 1rem !important;\n }\n .ps-xxl-4 {\n padding-left: 1.5rem !important;\n }\n .ps-xxl-5 {\n padding-left: 3rem !important;\n }\n}\n@media print {\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-grid {\n display: grid !important;\n }\n .d-print-inline-grid {\n display: inline-grid !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n .d-print-none {\n display: none !important;\n }\n}\n\n/*# sourceMappingURL=bootstrap-grid.css.map */","// Container mixins\n\n@mixin make-container($gutter: $container-padding-x) {\n --#{$prefix}gutter-x: #{$gutter};\n --#{$prefix}gutter-y: 0;\n width: 100%;\n padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n margin-right: auto;\n margin-left: auto;\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl xxl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @if not $n {\n @error \"breakpoint `#{$name}` not found in `#{$breakpoints}`\";\n }\n @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width.\n// The maximum value is reduced by 0.02px to work around the limitations of\n// `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $max: map-get($breakpoints, $name);\n @return if($max and $max > 0, $max - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $next: breakpoint-next($name, $breakpoints);\n $max: breakpoint-max($next, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($next, $breakpoints) {\n @content;\n }\n }\n}\n","// Row\n//\n// Rows contain your columns.\n\n:root {\n @each $name, $value in $grid-breakpoints {\n --#{$prefix}breakpoint-#{$name}: #{$value};\n }\n}\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n\n > * {\n @include make-col-ready();\n }\n }\n}\n\n@if $enable-cssgrid {\n .grid {\n display: grid;\n grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr);\n grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr);\n gap: var(--#{$prefix}gap, #{$grid-gutter-width});\n\n @include make-cssgrid();\n }\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-row($gutter: $grid-gutter-width) {\n --#{$prefix}gutter-x: #{$gutter};\n --#{$prefix}gutter-y: 0;\n display: flex;\n flex-wrap: wrap;\n // TODO: Revisit calc order after https://github.com/react-bootstrap/react-bootstrap/issues/6039 is fixed\n margin-top: calc(-1 * var(--#{$prefix}gutter-y)); // stylelint-disable-line function-disallowed-list\n margin-right: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n margin-left: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n}\n\n@mixin make-col-ready() {\n // Add box sizing if only the grid is loaded\n box-sizing: if(variable-exists(include-column-box-sizing) and $include-column-box-sizing, border-box, null);\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we set the width\n // later on to override this initial width.\n flex-shrink: 0;\n width: 100%;\n max-width: 100%; // Prevent `.col-auto`, `.col` (& responsive variants) from breaking out the grid\n padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n margin-top: var(--#{$prefix}gutter-y);\n}\n\n@mixin make-col($size: false, $columns: $grid-columns) {\n @if $size {\n flex: 0 0 auto;\n width: percentage(divide($size, $columns));\n\n } @else {\n flex: 1 1 0;\n max-width: 100%;\n }\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: divide($size, $columns);\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// number of columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 auto;\n width: percentage(divide(1, $count));\n }\n}\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex: 1 0 0%; // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n }\n\n .row-cols#{$infix}-auto > * {\n @include make-col-auto();\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n\n // Gutters\n //\n // Make use of `.g-*`, `.gx-*` or `.gy-*` utilities to change spacing between the columns.\n @each $key, $value in $gutters {\n .g#{$infix}-#{$key},\n .gx#{$infix}-#{$key} {\n --#{$prefix}gutter-x: #{$value};\n }\n\n .g#{$infix}-#{$key},\n .gy#{$infix}-#{$key} {\n --#{$prefix}gutter-y: #{$value};\n }\n }\n }\n }\n}\n\n@mixin make-cssgrid($columns: $grid-columns, $breakpoints: $grid-breakpoints) {\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .g-col#{$infix}-#{$i} {\n grid-column: auto / span $i;\n }\n }\n\n // Start with `1` because `0` is an invalid value.\n // Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible.\n @for $i from 1 through ($columns - 1) {\n .g-start#{$infix}-#{$i} {\n grid-column-start: $i;\n }\n }\n }\n }\n }\n}\n","// Utility generator\n// Used to generate utilities & print utilities\n@mixin generate-utility($utility, $infix: \"\", $is-rfs-media-query: false) {\n $values: map-get($utility, values);\n\n // If the values are a list or string, convert it into a map\n @if type-of($values) == \"string\" or type-of(nth($values, 1)) != \"list\" {\n $values: zip($values, $values);\n }\n\n @each $key, $value in $values {\n $properties: map-get($utility, property);\n\n // Multiple properties are possible, for example with vertical or horizontal margins or paddings\n @if type-of($properties) == \"string\" {\n $properties: append((), $properties);\n }\n\n // Use custom class if present\n $property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1));\n $property-class: if($property-class == null, \"\", $property-class);\n\n // Use custom CSS variable name if present, otherwise default to `class`\n $css-variable-name: if(map-has-key($utility, css-variable-name), map-get($utility, css-variable-name), map-get($utility, class));\n\n // State params to generate pseudo-classes\n $state: if(map-has-key($utility, state), map-get($utility, state), ());\n\n $infix: if($property-class == \"\" and str-slice($infix, 1, 1) == \"-\", str-slice($infix, 2), $infix);\n\n // Don't prefix if value key is null (e.g. with shadow class)\n $property-class-modifier: if($key, if($property-class == \"\" and $infix == \"\", \"\", \"-\") + $key, \"\");\n\n @if map-get($utility, rfs) {\n // Inside the media query\n @if $is-rfs-media-query {\n $val: rfs-value($value);\n\n // Do not render anything if fluid and non fluid values are the same\n $value: if($val == rfs-fluid-value($value), null, $val);\n }\n @else {\n $value: rfs-fluid-value($value);\n }\n }\n\n $is-css-var: map-get($utility, css-var);\n $is-local-vars: map-get($utility, local-vars);\n $is-rtl: map-get($utility, rtl);\n\n @if $value != null {\n @if $is-rtl == false {\n /* rtl:begin:remove */\n }\n\n @if $is-css-var {\n .#{$property-class + $infix + $property-class-modifier} {\n --#{$prefix}#{$css-variable-name}: #{$value};\n }\n\n @each $pseudo in $state {\n .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n --#{$prefix}#{$css-variable-name}: #{$value};\n }\n }\n } @else {\n .#{$property-class + $infix + $property-class-modifier} {\n @each $property in $properties {\n @if $is-local-vars {\n @each $local-var, $variable in $is-local-vars {\n --#{$prefix}#{$local-var}: #{$variable};\n }\n }\n #{$property}: $value if($enable-important-utilities, !important, null);\n }\n }\n\n @each $pseudo in $state {\n .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n @each $property in $properties {\n @if $is-local-vars {\n @each $local-var, $variable in $is-local-vars {\n --#{$prefix}#{$local-var}: #{$variable};\n }\n }\n #{$property}: $value if($enable-important-utilities, !important, null);\n }\n }\n }\n }\n\n @if $is-rtl == false {\n /* rtl:end:remove */\n }\n }\n }\n}\n","// Loop over each breakpoint\n@each $breakpoint in map-keys($grid-breakpoints) {\n\n // Generate media query if needed\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n // Loop over each utility property\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Only proceed if responsive media queries are enabled or if it's the base media query\n @if type-of($utility) == \"map\" and (map-get($utility, responsive) or $infix == \"\") {\n @include generate-utility($utility, $infix);\n }\n }\n }\n}\n\n// RFS rescaling\n@media (min-width: $rfs-mq-value) {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) {\n // Loop over each utility property\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Only proceed if responsive media queries are enabled or if it's the base media query\n @if type-of($utility) == \"map\" and map-get($utility, rfs) and (map-get($utility, responsive) or $infix == \"\") {\n @include generate-utility($utility, $infix, true);\n }\n }\n }\n }\n}\n\n\n// Print utilities\n@media print {\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Then check if the utility needs print styles\n @if type-of($utility) == \"map\" and map-get($utility, print) == true {\n @include generate-utility($utility, \"-print\");\n }\n }\n}\n"]} \ No newline at end of file diff --git a/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css new file mode 100644 index 0000000..1a5d656 --- /dev/null +++ b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css @@ -0,0 +1,4084 @@ +/*! + * Bootstrap Grid v5.3.3 (https://getbootstrap.com/) + * Copyright 2011-2024 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +.container, +.container-fluid, +.container-xxl, +.container-xl, +.container-lg, +.container-md, +.container-sm { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + width: 100%; + padding-left: calc(var(--bs-gutter-x) * 0.5); + padding-right: calc(var(--bs-gutter-x) * 0.5); + margin-left: auto; + margin-right: auto; +} + +@media (min-width: 576px) { + .container-sm, .container { + max-width: 540px; + } +} +@media (min-width: 768px) { + .container-md, .container-sm, .container { + max-width: 720px; + } +} +@media (min-width: 992px) { + .container-lg, .container-md, .container-sm, .container { + max-width: 960px; + } +} +@media (min-width: 1200px) { + .container-xl, .container-lg, .container-md, .container-sm, .container { + max-width: 1140px; + } +} +@media (min-width: 1400px) { + .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container { + max-width: 1320px; + } +} +:root { + --bs-breakpoint-xs: 0; + --bs-breakpoint-sm: 576px; + --bs-breakpoint-md: 768px; + --bs-breakpoint-lg: 992px; + --bs-breakpoint-xl: 1200px; + --bs-breakpoint-xxl: 1400px; +} + +.row { + --bs-gutter-x: 1.5rem; + --bs-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-top: calc(-1 * var(--bs-gutter-y)); + margin-left: calc(-0.5 * var(--bs-gutter-x)); + margin-right: calc(-0.5 * var(--bs-gutter-x)); +} +.row > * { + box-sizing: border-box; + flex-shrink: 0; + width: 100%; + max-width: 100%; + padding-left: calc(var(--bs-gutter-x) * 0.5); + padding-right: calc(var(--bs-gutter-x) * 0.5); + margin-top: var(--bs-gutter-y); +} + +.col { + flex: 1 0 0%; +} + +.row-cols-auto > * { + flex: 0 0 auto; + width: auto; +} + +.row-cols-1 > * { + flex: 0 0 auto; + width: 100%; +} + +.row-cols-2 > * { + flex: 0 0 auto; + width: 50%; +} + +.row-cols-3 > * { + flex: 0 0 auto; + width: 33.33333333%; +} + +.row-cols-4 > * { + flex: 0 0 auto; + width: 25%; +} + +.row-cols-5 > * { + flex: 0 0 auto; + width: 20%; +} + +.row-cols-6 > * { + flex: 0 0 auto; + width: 16.66666667%; +} + +.col-auto { + flex: 0 0 auto; + width: auto; +} + +.col-1 { + flex: 0 0 auto; + width: 8.33333333%; +} + +.col-2 { + flex: 0 0 auto; + width: 16.66666667%; +} + +.col-3 { + flex: 0 0 auto; + width: 25%; +} + +.col-4 { + flex: 0 0 auto; + width: 33.33333333%; +} + +.col-5 { + flex: 0 0 auto; + width: 41.66666667%; +} + +.col-6 { + flex: 0 0 auto; + width: 50%; +} + +.col-7 { + flex: 0 0 auto; + width: 58.33333333%; +} + +.col-8 { + flex: 0 0 auto; + width: 66.66666667%; +} + +.col-9 { + flex: 0 0 auto; + width: 75%; +} + +.col-10 { + flex: 0 0 auto; + width: 83.33333333%; +} + +.col-11 { + flex: 0 0 auto; + width: 91.66666667%; +} + +.col-12 { + flex: 0 0 auto; + width: 100%; +} + +.offset-1 { + margin-right: 8.33333333%; +} + +.offset-2 { + margin-right: 16.66666667%; +} + +.offset-3 { + margin-right: 25%; +} + +.offset-4 { + margin-right: 33.33333333%; +} + +.offset-5 { + margin-right: 41.66666667%; +} + +.offset-6 { + margin-right: 50%; +} + +.offset-7 { + margin-right: 58.33333333%; +} + +.offset-8 { + margin-right: 66.66666667%; +} + +.offset-9 { + margin-right: 75%; +} + +.offset-10 { + margin-right: 83.33333333%; +} + +.offset-11 { + margin-right: 91.66666667%; +} + +.g-0, +.gx-0 { + --bs-gutter-x: 0; +} + +.g-0, +.gy-0 { + --bs-gutter-y: 0; +} + +.g-1, +.gx-1 { + --bs-gutter-x: 0.25rem; +} + +.g-1, +.gy-1 { + --bs-gutter-y: 0.25rem; +} + +.g-2, +.gx-2 { + --bs-gutter-x: 0.5rem; +} + +.g-2, +.gy-2 { + --bs-gutter-y: 0.5rem; +} + +.g-3, +.gx-3 { + --bs-gutter-x: 1rem; +} + +.g-3, +.gy-3 { + --bs-gutter-y: 1rem; +} + +.g-4, +.gx-4 { + --bs-gutter-x: 1.5rem; +} + +.g-4, +.gy-4 { + --bs-gutter-y: 1.5rem; +} + +.g-5, +.gx-5 { + --bs-gutter-x: 3rem; +} + +.g-5, +.gy-5 { + --bs-gutter-y: 3rem; +} + +@media (min-width: 576px) { + .col-sm { + flex: 1 0 0%; + } + .row-cols-sm-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-sm-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-sm-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-sm-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-sm-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-sm-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-sm-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-sm-auto { + flex: 0 0 auto; + width: auto; + } + .col-sm-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-sm-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-sm-3 { + flex: 0 0 auto; + width: 25%; + } + .col-sm-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-sm-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-sm-6 { + flex: 0 0 auto; + width: 50%; + } + .col-sm-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-sm-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-sm-9 { + flex: 0 0 auto; + width: 75%; + } + .col-sm-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-sm-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-sm-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-sm-0 { + margin-right: 0; + } + .offset-sm-1 { + margin-right: 8.33333333%; + } + .offset-sm-2 { + margin-right: 16.66666667%; + } + .offset-sm-3 { + margin-right: 25%; + } + .offset-sm-4 { + margin-right: 33.33333333%; + } + .offset-sm-5 { + margin-right: 41.66666667%; + } + .offset-sm-6 { + margin-right: 50%; + } + .offset-sm-7 { + margin-right: 58.33333333%; + } + .offset-sm-8 { + margin-right: 66.66666667%; + } + .offset-sm-9 { + margin-right: 75%; + } + .offset-sm-10 { + margin-right: 83.33333333%; + } + .offset-sm-11 { + margin-right: 91.66666667%; + } + .g-sm-0, + .gx-sm-0 { + --bs-gutter-x: 0; + } + .g-sm-0, + .gy-sm-0 { + --bs-gutter-y: 0; + } + .g-sm-1, + .gx-sm-1 { + --bs-gutter-x: 0.25rem; + } + .g-sm-1, + .gy-sm-1 { + --bs-gutter-y: 0.25rem; + } + .g-sm-2, + .gx-sm-2 { + --bs-gutter-x: 0.5rem; + } + .g-sm-2, + .gy-sm-2 { + --bs-gutter-y: 0.5rem; + } + .g-sm-3, + .gx-sm-3 { + --bs-gutter-x: 1rem; + } + .g-sm-3, + .gy-sm-3 { + --bs-gutter-y: 1rem; + } + .g-sm-4, + .gx-sm-4 { + --bs-gutter-x: 1.5rem; + } + .g-sm-4, + .gy-sm-4 { + --bs-gutter-y: 1.5rem; + } + .g-sm-5, + .gx-sm-5 { + --bs-gutter-x: 3rem; + } + .g-sm-5, + .gy-sm-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 768px) { + .col-md { + flex: 1 0 0%; + } + .row-cols-md-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-md-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-md-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-md-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-md-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-md-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-md-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-md-auto { + flex: 0 0 auto; + width: auto; + } + .col-md-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-md-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-md-3 { + flex: 0 0 auto; + width: 25%; + } + .col-md-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-md-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-md-6 { + flex: 0 0 auto; + width: 50%; + } + .col-md-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-md-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-md-9 { + flex: 0 0 auto; + width: 75%; + } + .col-md-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-md-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-md-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-md-0 { + margin-right: 0; + } + .offset-md-1 { + margin-right: 8.33333333%; + } + .offset-md-2 { + margin-right: 16.66666667%; + } + .offset-md-3 { + margin-right: 25%; + } + .offset-md-4 { + margin-right: 33.33333333%; + } + .offset-md-5 { + margin-right: 41.66666667%; + } + .offset-md-6 { + margin-right: 50%; + } + .offset-md-7 { + margin-right: 58.33333333%; + } + .offset-md-8 { + margin-right: 66.66666667%; + } + .offset-md-9 { + margin-right: 75%; + } + .offset-md-10 { + margin-right: 83.33333333%; + } + .offset-md-11 { + margin-right: 91.66666667%; + } + .g-md-0, + .gx-md-0 { + --bs-gutter-x: 0; + } + .g-md-0, + .gy-md-0 { + --bs-gutter-y: 0; + } + .g-md-1, + .gx-md-1 { + --bs-gutter-x: 0.25rem; + } + .g-md-1, + .gy-md-1 { + --bs-gutter-y: 0.25rem; + } + .g-md-2, + .gx-md-2 { + --bs-gutter-x: 0.5rem; + } + .g-md-2, + .gy-md-2 { + --bs-gutter-y: 0.5rem; + } + .g-md-3, + .gx-md-3 { + --bs-gutter-x: 1rem; + } + .g-md-3, + .gy-md-3 { + --bs-gutter-y: 1rem; + } + .g-md-4, + .gx-md-4 { + --bs-gutter-x: 1.5rem; + } + .g-md-4, + .gy-md-4 { + --bs-gutter-y: 1.5rem; + } + .g-md-5, + .gx-md-5 { + --bs-gutter-x: 3rem; + } + .g-md-5, + .gy-md-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 992px) { + .col-lg { + flex: 1 0 0%; + } + .row-cols-lg-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-lg-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-lg-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-lg-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-lg-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-lg-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-lg-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-lg-auto { + flex: 0 0 auto; + width: auto; + } + .col-lg-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-lg-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-lg-3 { + flex: 0 0 auto; + width: 25%; + } + .col-lg-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-lg-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-lg-6 { + flex: 0 0 auto; + width: 50%; + } + .col-lg-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-lg-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-lg-9 { + flex: 0 0 auto; + width: 75%; + } + .col-lg-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-lg-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-lg-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-lg-0 { + margin-right: 0; + } + .offset-lg-1 { + margin-right: 8.33333333%; + } + .offset-lg-2 { + margin-right: 16.66666667%; + } + .offset-lg-3 { + margin-right: 25%; + } + .offset-lg-4 { + margin-right: 33.33333333%; + } + .offset-lg-5 { + margin-right: 41.66666667%; + } + .offset-lg-6 { + margin-right: 50%; + } + .offset-lg-7 { + margin-right: 58.33333333%; + } + .offset-lg-8 { + margin-right: 66.66666667%; + } + .offset-lg-9 { + margin-right: 75%; + } + .offset-lg-10 { + margin-right: 83.33333333%; + } + .offset-lg-11 { + margin-right: 91.66666667%; + } + .g-lg-0, + .gx-lg-0 { + --bs-gutter-x: 0; + } + .g-lg-0, + .gy-lg-0 { + --bs-gutter-y: 0; + } + .g-lg-1, + .gx-lg-1 { + --bs-gutter-x: 0.25rem; + } + .g-lg-1, + .gy-lg-1 { + --bs-gutter-y: 0.25rem; + } + .g-lg-2, + .gx-lg-2 { + --bs-gutter-x: 0.5rem; + } + .g-lg-2, + .gy-lg-2 { + --bs-gutter-y: 0.5rem; + } + .g-lg-3, + .gx-lg-3 { + --bs-gutter-x: 1rem; + } + .g-lg-3, + .gy-lg-3 { + --bs-gutter-y: 1rem; + } + .g-lg-4, + .gx-lg-4 { + --bs-gutter-x: 1.5rem; + } + .g-lg-4, + .gy-lg-4 { + --bs-gutter-y: 1.5rem; + } + .g-lg-5, + .gx-lg-5 { + --bs-gutter-x: 3rem; + } + .g-lg-5, + .gy-lg-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1200px) { + .col-xl { + flex: 1 0 0%; + } + .row-cols-xl-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-xl-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-xl-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-xl-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-xl-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-xl-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-xl-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xl-auto { + flex: 0 0 auto; + width: auto; + } + .col-xl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-xl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xl-3 { + flex: 0 0 auto; + width: 25%; + } + .col-xl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-xl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-xl-6 { + flex: 0 0 auto; + width: 50%; + } + .col-xl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-xl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-xl-9 { + flex: 0 0 auto; + width: 75%; + } + .col-xl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-xl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-xl-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-xl-0 { + margin-right: 0; + } + .offset-xl-1 { + margin-right: 8.33333333%; + } + .offset-xl-2 { + margin-right: 16.66666667%; + } + .offset-xl-3 { + margin-right: 25%; + } + .offset-xl-4 { + margin-right: 33.33333333%; + } + .offset-xl-5 { + margin-right: 41.66666667%; + } + .offset-xl-6 { + margin-right: 50%; + } + .offset-xl-7 { + margin-right: 58.33333333%; + } + .offset-xl-8 { + margin-right: 66.66666667%; + } + .offset-xl-9 { + margin-right: 75%; + } + .offset-xl-10 { + margin-right: 83.33333333%; + } + .offset-xl-11 { + margin-right: 91.66666667%; + } + .g-xl-0, + .gx-xl-0 { + --bs-gutter-x: 0; + } + .g-xl-0, + .gy-xl-0 { + --bs-gutter-y: 0; + } + .g-xl-1, + .gx-xl-1 { + --bs-gutter-x: 0.25rem; + } + .g-xl-1, + .gy-xl-1 { + --bs-gutter-y: 0.25rem; + } + .g-xl-2, + .gx-xl-2 { + --bs-gutter-x: 0.5rem; + } + .g-xl-2, + .gy-xl-2 { + --bs-gutter-y: 0.5rem; + } + .g-xl-3, + .gx-xl-3 { + --bs-gutter-x: 1rem; + } + .g-xl-3, + .gy-xl-3 { + --bs-gutter-y: 1rem; + } + .g-xl-4, + .gx-xl-4 { + --bs-gutter-x: 1.5rem; + } + .g-xl-4, + .gy-xl-4 { + --bs-gutter-y: 1.5rem; + } + .g-xl-5, + .gx-xl-5 { + --bs-gutter-x: 3rem; + } + .g-xl-5, + .gy-xl-5 { + --bs-gutter-y: 3rem; + } +} +@media (min-width: 1400px) { + .col-xxl { + flex: 1 0 0%; + } + .row-cols-xxl-auto > * { + flex: 0 0 auto; + width: auto; + } + .row-cols-xxl-1 > * { + flex: 0 0 auto; + width: 100%; + } + .row-cols-xxl-2 > * { + flex: 0 0 auto; + width: 50%; + } + .row-cols-xxl-3 > * { + flex: 0 0 auto; + width: 33.33333333%; + } + .row-cols-xxl-4 > * { + flex: 0 0 auto; + width: 25%; + } + .row-cols-xxl-5 > * { + flex: 0 0 auto; + width: 20%; + } + .row-cols-xxl-6 > * { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xxl-auto { + flex: 0 0 auto; + width: auto; + } + .col-xxl-1 { + flex: 0 0 auto; + width: 8.33333333%; + } + .col-xxl-2 { + flex: 0 0 auto; + width: 16.66666667%; + } + .col-xxl-3 { + flex: 0 0 auto; + width: 25%; + } + .col-xxl-4 { + flex: 0 0 auto; + width: 33.33333333%; + } + .col-xxl-5 { + flex: 0 0 auto; + width: 41.66666667%; + } + .col-xxl-6 { + flex: 0 0 auto; + width: 50%; + } + .col-xxl-7 { + flex: 0 0 auto; + width: 58.33333333%; + } + .col-xxl-8 { + flex: 0 0 auto; + width: 66.66666667%; + } + .col-xxl-9 { + flex: 0 0 auto; + width: 75%; + } + .col-xxl-10 { + flex: 0 0 auto; + width: 83.33333333%; + } + .col-xxl-11 { + flex: 0 0 auto; + width: 91.66666667%; + } + .col-xxl-12 { + flex: 0 0 auto; + width: 100%; + } + .offset-xxl-0 { + margin-right: 0; + } + .offset-xxl-1 { + margin-right: 8.33333333%; + } + .offset-xxl-2 { + margin-right: 16.66666667%; + } + .offset-xxl-3 { + margin-right: 25%; + } + .offset-xxl-4 { + margin-right: 33.33333333%; + } + .offset-xxl-5 { + margin-right: 41.66666667%; + } + .offset-xxl-6 { + margin-right: 50%; + } + .offset-xxl-7 { + margin-right: 58.33333333%; + } + .offset-xxl-8 { + margin-right: 66.66666667%; + } + .offset-xxl-9 { + margin-right: 75%; + } + .offset-xxl-10 { + margin-right: 83.33333333%; + } + .offset-xxl-11 { + margin-right: 91.66666667%; + } + .g-xxl-0, + .gx-xxl-0 { + --bs-gutter-x: 0; + } + .g-xxl-0, + .gy-xxl-0 { + --bs-gutter-y: 0; + } + .g-xxl-1, + .gx-xxl-1 { + --bs-gutter-x: 0.25rem; + } + .g-xxl-1, + .gy-xxl-1 { + --bs-gutter-y: 0.25rem; + } + .g-xxl-2, + .gx-xxl-2 { + --bs-gutter-x: 0.5rem; + } + .g-xxl-2, + .gy-xxl-2 { + --bs-gutter-y: 0.5rem; + } + .g-xxl-3, + .gx-xxl-3 { + --bs-gutter-x: 1rem; + } + .g-xxl-3, + .gy-xxl-3 { + --bs-gutter-y: 1rem; + } + .g-xxl-4, + .gx-xxl-4 { + --bs-gutter-x: 1.5rem; + } + .g-xxl-4, + .gy-xxl-4 { + --bs-gutter-y: 1.5rem; + } + .g-xxl-5, + .gx-xxl-5 { + --bs-gutter-x: 3rem; + } + .g-xxl-5, + .gy-xxl-5 { + --bs-gutter-y: 3rem; + } +} +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-grid { + display: grid !important; +} + +.d-inline-grid { + display: inline-grid !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: flex !important; +} + +.d-inline-flex { + display: inline-flex !important; +} + +.d-none { + display: none !important; +} + +.flex-fill { + flex: 1 1 auto !important; +} + +.flex-row { + flex-direction: row !important; +} + +.flex-column { + flex-direction: column !important; +} + +.flex-row-reverse { + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + flex-direction: column-reverse !important; +} + +.flex-grow-0 { + flex-grow: 0 !important; +} + +.flex-grow-1 { + flex-grow: 1 !important; +} + +.flex-shrink-0 { + flex-shrink: 0 !important; +} + +.flex-shrink-1 { + flex-shrink: 1 !important; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.flex-nowrap { + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + justify-content: flex-start !important; +} + +.justify-content-end { + justify-content: flex-end !important; +} + +.justify-content-center { + justify-content: center !important; +} + +.justify-content-between { + justify-content: space-between !important; +} + +.justify-content-around { + justify-content: space-around !important; +} + +.justify-content-evenly { + justify-content: space-evenly !important; +} + +.align-items-start { + align-items: flex-start !important; +} + +.align-items-end { + align-items: flex-end !important; +} + +.align-items-center { + align-items: center !important; +} + +.align-items-baseline { + align-items: baseline !important; +} + +.align-items-stretch { + align-items: stretch !important; +} + +.align-content-start { + align-content: flex-start !important; +} + +.align-content-end { + align-content: flex-end !important; +} + +.align-content-center { + align-content: center !important; +} + +.align-content-between { + align-content: space-between !important; +} + +.align-content-around { + align-content: space-around !important; +} + +.align-content-stretch { + align-content: stretch !important; +} + +.align-self-auto { + align-self: auto !important; +} + +.align-self-start { + align-self: flex-start !important; +} + +.align-self-end { + align-self: flex-end !important; +} + +.align-self-center { + align-self: center !important; +} + +.align-self-baseline { + align-self: baseline !important; +} + +.align-self-stretch { + align-self: stretch !important; +} + +.order-first { + order: -1 !important; +} + +.order-0 { + order: 0 !important; +} + +.order-1 { + order: 1 !important; +} + +.order-2 { + order: 2 !important; +} + +.order-3 { + order: 3 !important; +} + +.order-4 { + order: 4 !important; +} + +.order-5 { + order: 5 !important; +} + +.order-last { + order: 6 !important; +} + +.m-0 { + margin: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mx-0 { + margin-left: 0 !important; + margin-right: 0 !important; +} + +.mx-1 { + margin-left: 0.25rem !important; + margin-right: 0.25rem !important; +} + +.mx-2 { + margin-left: 0.5rem !important; + margin-right: 0.5rem !important; +} + +.mx-3 { + margin-left: 1rem !important; + margin-right: 1rem !important; +} + +.mx-4 { + margin-left: 1.5rem !important; + margin-right: 1.5rem !important; +} + +.mx-5 { + margin-left: 3rem !important; + margin-right: 3rem !important; +} + +.mx-auto { + margin-left: auto !important; + margin-right: auto !important; +} + +.my-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; +} + +.my-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; +} + +.my-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; +} + +.my-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; +} + +.my-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; +} + +.my-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; +} + +.my-auto { + margin-top: auto !important; + margin-bottom: auto !important; +} + +.mt-0 { + margin-top: 0 !important; +} + +.mt-1 { + margin-top: 0.25rem !important; +} + +.mt-2 { + margin-top: 0.5rem !important; +} + +.mt-3 { + margin-top: 1rem !important; +} + +.mt-4 { + margin-top: 1.5rem !important; +} + +.mt-5 { + margin-top: 3rem !important; +} + +.mt-auto { + margin-top: auto !important; +} + +.me-0 { + margin-left: 0 !important; +} + +.me-1 { + margin-left: 0.25rem !important; +} + +.me-2 { + margin-left: 0.5rem !important; +} + +.me-3 { + margin-left: 1rem !important; +} + +.me-4 { + margin-left: 1.5rem !important; +} + +.me-5 { + margin-left: 3rem !important; +} + +.me-auto { + margin-left: auto !important; +} + +.mb-0 { + margin-bottom: 0 !important; +} + +.mb-1 { + margin-bottom: 0.25rem !important; +} + +.mb-2 { + margin-bottom: 0.5rem !important; +} + +.mb-3 { + margin-bottom: 1rem !important; +} + +.mb-4 { + margin-bottom: 1.5rem !important; +} + +.mb-5 { + margin-bottom: 3rem !important; +} + +.mb-auto { + margin-bottom: auto !important; +} + +.ms-0 { + margin-right: 0 !important; +} + +.ms-1 { + margin-right: 0.25rem !important; +} + +.ms-2 { + margin-right: 0.5rem !important; +} + +.ms-3 { + margin-right: 1rem !important; +} + +.ms-4 { + margin-right: 1.5rem !important; +} + +.ms-5 { + margin-right: 3rem !important; +} + +.ms-auto { + margin-right: auto !important; +} + +.p-0 { + padding: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.px-0 { + padding-left: 0 !important; + padding-right: 0 !important; +} + +.px-1 { + padding-left: 0.25rem !important; + padding-right: 0.25rem !important; +} + +.px-2 { + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; +} + +.px-3 { + padding-left: 1rem !important; + padding-right: 1rem !important; +} + +.px-4 { + padding-left: 1.5rem !important; + padding-right: 1.5rem !important; +} + +.px-5 { + padding-left: 3rem !important; + padding-right: 3rem !important; +} + +.py-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; +} + +.py-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; +} + +.py-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; +} + +.py-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; +} + +.py-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; +} + +.py-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; +} + +.pt-0 { + padding-top: 0 !important; +} + +.pt-1 { + padding-top: 0.25rem !important; +} + +.pt-2 { + padding-top: 0.5rem !important; +} + +.pt-3 { + padding-top: 1rem !important; +} + +.pt-4 { + padding-top: 1.5rem !important; +} + +.pt-5 { + padding-top: 3rem !important; +} + +.pe-0 { + padding-left: 0 !important; +} + +.pe-1 { + padding-left: 0.25rem !important; +} + +.pe-2 { + padding-left: 0.5rem !important; +} + +.pe-3 { + padding-left: 1rem !important; +} + +.pe-4 { + padding-left: 1.5rem !important; +} + +.pe-5 { + padding-left: 3rem !important; +} + +.pb-0 { + padding-bottom: 0 !important; +} + +.pb-1 { + padding-bottom: 0.25rem !important; +} + +.pb-2 { + padding-bottom: 0.5rem !important; +} + +.pb-3 { + padding-bottom: 1rem !important; +} + +.pb-4 { + padding-bottom: 1.5rem !important; +} + +.pb-5 { + padding-bottom: 3rem !important; +} + +.ps-0 { + padding-right: 0 !important; +} + +.ps-1 { + padding-right: 0.25rem !important; +} + +.ps-2 { + padding-right: 0.5rem !important; +} + +.ps-3 { + padding-right: 1rem !important; +} + +.ps-4 { + padding-right: 1.5rem !important; +} + +.ps-5 { + padding-right: 3rem !important; +} + +@media (min-width: 576px) { + .d-sm-inline { + display: inline !important; + } + .d-sm-inline-block { + display: inline-block !important; + } + .d-sm-block { + display: block !important; + } + .d-sm-grid { + display: grid !important; + } + .d-sm-inline-grid { + display: inline-grid !important; + } + .d-sm-table { + display: table !important; + } + .d-sm-table-row { + display: table-row !important; + } + .d-sm-table-cell { + display: table-cell !important; + } + .d-sm-flex { + display: flex !important; + } + .d-sm-inline-flex { + display: inline-flex !important; + } + .d-sm-none { + display: none !important; + } + .flex-sm-fill { + flex: 1 1 auto !important; + } + .flex-sm-row { + flex-direction: row !important; + } + .flex-sm-column { + flex-direction: column !important; + } + .flex-sm-row-reverse { + flex-direction: row-reverse !important; + } + .flex-sm-column-reverse { + flex-direction: column-reverse !important; + } + .flex-sm-grow-0 { + flex-grow: 0 !important; + } + .flex-sm-grow-1 { + flex-grow: 1 !important; + } + .flex-sm-shrink-0 { + flex-shrink: 0 !important; + } + .flex-sm-shrink-1 { + flex-shrink: 1 !important; + } + .flex-sm-wrap { + flex-wrap: wrap !important; + } + .flex-sm-nowrap { + flex-wrap: nowrap !important; + } + .flex-sm-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-sm-start { + justify-content: flex-start !important; + } + .justify-content-sm-end { + justify-content: flex-end !important; + } + .justify-content-sm-center { + justify-content: center !important; + } + .justify-content-sm-between { + justify-content: space-between !important; + } + .justify-content-sm-around { + justify-content: space-around !important; + } + .justify-content-sm-evenly { + justify-content: space-evenly !important; + } + .align-items-sm-start { + align-items: flex-start !important; + } + .align-items-sm-end { + align-items: flex-end !important; + } + .align-items-sm-center { + align-items: center !important; + } + .align-items-sm-baseline { + align-items: baseline !important; + } + .align-items-sm-stretch { + align-items: stretch !important; + } + .align-content-sm-start { + align-content: flex-start !important; + } + .align-content-sm-end { + align-content: flex-end !important; + } + .align-content-sm-center { + align-content: center !important; + } + .align-content-sm-between { + align-content: space-between !important; + } + .align-content-sm-around { + align-content: space-around !important; + } + .align-content-sm-stretch { + align-content: stretch !important; + } + .align-self-sm-auto { + align-self: auto !important; + } + .align-self-sm-start { + align-self: flex-start !important; + } + .align-self-sm-end { + align-self: flex-end !important; + } + .align-self-sm-center { + align-self: center !important; + } + .align-self-sm-baseline { + align-self: baseline !important; + } + .align-self-sm-stretch { + align-self: stretch !important; + } + .order-sm-first { + order: -1 !important; + } + .order-sm-0 { + order: 0 !important; + } + .order-sm-1 { + order: 1 !important; + } + .order-sm-2 { + order: 2 !important; + } + .order-sm-3 { + order: 3 !important; + } + .order-sm-4 { + order: 4 !important; + } + .order-sm-5 { + order: 5 !important; + } + .order-sm-last { + order: 6 !important; + } + .m-sm-0 { + margin: 0 !important; + } + .m-sm-1 { + margin: 0.25rem !important; + } + .m-sm-2 { + margin: 0.5rem !important; + } + .m-sm-3 { + margin: 1rem !important; + } + .m-sm-4 { + margin: 1.5rem !important; + } + .m-sm-5 { + margin: 3rem !important; + } + .m-sm-auto { + margin: auto !important; + } + .mx-sm-0 { + margin-left: 0 !important; + margin-right: 0 !important; + } + .mx-sm-1 { + margin-left: 0.25rem !important; + margin-right: 0.25rem !important; + } + .mx-sm-2 { + margin-left: 0.5rem !important; + margin-right: 0.5rem !important; + } + .mx-sm-3 { + margin-left: 1rem !important; + margin-right: 1rem !important; + } + .mx-sm-4 { + margin-left: 1.5rem !important; + margin-right: 1.5rem !important; + } + .mx-sm-5 { + margin-left: 3rem !important; + margin-right: 3rem !important; + } + .mx-sm-auto { + margin-left: auto !important; + margin-right: auto !important; + } + .my-sm-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-sm-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-sm-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-sm-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-sm-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-sm-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-sm-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-sm-0 { + margin-top: 0 !important; + } + .mt-sm-1 { + margin-top: 0.25rem !important; + } + .mt-sm-2 { + margin-top: 0.5rem !important; + } + .mt-sm-3 { + margin-top: 1rem !important; + } + .mt-sm-4 { + margin-top: 1.5rem !important; + } + .mt-sm-5 { + margin-top: 3rem !important; + } + .mt-sm-auto { + margin-top: auto !important; + } + .me-sm-0 { + margin-left: 0 !important; + } + .me-sm-1 { + margin-left: 0.25rem !important; + } + .me-sm-2 { + margin-left: 0.5rem !important; + } + .me-sm-3 { + margin-left: 1rem !important; + } + .me-sm-4 { + margin-left: 1.5rem !important; + } + .me-sm-5 { + margin-left: 3rem !important; + } + .me-sm-auto { + margin-left: auto !important; + } + .mb-sm-0 { + margin-bottom: 0 !important; + } + .mb-sm-1 { + margin-bottom: 0.25rem !important; + } + .mb-sm-2 { + margin-bottom: 0.5rem !important; + } + .mb-sm-3 { + margin-bottom: 1rem !important; + } + .mb-sm-4 { + margin-bottom: 1.5rem !important; + } + .mb-sm-5 { + margin-bottom: 3rem !important; + } + .mb-sm-auto { + margin-bottom: auto !important; + } + .ms-sm-0 { + margin-right: 0 !important; + } + .ms-sm-1 { + margin-right: 0.25rem !important; + } + .ms-sm-2 { + margin-right: 0.5rem !important; + } + .ms-sm-3 { + margin-right: 1rem !important; + } + .ms-sm-4 { + margin-right: 1.5rem !important; + } + .ms-sm-5 { + margin-right: 3rem !important; + } + .ms-sm-auto { + margin-right: auto !important; + } + .p-sm-0 { + padding: 0 !important; + } + .p-sm-1 { + padding: 0.25rem !important; + } + .p-sm-2 { + padding: 0.5rem !important; + } + .p-sm-3 { + padding: 1rem !important; + } + .p-sm-4 { + padding: 1.5rem !important; + } + .p-sm-5 { + padding: 3rem !important; + } + .px-sm-0 { + padding-left: 0 !important; + padding-right: 0 !important; + } + .px-sm-1 { + padding-left: 0.25rem !important; + padding-right: 0.25rem !important; + } + .px-sm-2 { + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; + } + .px-sm-3 { + padding-left: 1rem !important; + padding-right: 1rem !important; + } + .px-sm-4 { + padding-left: 1.5rem !important; + padding-right: 1.5rem !important; + } + .px-sm-5 { + padding-left: 3rem !important; + padding-right: 3rem !important; + } + .py-sm-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-sm-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-sm-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-sm-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-sm-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-sm-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-sm-0 { + padding-top: 0 !important; + } + .pt-sm-1 { + padding-top: 0.25rem !important; + } + .pt-sm-2 { + padding-top: 0.5rem !important; + } + .pt-sm-3 { + padding-top: 1rem !important; + } + .pt-sm-4 { + padding-top: 1.5rem !important; + } + .pt-sm-5 { + padding-top: 3rem !important; + } + .pe-sm-0 { + padding-left: 0 !important; + } + .pe-sm-1 { + padding-left: 0.25rem !important; + } + .pe-sm-2 { + padding-left: 0.5rem !important; + } + .pe-sm-3 { + padding-left: 1rem !important; + } + .pe-sm-4 { + padding-left: 1.5rem !important; + } + .pe-sm-5 { + padding-left: 3rem !important; + } + .pb-sm-0 { + padding-bottom: 0 !important; + } + .pb-sm-1 { + padding-bottom: 0.25rem !important; + } + .pb-sm-2 { + padding-bottom: 0.5rem !important; + } + .pb-sm-3 { + padding-bottom: 1rem !important; + } + .pb-sm-4 { + padding-bottom: 1.5rem !important; + } + .pb-sm-5 { + padding-bottom: 3rem !important; + } + .ps-sm-0 { + padding-right: 0 !important; + } + .ps-sm-1 { + padding-right: 0.25rem !important; + } + .ps-sm-2 { + padding-right: 0.5rem !important; + } + .ps-sm-3 { + padding-right: 1rem !important; + } + .ps-sm-4 { + padding-right: 1.5rem !important; + } + .ps-sm-5 { + padding-right: 3rem !important; + } +} +@media (min-width: 768px) { + .d-md-inline { + display: inline !important; + } + .d-md-inline-block { + display: inline-block !important; + } + .d-md-block { + display: block !important; + } + .d-md-grid { + display: grid !important; + } + .d-md-inline-grid { + display: inline-grid !important; + } + .d-md-table { + display: table !important; + } + .d-md-table-row { + display: table-row !important; + } + .d-md-table-cell { + display: table-cell !important; + } + .d-md-flex { + display: flex !important; + } + .d-md-inline-flex { + display: inline-flex !important; + } + .d-md-none { + display: none !important; + } + .flex-md-fill { + flex: 1 1 auto !important; + } + .flex-md-row { + flex-direction: row !important; + } + .flex-md-column { + flex-direction: column !important; + } + .flex-md-row-reverse { + flex-direction: row-reverse !important; + } + .flex-md-column-reverse { + flex-direction: column-reverse !important; + } + .flex-md-grow-0 { + flex-grow: 0 !important; + } + .flex-md-grow-1 { + flex-grow: 1 !important; + } + .flex-md-shrink-0 { + flex-shrink: 0 !important; + } + .flex-md-shrink-1 { + flex-shrink: 1 !important; + } + .flex-md-wrap { + flex-wrap: wrap !important; + } + .flex-md-nowrap { + flex-wrap: nowrap !important; + } + .flex-md-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-md-start { + justify-content: flex-start !important; + } + .justify-content-md-end { + justify-content: flex-end !important; + } + .justify-content-md-center { + justify-content: center !important; + } + .justify-content-md-between { + justify-content: space-between !important; + } + .justify-content-md-around { + justify-content: space-around !important; + } + .justify-content-md-evenly { + justify-content: space-evenly !important; + } + .align-items-md-start { + align-items: flex-start !important; + } + .align-items-md-end { + align-items: flex-end !important; + } + .align-items-md-center { + align-items: center !important; + } + .align-items-md-baseline { + align-items: baseline !important; + } + .align-items-md-stretch { + align-items: stretch !important; + } + .align-content-md-start { + align-content: flex-start !important; + } + .align-content-md-end { + align-content: flex-end !important; + } + .align-content-md-center { + align-content: center !important; + } + .align-content-md-between { + align-content: space-between !important; + } + .align-content-md-around { + align-content: space-around !important; + } + .align-content-md-stretch { + align-content: stretch !important; + } + .align-self-md-auto { + align-self: auto !important; + } + .align-self-md-start { + align-self: flex-start !important; + } + .align-self-md-end { + align-self: flex-end !important; + } + .align-self-md-center { + align-self: center !important; + } + .align-self-md-baseline { + align-self: baseline !important; + } + .align-self-md-stretch { + align-self: stretch !important; + } + .order-md-first { + order: -1 !important; + } + .order-md-0 { + order: 0 !important; + } + .order-md-1 { + order: 1 !important; + } + .order-md-2 { + order: 2 !important; + } + .order-md-3 { + order: 3 !important; + } + .order-md-4 { + order: 4 !important; + } + .order-md-5 { + order: 5 !important; + } + .order-md-last { + order: 6 !important; + } + .m-md-0 { + margin: 0 !important; + } + .m-md-1 { + margin: 0.25rem !important; + } + .m-md-2 { + margin: 0.5rem !important; + } + .m-md-3 { + margin: 1rem !important; + } + .m-md-4 { + margin: 1.5rem !important; + } + .m-md-5 { + margin: 3rem !important; + } + .m-md-auto { + margin: auto !important; + } + .mx-md-0 { + margin-left: 0 !important; + margin-right: 0 !important; + } + .mx-md-1 { + margin-left: 0.25rem !important; + margin-right: 0.25rem !important; + } + .mx-md-2 { + margin-left: 0.5rem !important; + margin-right: 0.5rem !important; + } + .mx-md-3 { + margin-left: 1rem !important; + margin-right: 1rem !important; + } + .mx-md-4 { + margin-left: 1.5rem !important; + margin-right: 1.5rem !important; + } + .mx-md-5 { + margin-left: 3rem !important; + margin-right: 3rem !important; + } + .mx-md-auto { + margin-left: auto !important; + margin-right: auto !important; + } + .my-md-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-md-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-md-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-md-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-md-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-md-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-md-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-md-0 { + margin-top: 0 !important; + } + .mt-md-1 { + margin-top: 0.25rem !important; + } + .mt-md-2 { + margin-top: 0.5rem !important; + } + .mt-md-3 { + margin-top: 1rem !important; + } + .mt-md-4 { + margin-top: 1.5rem !important; + } + .mt-md-5 { + margin-top: 3rem !important; + } + .mt-md-auto { + margin-top: auto !important; + } + .me-md-0 { + margin-left: 0 !important; + } + .me-md-1 { + margin-left: 0.25rem !important; + } + .me-md-2 { + margin-left: 0.5rem !important; + } + .me-md-3 { + margin-left: 1rem !important; + } + .me-md-4 { + margin-left: 1.5rem !important; + } + .me-md-5 { + margin-left: 3rem !important; + } + .me-md-auto { + margin-left: auto !important; + } + .mb-md-0 { + margin-bottom: 0 !important; + } + .mb-md-1 { + margin-bottom: 0.25rem !important; + } + .mb-md-2 { + margin-bottom: 0.5rem !important; + } + .mb-md-3 { + margin-bottom: 1rem !important; + } + .mb-md-4 { + margin-bottom: 1.5rem !important; + } + .mb-md-5 { + margin-bottom: 3rem !important; + } + .mb-md-auto { + margin-bottom: auto !important; + } + .ms-md-0 { + margin-right: 0 !important; + } + .ms-md-1 { + margin-right: 0.25rem !important; + } + .ms-md-2 { + margin-right: 0.5rem !important; + } + .ms-md-3 { + margin-right: 1rem !important; + } + .ms-md-4 { + margin-right: 1.5rem !important; + } + .ms-md-5 { + margin-right: 3rem !important; + } + .ms-md-auto { + margin-right: auto !important; + } + .p-md-0 { + padding: 0 !important; + } + .p-md-1 { + padding: 0.25rem !important; + } + .p-md-2 { + padding: 0.5rem !important; + } + .p-md-3 { + padding: 1rem !important; + } + .p-md-4 { + padding: 1.5rem !important; + } + .p-md-5 { + padding: 3rem !important; + } + .px-md-0 { + padding-left: 0 !important; + padding-right: 0 !important; + } + .px-md-1 { + padding-left: 0.25rem !important; + padding-right: 0.25rem !important; + } + .px-md-2 { + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; + } + .px-md-3 { + padding-left: 1rem !important; + padding-right: 1rem !important; + } + .px-md-4 { + padding-left: 1.5rem !important; + padding-right: 1.5rem !important; + } + .px-md-5 { + padding-left: 3rem !important; + padding-right: 3rem !important; + } + .py-md-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-md-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-md-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-md-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-md-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-md-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-md-0 { + padding-top: 0 !important; + } + .pt-md-1 { + padding-top: 0.25rem !important; + } + .pt-md-2 { + padding-top: 0.5rem !important; + } + .pt-md-3 { + padding-top: 1rem !important; + } + .pt-md-4 { + padding-top: 1.5rem !important; + } + .pt-md-5 { + padding-top: 3rem !important; + } + .pe-md-0 { + padding-left: 0 !important; + } + .pe-md-1 { + padding-left: 0.25rem !important; + } + .pe-md-2 { + padding-left: 0.5rem !important; + } + .pe-md-3 { + padding-left: 1rem !important; + } + .pe-md-4 { + padding-left: 1.5rem !important; + } + .pe-md-5 { + padding-left: 3rem !important; + } + .pb-md-0 { + padding-bottom: 0 !important; + } + .pb-md-1 { + padding-bottom: 0.25rem !important; + } + .pb-md-2 { + padding-bottom: 0.5rem !important; + } + .pb-md-3 { + padding-bottom: 1rem !important; + } + .pb-md-4 { + padding-bottom: 1.5rem !important; + } + .pb-md-5 { + padding-bottom: 3rem !important; + } + .ps-md-0 { + padding-right: 0 !important; + } + .ps-md-1 { + padding-right: 0.25rem !important; + } + .ps-md-2 { + padding-right: 0.5rem !important; + } + .ps-md-3 { + padding-right: 1rem !important; + } + .ps-md-4 { + padding-right: 1.5rem !important; + } + .ps-md-5 { + padding-right: 3rem !important; + } +} +@media (min-width: 992px) { + .d-lg-inline { + display: inline !important; + } + .d-lg-inline-block { + display: inline-block !important; + } + .d-lg-block { + display: block !important; + } + .d-lg-grid { + display: grid !important; + } + .d-lg-inline-grid { + display: inline-grid !important; + } + .d-lg-table { + display: table !important; + } + .d-lg-table-row { + display: table-row !important; + } + .d-lg-table-cell { + display: table-cell !important; + } + .d-lg-flex { + display: flex !important; + } + .d-lg-inline-flex { + display: inline-flex !important; + } + .d-lg-none { + display: none !important; + } + .flex-lg-fill { + flex: 1 1 auto !important; + } + .flex-lg-row { + flex-direction: row !important; + } + .flex-lg-column { + flex-direction: column !important; + } + .flex-lg-row-reverse { + flex-direction: row-reverse !important; + } + .flex-lg-column-reverse { + flex-direction: column-reverse !important; + } + .flex-lg-grow-0 { + flex-grow: 0 !important; + } + .flex-lg-grow-1 { + flex-grow: 1 !important; + } + .flex-lg-shrink-0 { + flex-shrink: 0 !important; + } + .flex-lg-shrink-1 { + flex-shrink: 1 !important; + } + .flex-lg-wrap { + flex-wrap: wrap !important; + } + .flex-lg-nowrap { + flex-wrap: nowrap !important; + } + .flex-lg-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-lg-start { + justify-content: flex-start !important; + } + .justify-content-lg-end { + justify-content: flex-end !important; + } + .justify-content-lg-center { + justify-content: center !important; + } + .justify-content-lg-between { + justify-content: space-between !important; + } + .justify-content-lg-around { + justify-content: space-around !important; + } + .justify-content-lg-evenly { + justify-content: space-evenly !important; + } + .align-items-lg-start { + align-items: flex-start !important; + } + .align-items-lg-end { + align-items: flex-end !important; + } + .align-items-lg-center { + align-items: center !important; + } + .align-items-lg-baseline { + align-items: baseline !important; + } + .align-items-lg-stretch { + align-items: stretch !important; + } + .align-content-lg-start { + align-content: flex-start !important; + } + .align-content-lg-end { + align-content: flex-end !important; + } + .align-content-lg-center { + align-content: center !important; + } + .align-content-lg-between { + align-content: space-between !important; + } + .align-content-lg-around { + align-content: space-around !important; + } + .align-content-lg-stretch { + align-content: stretch !important; + } + .align-self-lg-auto { + align-self: auto !important; + } + .align-self-lg-start { + align-self: flex-start !important; + } + .align-self-lg-end { + align-self: flex-end !important; + } + .align-self-lg-center { + align-self: center !important; + } + .align-self-lg-baseline { + align-self: baseline !important; + } + .align-self-lg-stretch { + align-self: stretch !important; + } + .order-lg-first { + order: -1 !important; + } + .order-lg-0 { + order: 0 !important; + } + .order-lg-1 { + order: 1 !important; + } + .order-lg-2 { + order: 2 !important; + } + .order-lg-3 { + order: 3 !important; + } + .order-lg-4 { + order: 4 !important; + } + .order-lg-5 { + order: 5 !important; + } + .order-lg-last { + order: 6 !important; + } + .m-lg-0 { + margin: 0 !important; + } + .m-lg-1 { + margin: 0.25rem !important; + } + .m-lg-2 { + margin: 0.5rem !important; + } + .m-lg-3 { + margin: 1rem !important; + } + .m-lg-4 { + margin: 1.5rem !important; + } + .m-lg-5 { + margin: 3rem !important; + } + .m-lg-auto { + margin: auto !important; + } + .mx-lg-0 { + margin-left: 0 !important; + margin-right: 0 !important; + } + .mx-lg-1 { + margin-left: 0.25rem !important; + margin-right: 0.25rem !important; + } + .mx-lg-2 { + margin-left: 0.5rem !important; + margin-right: 0.5rem !important; + } + .mx-lg-3 { + margin-left: 1rem !important; + margin-right: 1rem !important; + } + .mx-lg-4 { + margin-left: 1.5rem !important; + margin-right: 1.5rem !important; + } + .mx-lg-5 { + margin-left: 3rem !important; + margin-right: 3rem !important; + } + .mx-lg-auto { + margin-left: auto !important; + margin-right: auto !important; + } + .my-lg-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-lg-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-lg-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-lg-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-lg-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-lg-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-lg-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-lg-0 { + margin-top: 0 !important; + } + .mt-lg-1 { + margin-top: 0.25rem !important; + } + .mt-lg-2 { + margin-top: 0.5rem !important; + } + .mt-lg-3 { + margin-top: 1rem !important; + } + .mt-lg-4 { + margin-top: 1.5rem !important; + } + .mt-lg-5 { + margin-top: 3rem !important; + } + .mt-lg-auto { + margin-top: auto !important; + } + .me-lg-0 { + margin-left: 0 !important; + } + .me-lg-1 { + margin-left: 0.25rem !important; + } + .me-lg-2 { + margin-left: 0.5rem !important; + } + .me-lg-3 { + margin-left: 1rem !important; + } + .me-lg-4 { + margin-left: 1.5rem !important; + } + .me-lg-5 { + margin-left: 3rem !important; + } + .me-lg-auto { + margin-left: auto !important; + } + .mb-lg-0 { + margin-bottom: 0 !important; + } + .mb-lg-1 { + margin-bottom: 0.25rem !important; + } + .mb-lg-2 { + margin-bottom: 0.5rem !important; + } + .mb-lg-3 { + margin-bottom: 1rem !important; + } + .mb-lg-4 { + margin-bottom: 1.5rem !important; + } + .mb-lg-5 { + margin-bottom: 3rem !important; + } + .mb-lg-auto { + margin-bottom: auto !important; + } + .ms-lg-0 { + margin-right: 0 !important; + } + .ms-lg-1 { + margin-right: 0.25rem !important; + } + .ms-lg-2 { + margin-right: 0.5rem !important; + } + .ms-lg-3 { + margin-right: 1rem !important; + } + .ms-lg-4 { + margin-right: 1.5rem !important; + } + .ms-lg-5 { + margin-right: 3rem !important; + } + .ms-lg-auto { + margin-right: auto !important; + } + .p-lg-0 { + padding: 0 !important; + } + .p-lg-1 { + padding: 0.25rem !important; + } + .p-lg-2 { + padding: 0.5rem !important; + } + .p-lg-3 { + padding: 1rem !important; + } + .p-lg-4 { + padding: 1.5rem !important; + } + .p-lg-5 { + padding: 3rem !important; + } + .px-lg-0 { + padding-left: 0 !important; + padding-right: 0 !important; + } + .px-lg-1 { + padding-left: 0.25rem !important; + padding-right: 0.25rem !important; + } + .px-lg-2 { + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; + } + .px-lg-3 { + padding-left: 1rem !important; + padding-right: 1rem !important; + } + .px-lg-4 { + padding-left: 1.5rem !important; + padding-right: 1.5rem !important; + } + .px-lg-5 { + padding-left: 3rem !important; + padding-right: 3rem !important; + } + .py-lg-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-lg-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-lg-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-lg-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-lg-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-lg-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-lg-0 { + padding-top: 0 !important; + } + .pt-lg-1 { + padding-top: 0.25rem !important; + } + .pt-lg-2 { + padding-top: 0.5rem !important; + } + .pt-lg-3 { + padding-top: 1rem !important; + } + .pt-lg-4 { + padding-top: 1.5rem !important; + } + .pt-lg-5 { + padding-top: 3rem !important; + } + .pe-lg-0 { + padding-left: 0 !important; + } + .pe-lg-1 { + padding-left: 0.25rem !important; + } + .pe-lg-2 { + padding-left: 0.5rem !important; + } + .pe-lg-3 { + padding-left: 1rem !important; + } + .pe-lg-4 { + padding-left: 1.5rem !important; + } + .pe-lg-5 { + padding-left: 3rem !important; + } + .pb-lg-0 { + padding-bottom: 0 !important; + } + .pb-lg-1 { + padding-bottom: 0.25rem !important; + } + .pb-lg-2 { + padding-bottom: 0.5rem !important; + } + .pb-lg-3 { + padding-bottom: 1rem !important; + } + .pb-lg-4 { + padding-bottom: 1.5rem !important; + } + .pb-lg-5 { + padding-bottom: 3rem !important; + } + .ps-lg-0 { + padding-right: 0 !important; + } + .ps-lg-1 { + padding-right: 0.25rem !important; + } + .ps-lg-2 { + padding-right: 0.5rem !important; + } + .ps-lg-3 { + padding-right: 1rem !important; + } + .ps-lg-4 { + padding-right: 1.5rem !important; + } + .ps-lg-5 { + padding-right: 3rem !important; + } +} +@media (min-width: 1200px) { + .d-xl-inline { + display: inline !important; + } + .d-xl-inline-block { + display: inline-block !important; + } + .d-xl-block { + display: block !important; + } + .d-xl-grid { + display: grid !important; + } + .d-xl-inline-grid { + display: inline-grid !important; + } + .d-xl-table { + display: table !important; + } + .d-xl-table-row { + display: table-row !important; + } + .d-xl-table-cell { + display: table-cell !important; + } + .d-xl-flex { + display: flex !important; + } + .d-xl-inline-flex { + display: inline-flex !important; + } + .d-xl-none { + display: none !important; + } + .flex-xl-fill { + flex: 1 1 auto !important; + } + .flex-xl-row { + flex-direction: row !important; + } + .flex-xl-column { + flex-direction: column !important; + } + .flex-xl-row-reverse { + flex-direction: row-reverse !important; + } + .flex-xl-column-reverse { + flex-direction: column-reverse !important; + } + .flex-xl-grow-0 { + flex-grow: 0 !important; + } + .flex-xl-grow-1 { + flex-grow: 1 !important; + } + .flex-xl-shrink-0 { + flex-shrink: 0 !important; + } + .flex-xl-shrink-1 { + flex-shrink: 1 !important; + } + .flex-xl-wrap { + flex-wrap: wrap !important; + } + .flex-xl-nowrap { + flex-wrap: nowrap !important; + } + .flex-xl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-xl-start { + justify-content: flex-start !important; + } + .justify-content-xl-end { + justify-content: flex-end !important; + } + .justify-content-xl-center { + justify-content: center !important; + } + .justify-content-xl-between { + justify-content: space-between !important; + } + .justify-content-xl-around { + justify-content: space-around !important; + } + .justify-content-xl-evenly { + justify-content: space-evenly !important; + } + .align-items-xl-start { + align-items: flex-start !important; + } + .align-items-xl-end { + align-items: flex-end !important; + } + .align-items-xl-center { + align-items: center !important; + } + .align-items-xl-baseline { + align-items: baseline !important; + } + .align-items-xl-stretch { + align-items: stretch !important; + } + .align-content-xl-start { + align-content: flex-start !important; + } + .align-content-xl-end { + align-content: flex-end !important; + } + .align-content-xl-center { + align-content: center !important; + } + .align-content-xl-between { + align-content: space-between !important; + } + .align-content-xl-around { + align-content: space-around !important; + } + .align-content-xl-stretch { + align-content: stretch !important; + } + .align-self-xl-auto { + align-self: auto !important; + } + .align-self-xl-start { + align-self: flex-start !important; + } + .align-self-xl-end { + align-self: flex-end !important; + } + .align-self-xl-center { + align-self: center !important; + } + .align-self-xl-baseline { + align-self: baseline !important; + } + .align-self-xl-stretch { + align-self: stretch !important; + } + .order-xl-first { + order: -1 !important; + } + .order-xl-0 { + order: 0 !important; + } + .order-xl-1 { + order: 1 !important; + } + .order-xl-2 { + order: 2 !important; + } + .order-xl-3 { + order: 3 !important; + } + .order-xl-4 { + order: 4 !important; + } + .order-xl-5 { + order: 5 !important; + } + .order-xl-last { + order: 6 !important; + } + .m-xl-0 { + margin: 0 !important; + } + .m-xl-1 { + margin: 0.25rem !important; + } + .m-xl-2 { + margin: 0.5rem !important; + } + .m-xl-3 { + margin: 1rem !important; + } + .m-xl-4 { + margin: 1.5rem !important; + } + .m-xl-5 { + margin: 3rem !important; + } + .m-xl-auto { + margin: auto !important; + } + .mx-xl-0 { + margin-left: 0 !important; + margin-right: 0 !important; + } + .mx-xl-1 { + margin-left: 0.25rem !important; + margin-right: 0.25rem !important; + } + .mx-xl-2 { + margin-left: 0.5rem !important; + margin-right: 0.5rem !important; + } + .mx-xl-3 { + margin-left: 1rem !important; + margin-right: 1rem !important; + } + .mx-xl-4 { + margin-left: 1.5rem !important; + margin-right: 1.5rem !important; + } + .mx-xl-5 { + margin-left: 3rem !important; + margin-right: 3rem !important; + } + .mx-xl-auto { + margin-left: auto !important; + margin-right: auto !important; + } + .my-xl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-xl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-xl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-xl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-xl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-xl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-xl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-xl-0 { + margin-top: 0 !important; + } + .mt-xl-1 { + margin-top: 0.25rem !important; + } + .mt-xl-2 { + margin-top: 0.5rem !important; + } + .mt-xl-3 { + margin-top: 1rem !important; + } + .mt-xl-4 { + margin-top: 1.5rem !important; + } + .mt-xl-5 { + margin-top: 3rem !important; + } + .mt-xl-auto { + margin-top: auto !important; + } + .me-xl-0 { + margin-left: 0 !important; + } + .me-xl-1 { + margin-left: 0.25rem !important; + } + .me-xl-2 { + margin-left: 0.5rem !important; + } + .me-xl-3 { + margin-left: 1rem !important; + } + .me-xl-4 { + margin-left: 1.5rem !important; + } + .me-xl-5 { + margin-left: 3rem !important; + } + .me-xl-auto { + margin-left: auto !important; + } + .mb-xl-0 { + margin-bottom: 0 !important; + } + .mb-xl-1 { + margin-bottom: 0.25rem !important; + } + .mb-xl-2 { + margin-bottom: 0.5rem !important; + } + .mb-xl-3 { + margin-bottom: 1rem !important; + } + .mb-xl-4 { + margin-bottom: 1.5rem !important; + } + .mb-xl-5 { + margin-bottom: 3rem !important; + } + .mb-xl-auto { + margin-bottom: auto !important; + } + .ms-xl-0 { + margin-right: 0 !important; + } + .ms-xl-1 { + margin-right: 0.25rem !important; + } + .ms-xl-2 { + margin-right: 0.5rem !important; + } + .ms-xl-3 { + margin-right: 1rem !important; + } + .ms-xl-4 { + margin-right: 1.5rem !important; + } + .ms-xl-5 { + margin-right: 3rem !important; + } + .ms-xl-auto { + margin-right: auto !important; + } + .p-xl-0 { + padding: 0 !important; + } + .p-xl-1 { + padding: 0.25rem !important; + } + .p-xl-2 { + padding: 0.5rem !important; + } + .p-xl-3 { + padding: 1rem !important; + } + .p-xl-4 { + padding: 1.5rem !important; + } + .p-xl-5 { + padding: 3rem !important; + } + .px-xl-0 { + padding-left: 0 !important; + padding-right: 0 !important; + } + .px-xl-1 { + padding-left: 0.25rem !important; + padding-right: 0.25rem !important; + } + .px-xl-2 { + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; + } + .px-xl-3 { + padding-left: 1rem !important; + padding-right: 1rem !important; + } + .px-xl-4 { + padding-left: 1.5rem !important; + padding-right: 1.5rem !important; + } + .px-xl-5 { + padding-left: 3rem !important; + padding-right: 3rem !important; + } + .py-xl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-xl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-xl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-xl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-xl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-xl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-xl-0 { + padding-top: 0 !important; + } + .pt-xl-1 { + padding-top: 0.25rem !important; + } + .pt-xl-2 { + padding-top: 0.5rem !important; + } + .pt-xl-3 { + padding-top: 1rem !important; + } + .pt-xl-4 { + padding-top: 1.5rem !important; + } + .pt-xl-5 { + padding-top: 3rem !important; + } + .pe-xl-0 { + padding-left: 0 !important; + } + .pe-xl-1 { + padding-left: 0.25rem !important; + } + .pe-xl-2 { + padding-left: 0.5rem !important; + } + .pe-xl-3 { + padding-left: 1rem !important; + } + .pe-xl-4 { + padding-left: 1.5rem !important; + } + .pe-xl-5 { + padding-left: 3rem !important; + } + .pb-xl-0 { + padding-bottom: 0 !important; + } + .pb-xl-1 { + padding-bottom: 0.25rem !important; + } + .pb-xl-2 { + padding-bottom: 0.5rem !important; + } + .pb-xl-3 { + padding-bottom: 1rem !important; + } + .pb-xl-4 { + padding-bottom: 1.5rem !important; + } + .pb-xl-5 { + padding-bottom: 3rem !important; + } + .ps-xl-0 { + padding-right: 0 !important; + } + .ps-xl-1 { + padding-right: 0.25rem !important; + } + .ps-xl-2 { + padding-right: 0.5rem !important; + } + .ps-xl-3 { + padding-right: 1rem !important; + } + .ps-xl-4 { + padding-right: 1.5rem !important; + } + .ps-xl-5 { + padding-right: 3rem !important; + } +} +@media (min-width: 1400px) { + .d-xxl-inline { + display: inline !important; + } + .d-xxl-inline-block { + display: inline-block !important; + } + .d-xxl-block { + display: block !important; + } + .d-xxl-grid { + display: grid !important; + } + .d-xxl-inline-grid { + display: inline-grid !important; + } + .d-xxl-table { + display: table !important; + } + .d-xxl-table-row { + display: table-row !important; + } + .d-xxl-table-cell { + display: table-cell !important; + } + .d-xxl-flex { + display: flex !important; + } + .d-xxl-inline-flex { + display: inline-flex !important; + } + .d-xxl-none { + display: none !important; + } + .flex-xxl-fill { + flex: 1 1 auto !important; + } + .flex-xxl-row { + flex-direction: row !important; + } + .flex-xxl-column { + flex-direction: column !important; + } + .flex-xxl-row-reverse { + flex-direction: row-reverse !important; + } + .flex-xxl-column-reverse { + flex-direction: column-reverse !important; + } + .flex-xxl-grow-0 { + flex-grow: 0 !important; + } + .flex-xxl-grow-1 { + flex-grow: 1 !important; + } + .flex-xxl-shrink-0 { + flex-shrink: 0 !important; + } + .flex-xxl-shrink-1 { + flex-shrink: 1 !important; + } + .flex-xxl-wrap { + flex-wrap: wrap !important; + } + .flex-xxl-nowrap { + flex-wrap: nowrap !important; + } + .flex-xxl-wrap-reverse { + flex-wrap: wrap-reverse !important; + } + .justify-content-xxl-start { + justify-content: flex-start !important; + } + .justify-content-xxl-end { + justify-content: flex-end !important; + } + .justify-content-xxl-center { + justify-content: center !important; + } + .justify-content-xxl-between { + justify-content: space-between !important; + } + .justify-content-xxl-around { + justify-content: space-around !important; + } + .justify-content-xxl-evenly { + justify-content: space-evenly !important; + } + .align-items-xxl-start { + align-items: flex-start !important; + } + .align-items-xxl-end { + align-items: flex-end !important; + } + .align-items-xxl-center { + align-items: center !important; + } + .align-items-xxl-baseline { + align-items: baseline !important; + } + .align-items-xxl-stretch { + align-items: stretch !important; + } + .align-content-xxl-start { + align-content: flex-start !important; + } + .align-content-xxl-end { + align-content: flex-end !important; + } + .align-content-xxl-center { + align-content: center !important; + } + .align-content-xxl-between { + align-content: space-between !important; + } + .align-content-xxl-around { + align-content: space-around !important; + } + .align-content-xxl-stretch { + align-content: stretch !important; + } + .align-self-xxl-auto { + align-self: auto !important; + } + .align-self-xxl-start { + align-self: flex-start !important; + } + .align-self-xxl-end { + align-self: flex-end !important; + } + .align-self-xxl-center { + align-self: center !important; + } + .align-self-xxl-baseline { + align-self: baseline !important; + } + .align-self-xxl-stretch { + align-self: stretch !important; + } + .order-xxl-first { + order: -1 !important; + } + .order-xxl-0 { + order: 0 !important; + } + .order-xxl-1 { + order: 1 !important; + } + .order-xxl-2 { + order: 2 !important; + } + .order-xxl-3 { + order: 3 !important; + } + .order-xxl-4 { + order: 4 !important; + } + .order-xxl-5 { + order: 5 !important; + } + .order-xxl-last { + order: 6 !important; + } + .m-xxl-0 { + margin: 0 !important; + } + .m-xxl-1 { + margin: 0.25rem !important; + } + .m-xxl-2 { + margin: 0.5rem !important; + } + .m-xxl-3 { + margin: 1rem !important; + } + .m-xxl-4 { + margin: 1.5rem !important; + } + .m-xxl-5 { + margin: 3rem !important; + } + .m-xxl-auto { + margin: auto !important; + } + .mx-xxl-0 { + margin-left: 0 !important; + margin-right: 0 !important; + } + .mx-xxl-1 { + margin-left: 0.25rem !important; + margin-right: 0.25rem !important; + } + .mx-xxl-2 { + margin-left: 0.5rem !important; + margin-right: 0.5rem !important; + } + .mx-xxl-3 { + margin-left: 1rem !important; + margin-right: 1rem !important; + } + .mx-xxl-4 { + margin-left: 1.5rem !important; + margin-right: 1.5rem !important; + } + .mx-xxl-5 { + margin-left: 3rem !important; + margin-right: 3rem !important; + } + .mx-xxl-auto { + margin-left: auto !important; + margin-right: auto !important; + } + .my-xxl-0 { + margin-top: 0 !important; + margin-bottom: 0 !important; + } + .my-xxl-1 { + margin-top: 0.25rem !important; + margin-bottom: 0.25rem !important; + } + .my-xxl-2 { + margin-top: 0.5rem !important; + margin-bottom: 0.5rem !important; + } + .my-xxl-3 { + margin-top: 1rem !important; + margin-bottom: 1rem !important; + } + .my-xxl-4 { + margin-top: 1.5rem !important; + margin-bottom: 1.5rem !important; + } + .my-xxl-5 { + margin-top: 3rem !important; + margin-bottom: 3rem !important; + } + .my-xxl-auto { + margin-top: auto !important; + margin-bottom: auto !important; + } + .mt-xxl-0 { + margin-top: 0 !important; + } + .mt-xxl-1 { + margin-top: 0.25rem !important; + } + .mt-xxl-2 { + margin-top: 0.5rem !important; + } + .mt-xxl-3 { + margin-top: 1rem !important; + } + .mt-xxl-4 { + margin-top: 1.5rem !important; + } + .mt-xxl-5 { + margin-top: 3rem !important; + } + .mt-xxl-auto { + margin-top: auto !important; + } + .me-xxl-0 { + margin-left: 0 !important; + } + .me-xxl-1 { + margin-left: 0.25rem !important; + } + .me-xxl-2 { + margin-left: 0.5rem !important; + } + .me-xxl-3 { + margin-left: 1rem !important; + } + .me-xxl-4 { + margin-left: 1.5rem !important; + } + .me-xxl-5 { + margin-left: 3rem !important; + } + .me-xxl-auto { + margin-left: auto !important; + } + .mb-xxl-0 { + margin-bottom: 0 !important; + } + .mb-xxl-1 { + margin-bottom: 0.25rem !important; + } + .mb-xxl-2 { + margin-bottom: 0.5rem !important; + } + .mb-xxl-3 { + margin-bottom: 1rem !important; + } + .mb-xxl-4 { + margin-bottom: 1.5rem !important; + } + .mb-xxl-5 { + margin-bottom: 3rem !important; + } + .mb-xxl-auto { + margin-bottom: auto !important; + } + .ms-xxl-0 { + margin-right: 0 !important; + } + .ms-xxl-1 { + margin-right: 0.25rem !important; + } + .ms-xxl-2 { + margin-right: 0.5rem !important; + } + .ms-xxl-3 { + margin-right: 1rem !important; + } + .ms-xxl-4 { + margin-right: 1.5rem !important; + } + .ms-xxl-5 { + margin-right: 3rem !important; + } + .ms-xxl-auto { + margin-right: auto !important; + } + .p-xxl-0 { + padding: 0 !important; + } + .p-xxl-1 { + padding: 0.25rem !important; + } + .p-xxl-2 { + padding: 0.5rem !important; + } + .p-xxl-3 { + padding: 1rem !important; + } + .p-xxl-4 { + padding: 1.5rem !important; + } + .p-xxl-5 { + padding: 3rem !important; + } + .px-xxl-0 { + padding-left: 0 !important; + padding-right: 0 !important; + } + .px-xxl-1 { + padding-left: 0.25rem !important; + padding-right: 0.25rem !important; + } + .px-xxl-2 { + padding-left: 0.5rem !important; + padding-right: 0.5rem !important; + } + .px-xxl-3 { + padding-left: 1rem !important; + padding-right: 1rem !important; + } + .px-xxl-4 { + padding-left: 1.5rem !important; + padding-right: 1.5rem !important; + } + .px-xxl-5 { + padding-left: 3rem !important; + padding-right: 3rem !important; + } + .py-xxl-0 { + padding-top: 0 !important; + padding-bottom: 0 !important; + } + .py-xxl-1 { + padding-top: 0.25rem !important; + padding-bottom: 0.25rem !important; + } + .py-xxl-2 { + padding-top: 0.5rem !important; + padding-bottom: 0.5rem !important; + } + .py-xxl-3 { + padding-top: 1rem !important; + padding-bottom: 1rem !important; + } + .py-xxl-4 { + padding-top: 1.5rem !important; + padding-bottom: 1.5rem !important; + } + .py-xxl-5 { + padding-top: 3rem !important; + padding-bottom: 3rem !important; + } + .pt-xxl-0 { + padding-top: 0 !important; + } + .pt-xxl-1 { + padding-top: 0.25rem !important; + } + .pt-xxl-2 { + padding-top: 0.5rem !important; + } + .pt-xxl-3 { + padding-top: 1rem !important; + } + .pt-xxl-4 { + padding-top: 1.5rem !important; + } + .pt-xxl-5 { + padding-top: 3rem !important; + } + .pe-xxl-0 { + padding-left: 0 !important; + } + .pe-xxl-1 { + padding-left: 0.25rem !important; + } + .pe-xxl-2 { + padding-left: 0.5rem !important; + } + .pe-xxl-3 { + padding-left: 1rem !important; + } + .pe-xxl-4 { + padding-left: 1.5rem !important; + } + .pe-xxl-5 { + padding-left: 3rem !important; + } + .pb-xxl-0 { + padding-bottom: 0 !important; + } + .pb-xxl-1 { + padding-bottom: 0.25rem !important; + } + .pb-xxl-2 { + padding-bottom: 0.5rem !important; + } + .pb-xxl-3 { + padding-bottom: 1rem !important; + } + .pb-xxl-4 { + padding-bottom: 1.5rem !important; + } + .pb-xxl-5 { + padding-bottom: 3rem !important; + } + .ps-xxl-0 { + padding-right: 0 !important; + } + .ps-xxl-1 { + padding-right: 0.25rem !important; + } + .ps-xxl-2 { + padding-right: 0.5rem !important; + } + .ps-xxl-3 { + padding-right: 1rem !important; + } + .ps-xxl-4 { + padding-right: 1.5rem !important; + } + .ps-xxl-5 { + padding-right: 3rem !important; + } +} +@media print { + .d-print-inline { + display: inline !important; + } + .d-print-inline-block { + display: inline-block !important; + } + .d-print-block { + display: block !important; + } + .d-print-grid { + display: grid !important; + } + .d-print-inline-grid { + display: inline-grid !important; + } + .d-print-table { + display: table !important; + } + .d-print-table-row { + display: table-row !important; + } + .d-print-table-cell { + display: table-cell !important; + } + .d-print-flex { + display: flex !important; + } + .d-print-inline-flex { + display: inline-flex !important; + } + .d-print-none { + display: none !important; + } +} +/*# sourceMappingURL=bootstrap-grid.rtl.css.map */ \ No newline at end of file diff --git a/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map new file mode 100644 index 0000000..8df43cf --- /dev/null +++ b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/mixins/_banner.scss","../../scss/_containers.scss","../../scss/mixins/_container.scss","bootstrap-grid.css","../../scss/mixins/_breakpoints.scss","../../scss/_variables.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_utilities.scss","../../scss/utilities/_api.scss"],"names":[],"mappings":"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EE,mBAAA;EJ6+BR;EI1+BM;;IAEE,mBAAA;EJ4+BR;AACF;AKpiCQ;EAOI,0BAAA;ALgiCZ;;AKviCQ;EAOI,gCAAA;ALoiCZ;;AK3iCQ;EAOI,yBAAA;ALwiCZ;;AK/iCQ;EAOI,wBAAA;AL4iCZ;;AKnjCQ;EAOI,+BAAA;ALgjCZ;;AKvjCQ;EAOI,yBAAA;ALojCZ;;AK3jCQ;EAOI,6BAAA;ALwjCZ;;AK/jCQ;EAOI,8BAAA;AL4jCZ;;AKnkCQ;EAOI,wBAAA;ALgkCZ;;AKvkCQ;EAOI,+BAAA;ALokCZ;;AK3kCQ;EAOI,wBAAA;ALwkCZ;;AK/kCQ;EAOI,yBAAA;AL4kCZ;;AKnlCQ;EAOI,8BAAA;ALglCZ;;AKvlCQ;EAOI,iCAAA;ALolCZ;;AK3lCQ;EAOI,sCAAA;ALwlCZ;;AK/lCQ;EAOI,yCAAA;AL4lCZ;;AKnmCQ;EAOI,uBAAA;ALgmCZ;;AKvmCQ;EAOI,uBAAA;ALomCZ;;AK3mCQ;EAOI,yBAAA;ALwmCZ;;AK/mCQ;EAOI,yBAAA;AL4mCZ;;AKnnCQ;EAOI,0BAAA;ALgnCZ;;AKvnCQ;EAOI,4BAAA;ALonCZ;;AK3nCQ;EAOI,kCAAA;ALwnCZ;;AK/nCQ;EAOI,sCAAA;AL4nCZ;;AKnoCQ;EAOI,oCAAA;ALgoCZ;;AKvoCQ;EAOI,kCAAA;ALooCZ;;AK3oCQ;EAOI,yCAAA;ALwoCZ;;AK/oCQ;EAOI,wCAAA;AL4oCZ;;AKnpCQ;EAOI,wCAAA;ALgpCZ;;AKvpCQ;EAOI,kCAAA;ALopCZ;;AK3pCQ;EAOI,gCAAA;ALwpCZ;;AK/pCQ;EAOI,8BAAA;AL4pCZ;;AKnqCQ;EAOI,gCAAA;ALgqCZ;;AKvqCQ;EAOI,+BAAA;ALoqCZ;;AK3qCQ;EAOI,oCAAA;ALwqCZ;;AK/qCQ;EAOI,kCAAA;AL4qCZ;;AKnrCQ;EAOI,gCAAA;ALgrCZ;;AKvrCQ;EAOI,uCAAA;ALorCZ;;AK3rCQ;EAOI,sCAAA;ALwrCZ;;AK/rCQ;EAOI,iCAAA;AL4rCZ;;AKnsCQ;EAOI,2BAAA;ALgsCZ;;AKvsCQ;EAOI,iCAAA;ALosCZ;;AK3sCQ;EAOI,+BAAA;ALwsCZ;;AK/sCQ;EAOI,6BAAA;AL4sCZ;;AKntCQ;EA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;AL8iDZ;;AKrjDQ;EAOI,4BAAA;ALkjDZ;;AKzjDQ;EAOI,0BAAA;ALsjDZ;;AK7jDQ;EAOI,gCAAA;AL0jDZ;;AKjkDQ;EAOI,+BAAA;AL8jDZ;;AKrkDQ;EAOI,6BAAA;ALkkDZ;;AKzkDQ;EAOI,+BAAA;ALskDZ;;AK7kDQ;EAOI,6BAAA;AL0kDZ;;AKjlDQ;EAOI,4BAAA;AL8kDZ;;AKrlDQ;EAOI,kCAAA;ALklDZ;;AKzlDQ;EAOI,iCAAA;ALslDZ;;AK7lDQ;EAOI,+BAAA;AL0lDZ;;AKjmDQ;EAOI,iCAAA;AL8lDZ;;AKrmDQ;EAOI,+BAAA;ALkmDZ;;AKzmDQ;EAOI,2BAAA;ALsmDZ;;AK7mDQ;EAOI,iCAAA;AL0mDZ;;AKjnDQ;EAOI,gCAAA;AL8mDZ;;AKrnDQ;EAOI,8BAAA;ALknDZ;;AKznDQ;EAOI,gCAAA;ALsnDZ;;AK7nDQ;EAOI,8BAAA;AL0nDZ;;ACpoDI;EIGI;IAOI,0BAAA;EL+nDV;EKtoDM;IAOI,gCAAA;ELkoDV;EKzoDM;IAOI,yBAAA;ELqoDV;EK5oDM;IAOI,wBAAA;ELwoDV;EK/oDM;IAOI,+BAAA;EL2oDV;EKlpDM;IAOI,yBAAA;EL8oDV;EKrpDM;IAOI,6BAAA;ELipDV;EKxpDM;IAOI,8BAAA;ELopDV;EK3pDM;IAOI,wBAAA;ELupDV;EK9pDM;IAOI,+BAAA;EL0pDV;EKjqDM;IAOI,wBAAA;EL6pDV;EKpqDM;IAOI,yBAAA;ELgqDV;EKvqDM;IAOI,8BAAA;ELmqDV;EK1qDM;IAOI,iCAAA;ELsqDV;EK7qDM;IAOI,sCAAA;ELyqDV;EKhrDM;IAOI,yCAAA;EL4qDV;EKnrDM;IAOI,uBAAA;EL+qDV;EKtrDM;IAOI,uBAAA;ELkrDV;EKzrDM;IAOI,yBAAA;ELqrDV;EK5rDM;IAOI,yBAAA;ELwrDV;EK/rDM;IAOI,0BAAA;EL2rDV;EKlsDM;IAOI,4BAAA;EL8rDV;EKrsDM;IAOI,kCAAA;ELisDV;EKxsDM;IAOI,sCAAA;ELosDV;EK3sDM;IAOI,oCAAA;ELusDV;EK9sDM;IAOI,kCAAA;EL0sDV;EKjtDM;IAOI,yCAAA;EL6sDV;EKptDM;IAOI,wCAAA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nEV;EK/nEM;IAOI,yCAAA;EL2nEV;EKloEM;IAOI,uBAAA;EL8nEV;EKroEM;IAOI,uBAAA;ELioEV;EKxoEM;IAOI,yBAAA;ELooEV;EK3oEM;IAOI,yBAAA;ELuoEV;EK9oEM;IAOI,0BAAA;EL0oEV;EKjpEM;IAOI,4BAAA;EL6oEV;EKppEM;IAOI,kCAAA;ELgpEV;EKvpEM;IAOI,sCAAA;ELmpEV;EK1pEM;IAOI,oCAAA;ELspEV;EK7pEM;IAOI,kCAAA;ELypEV;EKhqEM;IAOI,yCAAA;EL4pEV;EKnqEM;IAOI,wCAAA;EL+pEV;EKtqEM;IAOI,wCAAA;ELkqEV;EKzqEM;IAOI,kCAAA;ELqqEV;EK5qEM;IAOI,gCAAA;ELwqEV;EK/qEM;IAOI,8BAAA;EL2qEV;EKlrEM;IAOI,gCAAA;EL8qEV;EKrrEM;IAOI,+BAAA;ELirEV;EKxrEM;IAOI,oCAAA;ELorEV;EK3rEM;IAOI,kCAAA;ELurEV;EK9rEM;IAOI,gCAAA;EL0rEV;EKjsEM;IAOI,uCAAA;EL6rEV;EKpsEM;IAOI,sCAAA;ELgsEV;EKvsEM;IAOI,iCAAA;ELmsEV;EK1sEM;IAOI,2BAAA;ELssEV;EK7sEM;IAOI,iCAAA;ELysEV;EKhtEM;IAOI,+BAAA;EL4sEV;EKntEM;IAOI,6BAAA;EL+sEV;EKttEM;IAOI,+BAAA;ELktEV;EKztEM;IAOI,8BAAA;ELqtEV;EK5tEM;IAOI,oBAAA;ELwtEV;EK/tEM;IAOI,mBAAA;EL2tEV;EKluEM;IAOI,mBAAA;EL8tEV;EKruEM;IAOI,mBAAA;ELiuEV;EKxuEM;IAOI,mBAAA;ELouEV;EK3uEM;IAOI,mBAAA;ELuuEV;EK9uEM;IAOI,mBAAA;EL0uEV;EKjvEM;IAOI,mBAAA;EL6uEV;EKpvEM;IAOI,oBAAA;ELgvEV;EKvvEM;IAOI,0BAAA;ELmvEV;EK1vEM;IAOI,yBAAA;ELsvEV;EK7vEM;IAOI,uBAAA;ELyvEV;EKhwEM;IAOI,yBAAA;EL4vEV;EKnwEM;IAOI,uBAAA;EL+vEV;EKtwEM;IAOI,uBAAA;ELkwEV;EKzwEM;IAOI,yBAAA;IAAA,0BAAA;ELswEV;EK7wEM;IAO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EKviFM;IAOI,yBAAA;ELmiFV;EK1iFM;IAOI,wBAAA;ELsiFV;EK7iFM;IAOI,+BAAA;ELyiFV;EKhjFM;IAOI,yBAAA;EL4iFV;EKnjFM;IAOI,6BAAA;EL+iFV;EKtjFM;IAOI,8BAAA;ELkjFV;EKzjFM;IAOI,wBAAA;ELqjFV;EK5jFM;IAOI,+BAAA;ELwjFV;EK/jFM;IAOI,wBAAA;EL2jFV;EKlkFM;IAOI,yBAAA;EL8jFV;EKrkFM;IAOI,8BAAA;ELikFV;EKxkFM;IAOI,iCAAA;ELokFV;EK3kFM;IAOI,sCAAA;ELukFV;EK9kFM;IAOI,yCAAA;EL0kFV;EKjlFM;IAOI,uBAAA;EL6kFV;EKplFM;IAOI,uBAAA;ELglFV;EKvlFM;IAOI,yBAAA;ELmlFV;EK1lFM;IAOI,yBAAA;ELslFV;EK7lFM;IAOI,0BAAA;ELylFV;EKhmFM;IAOI,4BAAA;EL4lFV;EKnmFM;IAOI,kCAAA;EL+lFV;EKtmFM;IAOI,sCAAA;ELkmFV;EKzmFM;IAOI,oCAAA;ELqmFV;EK5mFM;IAOI,kCAAA;ELwmFV;EK/mFM;IAOI,yCAAA;EL2mFV;EKlnFM;IAOI,wCAAA;EL8mFV;EKrnFM;IAOI,wCAAA;ELinFV;EKxnFM;IAOI,kCAAA;ELonFV;EK3nFM;IAOI,gCAAA;ELunFV;EK9nFM;IAOI,8BAAA;EL0nFV;EKjoFM;IAOI,gCAAA;EL6nFV;EKpoFM;IAOI,+BAAA;ELgoFV;EKvoFM;IAOI,oCAAA;ELmoFV;EK1oFM;IAOI,kCAAA;ELsoFV;EK7oFM;IAOI,gCAAA;ELyoFV;EKhpFM;IAOI,uCAAA;EL4oFV;EKnpFM;IAOI,sCAAA;EL+oFV;EKtpFM;IAOI,iCAAA;ELkpFV;EKzpFM;IAOI,2BAAA;ELqpFV;EK5pFM;IAOI,iCAAA;ELwpFV;EK/pFM;IAOI,+BAAA;EL2pFV;EKlqFM;IAOI,6BAAA;EL8pFV;EKrqFM;IAOI,+BAAA;ELiqFV;EKxqFM;IAOI,8BAAA;ELoqFV;EK3qFM;IAOI,oBAAA;ELuqFV;EK9qFM;IAOI,mBAAA;EL0qFV;EKjrFM;IAOI,mBAAA;EL6qFV;EKprFM;IAOI,mBAAA;ELgrFV;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AAA;ELy8FV;EKh9FM;IAOI,iCAAA;EL48FV;EKn9FM;IAOI,+BAAA;EL+8FV;EKt9FM;IAOI,iCAAA;ELk9FV;EKz9FM;IAOI,+BAAA;ELq9FV;EK59FM;IAOI,2BAAA;ELw9FV;EK/9FM;IAOI,iCAAA;EL29FV;EKl+FM;IAOI,gCAAA;EL89FV;EKr+FM;IAOI,8BAAA;ELi+FV;EKx+FM;IAOI,gCAAA;ELo+FV;EK3+FM;IAOI,8BAAA;ELu+FV;AACF;ACl/FI;EIGI;IAOI,0BAAA;EL4+FV;EKn/FM;IAOI,gCAAA;EL++FV;EKt/FM;IAOI,yBAAA;ELk/FV;EKz/FM;IAOI,wBAAA;ELq/FV;EK5/FM;IAOI,+BAAA;ELw/FV;EK//FM;IAOI,yBAAA;EL2/FV;EKlgGM;IAOI,6BAAA;EL8/FV;EKrgGM;IAOI,8BAAA;ELigGV;EKxgGM;IAOI,wBAAA;ELogGV;EK3gGM;IAOI,+BAAA;ELugGV;EK9gGM;IAOI,wBAAA;EL0gGV;EKjhGM;IAOI,yBAAA;EL6gGV;EKphGM;IAOI,8BAAA;ELghGV;EKvhGM;IAOI,iCAAA;ELmhGV;EK1hGM;IAOI,sCAAA;ELshGV;EK7hGM;IAOI,yCAAA;ELyhGV;EKhiGM;IAOI,uBAAA;EL4hGV;EKniGM;IAOI,uBAAA;EL+hGV;EKtiGM;IAOI,yBAAA;ELkiGV;EKziGM;IAOI,yBAAA;ELqiGV;EK5iGM;IAOI,0BAAA;ELwiGV;EK/iGM;IAOI,4BAAA;EL2iGV;EKljGM;IAOI,kCAAA;EL8iGV;EKrjGM;IAOI,sCAAA;ELijGV;EKxjGM;IAOI,oCAAA;ELojGV;EK3jGM;IAOI,kCAAA;ELujGV;EK9jGM;IAOI,yCAAA;EL0jGV;EKjkGM;IAOI,wCAAA;EL6jGV;EKpkGM;IAOI,wCAAA;ELgkGV;EKvkGM;IAOI,kCAAA;ELmkGV;EK1kGM;IAOI,gCAAA;ELskGV;EK7kGM;IAOI,8BAAA;ELykGV;EKhlGM;IAOI,gCAAA;EL4kGV;EKnlGM;IAOI,+BAAA;EL+kGV;EKtlGM;IAOI,oCAAA;ELklGV;EKzlGM;IAOI,kCAAA;ELqlGV;EK5lGM;IAOI,gCAAA;ELwlGV;EK/l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ELi3GV;EKx3GM;IAOI,+BAAA;ELo3GV;EK33GM;IAOI,8BAAA;ELu3GV;EK93GM;IAOI,4BAAA;EL03GV;EKj4GM;IAOI,8BAAA;EL63GV;EKp4GM;IAOI,4BAAA;ELg4GV;EKv4GM;IAOI,0BAAA;ELm4GV;EK14GM;IAOI,gCAAA;ELs4GV;EK74GM;IAOI,+BAAA;ELy4GV;EKh5GM;IAOI,6BAAA;EL44GV;EKn5GM;IAOI,+BAAA;EL+4GV;EKt5GM;IAOI,6BAAA;ELk5GV;EKz5GM;IAOI,4BAAA;ELq5GV;EK55GM;IAOI,kCAAA;ELw5GV;EK/5GM;IAOI,iCAAA;EL25GV;EKl6GM;IAOI,+BAAA;EL85GV;EKr6GM;IAOI,iCAAA;ELi6GV;EKx6GM;IAOI,+BAAA;ELo6GV;EK36GM;IAOI,2BAAA;ELu6GV;EK96GM;IAOI,iCAAA;EL06GV;EKj7GM;IAOI,gCAAA;EL66GV;EKp7GM;IAOI,8BAAA;ELg7GV;EKv7GM;IAOI,gCAAA;ELm7GV;EK17GM;IAOI,8BAAA;ELs7GV;AACF;ACj8GI;EIGI;IAOI,0BAAA;EL27GV;EKl8GM;IAOI,gCAAA;EL87GV;EKr8GM;IAOI,yBAAA;ELi8GV;EKx8GM;IAOI,wBAAA;ELo8GV;EK38GM;IAOI,+BAAA;ELu8GV;EK98GM;IAOI,yBAAA;EL08GV;EKj9GM;IAOI,6BAAA;EL68GV;EKp9GM;IAOI,8BAAA;ELg9GV;EKv9GM;IAOI,wBAAA;ELm9GV;EK19GM;IAOI,+BAAA;ELs9GV;EK79GM;IAOI,wBAAA;ELy9GV;EKh+GM;IAOI,yBAAA;EL49GV;EKn+GM;IAOI,8BAAA;EL+9GV;EKt+GM;IAOI,iCAAA;ELk+GV;EKz+GM;IAOI,sCAAA;ELq+GV;EK5+GM;IAOI,yCAAA;ELw+GV;EK/+GM;IAOI,uBAAA;EL2+GV;EKl/GM;IAOI,uBAAA;EL8+GV;EKr/GM;IAOI,yBAAA;ELi/GV;EKx/GM;IAOI,yBAAA;ELo/GV;EK3/GM;IAOI,0BAAA;ELu/GV;EK9/GM;IAOI,4BAAA;EL0/GV;EKjgHM;IAOI,kCAAA;EL6/GV;EKpgHM;IAOI,sCAAA;ELggHV;EKvgHM;IAOI,oCAAA;ELmgHV;EK1gHM;IAOI,kCAAA;ELsgHV;EK7gHM;IAOI,yCAAA;ELygHV;EKhhHM;IAOI,wCAAA;EL4gHV;EKnhHM;IAOI,wCAAA;EL+gHV;EKthHM;IAOI,kCAAA;ELkhHV;EKzhHM;IAOI,gCAAA;ELqhHV;EK5hHM;IAOI,8BAAA;ELwhHV;EK/hHM;IAOI,gCAAA;EL2hHV;EKliHM;IAOI,+BAAA;EL8hHV;EKriHM;IAOI,oCAAA;ELiiHV;EKxiHM;IAOI,kCAAA;ELoiHV;EK3iHM;IAOI,gCAAA;ELuiHV;EK9iHM;IAOI,uCAAA;EL0iHV;EKjjHM;IAOI,sCAAA;EL6iHV;EKpjHM;IAOI,iCAAA;ELgjHV;EKvjHM;IAOI,2BAAA;ELmjHV;EK1jHM;IAOI,iCAAA;ELsjHV;EK7jHM;IAOI,+BAAA;ELyjHV;EKhkHM;IAOI,6BAAA;EL4jHV;EKnkHM;IAOI,+BAAA;EL+jHV;EKtkHM;IAOI,8BAAA;ELkkHV;EKzkHM;IAOI,oBAAA;ELqkHV;EK5kHM;IAOI,mBAAA;ELwkHV;EK/kHM;IAOI,mBAAA;EL2kHV;EKllHM;IAOI,mBAAA;EL8kHV;EKrlHM;IAOI,mBAAA;ELilHV;EKxlHM;IAOI,mBAAA;ELolHV;EK3lHM;IAOI,mBAAA;ELulHV;EK9lHM;IAOI,mBAAA;EL0lHV;EKjmHM;IAOI,oBAAA;EL6lHV;EKpmHM;IAOI,0BAAA;ELgmHV;EKvmHM;IAOI,yBAAA;ELmmHV;EK1mHM;IAOI,uBAAA;ELsmHV;EK7mHM;IAOI,yBAAA;ELymHV;EKhnHM;IAOI,uBAAA;EL4mHV;EKnnHM;IAOI,uBAAA;EL+mHV;EKtnHM;IAOI,yBAAA;IAAA,0BAAA;ELmnHV;EK1nHM;IAOI,+BAAA;IAAA,gCAAA;ELunHV;EK9nHM;IAOI,8BAAA;IAAA,+BAAA;EL2nHV;EKloHM;IAOI,4BAAA;IAAA,6BAAA;EL+nHV;EKtoHM;IAOI,8BAAA;IAAA,+BAAA;ELmoHV;EK1oHM;IAOI,4BAAA;IAAA,6BAAA;ELuoHV;EK9oHM;IAOI,4BAAA;IAAA,6BAAA;EL2oHV;EKlpHM;IAOI,wBAAA;IAAA,2BAAA;EL+oHV;EKtpHM;IAOI,8BAAA;IAAA,iCAAA;ELmpHV;EK1pHM;IAOI,6BAAA;IAAA,gCAAA;ELupHV;EK9pHM;IAOI,2BAAA;IAAA,8BAAA;EL2pHV;EKlqHM;IAOI,6BAAA;IAAA,gCAAA;EL+pHV;EKtqHM;IAOI,2BAAA;IAAA,8BAAA;ELmqHV;EK1qHM;IAOI,2BAAA;IAAA,8BAAA;ELuqHV;EK9qHM;IAOI,wBAAA;EL0qHV;EKjrHM;IAOI,8BAAA;EL6qHV;EKprHM;IAOI,6BAAA;ELgrHV;EKvrHM;IAOI,2BAAA;ELmrHV;EK1rHM;IAOI,6BAAA;ELsrHV;EK7rHM;IAOI,2BAAA;ELyrHV;EKhsHM;IAOI,2BAAA;EL4rHV;EKnsHM;IAOI,yBAAA;EL+rHV;EKtsHM;IAOI,+BAAA;ELksHV;EKzsHM;IAOI,8BAAA;ELqsHV;EK5sHM;IAOI,4BAAA;ELwsHV;EK/sHM;IAOI,8BAAA;EL2sHV;EKltHM;IAOI,4BAAA;EL8sHV;EKrtHM;IAOI,4BAAA;ELitHV;EKxtHM;IAOI,2BAAA;ELotHV;EK3tHM;IAOI,iCAAA;ELutHV;EK9tHM;IAOI,gCAAA;EL0tHV;EKjuHM;IAOI,8BAAA;EL6tHV;EKpuHM;IAOI,gCAAA;ELguHV;EKvuHM;IAOI,8BAAA;ELmuHV;EK1uHM;IAOI,8BAAA;ELsuHV;EK7uHM;IAOI,0BAAA;ELyuHV;EKhvHM;IAOI,gCAAA;EL4uHV;EKnvHM;IAOI,+BAAA;EL+uHV;EKtvHM;IAOI,6BAAA;ELkvHV;EKzvHM;IAOI,+BAAA;ELqvHV;EK5vHM;IAOI,6BAAA;ELwvHV;EK/vHM;IAOI,6BAAA;EL2vHV;EKlwHM;IAOI,qBAAA;EL8vHV;EKrwHM;IAOI,2BAAA;ELiwHV;EKxwHM;IAOI,0BAAA;ELowHV;EK3wHM;IAOI,wBAAA;ELuwHV;EK9wHM;IAOI,0BAAA;EL0wHV;EKjxHM;IAOI,wBAAA;EL6wHV;EKpxHM;IAOI,0BAAA;IAAA,2BAAA;ELixHV;EKxxHM;IAOI,gCAAA;IAAA,iCAAA;ELqxHV;EK5xHM;IAOI,+BAAA;IAAA,gCAAA;ELyxHV;EKhyHM;IAOI,6BAAA;IAAA,8BAAA;EL6xHV;EKpyHM;IAOI,+BAAA;IAAA,gCAAA;ELiyHV;EKxyHM;IAOI,6BAAA;IAAA,8BAAA;ELqyHV;EK5yHM;IAOI,yBAAA;IAAA,4BAAA;ELyyHV;EKhzHM;IAOI,+BAAA;IAAA,kCAAA;EL6yHV;EKpzHM;IAOI,8BAAA;IAAA,iCAAA;ELizHV;EKxzHM;IAOI,4BAAA;IAAA,+BAAA;ELqzHV;EK5zHM;IAOI,8BAAA;IAAA,iCAAA;ELyzHV;EKh0HM;IAOI,4BAAA;IAAA,+BAAA;EL6zHV;EKp0HM;IAOI,yBAAA;ELg0HV;EKv0HM;IAOI,+BAAA;ELm0HV;EK10HM;IAOI,8BAAA;ELs0HV;EK70HM;IAOI,4BAAA;ELy0HV;EKh1HM;IAOI,8BAAA;EL40HV;EKn1HM;IAOI,4BAAA;EL+0HV;EKt1HM;IAOI,0BAAA;ELk1HV;EKz1HM;IAOI,gCAAA;ELq1HV;EK51HM;IAOI,+BAAA;ELw1HV;EK/1HM;IAOI,6BAAA;EL21HV;EKl2HM;IAOI,+BAAA;EL81HV;EKr2HM;IAOI,6BAAA;ELi2HV;EKx2HM;IAOI,4BAAA;ELo2HV;EK32HM;IAOI,kCAAA;ELu2HV;EK92HM;IAOI,iCAAA;EL02HV;EKj3HM;IAOI,+BAAA;EL62HV;EKp3HM;IAOI,iCAAA;ELg3HV;EKv3HM;IAOI,+BAAA;ELm3HV;EK13HM;IAOI,2BAAA;ELs3HV;EK73HM;IAOI,iCAAA;ELy3HV;EKh4HM;IAOI,gCAAA;EL43HV;EKn4HM;IAOI,8BAAA;EL+3HV;EKt4HM;IAOI,gCAAA;ELk4HV;EKz4HM;IAOI,8BAAA;ELq4HV;AACF;AMz6HA;ED4BQ;IAOI,0BAAA;EL04HV;EKj5HM;IAOI,gCAAA;EL64HV;EKp5HM;IAOI,yBAAA;ELg5HV;EKv5HM;IAOI,wBAAA;ELm5HV;EK15HM;IAOI,+BAAA;ELs5HV;EK75HM;IAOI,yBAAA;ELy5HV;EKh6HM;IAOI,6BAAA;EL45HV;EKn6HM;IAOI,8BAAA;EL+5HV;EKt6HM;IAOI,wBAAA;ELk6HV;EKz6HM;IAOI,+BAAA;ELq6HV;EK56HM;IAOI,wBAAA;ELw6HV;AACF","file":"bootstrap-grid.rtl.css","sourcesContent":["@mixin bsBanner($file) {\n /*!\n * Bootstrap #{$file} v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-container-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n","// Container mixins\n\n@mixin make-container($gutter: $container-padding-x) {\n --#{$prefix}gutter-x: #{$gutter};\n --#{$prefix}gutter-y: 0;\n width: 100%;\n padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n margin-right: auto;\n margin-left: auto;\n}\n","/*!\n * Bootstrap Grid v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n --bs-gutter-x: 1.5rem;\n --bs-gutter-y: 0;\n width: 100%;\n padding-right: calc(var(--bs-gutter-x) * 0.5);\n padding-left: calc(var(--bs-gutter-x) * 0.5);\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container-sm, .container {\n max-width: 540px;\n }\n}\n@media (min-width: 768px) {\n .container-md, .container-sm, .container {\n max-width: 720px;\n }\n}\n@media (min-width: 992px) {\n .container-lg, .container-md, .container-sm, .container {\n max-width: 960px;\n }\n}\n@media (min-width: 1200px) {\n .container-xl, .container-lg, .container-md, .container-sm, .container {\n max-width: 1140px;\n }\n}\n@media (min-width: 1400px) {\n .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n max-width: 1320px;\n }\n}\n:root {\n --bs-breakpoint-xs: 0;\n --bs-breakpoint-sm: 576px;\n --bs-breakpoint-md: 768px;\n --bs-breakpoint-lg: 992px;\n --bs-breakpoint-xl: 1200px;\n --bs-breakpoint-xxl: 1400px;\n}\n\n.row {\n --bs-gutter-x: 1.5rem;\n --bs-gutter-y: 0;\n display: flex;\n flex-wrap: wrap;\n margin-top: calc(-1 * var(--bs-gutter-y));\n margin-right: calc(-0.5 * var(--bs-gutter-x));\n margin-left: calc(-0.5 * var(--bs-gutter-x));\n}\n.row > * {\n box-sizing: border-box;\n flex-shrink: 0;\n width: 100%;\n max-width: 100%;\n padding-right: calc(var(--bs-gutter-x) * 0.5);\n padding-left: calc(var(--bs-gutter-x) * 0.5);\n margin-top: var(--bs-gutter-y);\n}\n\n.col {\n flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n flex: 0 0 auto;\n width: auto;\n}\n\n.row-cols-1 > * {\n flex: 0 0 auto;\n width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 auto;\n width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 auto;\n width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 auto;\n width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n}\n\n.col-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n}\n\n.col-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n}\n\n.col-3 {\n flex: 0 0 auto;\n width: 25%;\n}\n\n.col-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n}\n\n.col-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n}\n\n.col-6 {\n flex: 0 0 auto;\n width: 50%;\n}\n\n.col-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n}\n\n.col-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n}\n\n.col-9 {\n flex: 0 0 auto;\n width: 75%;\n}\n\n.col-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n}\n\n.col-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n}\n\n.col-12 {\n flex: 0 0 auto;\n width: 100%;\n}\n\n.offset-1 {\n margin-left: 8.33333333%;\n}\n\n.offset-2 {\n margin-left: 16.66666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.33333333%;\n}\n\n.offset-5 {\n margin-left: 41.66666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.33333333%;\n}\n\n.offset-8 {\n margin-left: 66.66666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.33333333%;\n}\n\n.offset-11 {\n margin-left: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex: 1 0 0%;\n }\n .row-cols-sm-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-sm-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-sm-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-sm-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-sm-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-sm-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-sm-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-sm-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-sm-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-sm-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.33333333%;\n }\n .offset-sm-2 {\n margin-left: 16.66666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.33333333%;\n }\n .offset-sm-5 {\n margin-left: 41.66666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.33333333%;\n }\n .offset-sm-8 {\n margin-left: 66.66666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.33333333%;\n }\n .offset-sm-11 {\n margin-left: 91.66666667%;\n }\n .g-sm-0,\n .gx-sm-0 {\n --bs-gutter-x: 0;\n }\n .g-sm-0,\n .gy-sm-0 {\n --bs-gutter-y: 0;\n }\n .g-sm-1,\n .gx-sm-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-sm-1,\n .gy-sm-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-sm-2,\n .gx-sm-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-sm-2,\n .gy-sm-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-sm-3,\n .gx-sm-3 {\n --bs-gutter-x: 1rem;\n }\n .g-sm-3,\n .gy-sm-3 {\n --bs-gutter-y: 1rem;\n }\n .g-sm-4,\n .gx-sm-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-sm-4,\n .gy-sm-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-sm-5,\n .gx-sm-5 {\n --bs-gutter-x: 3rem;\n }\n .g-sm-5,\n .gy-sm-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 768px) {\n .col-md {\n flex: 1 0 0%;\n }\n .row-cols-md-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-md-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-md-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-md-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-md-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-md-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-md-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-md-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-md-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-md-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-md-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-md-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-md-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-md-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.33333333%;\n }\n .offset-md-2 {\n margin-left: 16.66666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.33333333%;\n }\n .offset-md-5 {\n margin-left: 41.66666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.33333333%;\n }\n .offset-md-8 {\n margin-left: 66.66666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.33333333%;\n }\n .offset-md-11 {\n margin-left: 91.66666667%;\n }\n .g-md-0,\n .gx-md-0 {\n --bs-gutter-x: 0;\n }\n .g-md-0,\n .gy-md-0 {\n --bs-gutter-y: 0;\n }\n .g-md-1,\n .gx-md-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-md-1,\n .gy-md-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-md-2,\n .gx-md-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-md-2,\n .gy-md-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-md-3,\n .gx-md-3 {\n --bs-gutter-x: 1rem;\n }\n .g-md-3,\n .gy-md-3 {\n --bs-gutter-y: 1rem;\n }\n .g-md-4,\n .gx-md-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-md-4,\n .gy-md-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-md-5,\n .gx-md-5 {\n --bs-gutter-x: 3rem;\n }\n .g-md-5,\n .gy-md-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 992px) {\n .col-lg {\n flex: 1 0 0%;\n }\n .row-cols-lg-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-lg-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-lg-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-lg-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-lg-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-lg-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-lg-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-lg-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-lg-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-lg-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.33333333%;\n }\n .offset-lg-2 {\n margin-left: 16.66666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.33333333%;\n }\n .offset-lg-5 {\n margin-left: 41.66666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.33333333%;\n }\n .offset-lg-8 {\n margin-left: 66.66666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.33333333%;\n }\n .offset-lg-11 {\n margin-left: 91.66666667%;\n }\n .g-lg-0,\n .gx-lg-0 {\n --bs-gutter-x: 0;\n }\n .g-lg-0,\n .gy-lg-0 {\n --bs-gutter-y: 0;\n }\n .g-lg-1,\n .gx-lg-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-lg-1,\n .gy-lg-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-lg-2,\n .gx-lg-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-lg-2,\n .gy-lg-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-lg-3,\n .gx-lg-3 {\n --bs-gutter-x: 1rem;\n }\n .g-lg-3,\n .gy-lg-3 {\n --bs-gutter-y: 1rem;\n }\n .g-lg-4,\n .gx-lg-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-lg-4,\n .gy-lg-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-lg-5,\n .gx-lg-5 {\n --bs-gutter-x: 3rem;\n }\n .g-lg-5,\n .gy-lg-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 1200px) {\n .col-xl {\n flex: 1 0 0%;\n }\n .row-cols-xl-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-xl-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-xl-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xl-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-xl-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-xl-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-xl-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-xl-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-xl-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-xl-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.33333333%;\n }\n .offset-xl-2 {\n margin-left: 16.66666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.33333333%;\n }\n .offset-xl-5 {\n margin-left: 41.66666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.33333333%;\n }\n .offset-xl-8 {\n margin-left: 66.66666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.33333333%;\n }\n .offset-xl-11 {\n margin-left: 91.66666667%;\n }\n .g-xl-0,\n .gx-xl-0 {\n --bs-gutter-x: 0;\n }\n .g-xl-0,\n .gy-xl-0 {\n --bs-gutter-y: 0;\n }\n .g-xl-1,\n .gx-xl-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-xl-1,\n .gy-xl-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-xl-2,\n .gx-xl-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-xl-2,\n .gy-xl-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-xl-3,\n .gx-xl-3 {\n --bs-gutter-x: 1rem;\n }\n .g-xl-3,\n .gy-xl-3 {\n --bs-gutter-y: 1rem;\n }\n .g-xl-4,\n .gx-xl-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-xl-4,\n .gy-xl-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-xl-5,\n .gx-xl-5 {\n --bs-gutter-x: 3rem;\n }\n .g-xl-5,\n .gy-xl-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 1400px) {\n .col-xxl {\n flex: 1 0 0%;\n }\n .row-cols-xxl-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-xxl-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-xxl-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-xxl-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-xxl-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-xxl-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-xxl-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xxl-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-xxl-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-xxl-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xxl-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-xxl-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-xxl-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-xxl-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-xxl-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-xxl-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-xxl-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-xxl-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-xxl-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-xxl-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-xxl-0 {\n margin-left: 0;\n }\n .offset-xxl-1 {\n margin-left: 8.33333333%;\n }\n .offset-xxl-2 {\n margin-left: 16.66666667%;\n }\n .offset-xxl-3 {\n margin-left: 25%;\n }\n .offset-xxl-4 {\n margin-left: 33.33333333%;\n }\n .offset-xxl-5 {\n margin-left: 41.66666667%;\n }\n .offset-xxl-6 {\n margin-left: 50%;\n }\n .offset-xxl-7 {\n margin-left: 58.33333333%;\n }\n .offset-xxl-8 {\n margin-left: 66.66666667%;\n }\n .offset-xxl-9 {\n margin-left: 75%;\n }\n .offset-xxl-10 {\n margin-left: 83.33333333%;\n }\n .offset-xxl-11 {\n margin-left: 91.66666667%;\n }\n .g-xxl-0,\n .gx-xxl-0 {\n --bs-gutter-x: 0;\n }\n .g-xxl-0,\n .gy-xxl-0 {\n --bs-gutter-y: 0;\n }\n .g-xxl-1,\n .gx-xxl-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-xxl-1,\n .gy-xxl-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-xxl-2,\n .gx-xxl-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-xxl-2,\n .gy-xxl-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-xxl-3,\n .gx-xxl-3 {\n --bs-gutter-x: 1rem;\n }\n .g-xxl-3,\n .gy-xxl-3 {\n --bs-gutter-y: 1rem;\n }\n .g-xxl-4,\n .gx-xxl-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-xxl-4,\n .gy-xxl-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-xxl-5,\n .gx-xxl-5 {\n --bs-gutter-x: 3rem;\n }\n .g-xxl-5,\n .gy-xxl-5 {\n --bs-gutter-y: 3rem;\n }\n}\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-grid {\n display: grid !important;\n}\n\n.d-inline-grid {\n display: inline-grid !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n.d-none {\n display: none !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n justify-content: space-evenly !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n.order-first {\n order: -1 !important;\n}\n\n.order-0 {\n order: 0 !important;\n}\n\n.order-1 {\n order: 1 !important;\n}\n\n.order-2 {\n order: 2 !important;\n}\n\n.order-3 {\n order: 3 !important;\n}\n\n.order-4 {\n order: 4 !important;\n}\n\n.order-5 {\n order: 5 !important;\n}\n\n.order-last {\n order: 6 !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mx-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n}\n\n.mx-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n}\n\n.mx-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n}\n\n.mx-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n}\n\n.mx-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n}\n\n.mx-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n}\n\n.my-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n}\n\n.my-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n}\n\n.my-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n}\n\n.my-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n}\n\n.mt-0 {\n margin-top: 0 !important;\n}\n\n.mt-1 {\n margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n margin-top: 1rem !important;\n}\n\n.mt-4 {\n margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n margin-top: 3rem !important;\n}\n\n.mt-auto {\n margin-top: auto !important;\n}\n\n.me-0 {\n margin-right: 0 !important;\n}\n\n.me-1 {\n margin-right: 0.25rem !important;\n}\n\n.me-2 {\n margin-right: 0.5rem !important;\n}\n\n.me-3 {\n margin-right: 1rem !important;\n}\n\n.me-4 {\n margin-right: 1.5rem !important;\n}\n\n.me-5 {\n margin-right: 3rem !important;\n}\n\n.me-auto {\n margin-right: auto !important;\n}\n\n.mb-0 {\n margin-bottom: 0 !important;\n}\n\n.mb-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n margin-bottom: auto !important;\n}\n\n.ms-0 {\n margin-left: 0 !important;\n}\n\n.ms-1 {\n margin-left: 0.25rem !important;\n}\n\n.ms-2 {\n margin-left: 0.5rem !important;\n}\n\n.ms-3 {\n margin-left: 1rem !important;\n}\n\n.ms-4 {\n margin-left: 1.5rem !important;\n}\n\n.ms-5 {\n margin-left: 3rem !important;\n}\n\n.ms-auto {\n margin-left: auto !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.px-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n}\n\n.px-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n}\n\n.px-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n}\n\n.px-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n}\n\n.px-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n}\n\n.px-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n}\n\n.py-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n}\n\n.py-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n}\n\n.py-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n padding-top: 0 !important;\n}\n\n.pt-1 {\n padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n padding-top: 1rem !important;\n}\n\n.pt-4 {\n padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n padding-top: 3rem !important;\n}\n\n.pe-0 {\n padding-right: 0 !important;\n}\n\n.pe-1 {\n padding-right: 0.25rem !important;\n}\n\n.pe-2 {\n padding-right: 0.5rem !important;\n}\n\n.pe-3 {\n padding-right: 1rem !important;\n}\n\n.pe-4 {\n padding-right: 1.5rem !important;\n}\n\n.pe-5 {\n padding-right: 3rem !important;\n}\n\n.pb-0 {\n padding-bottom: 0 !important;\n}\n\n.pb-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n padding-left: 0 !important;\n}\n\n.ps-1 {\n padding-left: 0.25rem !important;\n}\n\n.ps-2 {\n padding-left: 0.5rem !important;\n}\n\n.ps-3 {\n padding-left: 1rem !important;\n}\n\n.ps-4 {\n padding-left: 1.5rem !important;\n}\n\n.ps-5 {\n padding-left: 3rem !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-grid {\n display: grid !important;\n }\n .d-sm-inline-grid {\n display: inline-grid !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n .d-sm-none {\n display: none !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .justify-content-sm-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n .order-sm-first {\n order: -1 !important;\n }\n .order-sm-0 {\n order: 0 !important;\n }\n .order-sm-1 {\n order: 1 !important;\n }\n .order-sm-2 {\n order: 2 !important;\n }\n .order-sm-3 {\n order: 3 !important;\n }\n .order-sm-4 {\n order: 4 !important;\n }\n .order-sm-5 {\n order: 5 !important;\n }\n .order-sm-last {\n order: 6 !important;\n }\n .m-sm-0 {\n margin: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mx-sm-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-sm-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-sm-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-sm-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-sm-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-sm-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-sm-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-sm-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-sm-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-sm-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-sm-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-sm-0 {\n margin-top: 0 !important;\n }\n .mt-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mt-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mt-sm-3 {\n margin-top: 1rem !important;\n }\n .mt-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mt-sm-5 {\n margin-top: 3rem !important;\n }\n .mt-sm-auto {\n margin-top: auto !important;\n }\n .me-sm-0 {\n margin-right: 0 !important;\n }\n .me-sm-1 {\n margin-right: 0.25rem !important;\n }\n .me-sm-2 {\n margin-right: 0.5rem !important;\n }\n .me-sm-3 {\n margin-right: 1rem !important;\n }\n .me-sm-4 {\n margin-right: 1.5rem !important;\n }\n .me-sm-5 {\n margin-right: 3rem !important;\n }\n .me-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-0 {\n margin-bottom: 0 !important;\n }\n .mb-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-sm-3 {\n margin-bottom: 1rem !important;\n }\n .mb-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-sm-5 {\n margin-bottom: 3rem !important;\n }\n .mb-sm-auto {\n margin-bottom: auto !important;\n }\n .ms-sm-0 {\n margin-left: 0 !important;\n }\n .ms-sm-1 {\n margin-left: 0.25rem !important;\n }\n .ms-sm-2 {\n margin-left: 0.5rem !important;\n }\n .ms-sm-3 {\n margin-left: 1rem !important;\n }\n .ms-sm-4 {\n margin-left: 1.5rem !important;\n }\n .ms-sm-5 {\n margin-left: 3rem !important;\n }\n .ms-sm-auto {\n margin-left: auto !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .px-sm-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-sm-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-sm-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-sm-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-sm-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-sm-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-sm-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-sm-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-sm-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-sm-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-sm-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-sm-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-sm-0 {\n padding-top: 0 !important;\n }\n .pt-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pt-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pt-sm-3 {\n padding-top: 1rem !important;\n }\n .pt-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pt-sm-5 {\n padding-top: 3rem !important;\n }\n .pe-sm-0 {\n padding-right: 0 !important;\n }\n .pe-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pe-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pe-sm-3 {\n padding-right: 1rem !important;\n }\n .pe-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pe-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-0 {\n padding-bottom: 0 !important;\n }\n .pb-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pb-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-sm-5 {\n padding-bottom: 3rem !important;\n }\n .ps-sm-0 {\n padding-left: 0 !important;\n }\n .ps-sm-1 {\n padding-left: 0.25rem !important;\n }\n .ps-sm-2 {\n padding-left: 0.5rem !important;\n }\n .ps-sm-3 {\n padding-left: 1rem !important;\n }\n .ps-sm-4 {\n padding-left: 1.5rem !important;\n }\n .ps-sm-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 768px) {\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-grid {\n display: grid !important;\n }\n .d-md-inline-grid {\n display: inline-grid !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n .d-md-none {\n display: none !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .justify-content-md-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n .order-md-first {\n order: -1 !important;\n }\n .order-md-0 {\n order: 0 !important;\n }\n .order-md-1 {\n order: 1 !important;\n }\n .order-md-2 {\n order: 2 !important;\n }\n .order-md-3 {\n order: 3 !important;\n }\n .order-md-4 {\n order: 4 !important;\n }\n .order-md-5 {\n order: 5 !important;\n }\n .order-md-last {\n order: 6 !important;\n }\n .m-md-0 {\n margin: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mx-md-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-md-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-md-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-md-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-md-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-md-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-md-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-md-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-md-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-md-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-md-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-md-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-md-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-md-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-md-0 {\n margin-top: 0 !important;\n }\n .mt-md-1 {\n margin-top: 0.25rem !important;\n }\n .mt-md-2 {\n margin-top: 0.5rem !important;\n }\n .mt-md-3 {\n margin-top: 1rem !important;\n }\n .mt-md-4 {\n margin-top: 1.5rem !important;\n }\n .mt-md-5 {\n margin-top: 3rem !important;\n }\n .mt-md-auto {\n margin-top: auto !important;\n }\n .me-md-0 {\n margin-right: 0 !important;\n }\n .me-md-1 {\n margin-right: 0.25rem !important;\n }\n .me-md-2 {\n margin-right: 0.5rem !important;\n }\n .me-md-3 {\n margin-right: 1rem !important;\n }\n .me-md-4 {\n margin-right: 1.5rem !important;\n }\n .me-md-5 {\n margin-right: 3rem !important;\n }\n .me-md-auto {\n margin-right: auto !important;\n }\n .mb-md-0 {\n margin-bottom: 0 !important;\n }\n .mb-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-md-3 {\n margin-bottom: 1rem !important;\n }\n .mb-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-md-5 {\n margin-bottom: 3rem !important;\n }\n .mb-md-auto {\n margin-bottom: auto !important;\n }\n .ms-md-0 {\n margin-left: 0 !important;\n }\n .ms-md-1 {\n margin-left: 0.25rem !important;\n }\n .ms-md-2 {\n margin-left: 0.5rem !important;\n }\n .ms-md-3 {\n margin-left: 1rem !important;\n }\n .ms-md-4 {\n margin-left: 1.5rem !important;\n }\n .ms-md-5 {\n margin-left: 3rem !important;\n }\n .ms-md-auto {\n margin-left: auto !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .px-md-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-md-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-md-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-md-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-md-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-md-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-md-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-md-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-md-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-md-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-md-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-md-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-md-0 {\n padding-top: 0 !important;\n }\n .pt-md-1 {\n padding-top: 0.25rem !important;\n }\n .pt-md-2 {\n padding-top: 0.5rem !important;\n }\n .pt-md-3 {\n padding-top: 1rem !important;\n }\n .pt-md-4 {\n padding-top: 1.5rem !important;\n }\n .pt-md-5 {\n padding-top: 3rem !important;\n }\n .pe-md-0 {\n padding-right: 0 !important;\n }\n .pe-md-1 {\n padding-right: 0.25rem !important;\n }\n .pe-md-2 {\n padding-right: 0.5rem !important;\n }\n .pe-md-3 {\n padding-right: 1rem !important;\n }\n .pe-md-4 {\n padding-right: 1.5rem !important;\n }\n .pe-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-0 {\n padding-bottom: 0 !important;\n }\n .pb-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-md-3 {\n padding-bottom: 1rem !important;\n }\n .pb-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-md-5 {\n padding-bottom: 3rem !important;\n }\n .ps-md-0 {\n padding-left: 0 !important;\n }\n .ps-md-1 {\n padding-left: 0.25rem !important;\n }\n .ps-md-2 {\n padding-left: 0.5rem !important;\n }\n .ps-md-3 {\n padding-left: 1rem !important;\n }\n .ps-md-4 {\n padding-left: 1.5rem !important;\n }\n .ps-md-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 992px) {\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-grid {\n display: grid !important;\n }\n .d-lg-inline-grid {\n display: inline-grid !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n .d-lg-none {\n display: none !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .justify-content-lg-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n .order-lg-first {\n order: -1 !important;\n }\n .order-lg-0 {\n order: 0 !important;\n }\n .order-lg-1 {\n order: 1 !important;\n }\n .order-lg-2 {\n order: 2 !important;\n }\n .order-lg-3 {\n order: 3 !important;\n }\n .order-lg-4 {\n order: 4 !important;\n }\n .order-lg-5 {\n order: 5 !important;\n }\n .order-lg-last {\n order: 6 !important;\n }\n .m-lg-0 {\n margin: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mx-lg-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-lg-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-lg-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-lg-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-lg-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-lg-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-lg-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-lg-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-lg-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-lg-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-lg-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-lg-0 {\n margin-top: 0 !important;\n }\n .mt-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mt-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mt-lg-3 {\n margin-top: 1rem !important;\n }\n .mt-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mt-lg-5 {\n margin-top: 3rem !important;\n }\n .mt-lg-auto {\n margin-top: auto !important;\n }\n .me-lg-0 {\n margin-right: 0 !important;\n }\n .me-lg-1 {\n margin-right: 0.25rem !important;\n }\n .me-lg-2 {\n margin-right: 0.5rem !important;\n }\n .me-lg-3 {\n margin-right: 1rem !important;\n }\n .me-lg-4 {\n margin-right: 1.5rem !important;\n }\n .me-lg-5 {\n margin-right: 3rem !important;\n }\n .me-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-0 {\n margin-bottom: 0 !important;\n }\n .mb-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-lg-3 {\n margin-bottom: 1rem !important;\n }\n .mb-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-lg-5 {\n margin-bottom: 3rem !important;\n }\n .mb-lg-auto {\n margin-bottom: auto !important;\n }\n .ms-lg-0 {\n margin-left: 0 !important;\n }\n .ms-lg-1 {\n margin-left: 0.25rem !important;\n }\n .ms-lg-2 {\n margin-left: 0.5rem !important;\n }\n .ms-lg-3 {\n margin-left: 1rem !important;\n }\n .ms-lg-4 {\n margin-left: 1.5rem !important;\n }\n .ms-lg-5 {\n margin-left: 3rem !important;\n }\n .ms-lg-auto {\n margin-left: auto !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .px-lg-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-lg-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-lg-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-lg-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-lg-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-lg-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-lg-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-lg-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-lg-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-lg-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-lg-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-lg-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-lg-0 {\n padding-top: 0 !important;\n }\n .pt-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pt-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pt-lg-3 {\n padding-top: 1rem !important;\n }\n .pt-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pt-lg-5 {\n padding-top: 3rem !important;\n }\n .pe-lg-0 {\n padding-right: 0 !important;\n }\n .pe-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pe-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pe-lg-3 {\n padding-right: 1rem !important;\n }\n .pe-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pe-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-0 {\n padding-bottom: 0 !important;\n }\n .pb-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pb-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-lg-5 {\n padding-bottom: 3rem !important;\n }\n .ps-lg-0 {\n padding-left: 0 !important;\n }\n .ps-lg-1 {\n padding-left: 0.25rem !important;\n }\n .ps-lg-2 {\n padding-left: 0.5rem !important;\n }\n .ps-lg-3 {\n padding-left: 1rem !important;\n }\n .ps-lg-4 {\n padding-left: 1.5rem !important;\n }\n .ps-lg-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 1200px) {\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-grid {\n display: grid !important;\n }\n .d-xl-inline-grid {\n display: inline-grid !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n .d-xl-none {\n display: none !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .justify-content-xl-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n .order-xl-first {\n order: -1 !important;\n }\n .order-xl-0 {\n order: 0 !important;\n }\n .order-xl-1 {\n order: 1 !important;\n }\n .order-xl-2 {\n order: 2 !important;\n }\n .order-xl-3 {\n order: 3 !important;\n }\n .order-xl-4 {\n order: 4 !important;\n }\n .order-xl-5 {\n order: 5 !important;\n }\n .order-xl-last {\n order: 6 !important;\n }\n .m-xl-0 {\n margin: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mx-xl-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-xl-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-xl-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-xl-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-xl-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-xl-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-xl-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-xl-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-xl-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-xl-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-xl-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-xl-0 {\n margin-top: 0 !important;\n }\n .mt-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mt-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mt-xl-3 {\n margin-top: 1rem !important;\n }\n .mt-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mt-xl-5 {\n margin-top: 3rem !important;\n }\n .mt-xl-auto {\n margin-top: auto !important;\n }\n .me-xl-0 {\n margin-right: 0 !important;\n }\n .me-xl-1 {\n margin-right: 0.25rem !important;\n }\n .me-xl-2 {\n margin-right: 0.5rem !important;\n }\n .me-xl-3 {\n margin-right: 1rem !important;\n }\n .me-xl-4 {\n margin-right: 1.5rem !important;\n }\n .me-xl-5 {\n margin-right: 3rem !important;\n }\n .me-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-0 {\n margin-bottom: 0 !important;\n }\n .mb-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-xl-3 {\n margin-bottom: 1rem !important;\n }\n .mb-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-xl-5 {\n margin-bottom: 3rem !important;\n }\n .mb-xl-auto {\n margin-bottom: auto !important;\n }\n .ms-xl-0 {\n margin-left: 0 !important;\n }\n .ms-xl-1 {\n margin-left: 0.25rem !important;\n }\n .ms-xl-2 {\n margin-left: 0.5rem !important;\n }\n .ms-xl-3 {\n margin-left: 1rem !important;\n }\n .ms-xl-4 {\n margin-left: 1.5rem !important;\n }\n .ms-xl-5 {\n margin-left: 3rem !important;\n }\n .ms-xl-auto {\n margin-left: auto !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .px-xl-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-xl-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-xl-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-xl-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-xl-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-xl-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-xl-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-xl-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-xl-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-xl-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-xl-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-xl-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-xl-0 {\n padding-top: 0 !important;\n }\n .pt-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pt-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pt-xl-3 {\n padding-top: 1rem !important;\n }\n .pt-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pt-xl-5 {\n padding-top: 3rem !important;\n }\n .pe-xl-0 {\n padding-right: 0 !important;\n }\n .pe-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pe-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pe-xl-3 {\n padding-right: 1rem !important;\n }\n .pe-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pe-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-0 {\n padding-bottom: 0 !important;\n }\n .pb-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pb-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-xl-5 {\n padding-bottom: 3rem !important;\n }\n .ps-xl-0 {\n padding-left: 0 !important;\n }\n .ps-xl-1 {\n padding-left: 0.25rem !important;\n }\n .ps-xl-2 {\n padding-left: 0.5rem !important;\n }\n .ps-xl-3 {\n padding-left: 1rem !important;\n }\n .ps-xl-4 {\n padding-left: 1.5rem !important;\n }\n .ps-xl-5 {\n padding-left: 3rem !important;\n }\n}\n@media (min-width: 1400px) {\n .d-xxl-inline {\n display: inline !important;\n }\n .d-xxl-inline-block {\n display: inline-block !important;\n }\n .d-xxl-block {\n display: block !important;\n }\n .d-xxl-grid {\n display: grid !important;\n }\n .d-xxl-inline-grid {\n display: inline-grid !important;\n }\n .d-xxl-table {\n display: table !important;\n }\n .d-xxl-table-row {\n display: table-row !important;\n }\n .d-xxl-table-cell {\n display: table-cell !important;\n }\n .d-xxl-flex {\n display: flex !important;\n }\n .d-xxl-inline-flex {\n display: inline-flex !important;\n }\n .d-xxl-none {\n display: none !important;\n }\n .flex-xxl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xxl-row {\n flex-direction: row !important;\n }\n .flex-xxl-column {\n flex-direction: column !important;\n }\n .flex-xxl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xxl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xxl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xxl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xxl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xxl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-xxl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xxl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xxl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xxl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xxl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xxl-center {\n justify-content: center !important;\n }\n .justify-content-xxl-between {\n justify-content: space-between !important;\n }\n .justify-content-xxl-around {\n justify-content: space-around !important;\n }\n .justify-content-xxl-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-xxl-start {\n align-items: flex-start !important;\n }\n .align-items-xxl-end {\n align-items: flex-end !important;\n }\n .align-items-xxl-center {\n align-items: center !important;\n }\n .align-items-xxl-baseline {\n align-items: baseline !important;\n }\n .align-items-xxl-stretch {\n align-items: stretch !important;\n }\n .align-content-xxl-start {\n align-content: flex-start !important;\n }\n .align-content-xxl-end {\n align-content: flex-end !important;\n }\n .align-content-xxl-center {\n align-content: center !important;\n }\n .align-content-xxl-between {\n align-content: space-between !important;\n }\n .align-content-xxl-around {\n align-content: space-around !important;\n }\n .align-content-xxl-stretch {\n align-content: stretch !important;\n }\n .align-self-xxl-auto {\n align-self: auto !important;\n }\n .align-self-xxl-start {\n align-self: flex-start !important;\n }\n .align-self-xxl-end {\n align-self: flex-end !important;\n }\n .align-self-xxl-center {\n align-self: center !important;\n }\n .align-self-xxl-baseline {\n align-self: baseline !important;\n }\n .align-self-xxl-stretch {\n align-self: stretch !important;\n }\n .order-xxl-first {\n order: -1 !important;\n }\n .order-xxl-0 {\n order: 0 !important;\n }\n .order-xxl-1 {\n order: 1 !important;\n }\n .order-xxl-2 {\n order: 2 !important;\n }\n .order-xxl-3 {\n order: 3 !important;\n }\n .order-xxl-4 {\n order: 4 !important;\n }\n .order-xxl-5 {\n order: 5 !important;\n }\n .order-xxl-last {\n order: 6 !important;\n }\n .m-xxl-0 {\n margin: 0 !important;\n }\n .m-xxl-1 {\n margin: 0.25rem !important;\n }\n .m-xxl-2 {\n margin: 0.5rem !important;\n }\n .m-xxl-3 {\n margin: 1rem !important;\n }\n .m-xxl-4 {\n margin: 1.5rem !important;\n }\n .m-xxl-5 {\n margin: 3rem !important;\n }\n .m-xxl-auto {\n margin: auto !important;\n }\n .mx-xxl-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-xxl-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-xxl-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-xxl-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-xxl-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-xxl-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-xxl-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-xxl-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-xxl-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-xxl-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-xxl-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-xxl-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-xxl-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-xxl-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-xxl-0 {\n margin-top: 0 !important;\n }\n .mt-xxl-1 {\n margin-top: 0.25rem !important;\n }\n .mt-xxl-2 {\n margin-top: 0.5rem !important;\n }\n .mt-xxl-3 {\n margin-top: 1rem !important;\n }\n .mt-xxl-4 {\n margin-top: 1.5rem !important;\n }\n .mt-xxl-5 {\n margin-top: 3rem !important;\n }\n .mt-xxl-auto {\n margin-top: auto !important;\n }\n .me-xxl-0 {\n margin-right: 0 !important;\n }\n .me-xxl-1 {\n margin-right: 0.25rem !important;\n }\n .me-xxl-2 {\n margin-right: 0.5rem !important;\n }\n .me-xxl-3 {\n margin-right: 1rem !important;\n }\n .me-xxl-4 {\n margin-right: 1.5rem !important;\n }\n .me-xxl-5 {\n margin-right: 3rem !important;\n }\n .me-xxl-auto {\n margin-right: auto !important;\n }\n .mb-xxl-0 {\n margin-bottom: 0 !important;\n }\n .mb-xxl-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-xxl-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-xxl-3 {\n margin-bottom: 1rem !important;\n }\n .mb-xxl-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-xxl-5 {\n margin-bottom: 3rem !important;\n }\n .mb-xxl-auto {\n margin-bottom: auto !important;\n }\n .ms-xxl-0 {\n margin-left: 0 !important;\n }\n .ms-xxl-1 {\n margin-left: 0.25rem !important;\n }\n .ms-xxl-2 {\n margin-left: 0.5rem !important;\n }\n .ms-xxl-3 {\n margin-left: 1rem !important;\n }\n .ms-xxl-4 {\n margin-left: 1.5rem !important;\n }\n .ms-xxl-5 {\n margin-left: 3rem !important;\n }\n .ms-xxl-auto {\n margin-left: auto !important;\n }\n .p-xxl-0 {\n padding: 0 !important;\n }\n .p-xxl-1 {\n padding: 0.25rem !important;\n }\n .p-xxl-2 {\n padding: 0.5rem !important;\n }\n .p-xxl-3 {\n padding: 1rem !important;\n }\n .p-xxl-4 {\n padding: 1.5rem !important;\n }\n .p-xxl-5 {\n padding: 3rem !important;\n }\n .px-xxl-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-xxl-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-xxl-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-xxl-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-xxl-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-xxl-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-xxl-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-xxl-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-xxl-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-xxl-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-xxl-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-xxl-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-xxl-0 {\n padding-top: 0 !important;\n }\n .pt-xxl-1 {\n padding-top: 0.25rem !important;\n }\n .pt-xxl-2 {\n padding-top: 0.5rem !important;\n }\n .pt-xxl-3 {\n padding-top: 1rem !important;\n }\n .pt-xxl-4 {\n padding-top: 1.5rem !important;\n }\n .pt-xxl-5 {\n padding-top: 3rem !important;\n }\n .pe-xxl-0 {\n padding-right: 0 !important;\n }\n .pe-xxl-1 {\n padding-right: 0.25rem !important;\n }\n .pe-xxl-2 {\n padding-right: 0.5rem !important;\n }\n .pe-xxl-3 {\n padding-right: 1rem !important;\n }\n .pe-xxl-4 {\n padding-right: 1.5rem !important;\n }\n .pe-xxl-5 {\n padding-right: 3rem !important;\n }\n .pb-xxl-0 {\n padding-bottom: 0 !important;\n }\n .pb-xxl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-xxl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-xxl-3 {\n padding-bottom: 1rem !important;\n }\n .pb-xxl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-xxl-5 {\n padding-bottom: 3rem !important;\n }\n .ps-xxl-0 {\n padding-left: 0 !important;\n }\n .ps-xxl-1 {\n padding-left: 0.25rem !important;\n }\n .ps-xxl-2 {\n padding-left: 0.5rem !important;\n }\n .ps-xxl-3 {\n padding-left: 1rem !important;\n }\n .ps-xxl-4 {\n padding-left: 1.5rem !important;\n }\n .ps-xxl-5 {\n padding-left: 3rem !important;\n }\n}\n@media print {\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-grid {\n display: grid !important;\n }\n .d-print-inline-grid {\n display: inline-grid !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n .d-print-none {\n display: none !important;\n }\n}\n\n/*# sourceMappingURL=bootstrap-grid.css.map */\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl xxl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @if not $n {\n @error \"breakpoint `#{$name}` not found in `#{$breakpoints}`\";\n }\n @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width.\n// The maximum value is reduced by 0.02px to work around the limitations of\n// `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $max: map-get($breakpoints, $name);\n @return if($max and $max > 0, $max - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $next: breakpoint-next($name, $breakpoints);\n $max: breakpoint-max($next, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($next, $breakpoints) {\n @content;\n }\n }\n}\n","// Variables\n//\n// Variables should follow the `$component-state-property-size` formula for\n// consistent naming. Ex: $nav-link-disabled-color and $modal-content-box-shadow-xs.\n\n// Color system\n\n// scss-docs-start gray-color-variables\n$white: #fff !default;\n$gray-100: #f8f9fa !default;\n$gray-200: #e9ecef !default;\n$gray-300: #dee2e6 !default;\n$gray-400: #ced4da !default;\n$gray-500: #adb5bd !default;\n$gray-600: #6c757d !default;\n$gray-700: #495057 !default;\n$gray-800: #343a40 !default;\n$gray-900: #212529 !default;\n$black: #000 !default;\n// scss-docs-end gray-color-variables\n\n// fusv-disable\n// scss-docs-start gray-colors-map\n$grays: (\n \"100\": $gray-100,\n \"200\": $gray-200,\n \"300\": $gray-300,\n \"400\": $gray-400,\n \"500\": $gray-500,\n \"600\": $gray-600,\n \"700\": $gray-700,\n \"800\": $gray-800,\n \"900\": $gray-900\n) !default;\n// scss-docs-end gray-colors-map\n// fusv-enable\n\n// scss-docs-start color-variables\n$blue: #0d6efd !default;\n$indigo: #6610f2 !default;\n$purple: #6f42c1 !default;\n$pink: #d63384 !default;\n$red: #dc3545 !default;\n$orange: #fd7e14 !default;\n$yellow: #ffc107 !default;\n$green: #198754 !default;\n$teal: #20c997 !default;\n$cyan: #0dcaf0 !default;\n// scss-docs-end color-variables\n\n// scss-docs-start colors-map\n$colors: (\n \"blue\": $blue,\n \"indigo\": $indigo,\n \"purple\": $purple,\n \"pink\": $pink,\n \"red\": $red,\n \"orange\": $orange,\n \"yellow\": $yellow,\n \"green\": $green,\n \"teal\": $teal,\n \"cyan\": $cyan,\n \"black\": $black,\n \"white\": $white,\n \"gray\": $gray-600,\n \"gray-dark\": $gray-800\n) !default;\n// scss-docs-end colors-map\n\n// The contrast ratio to reach against white, to determine if color changes from \"light\" to \"dark\". Acceptable values for WCAG 2.0 are 3, 4.5 and 7.\n// See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast\n$min-contrast-ratio: 4.5 !default;\n\n// Customize the light and dark text colors for use in our color contrast function.\n$color-contrast-dark: $black !default;\n$color-contrast-light: $white !default;\n\n// fusv-disable\n$blue-100: tint-color($blue, 80%) !default;\n$blue-200: tint-color($blue, 60%) !default;\n$blue-300: tint-color($blue, 40%) !default;\n$blue-400: tint-color($blue, 20%) !default;\n$blue-500: $blue !default;\n$blue-600: shade-color($blue, 20%) !default;\n$blue-700: shade-color($blue, 40%) !default;\n$blue-800: shade-color($blue, 60%) !default;\n$blue-900: shade-color($blue, 80%) !default;\n\n$indigo-100: tint-color($indigo, 80%) !default;\n$indigo-200: tint-color($indigo, 60%) !default;\n$indigo-300: tint-color($indigo, 40%) !default;\n$indigo-400: tint-color($indigo, 20%) !default;\n$indigo-500: $indigo !default;\n$indigo-600: shade-color($indigo, 20%) !default;\n$indigo-700: shade-color($indigo, 40%) !default;\n$indigo-800: shade-color($indigo, 60%) !default;\n$indigo-900: shade-color($indigo, 80%) !default;\n\n$purple-100: tint-color($purple, 80%) !default;\n$purple-200: tint-color($purple, 60%) !default;\n$purple-300: tint-color($purple, 40%) !default;\n$purple-400: tint-color($purple, 20%) !default;\n$purple-500: $purple !default;\n$purple-600: shade-color($purple, 20%) !default;\n$purple-700: shade-color($purple, 40%) !default;\n$purple-800: shade-color($purple, 60%) !default;\n$purple-900: shade-color($purple, 80%) !default;\n\n$pink-100: tint-color($pink, 80%) !default;\n$pink-200: tint-color($pink, 60%) !default;\n$pink-300: tint-color($pink, 40%) !default;\n$pink-400: tint-color($pink, 20%) !default;\n$pink-500: $pink !default;\n$pink-600: shade-color($pink, 20%) !default;\n$pink-700: shade-color($pink, 40%) !default;\n$pink-800: shade-color($pink, 60%) !default;\n$pink-900: shade-color($pink, 80%) !default;\n\n$red-100: tint-color($red, 80%) !default;\n$red-200: tint-color($red, 60%) !default;\n$red-300: tint-color($red, 40%) !default;\n$red-400: tint-color($red, 20%) !default;\n$red-500: $red !default;\n$red-600: shade-color($red, 20%) !default;\n$red-700: shade-color($red, 40%) !default;\n$red-800: shade-color($red, 60%) !default;\n$red-900: shade-color($red, 80%) !default;\n\n$orange-100: tint-color($orange, 80%) !default;\n$orange-200: tint-color($orange, 60%) !default;\n$orange-300: tint-color($orange, 40%) !default;\n$orange-400: tint-color($orange, 20%) !default;\n$orange-500: $orange !default;\n$orange-600: shade-color($orange, 20%) !default;\n$orange-700: shade-color($orange, 40%) !default;\n$orange-800: shade-color($orange, 60%) !default;\n$orange-900: shade-color($orange, 80%) !default;\n\n$yellow-100: tint-color($yellow, 80%) !default;\n$yellow-200: tint-color($yellow, 60%) !default;\n$yellow-300: tint-color($yellow, 40%) !default;\n$yellow-400: tint-color($yellow, 20%) !default;\n$yellow-500: $yellow !default;\n$yellow-600: shade-color($yellow, 20%) !default;\n$yellow-700: shade-color($yellow, 40%) !default;\n$yellow-800: shade-color($yellow, 60%) !default;\n$yellow-900: shade-color($yellow, 80%) !default;\n\n$green-100: tint-color($green, 80%) !default;\n$green-200: tint-color($green, 60%) !default;\n$green-300: tint-color($green, 40%) !default;\n$green-400: tint-color($green, 20%) !default;\n$green-500: $green !default;\n$green-600: shade-color($green, 20%) !default;\n$green-700: shade-color($green, 40%) !default;\n$green-800: shade-color($green, 60%) !default;\n$green-900: shade-color($green, 80%) !default;\n\n$teal-100: tint-color($teal, 80%) !default;\n$teal-200: tint-color($teal, 60%) !default;\n$teal-300: tint-color($teal, 40%) !default;\n$teal-400: tint-color($teal, 20%) !default;\n$teal-500: $teal !default;\n$teal-600: shade-color($teal, 20%) !default;\n$teal-700: shade-color($teal, 40%) !default;\n$teal-800: shade-color($teal, 60%) !default;\n$teal-900: shade-color($teal, 80%) !default;\n\n$cyan-100: tint-color($cyan, 80%) !default;\n$cyan-200: tint-color($cyan, 60%) !default;\n$cyan-300: tint-color($cyan, 40%) !default;\n$cyan-400: tint-color($cyan, 20%) !default;\n$cyan-500: $cyan !default;\n$cyan-600: shade-color($cyan, 20%) !default;\n$cyan-700: shade-color($cyan, 40%) !default;\n$cyan-800: shade-color($cyan, 60%) !default;\n$cyan-900: shade-color($cyan, 80%) !default;\n\n$blues: (\n \"blue-100\": $blue-100,\n \"blue-200\": $blue-200,\n \"blue-300\": $blue-300,\n \"blue-400\": $blue-400,\n \"blue-500\": $blue-500,\n \"blue-600\": $blue-600,\n \"blue-700\": $blue-700,\n \"blue-800\": $blue-800,\n \"blue-900\": $blue-900\n) !default;\n\n$indigos: (\n \"indigo-100\": $indigo-100,\n \"indigo-200\": $indigo-200,\n \"indigo-300\": $indigo-300,\n \"indigo-400\": $indigo-400,\n \"indigo-500\": $indigo-500,\n \"indigo-600\": $indigo-600,\n \"indigo-700\": $indigo-700,\n \"indigo-800\": $indigo-800,\n \"indigo-900\": $indigo-900\n) !default;\n\n$purples: (\n \"purple-100\": $purple-100,\n \"purple-200\": $purple-200,\n \"purple-300\": $purple-300,\n \"purple-400\": $purple-400,\n \"purple-500\": $purple-500,\n \"purple-600\": $purple-600,\n \"purple-700\": $purple-700,\n \"purple-800\": $purple-800,\n \"purple-900\": $purple-900\n) !default;\n\n$pinks: (\n \"pink-100\": $pink-100,\n \"pink-200\": $pink-200,\n \"pink-300\": $pink-300,\n \"pink-400\": $pink-400,\n \"pink-500\": $pink-500,\n \"pink-600\": $pink-600,\n \"pink-700\": $pink-700,\n \"pink-800\": $pink-800,\n \"pink-900\": $pink-900\n) !default;\n\n$reds: (\n \"red-100\": $red-100,\n \"red-200\": $red-200,\n \"red-300\": $red-300,\n \"red-400\": $red-400,\n \"red-500\": $red-500,\n \"red-600\": $red-600,\n \"red-700\": $red-700,\n \"red-800\": $red-800,\n \"red-900\": $red-900\n) !default;\n\n$oranges: (\n \"orange-100\": $orange-100,\n \"orange-200\": $orange-200,\n \"orange-300\": $orange-300,\n \"orange-400\": $orange-400,\n \"orange-500\": $orange-500,\n \"orange-600\": $orange-600,\n \"orange-700\": $orange-700,\n \"orange-800\": $orange-800,\n \"orange-900\": $orange-900\n) !default;\n\n$yellows: (\n \"yellow-100\": $yellow-100,\n \"yellow-200\": $yellow-200,\n \"yellow-300\": $yellow-300,\n \"yellow-400\": $yellow-400,\n \"yellow-500\": $yellow-500,\n \"yellow-600\": $yellow-600,\n \"yellow-700\": $yellow-700,\n \"yellow-800\": $yellow-800,\n \"yellow-900\": $yellow-900\n) !default;\n\n$greens: (\n \"green-100\": $green-100,\n \"green-200\": $green-200,\n \"green-300\": $green-300,\n \"green-400\": $green-400,\n \"green-500\": $green-500,\n \"green-600\": $green-600,\n \"green-700\": $green-700,\n \"green-800\": $green-800,\n \"green-900\": $green-900\n) !default;\n\n$teals: (\n \"teal-100\": $teal-100,\n \"teal-200\": $teal-200,\n \"teal-300\": $teal-300,\n \"teal-400\": $teal-400,\n \"teal-500\": $teal-500,\n \"teal-600\": $teal-600,\n \"teal-700\": $teal-700,\n \"teal-800\": $teal-800,\n \"teal-900\": $teal-900\n) !default;\n\n$cyans: (\n \"cyan-100\": $cyan-100,\n \"cyan-200\": $cyan-200,\n \"cyan-300\": $cyan-300,\n \"cyan-400\": $cyan-400,\n \"cyan-500\": $cyan-500,\n \"cyan-600\": $cyan-600,\n \"cyan-700\": $cyan-700,\n \"cyan-800\": $cyan-800,\n \"cyan-900\": $cyan-900\n) !default;\n// fusv-enable\n\n// scss-docs-start theme-color-variables\n$primary: $blue !default;\n$secondary: $gray-600 !default;\n$success: $green !default;\n$info: $cyan !default;\n$warning: $yellow !default;\n$danger: $red !default;\n$light: $gray-100 !default;\n$dark: $gray-900 !default;\n// scss-docs-end theme-color-variables\n\n// scss-docs-start theme-colors-map\n$theme-colors: (\n \"primary\": $primary,\n \"secondary\": $secondary,\n \"success\": $success,\n \"info\": $info,\n \"warning\": $warning,\n \"danger\": $danger,\n \"light\": $light,\n \"dark\": $dark\n) !default;\n// scss-docs-end theme-colors-map\n\n// scss-docs-start theme-text-variables\n$primary-text-emphasis: shade-color($primary, 60%) !default;\n$secondary-text-emphasis: shade-color($secondary, 60%) !default;\n$success-text-emphasis: shade-color($success, 60%) !default;\n$info-text-emphasis: shade-color($info, 60%) !default;\n$warning-text-emphasis: shade-color($warning, 60%) !default;\n$danger-text-emphasis: shade-color($danger, 60%) !default;\n$light-text-emphasis: $gray-700 !default;\n$dark-text-emphasis: $gray-700 !default;\n// scss-docs-end theme-text-variables\n\n// scss-docs-start theme-bg-subtle-variables\n$primary-bg-subtle: tint-color($primary, 80%) !default;\n$secondary-bg-subtle: tint-color($secondary, 80%) !default;\n$success-bg-subtle: tint-color($success, 80%) !default;\n$info-bg-subtle: tint-color($info, 80%) !default;\n$warning-bg-subtle: tint-color($warning, 80%) !default;\n$danger-bg-subtle: tint-color($danger, 80%) !default;\n$light-bg-subtle: mix($gray-100, $white) !default;\n$dark-bg-subtle: $gray-400 !default;\n// scss-docs-end theme-bg-subtle-variables\n\n// scss-docs-start theme-border-subtle-variables\n$primary-border-subtle: tint-color($primary, 60%) !default;\n$secondary-border-subtle: tint-color($secondary, 60%) !default;\n$success-border-subtle: tint-color($success, 60%) !default;\n$info-border-subtle: tint-color($info, 60%) !default;\n$warning-border-subtle: tint-color($warning, 60%) !default;\n$danger-border-subtle: tint-color($danger, 60%) !default;\n$light-border-subtle: $gray-200 !default;\n$dark-border-subtle: $gray-500 !default;\n// scss-docs-end theme-border-subtle-variables\n\n// Characters which are escaped by the escape-svg function\n$escaped-characters: (\n (\"<\", \"%3c\"),\n (\">\", \"%3e\"),\n (\"#\", \"%23\"),\n (\"(\", \"%28\"),\n (\")\", \"%29\"),\n) !default;\n\n// Options\n//\n// Quickly modify global styling by enabling or disabling optional features.\n\n$enable-caret: true !default;\n$enable-rounded: true !default;\n$enable-shadows: false !default;\n$enable-gradients: false !default;\n$enable-transitions: true !default;\n$enable-reduced-motion: true !default;\n$enable-smooth-scroll: true !default;\n$enable-grid-classes: true !default;\n$enable-container-classes: true !default;\n$enable-cssgrid: false !default;\n$enable-button-pointers: true !default;\n$enable-rfs: true !default;\n$enable-validation-icons: true !default;\n$enable-negative-margins: false !default;\n$enable-deprecation-messages: true !default;\n$enable-important-utilities: true !default;\n\n$enable-dark-mode: true !default;\n$color-mode-type: data !default; // `data` or `media-query`\n\n// Prefix for :root CSS variables\n\n$variable-prefix: bs- !default; // Deprecated in v5.2.0 for the shorter `$prefix`\n$prefix: $variable-prefix !default;\n\n// Gradient\n//\n// The gradient which is added to components if `$enable-gradients` is `true`\n// This gradient is also added to elements with `.bg-gradient`\n// scss-docs-start variable-gradient\n$gradient: linear-gradient(180deg, rgba($white, .15), rgba($white, 0)) !default;\n// scss-docs-end variable-gradient\n\n// Spacing\n//\n// Control the default styling of most Bootstrap elements by modifying these\n// variables. Mostly focused on spacing.\n// You can add more entries to the $spacers map, should you need more variation.\n\n// scss-docs-start spacer-variables-maps\n$spacer: 1rem !default;\n$spacers: (\n 0: 0,\n 1: $spacer * .25,\n 2: $spacer * .5,\n 3: $spacer,\n 4: $spacer * 1.5,\n 5: $spacer * 3,\n) !default;\n// scss-docs-end spacer-variables-maps\n\n// Position\n//\n// Define the edge positioning anchors of the position utilities.\n\n// scss-docs-start position-map\n$position-values: (\n 0: 0,\n 50: 50%,\n 100: 100%\n) !default;\n// scss-docs-end position-map\n\n// Body\n//\n// Settings for the `` element.\n\n$body-text-align: null !default;\n$body-color: $gray-900 !default;\n$body-bg: $white !default;\n\n$body-secondary-color: rgba($body-color, .75) !default;\n$body-secondary-bg: $gray-200 !default;\n\n$body-tertiary-color: rgba($body-color, .5) !default;\n$body-tertiary-bg: $gray-100 !default;\n\n$body-emphasis-color: $black !default;\n\n// Links\n//\n// Style anchor elements.\n\n$link-color: $primary !default;\n$link-decoration: underline !default;\n$link-shade-percentage: 20% !default;\n$link-hover-color: shift-color($link-color, $link-shade-percentage) !default;\n$link-hover-decoration: null !default;\n\n$stretched-link-pseudo-element: after !default;\n$stretched-link-z-index: 1 !default;\n\n// Icon links\n// scss-docs-start icon-link-variables\n$icon-link-gap: .375rem !default;\n$icon-link-underline-offset: .25em !default;\n$icon-link-icon-size: 1em !default;\n$icon-link-icon-transition: .2s ease-in-out transform !default;\n$icon-link-icon-transform: translate3d(.25em, 0, 0) !default;\n// scss-docs-end icon-link-variables\n\n// Paragraphs\n//\n// Style p element.\n\n$paragraph-margin-bottom: 1rem !default;\n\n\n// Grid breakpoints\n//\n// Define the minimum dimensions at which your layout will change,\n// adapting to different screen sizes, for use in media queries.\n\n// scss-docs-start grid-breakpoints\n$grid-breakpoints: (\n xs: 0,\n sm: 576px,\n md: 768px,\n lg: 992px,\n xl: 1200px,\n xxl: 1400px\n) !default;\n// scss-docs-end grid-breakpoints\n\n@include _assert-ascending($grid-breakpoints, \"$grid-breakpoints\");\n@include _assert-starts-at-zero($grid-breakpoints, \"$grid-breakpoints\");\n\n\n// Grid containers\n//\n// Define the maximum width of `.container` for different screen sizes.\n\n// scss-docs-start container-max-widths\n$container-max-widths: (\n sm: 540px,\n md: 720px,\n lg: 960px,\n xl: 1140px,\n xxl: 1320px\n) !default;\n// scss-docs-end container-max-widths\n\n@include _assert-ascending($container-max-widths, \"$container-max-widths\");\n\n\n// Grid columns\n//\n// Set the number of columns and specify the width of the gutters.\n\n$grid-columns: 12 !default;\n$grid-gutter-width: 1.5rem !default;\n$grid-row-columns: 6 !default;\n\n// Container padding\n\n$container-padding-x: $grid-gutter-width !default;\n\n\n// Components\n//\n// Define common padding and border radius sizes and more.\n\n// scss-docs-start border-variables\n$border-width: 1px !default;\n$border-widths: (\n 1: 1px,\n 2: 2px,\n 3: 3px,\n 4: 4px,\n 5: 5px\n) !default;\n$border-style: solid !default;\n$border-color: $gray-300 !default;\n$border-color-translucent: rgba($black, .175) !default;\n// scss-docs-end border-variables\n\n// scss-docs-start border-radius-variables\n$border-radius: .375rem !default;\n$border-radius-sm: .25rem !default;\n$border-radius-lg: .5rem !default;\n$border-radius-xl: 1rem !default;\n$border-radius-xxl: 2rem !default;\n$border-radius-pill: 50rem !default;\n// scss-docs-end border-radius-variables\n// fusv-disable\n$border-radius-2xl: $border-radius-xxl !default; // Deprecated in v5.3.0\n// fusv-enable\n\n// scss-docs-start box-shadow-variables\n$box-shadow: 0 .5rem 1rem rgba($black, .15) !default;\n$box-shadow-sm: 0 .125rem .25rem rgba($black, .075) !default;\n$box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;\n$box-shadow-inset: inset 0 1px 2px rgba($black, .075) !default;\n// scss-docs-end box-shadow-variables\n\n$component-active-color: $white !default;\n$component-active-bg: $primary !default;\n\n// scss-docs-start focus-ring-variables\n$focus-ring-width: .25rem !default;\n$focus-ring-opacity: .25 !default;\n$focus-ring-color: rgba($primary, $focus-ring-opacity) !default;\n$focus-ring-blur: 0 !default;\n$focus-ring-box-shadow: 0 0 $focus-ring-blur $focus-ring-width $focus-ring-color !default;\n// scss-docs-end focus-ring-variables\n\n// scss-docs-start caret-variables\n$caret-width: .3em !default;\n$caret-vertical-align: $caret-width * .85 !default;\n$caret-spacing: $caret-width * .85 !default;\n// scss-docs-end caret-variables\n\n$transition-base: all .2s ease-in-out !default;\n$transition-fade: opacity .15s linear !default;\n// scss-docs-start collapse-transition\n$transition-collapse: height .35s ease !default;\n$transition-collapse-width: width .35s ease !default;\n// scss-docs-end collapse-transition\n\n// stylelint-disable function-disallowed-list\n// scss-docs-start aspect-ratios\n$aspect-ratios: (\n \"1x1\": 100%,\n \"4x3\": calc(3 / 4 * 100%),\n \"16x9\": calc(9 / 16 * 100%),\n \"21x9\": calc(9 / 21 * 100%)\n) !default;\n// scss-docs-end aspect-ratios\n// stylelint-enable function-disallowed-list\n\n// Typography\n//\n// Font, line-height, and color for body text, headings, and more.\n\n// scss-docs-start font-variables\n// stylelint-disable value-keyword-case\n$font-family-sans-serif: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", \"Liberation Sans\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\" !default;\n$font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace !default;\n// stylelint-enable value-keyword-case\n$font-family-base: var(--#{$prefix}font-sans-serif) !default;\n$font-family-code: var(--#{$prefix}font-monospace) !default;\n\n// $font-size-root affects the value of `rem`, which is used for as well font sizes, paddings, and margins\n// $font-size-base affects the font size of the body text\n$font-size-root: null !default;\n$font-size-base: 1rem !default; // Assumes the browser default, typically `16px`\n$font-size-sm: $font-size-base * .875 !default;\n$font-size-lg: $font-size-base * 1.25 !default;\n\n$font-weight-lighter: lighter !default;\n$font-weight-light: 300 !default;\n$font-weight-normal: 400 !default;\n$font-weight-medium: 500 !default;\n$font-weight-semibold: 600 !default;\n$font-weight-bold: 700 !default;\n$font-weight-bolder: bolder !default;\n\n$font-weight-base: $font-weight-normal !default;\n\n$line-height-base: 1.5 !default;\n$line-height-sm: 1.25 !default;\n$line-height-lg: 2 !default;\n\n$h1-font-size: $font-size-base * 2.5 !default;\n$h2-font-size: $font-size-base * 2 !default;\n$h3-font-size: $font-size-base * 1.75 !default;\n$h4-font-size: $font-size-base * 1.5 !default;\n$h5-font-size: $font-size-base * 1.25 !default;\n$h6-font-size: $font-size-base !default;\n// scss-docs-end font-variables\n\n// scss-docs-start font-sizes\n$font-sizes: (\n 1: $h1-font-size,\n 2: $h2-font-size,\n 3: $h3-font-size,\n 4: $h4-font-size,\n 5: $h5-font-size,\n 6: $h6-font-size\n) !default;\n// scss-docs-end font-sizes\n\n// scss-docs-start headings-variables\n$headings-margin-bottom: $spacer * .5 !default;\n$headings-font-family: null !default;\n$headings-font-style: null !default;\n$headings-font-weight: 500 !default;\n$headings-line-height: 1.2 !default;\n$headings-color: inherit !default;\n// scss-docs-end headings-variables\n\n// scss-docs-start display-headings\n$display-font-sizes: (\n 1: 5rem,\n 2: 4.5rem,\n 3: 4rem,\n 4: 3.5rem,\n 5: 3rem,\n 6: 2.5rem\n) !default;\n\n$display-font-family: null !default;\n$display-font-style: null !default;\n$display-font-weight: 300 !default;\n$display-line-height: $headings-line-height !default;\n// scss-docs-end display-headings\n\n// scss-docs-start type-variables\n$lead-font-size: $font-size-base * 1.25 !default;\n$lead-font-weight: 300 !default;\n\n$small-font-size: .875em !default;\n\n$sub-sup-font-size: .75em !default;\n\n// fusv-disable\n$text-muted: var(--#{$prefix}secondary-color) !default; // Deprecated in 5.3.0\n// fusv-enable\n\n$initialism-font-size: $small-font-size !default;\n\n$blockquote-margin-y: $spacer !default;\n$blockquote-font-size: $font-size-base * 1.25 !default;\n$blockquote-footer-color: $gray-600 !default;\n$blockquote-footer-font-size: $small-font-size !default;\n\n$hr-margin-y: $spacer !default;\n$hr-color: inherit !default;\n\n// fusv-disable\n$hr-bg-color: null !default; // Deprecated in v5.2.0\n$hr-height: null !default; // Deprecated in v5.2.0\n// fusv-enable\n\n$hr-border-color: null !default; // Allows for inherited colors\n$hr-border-width: var(--#{$prefix}border-width) !default;\n$hr-opacity: .25 !default;\n\n// scss-docs-start vr-variables\n$vr-border-width: var(--#{$prefix}border-width) !default;\n// scss-docs-end vr-variables\n\n$legend-margin-bottom: .5rem !default;\n$legend-font-size: 1.5rem !default;\n$legend-font-weight: null !default;\n\n$dt-font-weight: $font-weight-bold !default;\n\n$list-inline-padding: .5rem !default;\n\n$mark-padding: .1875em !default;\n$mark-color: $body-color !default;\n$mark-bg: $yellow-100 !default;\n// scss-docs-end type-variables\n\n\n// Tables\n//\n// Customizes the `.table` component with basic values, each used across all table variations.\n\n// scss-docs-start table-variables\n$table-cell-padding-y: .5rem !default;\n$table-cell-padding-x: .5rem !default;\n$table-cell-padding-y-sm: .25rem !default;\n$table-cell-padding-x-sm: .25rem !default;\n\n$table-cell-vertical-align: top !default;\n\n$table-color: var(--#{$prefix}emphasis-color) !default;\n$table-bg: var(--#{$prefix}body-bg) !default;\n$table-accent-bg: transparent !default;\n\n$table-th-font-weight: null !default;\n\n$table-striped-color: $table-color !default;\n$table-striped-bg-factor: .05 !default;\n$table-striped-bg: rgba(var(--#{$prefix}emphasis-color-rgb), $table-striped-bg-factor) !default;\n\n$table-active-color: $table-color !default;\n$table-active-bg-factor: .1 !default;\n$table-active-bg: rgba(var(--#{$prefix}emphasis-color-rgb), $table-active-bg-factor) !default;\n\n$table-hover-color: $table-color !default;\n$table-hover-bg-factor: .075 !default;\n$table-hover-bg: rgba(var(--#{$prefix}emphasis-color-rgb), $table-hover-bg-factor) !default;\n\n$table-border-factor: .2 !default;\n$table-border-width: var(--#{$prefix}border-width) !default;\n$table-border-color: var(--#{$prefix}border-color) !default;\n\n$table-striped-order: odd !default;\n$table-striped-columns-order: even !default;\n\n$table-group-separator-color: currentcolor !default;\n\n$table-caption-color: var(--#{$prefix}secondary-color) !default;\n\n$table-bg-scale: -80% !default;\n// scss-docs-end table-variables\n\n// scss-docs-start table-loop\n$table-variants: (\n \"primary\": shift-color($primary, $table-bg-scale),\n \"secondary\": shift-color($secondary, $table-bg-scale),\n \"success\": shift-color($success, $table-bg-scale),\n \"info\": shift-color($info, $table-bg-scale),\n \"warning\": shift-color($warning, $table-bg-scale),\n \"danger\": shift-color($danger, $table-bg-scale),\n \"light\": $light,\n \"dark\": $dark,\n) !default;\n// scss-docs-end table-loop\n\n\n// Buttons + Forms\n//\n// Shared variables that are reassigned to `$input-` and `$btn-` specific variables.\n\n// scss-docs-start input-btn-variables\n$input-btn-padding-y: .375rem !default;\n$input-btn-padding-x: .75rem !default;\n$input-btn-font-family: null !default;\n$input-btn-font-size: $font-size-base !default;\n$input-btn-line-height: $line-height-base !default;\n\n$input-btn-focus-width: $focus-ring-width !default;\n$input-btn-focus-color-opacity: $focus-ring-opacity !default;\n$input-btn-focus-color: $focus-ring-color !default;\n$input-btn-focus-blur: $focus-ring-blur !default;\n$input-btn-focus-box-shadow: $focus-ring-box-shadow !default;\n\n$input-btn-padding-y-sm: .25rem !default;\n$input-btn-padding-x-sm: .5rem !default;\n$input-btn-font-size-sm: $font-size-sm !default;\n\n$input-btn-padding-y-lg: .5rem !default;\n$input-btn-padding-x-lg: 1rem !default;\n$input-btn-font-size-lg: $font-size-lg !default;\n\n$input-btn-border-width: var(--#{$prefix}border-width) !default;\n// scss-docs-end input-btn-variables\n\n\n// Buttons\n//\n// For each of Bootstrap's buttons, define text, background, and border color.\n\n// scss-docs-start btn-variables\n$btn-color: var(--#{$prefix}body-color) !default;\n$btn-padding-y: $input-btn-padding-y !default;\n$btn-padding-x: $input-btn-padding-x !default;\n$btn-font-family: $input-btn-font-family !default;\n$btn-font-size: $input-btn-font-size !default;\n$btn-line-height: $input-btn-line-height !default;\n$btn-white-space: null !default; // Set to `nowrap` to prevent text wrapping\n\n$btn-padding-y-sm: $input-btn-padding-y-sm !default;\n$btn-padding-x-sm: $input-btn-padding-x-sm !default;\n$btn-font-size-sm: $input-btn-font-size-sm !default;\n\n$btn-padding-y-lg: $input-btn-padding-y-lg !default;\n$btn-padding-x-lg: $input-btn-padding-x-lg !default;\n$btn-font-size-lg: $input-btn-font-size-lg !default;\n\n$btn-border-width: $input-btn-border-width !default;\n\n$btn-font-weight: $font-weight-normal !default;\n$btn-box-shadow: inset 0 1px 0 rgba($white, .15), 0 1px 1px rgba($black, .075) !default;\n$btn-focus-width: $input-btn-focus-width !default;\n$btn-focus-box-shadow: $input-btn-focus-box-shadow !default;\n$btn-disabled-opacity: .65 !default;\n$btn-active-box-shadow: inset 0 3px 5px rgba($black, .125) !default;\n\n$btn-link-color: var(--#{$prefix}link-color) !default;\n$btn-link-hover-color: var(--#{$prefix}link-hover-color) !default;\n$btn-link-disabled-color: $gray-600 !default;\n$btn-link-focus-shadow-rgb: to-rgb(mix(color-contrast($link-color), $link-color, 15%)) !default;\n\n// Allows for customizing button radius independently from global border radius\n$btn-border-radius: var(--#{$prefix}border-radius) !default;\n$btn-border-radius-sm: var(--#{$prefix}border-radius-sm) !default;\n$btn-border-radius-lg: var(--#{$prefix}border-radius-lg) !default;\n\n$btn-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$btn-hover-bg-shade-amount: 15% !default;\n$btn-hover-bg-tint-amount: 15% !default;\n$btn-hover-border-shade-amount: 20% !default;\n$btn-hover-border-tint-amount: 10% !default;\n$btn-active-bg-shade-amount: 20% !default;\n$btn-active-bg-tint-amount: 20% !default;\n$btn-active-border-shade-amount: 25% !default;\n$btn-active-border-tint-amount: 10% !default;\n// scss-docs-end btn-variables\n\n\n// Forms\n\n// scss-docs-start form-text-variables\n$form-text-margin-top: .25rem !default;\n$form-text-font-size: $small-font-size !default;\n$form-text-font-style: null !default;\n$form-text-font-weight: null !default;\n$form-text-color: var(--#{$prefix}secondary-color) !default;\n// scss-docs-end form-text-variables\n\n// scss-docs-start form-label-variables\n$form-label-margin-bottom: .5rem !default;\n$form-label-font-size: null !default;\n$form-label-font-style: null !default;\n$form-label-font-weight: null !default;\n$form-label-color: null !default;\n// scss-docs-end form-label-variables\n\n// scss-docs-start form-input-variables\n$input-padding-y: $input-btn-padding-y !default;\n$input-padding-x: $input-btn-padding-x !default;\n$input-font-family: $input-btn-font-family !default;\n$input-font-size: $input-btn-font-size !default;\n$input-font-weight: $font-weight-base !default;\n$input-line-height: $input-btn-line-height !default;\n\n$input-padding-y-sm: $input-btn-padding-y-sm !default;\n$input-padding-x-sm: $input-btn-padding-x-sm !default;\n$input-font-size-sm: $input-btn-font-size-sm !default;\n\n$input-padding-y-lg: $input-btn-padding-y-lg !default;\n$input-padding-x-lg: $input-btn-padding-x-lg !default;\n$input-font-size-lg: $input-btn-font-size-lg !default;\n\n$input-bg: var(--#{$prefix}body-bg) !default;\n$input-disabled-color: null !default;\n$input-disabled-bg: var(--#{$prefix}secondary-bg) !default;\n$input-disabled-border-color: null !default;\n\n$input-color: var(--#{$prefix}body-color) !default;\n$input-border-color: var(--#{$prefix}border-color) !default;\n$input-border-width: $input-btn-border-width !default;\n$input-box-shadow: var(--#{$prefix}box-shadow-inset) !default;\n\n$input-border-radius: var(--#{$prefix}border-radius) !default;\n$input-border-radius-sm: var(--#{$prefix}border-radius-sm) !default;\n$input-border-radius-lg: var(--#{$prefix}border-radius-lg) !default;\n\n$input-focus-bg: $input-bg !default;\n$input-focus-border-color: tint-color($component-active-bg, 50%) !default;\n$input-focus-color: $input-color !default;\n$input-focus-width: $input-btn-focus-width !default;\n$input-focus-box-shadow: $input-btn-focus-box-shadow !default;\n\n$input-placeholder-color: var(--#{$prefix}secondary-color) !default;\n$input-plaintext-color: var(--#{$prefix}body-color) !default;\n\n$input-height-border: calc(#{$input-border-width} * 2) !default; // stylelint-disable-line function-disallowed-list\n\n$input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default;\n$input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default;\n$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y * .5) !default;\n\n$input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default;\n$input-height-sm: add($input-line-height * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default;\n$input-height-lg: add($input-line-height * 1em, add($input-padding-y-lg * 2, $input-height-border, false)) !default;\n\n$input-transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$form-color-width: 3rem !default;\n// scss-docs-end form-input-variables\n\n// scss-docs-start form-check-variables\n$form-check-input-width: 1em !default;\n$form-check-min-height: $font-size-base * $line-height-base !default;\n$form-check-padding-start: $form-check-input-width + .5em !default;\n$form-check-margin-bottom: .125rem !default;\n$form-check-label-color: null !default;\n$form-check-label-cursor: null !default;\n$form-check-transition: null !default;\n\n$form-check-input-active-filter: brightness(90%) !default;\n\n$form-check-input-bg: $input-bg !default;\n$form-check-input-border: var(--#{$prefix}border-width) solid var(--#{$prefix}border-color) !default;\n$form-check-input-border-radius: .25em !default;\n$form-check-radio-border-radius: 50% !default;\n$form-check-input-focus-border: $input-focus-border-color !default;\n$form-check-input-focus-box-shadow: $focus-ring-box-shadow !default;\n\n$form-check-input-checked-color: $component-active-color !default;\n$form-check-input-checked-bg-color: $component-active-bg !default;\n$form-check-input-checked-border-color: $form-check-input-checked-bg-color !default;\n$form-check-input-checked-bg-image: url(\"data:image/svg+xml,\") !default;\n$form-check-radio-checked-bg-image: url(\"data:image/svg+xml,\") !default;\n\n$form-check-input-indeterminate-color: $component-active-color !default;\n$form-check-input-indeterminate-bg-color: $component-active-bg !default;\n$form-check-input-indeterminate-border-color: $form-check-input-indeterminate-bg-color !default;\n$form-check-input-indeterminate-bg-image: url(\"data:image/svg+xml,\") !default;\n\n$form-check-input-disabled-opacity: .5 !default;\n$form-check-label-disabled-opacity: $form-check-input-disabled-opacity !default;\n$form-check-btn-check-disabled-opacity: $btn-disabled-opacity !default;\n\n$form-check-inline-margin-end: 1rem !default;\n// scss-docs-end form-check-variables\n\n// scss-docs-start form-switch-variables\n$form-switch-color: rgba($black, .25) !default;\n$form-switch-width: 2em !default;\n$form-switch-padding-start: $form-switch-width + .5em !default;\n$form-switch-bg-image: url(\"data:image/svg+xml,\") !default;\n$form-switch-border-radius: $form-switch-width !default;\n$form-switch-transition: background-position .15s ease-in-out !default;\n\n$form-switch-focus-color: $input-focus-border-color !default;\n$form-switch-focus-bg-image: url(\"data:image/svg+xml,\") !default;\n\n$form-switch-checked-color: $component-active-color !default;\n$form-switch-checked-bg-image: url(\"data:image/svg+xml,\") !default;\n$form-switch-checked-bg-position: right center !default;\n// scss-docs-end form-switch-variables\n\n// scss-docs-start input-group-variables\n$input-group-addon-padding-y: $input-padding-y !default;\n$input-group-addon-padding-x: $input-padding-x !default;\n$input-group-addon-font-weight: $input-font-weight !default;\n$input-group-addon-color: $input-color !default;\n$input-group-addon-bg: var(--#{$prefix}tertiary-bg) !default;\n$input-group-addon-border-color: $input-border-color !default;\n// scss-docs-end input-group-variables\n\n// scss-docs-start form-select-variables\n$form-select-padding-y: $input-padding-y !default;\n$form-select-padding-x: $input-padding-x !default;\n$form-select-font-family: $input-font-family !default;\n$form-select-font-size: $input-font-size !default;\n$form-select-indicator-padding: $form-select-padding-x * 3 !default; // Extra padding for background-image\n$form-select-font-weight: $input-font-weight !default;\n$form-select-line-height: $input-line-height !default;\n$form-select-color: $input-color !default;\n$form-select-bg: $input-bg !default;\n$form-select-disabled-color: null !default;\n$form-select-disabled-bg: $input-disabled-bg !default;\n$form-select-disabled-border-color: $input-disabled-border-color !default;\n$form-select-bg-position: right $form-select-padding-x center !default;\n$form-select-bg-size: 16px 12px !default; // In pixels because image dimensions\n$form-select-indicator-color: $gray-800 !default;\n$form-select-indicator: url(\"data:image/svg+xml,\") !default;\n\n$form-select-feedback-icon-padding-end: $form-select-padding-x * 2.5 + $form-select-indicator-padding !default;\n$form-select-feedback-icon-position: center right $form-select-indicator-padding !default;\n$form-select-feedback-icon-size: $input-height-inner-half $input-height-inner-half !default;\n\n$form-select-border-width: $input-border-width !default;\n$form-select-border-color: $input-border-color !default;\n$form-select-border-radius: $input-border-radius !default;\n$form-select-box-shadow: var(--#{$prefix}box-shadow-inset) !default;\n\n$form-select-focus-border-color: $input-focus-border-color !default;\n$form-select-focus-width: $input-focus-width !default;\n$form-select-focus-box-shadow: 0 0 0 $form-select-focus-width $input-btn-focus-color !default;\n\n$form-select-padding-y-sm: $input-padding-y-sm !default;\n$form-select-padding-x-sm: $input-padding-x-sm !default;\n$form-select-font-size-sm: $input-font-size-sm !default;\n$form-select-border-radius-sm: $input-border-radius-sm !default;\n\n$form-select-padding-y-lg: $input-padding-y-lg !default;\n$form-select-padding-x-lg: $input-padding-x-lg !default;\n$form-select-font-size-lg: $input-font-size-lg !default;\n$form-select-border-radius-lg: $input-border-radius-lg !default;\n\n$form-select-transition: $input-transition !default;\n// scss-docs-end form-select-variables\n\n// scss-docs-start form-range-variables\n$form-range-track-width: 100% !default;\n$form-range-track-height: .5rem !default;\n$form-range-track-cursor: pointer !default;\n$form-range-track-bg: var(--#{$prefix}secondary-bg) !default;\n$form-range-track-border-radius: 1rem !default;\n$form-range-track-box-shadow: var(--#{$prefix}box-shadow-inset) !default;\n\n$form-range-thumb-width: 1rem !default;\n$form-range-thumb-height: $form-range-thumb-width !default;\n$form-range-thumb-bg: $component-active-bg !default;\n$form-range-thumb-border: 0 !default;\n$form-range-thumb-border-radius: 1rem !default;\n$form-range-thumb-box-shadow: 0 .1rem .25rem rgba($black, .1) !default;\n$form-range-thumb-focus-box-shadow: 0 0 0 1px $body-bg, $input-focus-box-shadow !default;\n$form-range-thumb-focus-box-shadow-width: $input-focus-width !default; // For focus box shadow issue in Edge\n$form-range-thumb-active-bg: tint-color($component-active-bg, 70%) !default;\n$form-range-thumb-disabled-bg: var(--#{$prefix}secondary-color) !default;\n$form-range-thumb-transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n// scss-docs-end form-range-variables\n\n// scss-docs-start form-file-variables\n$form-file-button-color: $input-color !default;\n$form-file-button-bg: var(--#{$prefix}tertiary-bg) !default;\n$form-file-button-hover-bg: var(--#{$prefix}secondary-bg) !default;\n// scss-docs-end form-file-variables\n\n// scss-docs-start form-floating-variables\n$form-floating-height: add(3.5rem, $input-height-border) !default;\n$form-floating-line-height: 1.25 !default;\n$form-floating-padding-x: $input-padding-x !default;\n$form-floating-padding-y: 1rem !default;\n$form-floating-input-padding-t: 1.625rem !default;\n$form-floating-input-padding-b: .625rem !default;\n$form-floating-label-height: 1.5em !default;\n$form-floating-label-opacity: .65 !default;\n$form-floating-label-transform: scale(.85) translateY(-.5rem) translateX(.15rem) !default;\n$form-floating-label-disabled-color: $gray-600 !default;\n$form-floating-transition: opacity .1s ease-in-out, transform .1s ease-in-out !default;\n// scss-docs-end form-floating-variables\n\n// Form validation\n\n// scss-docs-start form-feedback-variables\n$form-feedback-margin-top: $form-text-margin-top !default;\n$form-feedback-font-size: $form-text-font-size !default;\n$form-feedback-font-style: $form-text-font-style !default;\n$form-feedback-valid-color: $success !default;\n$form-feedback-invalid-color: $danger !default;\n\n$form-feedback-icon-valid-color: $form-feedback-valid-color !default;\n$form-feedback-icon-valid: url(\"data:image/svg+xml,\") !default;\n$form-feedback-icon-invalid-color: $form-feedback-invalid-color !default;\n$form-feedback-icon-invalid: url(\"data:image/svg+xml,\") !default;\n// scss-docs-end form-feedback-variables\n\n// scss-docs-start form-validation-colors\n$form-valid-color: $form-feedback-valid-color !default;\n$form-valid-border-color: $form-feedback-valid-color !default;\n$form-invalid-color: $form-feedback-invalid-color !default;\n$form-invalid-border-color: $form-feedback-invalid-color !default;\n// scss-docs-end form-validation-colors\n\n// scss-docs-start form-validation-states\n$form-validation-states: (\n \"valid\": (\n \"color\": var(--#{$prefix}form-valid-color),\n \"icon\": $form-feedback-icon-valid,\n \"tooltip-color\": #fff,\n \"tooltip-bg-color\": var(--#{$prefix}success),\n \"focus-box-shadow\": 0 0 $input-btn-focus-blur $input-focus-width rgba(var(--#{$prefix}success-rgb), $input-btn-focus-color-opacity),\n \"border-color\": var(--#{$prefix}form-valid-border-color),\n ),\n \"invalid\": (\n \"color\": var(--#{$prefix}form-invalid-color),\n \"icon\": $form-feedback-icon-invalid,\n \"tooltip-color\": #fff,\n \"tooltip-bg-color\": var(--#{$prefix}danger),\n \"focus-box-shadow\": 0 0 $input-btn-focus-blur $input-focus-width rgba(var(--#{$prefix}danger-rgb), $input-btn-focus-color-opacity),\n \"border-color\": var(--#{$prefix}form-invalid-border-color),\n )\n) !default;\n// scss-docs-end form-validation-states\n\n// Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n\n// scss-docs-start zindex-stack\n$zindex-dropdown: 1000 !default;\n$zindex-sticky: 1020 !default;\n$zindex-fixed: 1030 !default;\n$zindex-offcanvas-backdrop: 1040 !default;\n$zindex-offcanvas: 1045 !default;\n$zindex-modal-backdrop: 1050 !default;\n$zindex-modal: 1055 !default;\n$zindex-popover: 1070 !default;\n$zindex-tooltip: 1080 !default;\n$zindex-toast: 1090 !default;\n// scss-docs-end zindex-stack\n\n// scss-docs-start zindex-levels-map\n$zindex-levels: (\n n1: -1,\n 0: 0,\n 1: 1,\n 2: 2,\n 3: 3\n) !default;\n// scss-docs-end zindex-levels-map\n\n\n// Navs\n\n// scss-docs-start nav-variables\n$nav-link-padding-y: .5rem !default;\n$nav-link-padding-x: 1rem !default;\n$nav-link-font-size: null !default;\n$nav-link-font-weight: null !default;\n$nav-link-color: var(--#{$prefix}link-color) !default;\n$nav-link-hover-color: var(--#{$prefix}link-hover-color) !default;\n$nav-link-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out !default;\n$nav-link-disabled-color: var(--#{$prefix}secondary-color) !default;\n$nav-link-focus-box-shadow: $focus-ring-box-shadow !default;\n\n$nav-tabs-border-color: var(--#{$prefix}border-color) !default;\n$nav-tabs-border-width: var(--#{$prefix}border-width) !default;\n$nav-tabs-border-radius: var(--#{$prefix}border-radius) !default;\n$nav-tabs-link-hover-border-color: var(--#{$prefix}secondary-bg) var(--#{$prefix}secondary-bg) $nav-tabs-border-color !default;\n$nav-tabs-link-active-color: var(--#{$prefix}emphasis-color) !default;\n$nav-tabs-link-active-bg: var(--#{$prefix}body-bg) !default;\n$nav-tabs-link-active-border-color: var(--#{$prefix}border-color) var(--#{$prefix}border-color) $nav-tabs-link-active-bg !default;\n\n$nav-pills-border-radius: var(--#{$prefix}border-radius) !default;\n$nav-pills-link-active-color: $component-active-color !default;\n$nav-pills-link-active-bg: $component-active-bg !default;\n\n$nav-underline-gap: 1rem !default;\n$nav-underline-border-width: .125rem !default;\n$nav-underline-link-active-color: var(--#{$prefix}emphasis-color) !default;\n// scss-docs-end nav-variables\n\n\n// Navbar\n\n// scss-docs-start navbar-variables\n$navbar-padding-y: $spacer * .5 !default;\n$navbar-padding-x: null !default;\n\n$navbar-nav-link-padding-x: .5rem !default;\n\n$navbar-brand-font-size: $font-size-lg !default;\n// Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link\n$nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default;\n$navbar-brand-height: $navbar-brand-font-size * $line-height-base !default;\n$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) * .5 !default;\n$navbar-brand-margin-end: 1rem !default;\n\n$navbar-toggler-padding-y: .25rem !default;\n$navbar-toggler-padding-x: .75rem !default;\n$navbar-toggler-font-size: $font-size-lg !default;\n$navbar-toggler-border-radius: $btn-border-radius !default;\n$navbar-toggler-focus-width: $btn-focus-width !default;\n$navbar-toggler-transition: box-shadow .15s ease-in-out !default;\n\n$navbar-light-color: rgba(var(--#{$prefix}emphasis-color-rgb), .65) !default;\n$navbar-light-hover-color: rgba(var(--#{$prefix}emphasis-color-rgb), .8) !default;\n$navbar-light-active-color: rgba(var(--#{$prefix}emphasis-color-rgb), 1) !default;\n$navbar-light-disabled-color: rgba(var(--#{$prefix}emphasis-color-rgb), .3) !default;\n$navbar-light-icon-color: rgba($body-color, .75) !default;\n$navbar-light-toggler-icon-bg: url(\"data:image/svg+xml,\") !default;\n$navbar-light-toggler-border-color: rgba(var(--#{$prefix}emphasis-color-rgb), .15) !default;\n$navbar-light-brand-color: $navbar-light-active-color !default;\n$navbar-light-brand-hover-color: $navbar-light-active-color !default;\n// scss-docs-end navbar-variables\n\n// scss-docs-start navbar-dark-variables\n$navbar-dark-color: rgba($white, .55) !default;\n$navbar-dark-hover-color: rgba($white, .75) !default;\n$navbar-dark-active-color: $white !default;\n$navbar-dark-disabled-color: rgba($white, .25) !default;\n$navbar-dark-icon-color: $navbar-dark-color !default;\n$navbar-dark-toggler-icon-bg: url(\"data:image/svg+xml,\") !default;\n$navbar-dark-toggler-border-color: rgba($white, .1) !default;\n$navbar-dark-brand-color: $navbar-dark-active-color !default;\n$navbar-dark-brand-hover-color: $navbar-dark-active-color !default;\n// scss-docs-end navbar-dark-variables\n\n\n// Dropdowns\n//\n// Dropdown menu container and contents.\n\n// scss-docs-start dropdown-variables\n$dropdown-min-width: 10rem !default;\n$dropdown-padding-x: 0 !default;\n$dropdown-padding-y: .5rem !default;\n$dropdown-spacer: .125rem !default;\n$dropdown-font-size: $font-size-base !default;\n$dropdown-color: var(--#{$prefix}body-color) !default;\n$dropdown-bg: var(--#{$prefix}body-bg) !default;\n$dropdown-border-color: var(--#{$prefix}border-color-translucent) !default;\n$dropdown-border-radius: var(--#{$prefix}border-radius) !default;\n$dropdown-border-width: var(--#{$prefix}border-width) !default;\n$dropdown-inner-border-radius: calc(#{$dropdown-border-radius} - #{$dropdown-border-width}) !default; // stylelint-disable-line function-disallowed-list\n$dropdown-divider-bg: $dropdown-border-color !default;\n$dropdown-divider-margin-y: $spacer * .5 !default;\n$dropdown-box-shadow: var(--#{$prefix}box-shadow) !default;\n\n$dropdown-link-color: var(--#{$prefix}body-color) !default;\n$dropdown-link-hover-color: $dropdown-link-color !default;\n$dropdown-link-hover-bg: var(--#{$prefix}tertiary-bg) !default;\n\n$dropdown-link-active-color: $component-active-color !default;\n$dropdown-link-active-bg: $component-active-bg !default;\n\n$dropdown-link-disabled-color: var(--#{$prefix}tertiary-color) !default;\n\n$dropdown-item-padding-y: $spacer * .25 !default;\n$dropdown-item-padding-x: $spacer !default;\n\n$dropdown-header-color: $gray-600 !default;\n$dropdown-header-padding-x: $dropdown-item-padding-x !default;\n$dropdown-header-padding-y: $dropdown-padding-y !default;\n// fusv-disable\n$dropdown-header-padding: $dropdown-header-padding-y $dropdown-header-padding-x !default; // Deprecated in v5.2.0\n// fusv-enable\n// scss-docs-end dropdown-variables\n\n// scss-docs-start dropdown-dark-variables\n$dropdown-dark-color: $gray-300 !default;\n$dropdown-dark-bg: $gray-800 !default;\n$dropdown-dark-border-color: $dropdown-border-color !default;\n$dropdown-dark-divider-bg: $dropdown-divider-bg !default;\n$dropdown-dark-box-shadow: null !default;\n$dropdown-dark-link-color: $dropdown-dark-color !default;\n$dropdown-dark-link-hover-color: $white !default;\n$dropdown-dark-link-hover-bg: rgba($white, .15) !default;\n$dropdown-dark-link-active-color: $dropdown-link-active-color !default;\n$dropdown-dark-link-active-bg: $dropdown-link-active-bg !default;\n$dropdown-dark-link-disabled-color: $gray-500 !default;\n$dropdown-dark-header-color: $gray-500 !default;\n// scss-docs-end dropdown-dark-variables\n\n\n// Pagination\n\n// scss-docs-start pagination-variables\n$pagination-padding-y: .375rem !default;\n$pagination-padding-x: .75rem !default;\n$pagination-padding-y-sm: .25rem !default;\n$pagination-padding-x-sm: .5rem !default;\n$pagination-padding-y-lg: .75rem !default;\n$pagination-padding-x-lg: 1.5rem !default;\n\n$pagination-font-size: $font-size-base !default;\n\n$pagination-color: var(--#{$prefix}link-color) !default;\n$pagination-bg: var(--#{$prefix}body-bg) !default;\n$pagination-border-radius: var(--#{$prefix}border-radius) !default;\n$pagination-border-width: var(--#{$prefix}border-width) !default;\n$pagination-margin-start: calc(#{$pagination-border-width} * -1) !default; // stylelint-disable-line function-disallowed-list\n$pagination-border-color: var(--#{$prefix}border-color) !default;\n\n$pagination-focus-color: var(--#{$prefix}link-hover-color) !default;\n$pagination-focus-bg: var(--#{$prefix}secondary-bg) !default;\n$pagination-focus-box-shadow: $focus-ring-box-shadow !default;\n$pagination-focus-outline: 0 !default;\n\n$pagination-hover-color: var(--#{$prefix}link-hover-color) !default;\n$pagination-hover-bg: var(--#{$prefix}tertiary-bg) !default;\n$pagination-hover-border-color: var(--#{$prefix}border-color) !default; // Todo in v6: remove this?\n\n$pagination-active-color: $component-active-color !default;\n$pagination-active-bg: $component-active-bg !default;\n$pagination-active-border-color: $component-active-bg !default;\n\n$pagination-disabled-color: var(--#{$prefix}secondary-color) !default;\n$pagination-disabled-bg: var(--#{$prefix}secondary-bg) !default;\n$pagination-disabled-border-color: var(--#{$prefix}border-color) !default;\n\n$pagination-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out !default;\n\n$pagination-border-radius-sm: var(--#{$prefix}border-radius-sm) !default;\n$pagination-border-radius-lg: var(--#{$prefix}border-radius-lg) !default;\n// scss-docs-end pagination-variables\n\n\n// Placeholders\n\n// scss-docs-start placeholders\n$placeholder-opacity-max: .5 !default;\n$placeholder-opacity-min: .2 !default;\n// scss-docs-end placeholders\n\n// Cards\n\n// scss-docs-start card-variables\n$card-spacer-y: $spacer !default;\n$card-spacer-x: $spacer !default;\n$card-title-spacer-y: $spacer * .5 !default;\n$card-title-color: null !default;\n$card-subtitle-color: null !default;\n$card-border-width: var(--#{$prefix}border-width) !default;\n$card-border-color: var(--#{$prefix}border-color-translucent) !default;\n$card-border-radius: var(--#{$prefix}border-radius) !default;\n$card-box-shadow: null !default;\n$card-inner-border-radius: subtract($card-border-radius, $card-border-width) !default;\n$card-cap-padding-y: $card-spacer-y * .5 !default;\n$card-cap-padding-x: $card-spacer-x !default;\n$card-cap-bg: rgba(var(--#{$prefix}body-color-rgb), .03) !default;\n$card-cap-color: null !default;\n$card-height: null !default;\n$card-color: null !default;\n$card-bg: var(--#{$prefix}body-bg) !default;\n$card-img-overlay-padding: $spacer !default;\n$card-group-margin: $grid-gutter-width * .5 !default;\n// scss-docs-end card-variables\n\n// Accordion\n\n// scss-docs-start accordion-variables\n$accordion-padding-y: 1rem !default;\n$accordion-padding-x: 1.25rem !default;\n$accordion-color: var(--#{$prefix}body-color) !default;\n$accordion-bg: var(--#{$prefix}body-bg) !default;\n$accordion-border-width: var(--#{$prefix}border-width) !default;\n$accordion-border-color: var(--#{$prefix}border-color) !default;\n$accordion-border-radius: var(--#{$prefix}border-radius) !default;\n$accordion-inner-border-radius: subtract($accordion-border-radius, $accordion-border-width) !default;\n\n$accordion-body-padding-y: $accordion-padding-y !default;\n$accordion-body-padding-x: $accordion-padding-x !default;\n\n$accordion-button-padding-y: $accordion-padding-y !default;\n$accordion-button-padding-x: $accordion-padding-x !default;\n$accordion-button-color: var(--#{$prefix}body-color) !default;\n$accordion-button-bg: var(--#{$prefix}accordion-bg) !default;\n$accordion-transition: $btn-transition, border-radius .15s ease !default;\n$accordion-button-active-bg: var(--#{$prefix}primary-bg-subtle) !default;\n$accordion-button-active-color: var(--#{$prefix}primary-text-emphasis) !default;\n\n// fusv-disable\n$accordion-button-focus-border-color: $input-focus-border-color !default; // Deprecated in v5.3.3\n// fusv-enable\n$accordion-button-focus-box-shadow: $btn-focus-box-shadow !default;\n\n$accordion-icon-width: 1.25rem !default;\n$accordion-icon-color: $body-color !default;\n$accordion-icon-active-color: $primary-text-emphasis !default;\n$accordion-icon-transition: transform .2s ease-in-out !default;\n$accordion-icon-transform: rotate(-180deg) !default;\n\n$accordion-button-icon: url(\"data:image/svg+xml,\") !default;\n$accordion-button-active-icon: url(\"data:image/svg+xml,\") !default;\n// scss-docs-end accordion-variables\n\n// Tooltips\n\n// scss-docs-start tooltip-variables\n$tooltip-font-size: $font-size-sm !default;\n$tooltip-max-width: 200px !default;\n$tooltip-color: var(--#{$prefix}body-bg) !default;\n$tooltip-bg: var(--#{$prefix}emphasis-color) !default;\n$tooltip-border-radius: var(--#{$prefix}border-radius) !default;\n$tooltip-opacity: .9 !default;\n$tooltip-padding-y: $spacer * .25 !default;\n$tooltip-padding-x: $spacer * .5 !default;\n$tooltip-margin: null !default; // TODO: remove this in v6\n\n$tooltip-arrow-width: .8rem !default;\n$tooltip-arrow-height: .4rem !default;\n// fusv-disable\n$tooltip-arrow-color: null !default; // Deprecated in Bootstrap 5.2.0 for CSS variables\n// fusv-enable\n// scss-docs-end tooltip-variables\n\n// Form tooltips must come after regular tooltips\n// scss-docs-start tooltip-feedback-variables\n$form-feedback-tooltip-padding-y: $tooltip-padding-y !default;\n$form-feedback-tooltip-padding-x: $tooltip-padding-x !default;\n$form-feedback-tooltip-font-size: $tooltip-font-size !default;\n$form-feedback-tooltip-line-height: null !default;\n$form-feedback-tooltip-opacity: $tooltip-opacity !default;\n$form-feedback-tooltip-border-radius: $tooltip-border-radius !default;\n// scss-docs-end tooltip-feedback-variables\n\n\n// Popovers\n\n// scss-docs-start popover-variables\n$popover-font-size: $font-size-sm !default;\n$popover-bg: var(--#{$prefix}body-bg) !default;\n$popover-max-width: 276px !default;\n$popover-border-width: var(--#{$prefix}border-width) !default;\n$popover-border-color: var(--#{$prefix}border-color-translucent) !default;\n$popover-border-radius: var(--#{$prefix}border-radius-lg) !default;\n$popover-inner-border-radius: calc(#{$popover-border-radius} - #{$popover-border-width}) !default; // stylelint-disable-line function-disallowed-list\n$popover-box-shadow: var(--#{$prefix}box-shadow) !default;\n\n$popover-header-font-size: $font-size-base !default;\n$popover-header-bg: var(--#{$prefix}secondary-bg) !default;\n$popover-header-color: $headings-color !default;\n$popover-header-padding-y: .5rem !default;\n$popover-header-padding-x: $spacer !default;\n\n$popover-body-color: var(--#{$prefix}body-color) !default;\n$popover-body-padding-y: $spacer !default;\n$popover-body-padding-x: $spacer !default;\n\n$popover-arrow-width: 1rem !default;\n$popover-arrow-height: .5rem !default;\n// scss-docs-end popover-variables\n\n// fusv-disable\n// Deprecated in Bootstrap 5.2.0 for CSS variables\n$popover-arrow-color: $popover-bg !default;\n$popover-arrow-outer-color: var(--#{$prefix}border-color-translucent) !default;\n// fusv-enable\n\n\n// Toasts\n\n// scss-docs-start toast-variables\n$toast-max-width: 350px !default;\n$toast-padding-x: .75rem !default;\n$toast-padding-y: .5rem !default;\n$toast-font-size: .875rem !default;\n$toast-color: null !default;\n$toast-background-color: rgba(var(--#{$prefix}body-bg-rgb), .85) !default;\n$toast-border-width: var(--#{$prefix}border-width) !default;\n$toast-border-color: var(--#{$prefix}border-color-translucent) !default;\n$toast-border-radius: var(--#{$prefix}border-radius) !default;\n$toast-box-shadow: var(--#{$prefix}box-shadow) !default;\n$toast-spacing: $container-padding-x !default;\n\n$toast-header-color: var(--#{$prefix}secondary-color) !default;\n$toast-header-background-color: rgba(var(--#{$prefix}body-bg-rgb), .85) !default;\n$toast-header-border-color: $toast-border-color !default;\n// scss-docs-end toast-variables\n\n\n// Badges\n\n// scss-docs-start badge-variables\n$badge-font-size: .75em !default;\n$badge-font-weight: $font-weight-bold !default;\n$badge-color: $white !default;\n$badge-padding-y: .35em !default;\n$badge-padding-x: .65em !default;\n$badge-border-radius: var(--#{$prefix}border-radius) !default;\n// scss-docs-end badge-variables\n\n\n// Modals\n\n// scss-docs-start modal-variables\n$modal-inner-padding: $spacer !default;\n\n$modal-footer-margin-between: .5rem !default;\n\n$modal-dialog-margin: .5rem !default;\n$modal-dialog-margin-y-sm-up: 1.75rem !default;\n\n$modal-title-line-height: $line-height-base !default;\n\n$modal-content-color: null !default;\n$modal-content-bg: var(--#{$prefix}body-bg) !default;\n$modal-content-border-color: var(--#{$prefix}border-color-translucent) !default;\n$modal-content-border-width: var(--#{$prefix}border-width) !default;\n$modal-content-border-radius: var(--#{$prefix}border-radius-lg) !default;\n$modal-content-inner-border-radius: subtract($modal-content-border-radius, $modal-content-border-width) !default;\n$modal-content-box-shadow-xs: var(--#{$prefix}box-shadow-sm) !default;\n$modal-content-box-shadow-sm-up: var(--#{$prefix}box-shadow) !default;\n\n$modal-backdrop-bg: $black !default;\n$modal-backdrop-opacity: .5 !default;\n\n$modal-header-border-color: var(--#{$prefix}border-color) !default;\n$modal-header-border-width: $modal-content-border-width !default;\n$modal-header-padding-y: $modal-inner-padding !default;\n$modal-header-padding-x: $modal-inner-padding !default;\n$modal-header-padding: $modal-header-padding-y $modal-header-padding-x !default; // Keep this for backwards compatibility\n\n$modal-footer-bg: null !default;\n$modal-footer-border-color: $modal-header-border-color !default;\n$modal-footer-border-width: $modal-header-border-width !default;\n\n$modal-sm: 300px !default;\n$modal-md: 500px !default;\n$modal-lg: 800px !default;\n$modal-xl: 1140px !default;\n\n$modal-fade-transform: translate(0, -50px) !default;\n$modal-show-transform: none !default;\n$modal-transition: transform .3s ease-out !default;\n$modal-scale-transform: scale(1.02) !default;\n// scss-docs-end modal-variables\n\n\n// Alerts\n//\n// Define alert colors, border radius, and padding.\n\n// scss-docs-start alert-variables\n$alert-padding-y: $spacer !default;\n$alert-padding-x: $spacer !default;\n$alert-margin-bottom: 1rem !default;\n$alert-border-radius: var(--#{$prefix}border-radius) !default;\n$alert-link-font-weight: $font-weight-bold !default;\n$alert-border-width: var(--#{$prefix}border-width) !default;\n$alert-dismissible-padding-r: $alert-padding-x * 3 !default; // 3x covers width of x plus default padding on either side\n// scss-docs-end alert-variables\n\n// fusv-disable\n$alert-bg-scale: -80% !default; // Deprecated in v5.2.0, to be removed in v6\n$alert-border-scale: -70% !default; // Deprecated in v5.2.0, to be removed in v6\n$alert-color-scale: 40% !default; // Deprecated in v5.2.0, to be removed in v6\n// fusv-enable\n\n// Progress bars\n\n// scss-docs-start progress-variables\n$progress-height: 1rem !default;\n$progress-font-size: $font-size-base * .75 !default;\n$progress-bg: var(--#{$prefix}secondary-bg) !default;\n$progress-border-radius: var(--#{$prefix}border-radius) !default;\n$progress-box-shadow: var(--#{$prefix}box-shadow-inset) !default;\n$progress-bar-color: $white !default;\n$progress-bar-bg: $primary !default;\n$progress-bar-animation-timing: 1s linear infinite !default;\n$progress-bar-transition: width .6s ease !default;\n// scss-docs-end progress-variables\n\n\n// List group\n\n// scss-docs-start list-group-variables\n$list-group-color: var(--#{$prefix}body-color) !default;\n$list-group-bg: var(--#{$prefix}body-bg) !default;\n$list-group-border-color: var(--#{$prefix}border-color) !default;\n$list-group-border-width: var(--#{$prefix}border-width) !default;\n$list-group-border-radius: var(--#{$prefix}border-radius) !default;\n\n$list-group-item-padding-y: $spacer * .5 !default;\n$list-group-item-padding-x: $spacer !default;\n// fusv-disable\n$list-group-item-bg-scale: -80% !default; // Deprecated in v5.3.0\n$list-group-item-color-scale: 40% !default; // Deprecated in v5.3.0\n// fusv-enable\n\n$list-group-hover-bg: var(--#{$prefix}tertiary-bg) !default;\n$list-group-active-color: $component-active-color !default;\n$list-group-active-bg: $component-active-bg !default;\n$list-group-active-border-color: $list-group-active-bg !default;\n\n$list-group-disabled-color: var(--#{$prefix}secondary-color) !default;\n$list-group-disabled-bg: $list-group-bg !default;\n\n$list-group-action-color: var(--#{$prefix}secondary-color) !default;\n$list-group-action-hover-color: var(--#{$prefix}emphasis-color) !default;\n\n$list-group-action-active-color: var(--#{$prefix}body-color) !default;\n$list-group-action-active-bg: var(--#{$prefix}secondary-bg) !default;\n// scss-docs-end list-group-variables\n\n\n// Image thumbnails\n\n// scss-docs-start thumbnail-variables\n$thumbnail-padding: .25rem !default;\n$thumbnail-bg: var(--#{$prefix}body-bg) !default;\n$thumbnail-border-width: var(--#{$prefix}border-width) !default;\n$thumbnail-border-color: var(--#{$prefix}border-color) !default;\n$thumbnail-border-radius: var(--#{$prefix}border-radius) !default;\n$thumbnail-box-shadow: var(--#{$prefix}box-shadow-sm) !default;\n// scss-docs-end thumbnail-variables\n\n\n// Figures\n\n// scss-docs-start figure-variables\n$figure-caption-font-size: $small-font-size !default;\n$figure-caption-color: var(--#{$prefix}secondary-color) !default;\n// scss-docs-end figure-variables\n\n\n// Breadcrumbs\n\n// scss-docs-start breadcrumb-variables\n$breadcrumb-font-size: null !default;\n$breadcrumb-padding-y: 0 !default;\n$breadcrumb-padding-x: 0 !default;\n$breadcrumb-item-padding-x: .5rem !default;\n$breadcrumb-margin-bottom: 1rem !default;\n$breadcrumb-bg: null !default;\n$breadcrumb-divider-color: var(--#{$prefix}secondary-color) !default;\n$breadcrumb-active-color: var(--#{$prefix}secondary-color) !default;\n$breadcrumb-divider: quote(\"/\") !default;\n$breadcrumb-divider-flipped: $breadcrumb-divider !default;\n$breadcrumb-border-radius: null !default;\n// scss-docs-end breadcrumb-variables\n\n// Carousel\n\n// scss-docs-start carousel-variables\n$carousel-control-color: $white !default;\n$carousel-control-width: 15% !default;\n$carousel-control-opacity: .5 !default;\n$carousel-control-hover-opacity: .9 !default;\n$carousel-control-transition: opacity .15s ease !default;\n\n$carousel-indicator-width: 30px !default;\n$carousel-indicator-height: 3px !default;\n$carousel-indicator-hit-area-height: 10px !default;\n$carousel-indicator-spacer: 3px !default;\n$carousel-indicator-opacity: .5 !default;\n$carousel-indicator-active-bg: $white !default;\n$carousel-indicator-active-opacity: 1 !default;\n$carousel-indicator-transition: opacity .6s ease !default;\n\n$carousel-caption-width: 70% !default;\n$carousel-caption-color: $white !default;\n$carousel-caption-padding-y: 1.25rem !default;\n$carousel-caption-spacer: 1.25rem !default;\n\n$carousel-control-icon-width: 2rem !default;\n\n$carousel-control-prev-icon-bg: url(\"data:image/svg+xml,\") !default;\n$carousel-control-next-icon-bg: url(\"data:image/svg+xml,\") !default;\n\n$carousel-transition-duration: .6s !default;\n$carousel-transition: transform $carousel-transition-duration ease-in-out !default; // Define transform transition first if using multiple transitions (e.g., `transform 2s ease, opacity .5s ease-out`)\n// scss-docs-end carousel-variables\n\n// scss-docs-start carousel-dark-variables\n$carousel-dark-indicator-active-bg: $black !default;\n$carousel-dark-caption-color: $black !default;\n$carousel-dark-control-icon-filter: invert(1) grayscale(100) !default;\n// scss-docs-end carousel-dark-variables\n\n\n// Spinners\n\n// scss-docs-start spinner-variables\n$spinner-width: 2rem !default;\n$spinner-height: $spinner-width !default;\n$spinner-vertical-align: -.125em !default;\n$spinner-border-width: .25em !default;\n$spinner-animation-speed: .75s !default;\n\n$spinner-width-sm: 1rem !default;\n$spinner-height-sm: $spinner-width-sm !default;\n$spinner-border-width-sm: .2em !default;\n// scss-docs-end spinner-variables\n\n\n// Close\n\n// scss-docs-start close-variables\n$btn-close-width: 1em !default;\n$btn-close-height: $btn-close-width !default;\n$btn-close-padding-x: .25em !default;\n$btn-close-padding-y: $btn-close-padding-x !default;\n$btn-close-color: $black !default;\n$btn-close-bg: url(\"data:image/svg+xml,\") !default;\n$btn-close-focus-shadow: $focus-ring-box-shadow !default;\n$btn-close-opacity: .5 !default;\n$btn-close-hover-opacity: .75 !default;\n$btn-close-focus-opacity: 1 !default;\n$btn-close-disabled-opacity: .25 !default;\n$btn-close-white-filter: invert(1) grayscale(100%) brightness(200%) !default;\n// scss-docs-end close-variables\n\n\n// Offcanvas\n\n// scss-docs-start offcanvas-variables\n$offcanvas-padding-y: $modal-inner-padding !default;\n$offcanvas-padding-x: $modal-inner-padding !default;\n$offcanvas-horizontal-width: 400px !default;\n$offcanvas-vertical-height: 30vh !default;\n$offcanvas-transition-duration: .3s !default;\n$offcanvas-border-color: $modal-content-border-color !default;\n$offcanvas-border-width: $modal-content-border-width !default;\n$offcanvas-title-line-height: $modal-title-line-height !default;\n$offcanvas-bg-color: var(--#{$prefix}body-bg) !default;\n$offcanvas-color: var(--#{$prefix}body-color) !default;\n$offcanvas-box-shadow: $modal-content-box-shadow-xs !default;\n$offcanvas-backdrop-bg: $modal-backdrop-bg !default;\n$offcanvas-backdrop-opacity: $modal-backdrop-opacity !default;\n// scss-docs-end offcanvas-variables\n\n// Code\n\n$code-font-size: $small-font-size !default;\n$code-color: $pink !default;\n\n$kbd-padding-y: .1875rem !default;\n$kbd-padding-x: .375rem !default;\n$kbd-font-size: $code-font-size !default;\n$kbd-color: var(--#{$prefix}body-bg) !default;\n$kbd-bg: var(--#{$prefix}body-color) !default;\n$nested-kbd-font-weight: null !default; // Deprecated in v5.2.0, removing in v6\n\n$pre-color: null !default;\n\n@import \"variables-dark\"; // TODO: can be removed safely in v6, only here to avoid breaking changes in v5.3\n","// Row\n//\n// Rows contain your columns.\n\n:root {\n @each $name, $value in $grid-breakpoints {\n --#{$prefix}breakpoint-#{$name}: #{$value};\n }\n}\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n\n > * {\n @include make-col-ready();\n }\n }\n}\n\n@if $enable-cssgrid {\n .grid {\n display: grid;\n grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr);\n grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr);\n gap: var(--#{$prefix}gap, #{$grid-gutter-width});\n\n @include make-cssgrid();\n }\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-row($gutter: $grid-gutter-width) {\n --#{$prefix}gutter-x: #{$gutter};\n --#{$prefix}gutter-y: 0;\n display: flex;\n flex-wrap: wrap;\n // TODO: Revisit calc order after https://github.com/react-bootstrap/react-bootstrap/issues/6039 is fixed\n margin-top: calc(-1 * var(--#{$prefix}gutter-y)); // stylelint-disable-line function-disallowed-list\n margin-right: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n margin-left: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n}\n\n@mixin make-col-ready() {\n // Add box sizing if only the grid is loaded\n box-sizing: if(variable-exists(include-column-box-sizing) and $include-column-box-sizing, border-box, null);\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we set the width\n // later on to override this initial width.\n flex-shrink: 0;\n width: 100%;\n max-width: 100%; // Prevent `.col-auto`, `.col` (& responsive variants) from breaking out the grid\n padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n margin-top: var(--#{$prefix}gutter-y);\n}\n\n@mixin make-col($size: false, $columns: $grid-columns) {\n @if $size {\n flex: 0 0 auto;\n width: percentage(divide($size, $columns));\n\n } @else {\n flex: 1 1 0;\n max-width: 100%;\n }\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: divide($size, $columns);\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// number of columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 auto;\n width: percentage(divide(1, $count));\n }\n}\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex: 1 0 0%; // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n }\n\n .row-cols#{$infix}-auto > * {\n @include make-col-auto();\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n\n // Gutters\n //\n // Make use of `.g-*`, `.gx-*` or `.gy-*` utilities to change spacing between the columns.\n @each $key, $value in $gutters {\n .g#{$infix}-#{$key},\n .gx#{$infix}-#{$key} {\n --#{$prefix}gutter-x: #{$value};\n }\n\n .g#{$infix}-#{$key},\n .gy#{$infix}-#{$key} {\n --#{$prefix}gutter-y: #{$value};\n }\n }\n }\n }\n}\n\n@mixin make-cssgrid($columns: $grid-columns, $breakpoints: $grid-breakpoints) {\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .g-col#{$infix}-#{$i} {\n grid-column: auto / span $i;\n }\n }\n\n // Start with `1` because `0` is an invalid value.\n // Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible.\n @for $i from 1 through ($columns - 1) {\n .g-start#{$infix}-#{$i} {\n grid-column-start: $i;\n }\n }\n }\n }\n }\n}\n","// Utility generator\n// Used to generate utilities & print utilities\n@mixin generate-utility($utility, $infix: \"\", $is-rfs-media-query: false) {\n $values: map-get($utility, values);\n\n // If the values are a list or string, convert it into a map\n @if type-of($values) == \"string\" or type-of(nth($values, 1)) != \"list\" {\n $values: zip($values, $values);\n }\n\n @each $key, $value in $values {\n $properties: map-get($utility, property);\n\n // Multiple properties are possible, for example with vertical or horizontal margins or paddings\n @if type-of($properties) == \"string\" {\n $properties: append((), $properties);\n }\n\n // Use custom class if present\n $property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1));\n $property-class: if($property-class == null, \"\", $property-class);\n\n // Use custom CSS variable name if present, otherwise default to `class`\n $css-variable-name: if(map-has-key($utility, css-variable-name), map-get($utility, css-variable-name), map-get($utility, class));\n\n // State params to generate pseudo-classes\n $state: if(map-has-key($utility, state), map-get($utility, state), ());\n\n $infix: if($property-class == \"\" and str-slice($infix, 1, 1) == \"-\", str-slice($infix, 2), $infix);\n\n // Don't prefix if value key is null (e.g. with shadow class)\n $property-class-modifier: if($key, if($property-class == \"\" and $infix == \"\", \"\", \"-\") + $key, \"\");\n\n @if map-get($utility, rfs) {\n // Inside the media query\n @if $is-rfs-media-query {\n $val: rfs-value($value);\n\n // Do not render anything if fluid and non fluid values are the same\n $value: if($val == rfs-fluid-value($value), null, $val);\n }\n @else {\n $value: rfs-fluid-value($value);\n }\n }\n\n $is-css-var: map-get($utility, css-var);\n $is-local-vars: map-get($utility, local-vars);\n $is-rtl: map-get($utility, rtl);\n\n @if $value != null {\n @if $is-rtl == false {\n /* rtl:begin:remove */\n }\n\n @if $is-css-var {\n .#{$property-class + $infix + $property-class-modifier} {\n --#{$prefix}#{$css-variable-name}: #{$value};\n }\n\n @each $pseudo in $state {\n .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n --#{$prefix}#{$css-variable-name}: #{$value};\n }\n }\n } @else {\n .#{$property-class + $infix + $property-class-modifier} {\n @each $property in $properties {\n @if $is-local-vars {\n @each $local-var, $variable in $is-local-vars {\n --#{$prefix}#{$local-var}: #{$variable};\n }\n }\n #{$property}: $value if($enable-important-utilities, !important, null);\n }\n }\n\n @each $pseudo in $state {\n .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n @each $property in $properties {\n @if $is-local-vars {\n @each $local-var, $variable in $is-local-vars {\n --#{$prefix}#{$local-var}: #{$variable};\n }\n }\n #{$property}: $value if($enable-important-utilities, !important, null);\n }\n }\n }\n }\n\n @if $is-rtl == false {\n /* rtl:end:remove */\n }\n }\n }\n}\n","// Loop over each breakpoint\n@each $breakpoint in map-keys($grid-breakpoints) {\n\n // Generate media query if needed\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n // Loop over each utility property\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Only proceed if responsive media queries are enabled or if it's the base media query\n @if type-of($utility) == \"map\" and (map-get($utility, responsive) or $infix == \"\") {\n @include generate-utility($utility, $infix);\n }\n }\n }\n}\n\n// RFS rescaling\n@media (min-width: $rfs-mq-value) {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) {\n // Loop over each utility property\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Only proceed if responsive media queries are enabled or if it's the base media query\n @if type-of($utility) == \"map\" and map-get($utility, rfs) and (map-get($utility, responsive) or $infix == \"\") {\n @include generate-utility($utility, $infix, true);\n }\n }\n }\n }\n}\n\n\n// Print utilities\n@media print {\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Then check if the utility needs print styles\n @if type-of($utility) == \"map\" and map-get($utility, print) == true {\n @include generate-utility($utility, \"-print\");\n }\n }\n}\n"]} \ No newline at end of file diff --git a/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css new file mode 100644 index 0000000..672cbc2 --- /dev/null +++ b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap Grid v5.3.3 (https://getbootstrap.com/) + * Copyright 2011-2024 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-left:calc(var(--bs-gutter-x) * .5);padding-right:calc(var(--bs-gutter-x) * .5);margin-left:auto;margin-right:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}:root{--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-left:calc(-.5 * var(--bs-gutter-x));margin-right:calc(-.5 * var(--bs-gutter-x))}.row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-left:calc(var(--bs-gutter-x) * .5);padding-right:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.66666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-right:8.33333333%}.offset-2{margin-right:16.66666667%}.offset-3{margin-right:25%}.offset-4{margin-right:33.33333333%}.offset-5{margin-right:41.66666667%}.offset-6{margin-right:50%}.offset-7{margin-right:58.33333333%}.offset-8{margin-right:66.66666667%}.offset-9{margin-right:75%}.offset-10{margin-right:83.33333333%}.offset-11{margin-right:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.66666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-right:0}.offset-sm-1{margin-right:8.33333333%}.offset-sm-2{margin-right:16.66666667%}.offset-sm-3{margin-right:25%}.offset-sm-4{margin-right:33.33333333%}.offset-sm-5{margin-right:41.66666667%}.offset-sm-6{margin-right:50%}.offset-sm-7{margin-right:58.33333333%}.offset-sm-8{margin-right:66.66666667%}.offset-sm-9{margin-right:75%}.offset-sm-10{margin-right:83.33333333%}.offset-sm-11{margin-right:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.66666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-right:0}.offset-md-1{margin-right:8.33333333%}.offset-md-2{margin-right:16.66666667%}.offset-md-3{margin-right:25%}.offset-md-4{margin-right:33.33333333%}.offset-md-5{margin-right:41.66666667%}.offset-md-6{margin-right:50%}.offset-md-7{margin-right:58.33333333%}.offset-md-8{margin-right:66.66666667%}.offset-md-9{margin-right:75%}.offset-md-10{margin-right:83.33333333%}.offset-md-11{margin-right:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.66666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-right:0}.offset-lg-1{margin-right:8.33333333%}.offset-lg-2{margin-right:16.66666667%}.offset-lg-3{margin-right:25%}.offset-lg-4{margin-right:33.33333333%}.offset-lg-5{margin-right:41.66666667%}.offset-lg-6{margin-right:50%}.offset-lg-7{margin-right:58.33333333%}.offset-lg-8{margin-right:66.66666667%}.offset-lg-9{margin-right:75%}.offset-lg-10{margin-right:83.33333333%}.offset-lg-11{margin-right:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.66666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-right:0}.offset-xl-1{margin-right:8.33333333%}.offset-xl-2{margin-right:16.66666667%}.offset-xl-3{margin-right:25%}.offset-xl-4{margin-right:33.33333333%}.offset-xl-5{margin-right:41.66666667%}.offset-xl-6{margin-right:50%}.offset-xl-7{margin-right:58.33333333%}.offset-xl-8{margin-right:66.66666667%}.offset-xl-9{margin-right:75%}.offset-xl-10{margin-right:83.33333333%}.offset-xl-11{margin-right:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.33333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.66666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-right:0}.offset-xxl-1{margin-right:8.33333333%}.offset-xxl-2{margin-right:16.66666667%}.offset-xxl-3{margin-right:25%}.offset-xxl-4{margin-right:33.33333333%}.offset-xxl-5{margin-right:41.66666667%}.offset-xxl-6{margin-right:50%}.offset-xxl-7{margin-right:58.33333333%}.offset-xxl-8{margin-right:66.66666667%}.offset-xxl-9{margin-right:75%}.offset-xxl-10{margin-right:83.33333333%}.offset-xxl-11{margin-right:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-inline-grid{display:inline-grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-left:0!important;margin-right:0!important}.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-3{margin-left:1rem!important;margin-right:1rem!important}.mx-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-5{margin-left:3rem!important;margin-right:3rem!important}.mx-auto{margin-left:auto!important;margin-right:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-left:0!important}.me-1{margin-left:.25rem!important}.me-2{margin-left:.5rem!important}.me-3{margin-left:1rem!important}.me-4{margin-left:1.5rem!important}.me-5{margin-left:3rem!important}.me-auto{margin-left:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-right:0!important}.ms-1{margin-right:.25rem!important}.ms-2{margin-right:.5rem!important}.ms-3{margin-right:1rem!important}.ms-4{margin-right:1.5rem!important}.ms-5{margin-right:3rem!important}.ms-auto{margin-right:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-left:0!important;padding-right:0!important}.px-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-3{padding-left:1rem!important;padding-right:1rem!important}.px-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-5{padding-left:3rem!important;padding-right:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-left:0!important}.pe-1{padding-left:.25rem!important}.pe-2{padding-left:.5rem!important}.pe-3{padding-left:1rem!important}.pe-4{padding-left:1.5rem!important}.pe-5{padding-left:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-right:0!important}.ps-1{padding-right:.25rem!important}.ps-2{padding-right:.5rem!important}.ps-3{padding-right:1rem!important}.ps-4{padding-right:1.5rem!important}.ps-5{padding-right:3rem!important}@media (min-width:576px){.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-inline-grid{display:inline-grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-left:0!important;margin-right:0!important}.mx-sm-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-sm-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-sm-3{margin-left:1rem!important;margin-right:1rem!important}.mx-sm-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-sm-5{margin-left:3rem!important;margin-right:3rem!important}.mx-sm-auto{margin-left:auto!important;margin-right:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-left:0!important}.me-sm-1{margin-left:.25rem!important}.me-sm-2{margin-left:.5rem!important}.me-sm-3{margin-left:1rem!important}.me-sm-4{margin-left:1.5rem!important}.me-sm-5{margin-left:3rem!important}.me-sm-auto{margin-left:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-right:0!important}.ms-sm-1{margin-right:.25rem!important}.ms-sm-2{margin-right:.5rem!important}.ms-sm-3{margin-right:1rem!important}.ms-sm-4{margin-right:1.5rem!important}.ms-sm-5{margin-right:3rem!important}.ms-sm-auto{margin-right:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-left:0!important;padding-right:0!important}.px-sm-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-sm-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-sm-3{padding-left:1rem!important;padding-right:1rem!important}.px-sm-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-sm-5{padding-left:3rem!important;padding-right:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-left:0!important}.pe-sm-1{padding-left:.25rem!important}.pe-sm-2{padding-left:.5rem!important}.pe-sm-3{padding-left:1rem!important}.pe-sm-4{padding-left:1.5rem!important}.pe-sm-5{padding-left:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-right:0!important}.ps-sm-1{padding-right:.25rem!important}.ps-sm-2{padding-right:.5rem!important}.ps-sm-3{padding-right:1rem!important}.ps-sm-4{padding-right:1.5rem!important}.ps-sm-5{padding-right:3rem!important}}@media (min-width:768px){.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-inline-grid{display:inline-grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-left:0!important;margin-right:0!important}.mx-md-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-md-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-md-3{margin-left:1rem!important;margin-right:1rem!important}.mx-md-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-md-5{margin-left:3rem!important;margin-right:3rem!important}.mx-md-auto{margin-left:auto!important;margin-right:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-left:0!important}.me-md-1{margin-left:.25rem!important}.me-md-2{margin-left:.5rem!important}.me-md-3{margin-left:1rem!important}.me-md-4{margin-left:1.5rem!important}.me-md-5{margin-left:3rem!important}.me-md-auto{margin-left:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-right:0!important}.ms-md-1{margin-right:.25rem!important}.ms-md-2{margin-right:.5rem!important}.ms-md-3{margin-right:1rem!important}.ms-md-4{margin-right:1.5rem!important}.ms-md-5{margin-right:3rem!important}.ms-md-auto{margin-right:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-left:0!important;padding-right:0!important}.px-md-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-md-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-md-3{padding-left:1rem!important;padding-right:1rem!important}.px-md-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-md-5{padding-left:3rem!important;padding-right:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-left:0!important}.pe-md-1{padding-left:.25rem!important}.pe-md-2{padding-left:.5rem!important}.pe-md-3{padding-left:1rem!important}.pe-md-4{padding-left:1.5rem!important}.pe-md-5{padding-left:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-right:0!important}.ps-md-1{padding-right:.25rem!important}.ps-md-2{padding-right:.5rem!important}.ps-md-3{padding-right:1rem!important}.ps-md-4{padding-right:1.5rem!important}.ps-md-5{padding-right:3rem!important}}@media (min-width:992px){.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-inline-grid{display:inline-grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-left:0!important;margin-right:0!important}.mx-lg-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-lg-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-lg-3{margin-left:1rem!important;margin-right:1rem!important}.mx-lg-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-lg-5{margin-left:3rem!important;margin-right:3rem!important}.mx-lg-auto{margin-left:auto!important;margin-right:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-left:0!important}.me-lg-1{margin-left:.25rem!important}.me-lg-2{margin-left:.5rem!important}.me-lg-3{margin-left:1rem!important}.me-lg-4{margin-left:1.5rem!important}.me-lg-5{margin-left:3rem!important}.me-lg-auto{margin-left:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-right:0!important}.ms-lg-1{margin-right:.25rem!important}.ms-lg-2{margin-right:.5rem!important}.ms-lg-3{margin-right:1rem!important}.ms-lg-4{margin-right:1.5rem!important}.ms-lg-5{margin-right:3rem!important}.ms-lg-auto{margin-right:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-left:0!important;padding-right:0!important}.px-lg-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-lg-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-lg-3{padding-left:1rem!important;padding-right:1rem!important}.px-lg-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-lg-5{padding-left:3rem!important;padding-right:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-left:0!important}.pe-lg-1{padding-left:.25rem!important}.pe-lg-2{padding-left:.5rem!important}.pe-lg-3{padding-left:1rem!important}.pe-lg-4{padding-left:1.5rem!important}.pe-lg-5{padding-left:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-right:0!important}.ps-lg-1{padding-right:.25rem!important}.ps-lg-2{padding-right:.5rem!important}.ps-lg-3{padding-right:1rem!important}.ps-lg-4{padding-right:1.5rem!important}.ps-lg-5{padding-right:3rem!important}}@media (min-width:1200px){.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-inline-grid{display:inline-grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-left:0!important;margin-right:0!important}.mx-xl-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-xl-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-xl-3{margin-left:1rem!important;margin-right:1rem!important}.mx-xl-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-xl-5{margin-left:3rem!important;margin-right:3rem!important}.mx-xl-auto{margin-left:auto!important;margin-right:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-left:0!important}.me-xl-1{margin-left:.25rem!important}.me-xl-2{margin-left:.5rem!important}.me-xl-3{margin-left:1rem!important}.me-xl-4{margin-left:1.5rem!important}.me-xl-5{margin-left:3rem!important}.me-xl-auto{margin-left:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-right:0!important}.ms-xl-1{margin-right:.25rem!important}.ms-xl-2{margin-right:.5rem!important}.ms-xl-3{margin-right:1rem!important}.ms-xl-4{margin-right:1.5rem!important}.ms-xl-5{margin-right:3rem!important}.ms-xl-auto{margin-right:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-left:0!important;padding-right:0!important}.px-xl-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-xl-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-xl-3{padding-left:1rem!important;padding-right:1rem!important}.px-xl-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-xl-5{padding-left:3rem!important;padding-right:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-left:0!important}.pe-xl-1{padding-left:.25rem!important}.pe-xl-2{padding-left:.5rem!important}.pe-xl-3{padding-left:1rem!important}.pe-xl-4{padding-left:1.5rem!important}.pe-xl-5{padding-left:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-right:0!important}.ps-xl-1{padding-right:.25rem!important}.ps-xl-2{padding-right:.5rem!important}.ps-xl-3{padding-right:1rem!important}.ps-xl-4{padding-right:1.5rem!important}.ps-xl-5{padding-right:3rem!important}}@media (min-width:1400px){.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-inline-grid{display:inline-grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-left:0!important;margin-right:0!important}.mx-xxl-1{margin-left:.25rem!important;margin-right:.25rem!important}.mx-xxl-2{margin-left:.5rem!important;margin-right:.5rem!important}.mx-xxl-3{margin-left:1rem!important;margin-right:1rem!important}.mx-xxl-4{margin-left:1.5rem!important;margin-right:1.5rem!important}.mx-xxl-5{margin-left:3rem!important;margin-right:3rem!important}.mx-xxl-auto{margin-left:auto!important;margin-right:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-left:0!important}.me-xxl-1{margin-left:.25rem!important}.me-xxl-2{margin-left:.5rem!important}.me-xxl-3{margin-left:1rem!important}.me-xxl-4{margin-left:1.5rem!important}.me-xxl-5{margin-left:3rem!important}.me-xxl-auto{margin-left:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-right:0!important}.ms-xxl-1{margin-right:.25rem!important}.ms-xxl-2{margin-right:.5rem!important}.ms-xxl-3{margin-right:1rem!important}.ms-xxl-4{margin-right:1.5rem!important}.ms-xxl-5{margin-right:3rem!important}.ms-xxl-auto{margin-right:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-left:0!important;padding-right:0!important}.px-xxl-1{padding-left:.25rem!important;padding-right:.25rem!important}.px-xxl-2{padding-left:.5rem!important;padding-right:.5rem!important}.px-xxl-3{padding-left:1rem!important;padding-right:1rem!important}.px-xxl-4{padding-left:1.5rem!important;padding-right:1.5rem!important}.px-xxl-5{padding-left:3rem!important;padding-right:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-left:0!important}.pe-xxl-1{padding-left:.25rem!important}.pe-xxl-2{padding-left:.5rem!important}.pe-xxl-3{padding-left:1rem!important}.pe-xxl-4{padding-left:1.5rem!important}.pe-xxl-5{padding-left:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-right:0!important}.ps-xxl-1{padding-right:.25rem!important}.ps-xxl-2{padding-right:.5rem!important}.ps-xxl-3{padding-right:1rem!important}.ps-xxl-4{padding-right:1.5rem!important}.ps-xxl-5{padding-right:3rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-inline-grid{display:inline-grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} +/*# sourceMappingURL=bootstrap-grid.rtl.min.css.map */ \ No newline at end of file diff --git a/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map new file mode 100644 index 0000000..1c926af --- /dev/null +++ b/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/mixins/_banner.scss","../../scss/_containers.scss","dist/css/bootstrap-grid.rtl.css","../../scss/mixins/_container.scss","../../scss/mixins/_breakpoints.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_utilities.scss","../../scss/utilities/_api.scss"],"names":[],"mappings":"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","sourcesContent":["@mixin bsBanner($file) {\n /*!\n * Bootstrap #{$file} v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n}\n","// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n@if $enable-container-classes {\n // Single container class with breakpoint max-widths\n .container,\n // 100% wide container at all breakpoints\n .container-fluid {\n @include make-container();\n }\n\n // Responsive containers that are 100% wide until a breakpoint\n @each $breakpoint, $container-max-width in $container-max-widths {\n .container-#{$breakpoint} {\n @extend .container-fluid;\n }\n\n @include media-breakpoint-up($breakpoint, $grid-breakpoints) {\n %responsive-container-#{$breakpoint} {\n max-width: $container-max-width;\n }\n\n // Extend each breakpoint which is smaller or equal to the current breakpoint\n $extend-breakpoint: true;\n\n @each $name, $width in $grid-breakpoints {\n @if ($extend-breakpoint) {\n .container#{breakpoint-infix($name, $grid-breakpoints)} {\n @extend %responsive-container-#{$breakpoint};\n }\n\n // Once the current breakpoint is reached, stop extending\n @if ($breakpoint == $name) {\n $extend-breakpoint: false;\n }\n }\n }\n }\n }\n}\n","/*!\n * Bootstrap Grid v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n --bs-gutter-x: 1.5rem;\n --bs-gutter-y: 0;\n width: 100%;\n padding-left: calc(var(--bs-gutter-x) * 0.5);\n padding-right: calc(var(--bs-gutter-x) * 0.5);\n margin-left: auto;\n margin-right: auto;\n}\n\n@media (min-width: 576px) {\n .container-sm, .container {\n max-width: 540px;\n }\n}\n@media (min-width: 768px) {\n .container-md, .container-sm, .container {\n max-width: 720px;\n }\n}\n@media (min-width: 992px) {\n .container-lg, .container-md, .container-sm, .container {\n max-width: 960px;\n }\n}\n@media (min-width: 1200px) {\n .container-xl, .container-lg, .container-md, .container-sm, .container {\n max-width: 1140px;\n }\n}\n@media (min-width: 1400px) {\n .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n max-width: 1320px;\n }\n}\n:root {\n --bs-breakpoint-xs: 0;\n --bs-breakpoint-sm: 576px;\n --bs-breakpoint-md: 768px;\n --bs-breakpoint-lg: 992px;\n --bs-breakpoint-xl: 1200px;\n --bs-breakpoint-xxl: 1400px;\n}\n\n.row {\n --bs-gutter-x: 1.5rem;\n --bs-gutter-y: 0;\n display: flex;\n flex-wrap: wrap;\n margin-top: calc(-1 * var(--bs-gutter-y));\n margin-left: calc(-0.5 * var(--bs-gutter-x));\n margin-right: calc(-0.5 * var(--bs-gutter-x));\n}\n.row > * {\n box-sizing: border-box;\n flex-shrink: 0;\n width: 100%;\n max-width: 100%;\n padding-left: calc(var(--bs-gutter-x) * 0.5);\n padding-right: calc(var(--bs-gutter-x) * 0.5);\n margin-top: var(--bs-gutter-y);\n}\n\n.col {\n flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n flex: 0 0 auto;\n width: auto;\n}\n\n.row-cols-1 > * {\n flex: 0 0 auto;\n width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 auto;\n width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 auto;\n width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 auto;\n width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n}\n\n.col-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n}\n\n.col-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n}\n\n.col-3 {\n flex: 0 0 auto;\n width: 25%;\n}\n\n.col-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n}\n\n.col-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n}\n\n.col-6 {\n flex: 0 0 auto;\n width: 50%;\n}\n\n.col-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n}\n\n.col-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n}\n\n.col-9 {\n flex: 0 0 auto;\n width: 75%;\n}\n\n.col-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n}\n\n.col-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n}\n\n.col-12 {\n flex: 0 0 auto;\n width: 100%;\n}\n\n.offset-1 {\n margin-right: 8.33333333%;\n}\n\n.offset-2 {\n margin-right: 16.66666667%;\n}\n\n.offset-3 {\n margin-right: 25%;\n}\n\n.offset-4 {\n margin-right: 33.33333333%;\n}\n\n.offset-5 {\n margin-right: 41.66666667%;\n}\n\n.offset-6 {\n margin-right: 50%;\n}\n\n.offset-7 {\n margin-right: 58.33333333%;\n}\n\n.offset-8 {\n margin-right: 66.66666667%;\n}\n\n.offset-9 {\n margin-right: 75%;\n}\n\n.offset-10 {\n margin-right: 83.33333333%;\n}\n\n.offset-11 {\n margin-right: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex: 1 0 0%;\n }\n .row-cols-sm-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-sm-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-sm-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-sm-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-sm-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-sm-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-sm-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-sm-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-sm-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-sm-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-sm-0 {\n margin-right: 0;\n }\n .offset-sm-1 {\n margin-right: 8.33333333%;\n }\n .offset-sm-2 {\n margin-right: 16.66666667%;\n }\n .offset-sm-3 {\n margin-right: 25%;\n }\n .offset-sm-4 {\n margin-right: 33.33333333%;\n }\n .offset-sm-5 {\n margin-right: 41.66666667%;\n }\n .offset-sm-6 {\n margin-right: 50%;\n }\n .offset-sm-7 {\n margin-right: 58.33333333%;\n }\n .offset-sm-8 {\n margin-right: 66.66666667%;\n }\n .offset-sm-9 {\n margin-right: 75%;\n }\n .offset-sm-10 {\n margin-right: 83.33333333%;\n }\n .offset-sm-11 {\n margin-right: 91.66666667%;\n }\n .g-sm-0,\n .gx-sm-0 {\n --bs-gutter-x: 0;\n }\n .g-sm-0,\n .gy-sm-0 {\n --bs-gutter-y: 0;\n }\n .g-sm-1,\n .gx-sm-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-sm-1,\n .gy-sm-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-sm-2,\n .gx-sm-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-sm-2,\n .gy-sm-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-sm-3,\n .gx-sm-3 {\n --bs-gutter-x: 1rem;\n }\n .g-sm-3,\n .gy-sm-3 {\n --bs-gutter-y: 1rem;\n }\n .g-sm-4,\n .gx-sm-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-sm-4,\n .gy-sm-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-sm-5,\n .gx-sm-5 {\n --bs-gutter-x: 3rem;\n }\n .g-sm-5,\n .gy-sm-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 768px) {\n .col-md {\n flex: 1 0 0%;\n }\n .row-cols-md-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-md-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-md-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-md-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-md-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-md-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-md-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-md-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-md-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-md-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-md-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-md-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-md-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-md-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-md-0 {\n margin-right: 0;\n }\n .offset-md-1 {\n margin-right: 8.33333333%;\n }\n .offset-md-2 {\n margin-right: 16.66666667%;\n }\n .offset-md-3 {\n margin-right: 25%;\n }\n .offset-md-4 {\n margin-right: 33.33333333%;\n }\n .offset-md-5 {\n margin-right: 41.66666667%;\n }\n .offset-md-6 {\n margin-right: 50%;\n }\n .offset-md-7 {\n margin-right: 58.33333333%;\n }\n .offset-md-8 {\n margin-right: 66.66666667%;\n }\n .offset-md-9 {\n margin-right: 75%;\n }\n .offset-md-10 {\n margin-right: 83.33333333%;\n }\n .offset-md-11 {\n margin-right: 91.66666667%;\n }\n .g-md-0,\n .gx-md-0 {\n --bs-gutter-x: 0;\n }\n .g-md-0,\n .gy-md-0 {\n --bs-gutter-y: 0;\n }\n .g-md-1,\n .gx-md-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-md-1,\n .gy-md-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-md-2,\n .gx-md-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-md-2,\n .gy-md-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-md-3,\n .gx-md-3 {\n --bs-gutter-x: 1rem;\n }\n .g-md-3,\n .gy-md-3 {\n --bs-gutter-y: 1rem;\n }\n .g-md-4,\n .gx-md-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-md-4,\n .gy-md-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-md-5,\n .gx-md-5 {\n --bs-gutter-x: 3rem;\n }\n .g-md-5,\n .gy-md-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 992px) {\n .col-lg {\n flex: 1 0 0%;\n }\n .row-cols-lg-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-lg-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-lg-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-lg-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-lg-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-lg-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-lg-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-lg-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-lg-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-lg-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-lg-0 {\n margin-right: 0;\n }\n .offset-lg-1 {\n margin-right: 8.33333333%;\n }\n .offset-lg-2 {\n margin-right: 16.66666667%;\n }\n .offset-lg-3 {\n margin-right: 25%;\n }\n .offset-lg-4 {\n margin-right: 33.33333333%;\n }\n .offset-lg-5 {\n margin-right: 41.66666667%;\n }\n .offset-lg-6 {\n margin-right: 50%;\n }\n .offset-lg-7 {\n margin-right: 58.33333333%;\n }\n .offset-lg-8 {\n margin-right: 66.66666667%;\n }\n .offset-lg-9 {\n margin-right: 75%;\n }\n .offset-lg-10 {\n margin-right: 83.33333333%;\n }\n .offset-lg-11 {\n margin-right: 91.66666667%;\n }\n .g-lg-0,\n .gx-lg-0 {\n --bs-gutter-x: 0;\n }\n .g-lg-0,\n .gy-lg-0 {\n --bs-gutter-y: 0;\n }\n .g-lg-1,\n .gx-lg-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-lg-1,\n .gy-lg-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-lg-2,\n .gx-lg-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-lg-2,\n .gy-lg-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-lg-3,\n .gx-lg-3 {\n --bs-gutter-x: 1rem;\n }\n .g-lg-3,\n .gy-lg-3 {\n --bs-gutter-y: 1rem;\n }\n .g-lg-4,\n .gx-lg-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-lg-4,\n .gy-lg-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-lg-5,\n .gx-lg-5 {\n --bs-gutter-x: 3rem;\n }\n .g-lg-5,\n .gy-lg-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 1200px) {\n .col-xl {\n flex: 1 0 0%;\n }\n .row-cols-xl-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-xl-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-xl-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xl-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-xl-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-xl-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-xl-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-xl-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-xl-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-xl-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-xl-0 {\n margin-right: 0;\n }\n .offset-xl-1 {\n margin-right: 8.33333333%;\n }\n .offset-xl-2 {\n margin-right: 16.66666667%;\n }\n .offset-xl-3 {\n margin-right: 25%;\n }\n .offset-xl-4 {\n margin-right: 33.33333333%;\n }\n .offset-xl-5 {\n margin-right: 41.66666667%;\n }\n .offset-xl-6 {\n margin-right: 50%;\n }\n .offset-xl-7 {\n margin-right: 58.33333333%;\n }\n .offset-xl-8 {\n margin-right: 66.66666667%;\n }\n .offset-xl-9 {\n margin-right: 75%;\n }\n .offset-xl-10 {\n margin-right: 83.33333333%;\n }\n .offset-xl-11 {\n margin-right: 91.66666667%;\n }\n .g-xl-0,\n .gx-xl-0 {\n --bs-gutter-x: 0;\n }\n .g-xl-0,\n .gy-xl-0 {\n --bs-gutter-y: 0;\n }\n .g-xl-1,\n .gx-xl-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-xl-1,\n .gy-xl-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-xl-2,\n .gx-xl-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-xl-2,\n .gy-xl-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-xl-3,\n .gx-xl-3 {\n --bs-gutter-x: 1rem;\n }\n .g-xl-3,\n .gy-xl-3 {\n --bs-gutter-y: 1rem;\n }\n .g-xl-4,\n .gx-xl-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-xl-4,\n .gy-xl-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-xl-5,\n .gx-xl-5 {\n --bs-gutter-x: 3rem;\n }\n .g-xl-5,\n .gy-xl-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 1400px) {\n .col-xxl {\n flex: 1 0 0%;\n }\n .row-cols-xxl-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-xxl-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-xxl-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-xxl-3 > * {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .row-cols-xxl-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-xxl-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-xxl-6 > * {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xxl-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-xxl-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-xxl-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xxl-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-xxl-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-xxl-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-xxl-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-xxl-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-xxl-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-xxl-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-xxl-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-xxl-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-xxl-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-xxl-0 {\n margin-right: 0;\n }\n .offset-xxl-1 {\n margin-right: 8.33333333%;\n }\n .offset-xxl-2 {\n margin-right: 16.66666667%;\n }\n .offset-xxl-3 {\n margin-right: 25%;\n }\n .offset-xxl-4 {\n margin-right: 33.33333333%;\n }\n .offset-xxl-5 {\n margin-right: 41.66666667%;\n }\n .offset-xxl-6 {\n margin-right: 50%;\n }\n .offset-xxl-7 {\n margin-right: 58.33333333%;\n }\n .offset-xxl-8 {\n margin-right: 66.66666667%;\n }\n .offset-xxl-9 {\n margin-right: 75%;\n }\n .offset-xxl-10 {\n margin-right: 83.33333333%;\n }\n .offset-xxl-11 {\n margin-right: 91.66666667%;\n }\n .g-xxl-0,\n .gx-xxl-0 {\n --bs-gutter-x: 0;\n }\n .g-xxl-0,\n .gy-xxl-0 {\n --bs-gutter-y: 0;\n }\n .g-xxl-1,\n .gx-xxl-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-xxl-1,\n .gy-xxl-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-xxl-2,\n .gx-xxl-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-xxl-2,\n .gy-xxl-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-xxl-3,\n .gx-xxl-3 {\n --bs-gutter-x: 1rem;\n }\n .g-xxl-3,\n .gy-xxl-3 {\n --bs-gutter-y: 1rem;\n }\n .g-xxl-4,\n .gx-xxl-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-xxl-4,\n .gy-xxl-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-xxl-5,\n .gx-xxl-5 {\n --bs-gutter-x: 3rem;\n }\n .g-xxl-5,\n .gy-xxl-5 {\n --bs-gutter-y: 3rem;\n }\n}\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-grid {\n display: grid !important;\n}\n\n.d-inline-grid {\n display: inline-grid !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n.d-none {\n display: none !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n justify-content: space-evenly !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n.order-first {\n order: -1 !important;\n}\n\n.order-0 {\n order: 0 !important;\n}\n\n.order-1 {\n order: 1 !important;\n}\n\n.order-2 {\n order: 2 !important;\n}\n\n.order-3 {\n order: 3 !important;\n}\n\n.order-4 {\n order: 4 !important;\n}\n\n.order-5 {\n order: 5 !important;\n}\n\n.order-last {\n order: 6 !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mx-0 {\n margin-left: 0 !important;\n margin-right: 0 !important;\n}\n\n.mx-1 {\n margin-left: 0.25rem !important;\n margin-right: 0.25rem !important;\n}\n\n.mx-2 {\n margin-left: 0.5rem !important;\n margin-right: 0.5rem !important;\n}\n\n.mx-3 {\n margin-left: 1rem !important;\n margin-right: 1rem !important;\n}\n\n.mx-4 {\n margin-left: 1.5rem !important;\n margin-right: 1.5rem !important;\n}\n\n.mx-5 {\n margin-left: 3rem !important;\n margin-right: 3rem !important;\n}\n\n.mx-auto {\n margin-left: auto !important;\n margin-right: auto !important;\n}\n\n.my-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n}\n\n.my-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n}\n\n.my-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n}\n\n.my-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n}\n\n.mt-0 {\n margin-top: 0 !important;\n}\n\n.mt-1 {\n margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n margin-top: 1rem !important;\n}\n\n.mt-4 {\n margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n margin-top: 3rem !important;\n}\n\n.mt-auto {\n margin-top: auto !important;\n}\n\n.me-0 {\n margin-left: 0 !important;\n}\n\n.me-1 {\n margin-left: 0.25rem !important;\n}\n\n.me-2 {\n margin-left: 0.5rem !important;\n}\n\n.me-3 {\n margin-left: 1rem !important;\n}\n\n.me-4 {\n margin-left: 1.5rem !important;\n}\n\n.me-5 {\n margin-left: 3rem !important;\n}\n\n.me-auto {\n margin-left: auto !important;\n}\n\n.mb-0 {\n margin-bottom: 0 !important;\n}\n\n.mb-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n margin-bottom: auto !important;\n}\n\n.ms-0 {\n margin-right: 0 !important;\n}\n\n.ms-1 {\n margin-right: 0.25rem !important;\n}\n\n.ms-2 {\n margin-right: 0.5rem !important;\n}\n\n.ms-3 {\n margin-right: 1rem !important;\n}\n\n.ms-4 {\n margin-right: 1.5rem !important;\n}\n\n.ms-5 {\n margin-right: 3rem !important;\n}\n\n.ms-auto {\n margin-right: auto !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.px-0 {\n padding-left: 0 !important;\n padding-right: 0 !important;\n}\n\n.px-1 {\n padding-left: 0.25rem !important;\n padding-right: 0.25rem !important;\n}\n\n.px-2 {\n padding-left: 0.5rem !important;\n padding-right: 0.5rem !important;\n}\n\n.px-3 {\n padding-left: 1rem !important;\n padding-right: 1rem !important;\n}\n\n.px-4 {\n padding-left: 1.5rem !important;\n padding-right: 1.5rem !important;\n}\n\n.px-5 {\n padding-left: 3rem !important;\n padding-right: 3rem !important;\n}\n\n.py-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n}\n\n.py-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n}\n\n.py-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n padding-top: 0 !important;\n}\n\n.pt-1 {\n padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n padding-top: 1rem !important;\n}\n\n.pt-4 {\n padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n padding-top: 3rem !important;\n}\n\n.pe-0 {\n padding-left: 0 !important;\n}\n\n.pe-1 {\n padding-left: 0.25rem !important;\n}\n\n.pe-2 {\n padding-left: 0.5rem !important;\n}\n\n.pe-3 {\n padding-left: 1rem !important;\n}\n\n.pe-4 {\n padding-left: 1.5rem !important;\n}\n\n.pe-5 {\n padding-left: 3rem !important;\n}\n\n.pb-0 {\n padding-bottom: 0 !important;\n}\n\n.pb-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n padding-right: 0 !important;\n}\n\n.ps-1 {\n padding-right: 0.25rem !important;\n}\n\n.ps-2 {\n padding-right: 0.5rem !important;\n}\n\n.ps-3 {\n padding-right: 1rem !important;\n}\n\n.ps-4 {\n padding-right: 1.5rem !important;\n}\n\n.ps-5 {\n padding-right: 3rem !important;\n}\n\n@media (min-width: 576px) {\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-grid {\n display: grid !important;\n }\n .d-sm-inline-grid {\n display: inline-grid !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n .d-sm-none {\n display: none !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .justify-content-sm-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n .order-sm-first {\n order: -1 !important;\n }\n .order-sm-0 {\n order: 0 !important;\n }\n .order-sm-1 {\n order: 1 !important;\n }\n .order-sm-2 {\n order: 2 !important;\n }\n .order-sm-3 {\n order: 3 !important;\n }\n .order-sm-4 {\n order: 4 !important;\n }\n .order-sm-5 {\n order: 5 !important;\n }\n .order-sm-last {\n order: 6 !important;\n }\n .m-sm-0 {\n margin: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mx-sm-0 {\n margin-left: 0 !important;\n margin-right: 0 !important;\n }\n .mx-sm-1 {\n margin-left: 0.25rem !important;\n margin-right: 0.25rem !important;\n }\n .mx-sm-2 {\n margin-left: 0.5rem !important;\n margin-right: 0.5rem !important;\n }\n .mx-sm-3 {\n margin-left: 1rem !important;\n margin-right: 1rem !important;\n }\n .mx-sm-4 {\n margin-left: 1.5rem !important;\n margin-right: 1.5rem !important;\n }\n .mx-sm-5 {\n margin-left: 3rem !important;\n margin-right: 3rem !important;\n }\n .mx-sm-auto {\n margin-left: auto !important;\n margin-right: auto !important;\n }\n .my-sm-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-sm-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-sm-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-sm-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-sm-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-sm-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-sm-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-sm-0 {\n margin-top: 0 !important;\n }\n .mt-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mt-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mt-sm-3 {\n margin-top: 1rem !important;\n }\n .mt-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mt-sm-5 {\n margin-top: 3rem !important;\n }\n .mt-sm-auto {\n margin-top: auto !important;\n }\n .me-sm-0 {\n margin-left: 0 !important;\n }\n .me-sm-1 {\n margin-left: 0.25rem !important;\n }\n .me-sm-2 {\n margin-left: 0.5rem !important;\n }\n .me-sm-3 {\n margin-left: 1rem !important;\n }\n .me-sm-4 {\n margin-left: 1.5rem !important;\n }\n .me-sm-5 {\n margin-left: 3rem !important;\n }\n .me-sm-auto {\n margin-left: auto !important;\n }\n .mb-sm-0 {\n margin-bottom: 0 !important;\n }\n .mb-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-sm-3 {\n margin-bottom: 1rem !important;\n }\n .mb-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-sm-5 {\n margin-bottom: 3rem !important;\n }\n .mb-sm-auto {\n margin-bottom: auto !important;\n }\n .ms-sm-0 {\n margin-right: 0 !important;\n }\n .ms-sm-1 {\n margin-right: 0.25rem !important;\n }\n .ms-sm-2 {\n margin-right: 0.5rem !important;\n }\n .ms-sm-3 {\n margin-right: 1rem !important;\n }\n .ms-sm-4 {\n margin-right: 1.5rem !important;\n }\n .ms-sm-5 {\n margin-right: 3rem !important;\n }\n .ms-sm-auto {\n margin-right: auto !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .px-sm-0 {\n padding-left: 0 !important;\n padding-right: 0 !important;\n }\n .px-sm-1 {\n padding-left: 0.25rem !important;\n padding-right: 0.25rem !important;\n }\n .px-sm-2 {\n padding-left: 0.5rem !important;\n padding-right: 0.5rem !important;\n }\n .px-sm-3 {\n padding-left: 1rem !important;\n padding-right: 1rem !important;\n }\n .px-sm-4 {\n padding-left: 1.5rem !important;\n padding-right: 1.5rem !important;\n }\n .px-sm-5 {\n padding-left: 3rem !important;\n padding-right: 3rem !important;\n }\n .py-sm-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-sm-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-sm-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-sm-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-sm-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-sm-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-sm-0 {\n padding-top: 0 !important;\n }\n .pt-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pt-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pt-sm-3 {\n padding-top: 1rem !important;\n }\n .pt-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pt-sm-5 {\n padding-top: 3rem !important;\n }\n .pe-sm-0 {\n padding-left: 0 !important;\n }\n .pe-sm-1 {\n padding-left: 0.25rem !important;\n }\n .pe-sm-2 {\n padding-left: 0.5rem !important;\n }\n .pe-sm-3 {\n padding-left: 1rem !important;\n }\n .pe-sm-4 {\n padding-left: 1.5rem !important;\n }\n .pe-sm-5 {\n padding-left: 3rem !important;\n }\n .pb-sm-0 {\n padding-bottom: 0 !important;\n }\n .pb-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pb-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-sm-5 {\n padding-bottom: 3rem !important;\n }\n .ps-sm-0 {\n padding-right: 0 !important;\n }\n .ps-sm-1 {\n padding-right: 0.25rem !important;\n }\n .ps-sm-2 {\n padding-right: 0.5rem !important;\n }\n .ps-sm-3 {\n padding-right: 1rem !important;\n }\n .ps-sm-4 {\n padding-right: 1.5rem !important;\n }\n .ps-sm-5 {\n padding-right: 3rem !important;\n }\n}\n@media (min-width: 768px) {\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-grid {\n display: grid !important;\n }\n .d-md-inline-grid {\n display: inline-grid !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n .d-md-none {\n display: none !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .justify-content-md-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n .order-md-first {\n order: -1 !important;\n }\n .order-md-0 {\n order: 0 !important;\n }\n .order-md-1 {\n order: 1 !important;\n }\n .order-md-2 {\n order: 2 !important;\n }\n .order-md-3 {\n order: 3 !important;\n }\n .order-md-4 {\n order: 4 !important;\n }\n .order-md-5 {\n order: 5 !important;\n }\n .order-md-last {\n order: 6 !important;\n }\n .m-md-0 {\n margin: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mx-md-0 {\n margin-left: 0 !important;\n margin-right: 0 !important;\n }\n .mx-md-1 {\n margin-left: 0.25rem !important;\n margin-right: 0.25rem !important;\n }\n .mx-md-2 {\n margin-left: 0.5rem !important;\n margin-right: 0.5rem !important;\n }\n .mx-md-3 {\n margin-left: 1rem !important;\n margin-right: 1rem !important;\n }\n .mx-md-4 {\n margin-left: 1.5rem !important;\n margin-right: 1.5rem !important;\n }\n .mx-md-5 {\n margin-left: 3rem !important;\n margin-right: 3rem !important;\n }\n .mx-md-auto {\n margin-left: auto !important;\n margin-right: auto !important;\n }\n .my-md-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-md-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-md-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-md-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-md-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-md-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-md-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-md-0 {\n margin-top: 0 !important;\n }\n .mt-md-1 {\n margin-top: 0.25rem !important;\n }\n .mt-md-2 {\n margin-top: 0.5rem !important;\n }\n .mt-md-3 {\n margin-top: 1rem !important;\n }\n .mt-md-4 {\n margin-top: 1.5rem !important;\n }\n .mt-md-5 {\n margin-top: 3rem !important;\n }\n .mt-md-auto {\n margin-top: auto !important;\n }\n .me-md-0 {\n margin-left: 0 !important;\n }\n .me-md-1 {\n margin-left: 0.25rem !important;\n }\n .me-md-2 {\n margin-left: 0.5rem !important;\n }\n .me-md-3 {\n margin-left: 1rem !important;\n }\n .me-md-4 {\n margin-left: 1.5rem !important;\n }\n .me-md-5 {\n margin-left: 3rem !important;\n }\n .me-md-auto {\n margin-left: auto !important;\n }\n .mb-md-0 {\n margin-bottom: 0 !important;\n }\n .mb-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-md-3 {\n margin-bottom: 1rem !important;\n }\n .mb-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-md-5 {\n margin-bottom: 3rem !important;\n }\n .mb-md-auto {\n margin-bottom: auto !important;\n }\n .ms-md-0 {\n margin-right: 0 !important;\n }\n .ms-md-1 {\n margin-right: 0.25rem !important;\n }\n .ms-md-2 {\n margin-right: 0.5rem !important;\n }\n .ms-md-3 {\n margin-right: 1rem !important;\n }\n .ms-md-4 {\n margin-right: 1.5rem !important;\n }\n .ms-md-5 {\n margin-right: 3rem !important;\n }\n .ms-md-auto {\n margin-right: auto !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .px-md-0 {\n padding-left: 0 !important;\n padding-right: 0 !important;\n }\n .px-md-1 {\n padding-left: 0.25rem !important;\n padding-right: 0.25rem !important;\n }\n .px-md-2 {\n padding-left: 0.5rem !important;\n padding-right: 0.5rem !important;\n }\n .px-md-3 {\n padding-left: 1rem !important;\n padding-right: 1rem !important;\n }\n .px-md-4 {\n padding-left: 1.5rem !important;\n padding-right: 1.5rem !important;\n }\n .px-md-5 {\n padding-left: 3rem !important;\n padding-right: 3rem !important;\n }\n .py-md-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-md-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-md-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-md-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-md-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-md-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-md-0 {\n padding-top: 0 !important;\n }\n .pt-md-1 {\n padding-top: 0.25rem !important;\n }\n .pt-md-2 {\n padding-top: 0.5rem !important;\n }\n .pt-md-3 {\n padding-top: 1rem !important;\n }\n .pt-md-4 {\n padding-top: 1.5rem !important;\n }\n .pt-md-5 {\n padding-top: 3rem !important;\n }\n .pe-md-0 {\n padding-left: 0 !important;\n }\n .pe-md-1 {\n padding-left: 0.25rem !important;\n }\n .pe-md-2 {\n padding-left: 0.5rem !important;\n }\n .pe-md-3 {\n padding-left: 1rem !important;\n }\n .pe-md-4 {\n padding-left: 1.5rem !important;\n }\n .pe-md-5 {\n padding-left: 3rem !important;\n }\n .pb-md-0 {\n padding-bottom: 0 !important;\n }\n .pb-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-md-3 {\n padding-bottom: 1rem !important;\n }\n .pb-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-md-5 {\n padding-bottom: 3rem !important;\n }\n .ps-md-0 {\n padding-right: 0 !important;\n }\n .ps-md-1 {\n padding-right: 0.25rem !important;\n }\n .ps-md-2 {\n padding-right: 0.5rem !important;\n }\n .ps-md-3 {\n padding-right: 1rem !important;\n }\n .ps-md-4 {\n padding-right: 1.5rem !important;\n }\n .ps-md-5 {\n padding-right: 3rem !important;\n }\n}\n@media (min-width: 992px) {\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-grid {\n display: grid !important;\n }\n .d-lg-inline-grid {\n display: inline-grid !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n .d-lg-none {\n display: none !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .justify-content-lg-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n .order-lg-first {\n order: -1 !important;\n }\n .order-lg-0 {\n order: 0 !important;\n }\n .order-lg-1 {\n order: 1 !important;\n }\n .order-lg-2 {\n order: 2 !important;\n }\n .order-lg-3 {\n order: 3 !important;\n }\n .order-lg-4 {\n order: 4 !important;\n }\n .order-lg-5 {\n order: 5 !important;\n }\n .order-lg-last {\n order: 6 !important;\n }\n .m-lg-0 {\n margin: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mx-lg-0 {\n margin-left: 0 !important;\n margin-right: 0 !important;\n }\n .mx-lg-1 {\n margin-left: 0.25rem !important;\n margin-right: 0.25rem !important;\n }\n .mx-lg-2 {\n margin-left: 0.5rem !important;\n margin-right: 0.5rem !important;\n }\n .mx-lg-3 {\n margin-left: 1rem !important;\n margin-right: 1rem !important;\n }\n .mx-lg-4 {\n margin-left: 1.5rem !important;\n margin-right: 1.5rem !important;\n }\n .mx-lg-5 {\n margin-left: 3rem !important;\n margin-right: 3rem !important;\n }\n .mx-lg-auto {\n margin-left: auto !important;\n margin-right: auto !important;\n }\n .my-lg-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-lg-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-lg-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-lg-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-lg-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-lg-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-lg-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-lg-0 {\n margin-top: 0 !important;\n }\n .mt-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mt-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mt-lg-3 {\n margin-top: 1rem !important;\n }\n .mt-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mt-lg-5 {\n margin-top: 3rem !important;\n }\n .mt-lg-auto {\n margin-top: auto !important;\n }\n .me-lg-0 {\n margin-left: 0 !important;\n }\n .me-lg-1 {\n margin-left: 0.25rem !important;\n }\n .me-lg-2 {\n margin-left: 0.5rem !important;\n }\n .me-lg-3 {\n margin-left: 1rem !important;\n }\n .me-lg-4 {\n margin-left: 1.5rem !important;\n }\n .me-lg-5 {\n margin-left: 3rem !important;\n }\n .me-lg-auto {\n margin-left: auto !important;\n }\n .mb-lg-0 {\n margin-bottom: 0 !important;\n }\n .mb-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-lg-3 {\n margin-bottom: 1rem !important;\n }\n .mb-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-lg-5 {\n margin-bottom: 3rem !important;\n }\n .mb-lg-auto {\n margin-bottom: auto !important;\n }\n .ms-lg-0 {\n margin-right: 0 !important;\n }\n .ms-lg-1 {\n margin-right: 0.25rem !important;\n }\n .ms-lg-2 {\n margin-right: 0.5rem !important;\n }\n .ms-lg-3 {\n margin-right: 1rem !important;\n }\n .ms-lg-4 {\n margin-right: 1.5rem !important;\n }\n .ms-lg-5 {\n margin-right: 3rem !important;\n }\n .ms-lg-auto {\n margin-right: auto !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .px-lg-0 {\n padding-left: 0 !important;\n padding-right: 0 !important;\n }\n .px-lg-1 {\n padding-left: 0.25rem !important;\n padding-right: 0.25rem !important;\n }\n .px-lg-2 {\n padding-left: 0.5rem !important;\n padding-right: 0.5rem !important;\n }\n .px-lg-3 {\n padding-left: 1rem !important;\n padding-right: 1rem !important;\n }\n .px-lg-4 {\n padding-left: 1.5rem !important;\n padding-right: 1.5rem !important;\n }\n .px-lg-5 {\n padding-left: 3rem !important;\n padding-right: 3rem !important;\n }\n .py-lg-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-lg-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-lg-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-lg-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-lg-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-lg-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-lg-0 {\n padding-top: 0 !important;\n }\n .pt-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pt-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pt-lg-3 {\n padding-top: 1rem !important;\n }\n .pt-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pt-lg-5 {\n padding-top: 3rem !important;\n }\n .pe-lg-0 {\n padding-left: 0 !important;\n }\n .pe-lg-1 {\n padding-left: 0.25rem !important;\n }\n .pe-lg-2 {\n padding-left: 0.5rem !important;\n }\n .pe-lg-3 {\n padding-left: 1rem !important;\n }\n .pe-lg-4 {\n padding-left: 1.5rem !important;\n }\n .pe-lg-5 {\n padding-left: 3rem !important;\n }\n .pb-lg-0 {\n padding-bottom: 0 !important;\n }\n .pb-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pb-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-lg-5 {\n padding-bottom: 3rem !important;\n }\n .ps-lg-0 {\n padding-right: 0 !important;\n }\n .ps-lg-1 {\n padding-right: 0.25rem !important;\n }\n .ps-lg-2 {\n padding-right: 0.5rem !important;\n }\n .ps-lg-3 {\n padding-right: 1rem !important;\n }\n .ps-lg-4 {\n padding-right: 1.5rem !important;\n }\n .ps-lg-5 {\n padding-right: 3rem !important;\n }\n}\n@media (min-width: 1200px) {\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-grid {\n display: grid !important;\n }\n .d-xl-inline-grid {\n display: inline-grid !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n .d-xl-none {\n display: none !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .justify-content-xl-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n .order-xl-first {\n order: -1 !important;\n }\n .order-xl-0 {\n order: 0 !important;\n }\n .order-xl-1 {\n order: 1 !important;\n }\n .order-xl-2 {\n order: 2 !important;\n }\n .order-xl-3 {\n order: 3 !important;\n }\n .order-xl-4 {\n order: 4 !important;\n }\n .order-xl-5 {\n order: 5 !important;\n }\n .order-xl-last {\n order: 6 !important;\n }\n .m-xl-0 {\n margin: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mx-xl-0 {\n margin-left: 0 !important;\n margin-right: 0 !important;\n }\n .mx-xl-1 {\n margin-left: 0.25rem !important;\n margin-right: 0.25rem !important;\n }\n .mx-xl-2 {\n margin-left: 0.5rem !important;\n margin-right: 0.5rem !important;\n }\n .mx-xl-3 {\n margin-left: 1rem !important;\n margin-right: 1rem !important;\n }\n .mx-xl-4 {\n margin-left: 1.5rem !important;\n margin-right: 1.5rem !important;\n }\n .mx-xl-5 {\n margin-left: 3rem !important;\n margin-right: 3rem !important;\n }\n .mx-xl-auto {\n margin-left: auto !important;\n margin-right: auto !important;\n }\n .my-xl-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-xl-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-xl-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-xl-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-xl-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-xl-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-xl-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-xl-0 {\n margin-top: 0 !important;\n }\n .mt-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mt-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mt-xl-3 {\n margin-top: 1rem !important;\n }\n .mt-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mt-xl-5 {\n margin-top: 3rem !important;\n }\n .mt-xl-auto {\n margin-top: auto !important;\n }\n .me-xl-0 {\n margin-left: 0 !important;\n }\n .me-xl-1 {\n margin-left: 0.25rem !important;\n }\n .me-xl-2 {\n margin-left: 0.5rem !important;\n }\n .me-xl-3 {\n margin-left: 1rem !important;\n }\n .me-xl-4 {\n margin-left: 1.5rem !important;\n }\n .me-xl-5 {\n margin-left: 3rem !important;\n }\n .me-xl-auto {\n margin-left: auto !important;\n }\n .mb-xl-0 {\n margin-bottom: 0 !important;\n }\n .mb-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-xl-3 {\n margin-bottom: 1rem !important;\n }\n .mb-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-xl-5 {\n margin-bottom: 3rem !important;\n }\n .mb-xl-auto {\n margin-bottom: auto !important;\n }\n .ms-xl-0 {\n margin-right: 0 !important;\n }\n .ms-xl-1 {\n margin-right: 0.25rem !important;\n }\n .ms-xl-2 {\n margin-right: 0.5rem !important;\n }\n .ms-xl-3 {\n margin-right: 1rem !important;\n }\n .ms-xl-4 {\n margin-right: 1.5rem !important;\n }\n .ms-xl-5 {\n margin-right: 3rem !important;\n }\n .ms-xl-auto {\n margin-right: auto !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .px-xl-0 {\n padding-left: 0 !important;\n padding-right: 0 !important;\n }\n .px-xl-1 {\n padding-left: 0.25rem !important;\n padding-right: 0.25rem !important;\n }\n .px-xl-2 {\n padding-left: 0.5rem !important;\n padding-right: 0.5rem !important;\n }\n .px-xl-3 {\n padding-left: 1rem !important;\n padding-right: 1rem !important;\n }\n .px-xl-4 {\n padding-left: 1.5rem !important;\n padding-right: 1.5rem !important;\n }\n .px-xl-5 {\n padding-left: 3rem !important;\n padding-right: 3rem !important;\n }\n .py-xl-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-xl-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-xl-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-xl-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-xl-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-xl-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-xl-0 {\n padding-top: 0 !important;\n }\n .pt-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pt-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pt-xl-3 {\n padding-top: 1rem !important;\n }\n .pt-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pt-xl-5 {\n padding-top: 3rem !important;\n }\n .pe-xl-0 {\n padding-left: 0 !important;\n }\n .pe-xl-1 {\n padding-left: 0.25rem !important;\n }\n .pe-xl-2 {\n padding-left: 0.5rem !important;\n }\n .pe-xl-3 {\n padding-left: 1rem !important;\n }\n .pe-xl-4 {\n padding-left: 1.5rem !important;\n }\n .pe-xl-5 {\n padding-left: 3rem !important;\n }\n .pb-xl-0 {\n padding-bottom: 0 !important;\n }\n .pb-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pb-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-xl-5 {\n padding-bottom: 3rem !important;\n }\n .ps-xl-0 {\n padding-right: 0 !important;\n }\n .ps-xl-1 {\n padding-right: 0.25rem !important;\n }\n .ps-xl-2 {\n padding-right: 0.5rem !important;\n }\n .ps-xl-3 {\n padding-right: 1rem !important;\n }\n .ps-xl-4 {\n padding-right: 1.5rem !important;\n }\n .ps-xl-5 {\n padding-right: 3rem !important;\n }\n}\n@media (min-width: 1400px) {\n .d-xxl-inline {\n display: inline !important;\n }\n .d-xxl-inline-block {\n display: inline-block !important;\n }\n .d-xxl-block {\n display: block !important;\n }\n .d-xxl-grid {\n display: grid !important;\n }\n .d-xxl-inline-grid {\n display: inline-grid !important;\n }\n .d-xxl-table {\n display: table !important;\n }\n .d-xxl-table-row {\n display: table-row !important;\n }\n .d-xxl-table-cell {\n display: table-cell !important;\n }\n .d-xxl-flex {\n display: flex !important;\n }\n .d-xxl-inline-flex {\n display: inline-flex !important;\n }\n .d-xxl-none {\n display: none !important;\n }\n .flex-xxl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xxl-row {\n flex-direction: row !important;\n }\n .flex-xxl-column {\n flex-direction: column !important;\n }\n .flex-xxl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xxl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xxl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xxl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xxl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xxl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-xxl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xxl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xxl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xxl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xxl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xxl-center {\n justify-content: center !important;\n }\n .justify-content-xxl-between {\n justify-content: space-between !important;\n }\n .justify-content-xxl-around {\n justify-content: space-around !important;\n }\n .justify-content-xxl-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-xxl-start {\n align-items: flex-start !important;\n }\n .align-items-xxl-end {\n align-items: flex-end !important;\n }\n .align-items-xxl-center {\n align-items: center !important;\n }\n .align-items-xxl-baseline {\n align-items: baseline !important;\n }\n .align-items-xxl-stretch {\n align-items: stretch !important;\n }\n .align-content-xxl-start {\n align-content: flex-start !important;\n }\n .align-content-xxl-end {\n align-content: flex-end !important;\n }\n .align-content-xxl-center {\n align-content: center !important;\n }\n .align-content-xxl-between {\n align-content: space-between !important;\n }\n .align-content-xxl-around {\n align-content: space-around !important;\n }\n .align-content-xxl-stretch {\n align-content: stretch !important;\n }\n .align-self-xxl-auto {\n align-self: auto !important;\n }\n .align-self-xxl-start {\n align-self: flex-start !important;\n }\n .align-self-xxl-end {\n align-self: flex-end !important;\n }\n .align-self-xxl-center {\n align-self: center !important;\n }\n .align-self-xxl-baseline {\n align-self: baseline !important;\n }\n .align-self-xxl-stretch {\n align-self: stretch !important;\n }\n .order-xxl-first {\n order: -1 !important;\n }\n .order-xxl-0 {\n order: 0 !important;\n }\n .order-xxl-1 {\n order: 1 !important;\n }\n .order-xxl-2 {\n order: 2 !important;\n }\n .order-xxl-3 {\n order: 3 !important;\n }\n .order-xxl-4 {\n order: 4 !important;\n }\n .order-xxl-5 {\n order: 5 !important;\n }\n .order-xxl-last {\n order: 6 !important;\n }\n .m-xxl-0 {\n margin: 0 !important;\n }\n .m-xxl-1 {\n margin: 0.25rem !important;\n }\n .m-xxl-2 {\n margin: 0.5rem !important;\n }\n .m-xxl-3 {\n margin: 1rem !important;\n }\n .m-xxl-4 {\n margin: 1.5rem !important;\n }\n .m-xxl-5 {\n margin: 3rem !important;\n }\n .m-xxl-auto {\n margin: auto !important;\n }\n .mx-xxl-0 {\n margin-left: 0 !important;\n margin-right: 0 !important;\n }\n .mx-xxl-1 {\n margin-left: 0.25rem !important;\n margin-right: 0.25rem !important;\n }\n .mx-xxl-2 {\n margin-left: 0.5rem !important;\n margin-right: 0.5rem !important;\n }\n .mx-xxl-3 {\n margin-left: 1rem !important;\n margin-right: 1rem !important;\n }\n .mx-xxl-4 {\n margin-left: 1.5rem !important;\n margin-right: 1.5rem !important;\n }\n .mx-xxl-5 {\n margin-left: 3rem !important;\n margin-right: 3rem !important;\n }\n .mx-xxl-auto {\n margin-left: auto !important;\n margin-right: auto !important;\n }\n .my-xxl-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-xxl-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-xxl-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-xxl-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-xxl-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-xxl-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-xxl-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-xxl-0 {\n margin-top: 0 !important;\n }\n .mt-xxl-1 {\n margin-top: 0.25rem !important;\n }\n .mt-xxl-2 {\n margin-top: 0.5rem !important;\n }\n .mt-xxl-3 {\n margin-top: 1rem !important;\n }\n .mt-xxl-4 {\n margin-top: 1.5rem !important;\n }\n .mt-xxl-5 {\n margin-top: 3rem !important;\n }\n .mt-xxl-auto {\n margin-top: auto !important;\n }\n .me-xxl-0 {\n margin-left: 0 !important;\n }\n .me-xxl-1 {\n margin-left: 0.25rem !important;\n }\n .me-xxl-2 {\n margin-left: 0.5rem !important;\n }\n .me-xxl-3 {\n margin-left: 1rem !important;\n }\n .me-xxl-4 {\n margin-left: 1.5rem !important;\n }\n .me-xxl-5 {\n margin-left: 3rem !important;\n }\n .me-xxl-auto {\n margin-left: auto !important;\n }\n .mb-xxl-0 {\n margin-bottom: 0 !important;\n }\n .mb-xxl-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-xxl-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-xxl-3 {\n margin-bottom: 1rem !important;\n }\n .mb-xxl-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-xxl-5 {\n margin-bottom: 3rem !important;\n }\n .mb-xxl-auto {\n margin-bottom: auto !important;\n }\n .ms-xxl-0 {\n margin-right: 0 !important;\n }\n .ms-xxl-1 {\n margin-right: 0.25rem !important;\n }\n .ms-xxl-2 {\n margin-right: 0.5rem !important;\n }\n .ms-xxl-3 {\n margin-right: 1rem !important;\n }\n .ms-xxl-4 {\n margin-right: 1.5rem !important;\n }\n .ms-xxl-5 {\n margin-right: 3rem !important;\n }\n .ms-xxl-auto {\n margin-right: auto !important;\n }\n .p-xxl-0 {\n padding: 0 !important;\n }\n .p-xxl-1 {\n padding: 0.25rem !important;\n }\n .p-xxl-2 {\n padding: 0.5rem !important;\n }\n .p-xxl-3 {\n padding: 1rem !important;\n }\n .p-xxl-4 {\n padding: 1.5rem !important;\n }\n .p-xxl-5 {\n padding: 3rem !important;\n }\n .px-xxl-0 {\n padding-left: 0 !important;\n padding-right: 0 !important;\n }\n .px-xxl-1 {\n padding-left: 0.25rem !important;\n padding-right: 0.25rem !important;\n }\n .px-xxl-2 {\n padding-left: 0.5rem !important;\n padding-right: 0.5rem !important;\n }\n .px-xxl-3 {\n padding-left: 1rem !important;\n padding-right: 1rem !important;\n }\n .px-xxl-4 {\n padding-left: 1.5rem !important;\n padding-right: 1.5rem !important;\n }\n .px-xxl-5 {\n padding-left: 3rem !important;\n padding-right: 3rem !important;\n }\n .py-xxl-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-xxl-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-xxl-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-xxl-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-xxl-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-xxl-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-xxl-0 {\n padding-top: 0 !important;\n }\n .pt-xxl-1 {\n padding-top: 0.25rem !important;\n }\n .pt-xxl-2 {\n padding-top: 0.5rem !important;\n }\n .pt-xxl-3 {\n padding-top: 1rem !important;\n }\n .pt-xxl-4 {\n padding-top: 1.5rem !important;\n }\n .pt-xxl-5 {\n padding-top: 3rem !important;\n }\n .pe-xxl-0 {\n padding-left: 0 !important;\n }\n .pe-xxl-1 {\n padding-left: 0.25rem !important;\n }\n .pe-xxl-2 {\n padding-left: 0.5rem !important;\n }\n .pe-xxl-3 {\n padding-left: 1rem !important;\n }\n .pe-xxl-4 {\n padding-left: 1.5rem !important;\n }\n .pe-xxl-5 {\n padding-left: 3rem !important;\n }\n .pb-xxl-0 {\n padding-bottom: 0 !important;\n }\n .pb-xxl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-xxl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-xxl-3 {\n padding-bottom: 1rem !important;\n }\n .pb-xxl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-xxl-5 {\n padding-bottom: 3rem !important;\n }\n .ps-xxl-0 {\n padding-right: 0 !important;\n }\n .ps-xxl-1 {\n padding-right: 0.25rem !important;\n }\n .ps-xxl-2 {\n padding-right: 0.5rem !important;\n }\n .ps-xxl-3 {\n padding-right: 1rem !important;\n }\n .ps-xxl-4 {\n padding-right: 1.5rem !important;\n }\n .ps-xxl-5 {\n padding-right: 3rem !important;\n }\n}\n@media print {\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-grid {\n display: grid !important;\n }\n .d-print-inline-grid {\n display: inline-grid !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n .d-print-none {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap-grid.rtl.css.map */","// Container mixins\n\n@mixin make-container($gutter: $container-padding-x) {\n --#{$prefix}gutter-x: #{$gutter};\n --#{$prefix}gutter-y: 0;\n width: 100%;\n padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n margin-right: auto;\n margin-left: auto;\n}\n","// Breakpoint viewport sizes and media queries.\n//\n// Breakpoints are defined as a map of (name: minimum width), order from small to large:\n//\n// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px)\n//\n// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.\n\n// Name of the next breakpoint, or null for the last breakpoint.\n//\n// >> breakpoint-next(sm)\n// md\n// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// md\n// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl xxl))\n// md\n@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {\n $n: index($breakpoint-names, $name);\n @if not $n {\n @error \"breakpoint `#{$name}` not found in `#{$breakpoints}`\";\n }\n @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);\n}\n\n// Minimum breakpoint width. Null for the smallest (first) breakpoint.\n//\n// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// 576px\n@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {\n $min: map-get($breakpoints, $name);\n @return if($min != 0, $min, null);\n}\n\n// Maximum breakpoint width.\n// The maximum value is reduced by 0.02px to work around the limitations of\n// `min-` and `max-` prefixes and viewports with fractional widths.\n// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max\n// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.\n// See https://bugs.webkit.org/show_bug.cgi?id=178261\n//\n// >> breakpoint-max(md, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// 767.98px\n@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {\n $max: map-get($breakpoints, $name);\n @return if($max and $max > 0, $max - .02, null);\n}\n\n// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.\n// Useful for making responsive utilities.\n//\n// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// \"\" (Returns a blank string)\n// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px, xxl: 1400px))\n// \"-sm\"\n@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {\n @return if(breakpoint-min($name, $breakpoints) == null, \"\", \"-#{$name}\");\n}\n\n// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.\n// Makes the @content apply to the given breakpoint and wider.\n@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n @if $min {\n @media (min-width: $min) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media of at most the maximum breakpoint width. No query for the largest breakpoint.\n// Makes the @content apply to the given breakpoint and narrower.\n@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {\n $max: breakpoint-max($name, $breakpoints);\n @if $max {\n @media (max-width: $max) {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Media that spans multiple breakpoint widths.\n// Makes the @content apply between the min and max breakpoints\n@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($lower, $breakpoints);\n $max: breakpoint-max($upper, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($lower, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($upper, $breakpoints) {\n @content;\n }\n }\n}\n\n// Media between the breakpoint's minimum and maximum widths.\n// No minimum for the smallest breakpoint, and no maximum for the largest one.\n// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.\n@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {\n $min: breakpoint-min($name, $breakpoints);\n $next: breakpoint-next($name, $breakpoints);\n $max: breakpoint-max($next, $breakpoints);\n\n @if $min != null and $max != null {\n @media (min-width: $min) and (max-width: $max) {\n @content;\n }\n } @else if $max == null {\n @include media-breakpoint-up($name, $breakpoints) {\n @content;\n }\n } @else if $min == null {\n @include media-breakpoint-down($next, $breakpoints) {\n @content;\n }\n }\n}\n","// Row\n//\n// Rows contain your columns.\n\n:root {\n @each $name, $value in $grid-breakpoints {\n --#{$prefix}breakpoint-#{$name}: #{$value};\n }\n}\n\n@if $enable-grid-classes {\n .row {\n @include make-row();\n\n > * {\n @include make-col-ready();\n }\n }\n}\n\n@if $enable-cssgrid {\n .grid {\n display: grid;\n grid-template-rows: repeat(var(--#{$prefix}rows, 1), 1fr);\n grid-template-columns: repeat(var(--#{$prefix}columns, #{$grid-columns}), 1fr);\n gap: var(--#{$prefix}gap, #{$grid-gutter-width});\n\n @include make-cssgrid();\n }\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n@if $enable-grid-classes {\n @include make-grid-columns();\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n@mixin make-row($gutter: $grid-gutter-width) {\n --#{$prefix}gutter-x: #{$gutter};\n --#{$prefix}gutter-y: 0;\n display: flex;\n flex-wrap: wrap;\n // TODO: Revisit calc order after https://github.com/react-bootstrap/react-bootstrap/issues/6039 is fixed\n margin-top: calc(-1 * var(--#{$prefix}gutter-y)); // stylelint-disable-line function-disallowed-list\n margin-right: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n margin-left: calc(-.5 * var(--#{$prefix}gutter-x)); // stylelint-disable-line function-disallowed-list\n}\n\n@mixin make-col-ready() {\n // Add box sizing if only the grid is loaded\n box-sizing: if(variable-exists(include-column-box-sizing) and $include-column-box-sizing, border-box, null);\n // Prevent columns from becoming too narrow when at smaller grid tiers by\n // always setting `width: 100%;`. This works because we set the width\n // later on to override this initial width.\n flex-shrink: 0;\n width: 100%;\n max-width: 100%; // Prevent `.col-auto`, `.col` (& responsive variants) from breaking out the grid\n padding-right: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n padding-left: calc(var(--#{$prefix}gutter-x) * .5); // stylelint-disable-line function-disallowed-list\n margin-top: var(--#{$prefix}gutter-y);\n}\n\n@mixin make-col($size: false, $columns: $grid-columns) {\n @if $size {\n flex: 0 0 auto;\n width: percentage(divide($size, $columns));\n\n } @else {\n flex: 1 1 0;\n max-width: 100%;\n }\n}\n\n@mixin make-col-auto() {\n flex: 0 0 auto;\n width: auto;\n}\n\n@mixin make-col-offset($size, $columns: $grid-columns) {\n $num: divide($size, $columns);\n margin-left: if($num == 0, 0, percentage($num));\n}\n\n// Row columns\n//\n// Specify on a parent element(e.g., .row) to force immediate children into NN\n// number of columns. Supports wrapping to new lines, but does not do a Masonry\n// style grid.\n@mixin row-cols($count) {\n > * {\n flex: 0 0 auto;\n width: percentage(divide(1, $count));\n }\n}\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `$grid-columns`.\n\n@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n // Provide basic `.col-{bp}` classes for equal-width flexbox columns\n .col#{$infix} {\n flex: 1 0 0%; // Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4\n }\n\n .row-cols#{$infix}-auto > * {\n @include make-col-auto();\n }\n\n @if $grid-row-columns > 0 {\n @for $i from 1 through $grid-row-columns {\n .row-cols#{$infix}-#{$i} {\n @include row-cols($i);\n }\n }\n }\n\n .col#{$infix}-auto {\n @include make-col-auto();\n }\n\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .col#{$infix}-#{$i} {\n @include make-col($i, $columns);\n }\n }\n\n // `$columns - 1` because offsetting by the width of an entire row isn't possible\n @for $i from 0 through ($columns - 1) {\n @if not ($infix == \"\" and $i == 0) { // Avoid emitting useless .offset-0\n .offset#{$infix}-#{$i} {\n @include make-col-offset($i, $columns);\n }\n }\n }\n }\n\n // Gutters\n //\n // Make use of `.g-*`, `.gx-*` or `.gy-*` utilities to change spacing between the columns.\n @each $key, $value in $gutters {\n .g#{$infix}-#{$key},\n .gx#{$infix}-#{$key} {\n --#{$prefix}gutter-x: #{$value};\n }\n\n .g#{$infix}-#{$key},\n .gy#{$infix}-#{$key} {\n --#{$prefix}gutter-y: #{$value};\n }\n }\n }\n }\n}\n\n@mixin make-cssgrid($columns: $grid-columns, $breakpoints: $grid-breakpoints) {\n @each $breakpoint in map-keys($breakpoints) {\n $infix: breakpoint-infix($breakpoint, $breakpoints);\n\n @include media-breakpoint-up($breakpoint, $breakpoints) {\n @if $columns > 0 {\n @for $i from 1 through $columns {\n .g-col#{$infix}-#{$i} {\n grid-column: auto / span $i;\n }\n }\n\n // Start with `1` because `0` is an invalid value.\n // Ends with `$columns - 1` because offsetting by the width of an entire row isn't possible.\n @for $i from 1 through ($columns - 1) {\n .g-start#{$infix}-#{$i} {\n grid-column-start: $i;\n }\n }\n }\n }\n }\n}\n","// Utility generator\n// Used to generate utilities & print utilities\n@mixin generate-utility($utility, $infix: \"\", $is-rfs-media-query: false) {\n $values: map-get($utility, values);\n\n // If the values are a list or string, convert it into a map\n @if type-of($values) == \"string\" or type-of(nth($values, 1)) != \"list\" {\n $values: zip($values, $values);\n }\n\n @each $key, $value in $values {\n $properties: map-get($utility, property);\n\n // Multiple properties are possible, for example with vertical or horizontal margins or paddings\n @if type-of($properties) == \"string\" {\n $properties: append((), $properties);\n }\n\n // Use custom class if present\n $property-class: if(map-has-key($utility, class), map-get($utility, class), nth($properties, 1));\n $property-class: if($property-class == null, \"\", $property-class);\n\n // Use custom CSS variable name if present, otherwise default to `class`\n $css-variable-name: if(map-has-key($utility, css-variable-name), map-get($utility, css-variable-name), map-get($utility, class));\n\n // State params to generate pseudo-classes\n $state: if(map-has-key($utility, state), map-get($utility, state), ());\n\n $infix: if($property-class == \"\" and str-slice($infix, 1, 1) == \"-\", str-slice($infix, 2), $infix);\n\n // Don't prefix if value key is null (e.g. with shadow class)\n $property-class-modifier: if($key, if($property-class == \"\" and $infix == \"\", \"\", \"-\") + $key, \"\");\n\n @if map-get($utility, rfs) {\n // Inside the media query\n @if $is-rfs-media-query {\n $val: rfs-value($value);\n\n // Do not render anything if fluid and non fluid values are the same\n $value: if($val == rfs-fluid-value($value), null, $val);\n }\n @else {\n $value: rfs-fluid-value($value);\n }\n }\n\n $is-css-var: map-get($utility, css-var);\n $is-local-vars: map-get($utility, local-vars);\n $is-rtl: map-get($utility, rtl);\n\n @if $value != null {\n @if $is-rtl == false {\n /* rtl:begin:remove */\n }\n\n @if $is-css-var {\n .#{$property-class + $infix + $property-class-modifier} {\n --#{$prefix}#{$css-variable-name}: #{$value};\n }\n\n @each $pseudo in $state {\n .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n --#{$prefix}#{$css-variable-name}: #{$value};\n }\n }\n } @else {\n .#{$property-class + $infix + $property-class-modifier} {\n @each $property in $properties {\n @if $is-local-vars {\n @each $local-var, $variable in $is-local-vars {\n --#{$prefix}#{$local-var}: #{$variable};\n }\n }\n #{$property}: $value if($enable-important-utilities, !important, null);\n }\n }\n\n @each $pseudo in $state {\n .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {\n @each $property in $properties {\n @if $is-local-vars {\n @each $local-var, $variable in $is-local-vars {\n --#{$prefix}#{$local-var}: #{$variable};\n }\n }\n #{$property}: $value if($enable-important-utilities, !important, null);\n }\n }\n }\n }\n\n @if $is-rtl == false {\n /* rtl:end:remove */\n }\n }\n }\n}\n","// Loop over each breakpoint\n@each $breakpoint in map-keys($grid-breakpoints) {\n\n // Generate media query if needed\n @include media-breakpoint-up($breakpoint) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n // Loop over each utility property\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Only proceed if responsive media queries are enabled or if it's the base media query\n @if type-of($utility) == \"map\" and (map-get($utility, responsive) or $infix == \"\") {\n @include generate-utility($utility, $infix);\n }\n }\n }\n}\n\n// RFS rescaling\n@media (min-width: $rfs-mq-value) {\n @each $breakpoint in map-keys($grid-breakpoints) {\n $infix: breakpoint-infix($breakpoint, $grid-breakpoints);\n\n @if (map-get($grid-breakpoints, $breakpoint) < $rfs-breakpoint) {\n // Loop over each utility property\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Only proceed if responsive media queries are enabled or if it's the base media query\n @if type-of($utility) == \"map\" and map-get($utility, rfs) and (map-get($utility, responsive) or $infix == \"\") {\n @include generate-utility($utility, $infix, true);\n }\n }\n }\n }\n}\n\n\n// Print utilities\n@media print {\n @each $key, $utility in $utilities {\n // The utility can be disabled with `false`, thus check if the utility is a map first\n // Then check if the utility needs print styles\n @if type-of($utility) == \"map\" and map-get($utility, print) == true {\n @include generate-utility($utility, \"-print\");\n }\n }\n}\n"]} \ No newline at end of file diff --git a/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css b/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css new file mode 100644 index 0000000..6305410 --- /dev/null +++ b/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css @@ -0,0 +1,597 @@ +/*! + * Bootstrap Reboot v5.3.3 (https://getbootstrap.com/) + * Copyright 2011-2024 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +:root, +[data-bs-theme=light] { + --bs-blue: #0d6efd; + --bs-indigo: #6610f2; + --bs-purple: #6f42c1; + --bs-pink: #d63384; + --bs-red: #dc3545; + --bs-orange: #fd7e14; + --bs-yellow: #ffc107; + --bs-green: #198754; + --bs-teal: #20c997; + --bs-cyan: #0dcaf0; + --bs-black: #000; + --bs-white: #fff; + --bs-gray: #6c757d; + --bs-gray-dark: #343a40; + --bs-gray-100: #f8f9fa; + --bs-gray-200: #e9ecef; + --bs-gray-300: #dee2e6; + --bs-gray-400: #ced4da; + --bs-gray-500: #adb5bd; + --bs-gray-600: #6c757d; + --bs-gray-700: #495057; + --bs-gray-800: #343a40; + --bs-gray-900: #212529; + --bs-primary: #0d6efd; + --bs-secondary: #6c757d; + --bs-success: #198754; + --bs-info: #0dcaf0; + --bs-warning: #ffc107; + --bs-danger: #dc3545; + --bs-light: #f8f9fa; + --bs-dark: #212529; + --bs-primary-rgb: 13, 110, 253; + --bs-secondary-rgb: 108, 117, 125; + --bs-success-rgb: 25, 135, 84; + --bs-info-rgb: 13, 202, 240; + --bs-warning-rgb: 255, 193, 7; + --bs-danger-rgb: 220, 53, 69; + --bs-light-rgb: 248, 249, 250; + --bs-dark-rgb: 33, 37, 41; + --bs-primary-text-emphasis: #052c65; + --bs-secondary-text-emphasis: #2b2f32; + --bs-success-text-emphasis: #0a3622; + --bs-info-text-emphasis: #055160; + --bs-warning-text-emphasis: #664d03; + --bs-danger-text-emphasis: #58151c; + --bs-light-text-emphasis: #495057; + --bs-dark-text-emphasis: #495057; + --bs-primary-bg-subtle: #cfe2ff; + --bs-secondary-bg-subtle: #e2e3e5; + --bs-success-bg-subtle: #d1e7dd; + --bs-info-bg-subtle: #cff4fc; + --bs-warning-bg-subtle: #fff3cd; + --bs-danger-bg-subtle: #f8d7da; + --bs-light-bg-subtle: #fcfcfd; + --bs-dark-bg-subtle: #ced4da; + --bs-primary-border-subtle: #9ec5fe; + --bs-secondary-border-subtle: #c4c8cb; + --bs-success-border-subtle: #a3cfbb; + --bs-info-border-subtle: #9eeaf9; + --bs-warning-border-subtle: #ffe69c; + --bs-danger-border-subtle: #f1aeb5; + --bs-light-border-subtle: #e9ecef; + --bs-dark-border-subtle: #adb5bd; + --bs-white-rgb: 255, 255, 255; + --bs-black-rgb: 0, 0, 0; + --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0)); + --bs-body-font-family: var(--bs-font-sans-serif); + --bs-body-font-size: 1rem; + --bs-body-font-weight: 400; + --bs-body-line-height: 1.5; + --bs-body-color: #212529; + --bs-body-color-rgb: 33, 37, 41; + --bs-body-bg: #fff; + --bs-body-bg-rgb: 255, 255, 255; + --bs-emphasis-color: #000; + --bs-emphasis-color-rgb: 0, 0, 0; + --bs-secondary-color: rgba(33, 37, 41, 0.75); + --bs-secondary-color-rgb: 33, 37, 41; + --bs-secondary-bg: #e9ecef; + --bs-secondary-bg-rgb: 233, 236, 239; + --bs-tertiary-color: rgba(33, 37, 41, 0.5); + --bs-tertiary-color-rgb: 33, 37, 41; + --bs-tertiary-bg: #f8f9fa; + --bs-tertiary-bg-rgb: 248, 249, 250; + --bs-heading-color: inherit; + --bs-link-color: #0d6efd; + --bs-link-color-rgb: 13, 110, 253; + --bs-link-decoration: underline; + --bs-link-hover-color: #0a58ca; + --bs-link-hover-color-rgb: 10, 88, 202; + --bs-code-color: #d63384; + --bs-highlight-color: #212529; + --bs-highlight-bg: #fff3cd; + --bs-border-width: 1px; + --bs-border-style: solid; + --bs-border-color: #dee2e6; + --bs-border-color-translucent: rgba(0, 0, 0, 0.175); + --bs-border-radius: 0.375rem; + --bs-border-radius-sm: 0.25rem; + --bs-border-radius-lg: 0.5rem; + --bs-border-radius-xl: 1rem; + --bs-border-radius-xxl: 2rem; + --bs-border-radius-2xl: var(--bs-border-radius-xxl); + --bs-border-radius-pill: 50rem; + --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); + --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); + --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175); + --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075); + --bs-focus-ring-width: 0.25rem; + --bs-focus-ring-opacity: 0.25; + --bs-focus-ring-color: rgba(13, 110, 253, 0.25); + --bs-form-valid-color: #198754; + --bs-form-valid-border-color: #198754; + --bs-form-invalid-color: #dc3545; + --bs-form-invalid-border-color: #dc3545; +} + +[data-bs-theme=dark] { + color-scheme: dark; + --bs-body-color: #dee2e6; + --bs-body-color-rgb: 222, 226, 230; + --bs-body-bg: #212529; + --bs-body-bg-rgb: 33, 37, 41; + --bs-emphasis-color: #fff; + --bs-emphasis-color-rgb: 255, 255, 255; + --bs-secondary-color: rgba(222, 226, 230, 0.75); + --bs-secondary-color-rgb: 222, 226, 230; + --bs-secondary-bg: #343a40; + --bs-secondary-bg-rgb: 52, 58, 64; + --bs-tertiary-color: rgba(222, 226, 230, 0.5); + --bs-tertiary-color-rgb: 222, 226, 230; + --bs-tertiary-bg: #2b3035; + --bs-tertiary-bg-rgb: 43, 48, 53; + --bs-primary-text-emphasis: #6ea8fe; + --bs-secondary-text-emphasis: #a7acb1; + --bs-success-text-emphasis: #75b798; + --bs-info-text-emphasis: #6edff6; + --bs-warning-text-emphasis: #ffda6a; + --bs-danger-text-emphasis: #ea868f; + --bs-light-text-emphasis: #f8f9fa; + --bs-dark-text-emphasis: #dee2e6; + --bs-primary-bg-subtle: #031633; + --bs-secondary-bg-subtle: #161719; + --bs-success-bg-subtle: #051b11; + --bs-info-bg-subtle: #032830; + --bs-warning-bg-subtle: #332701; + --bs-danger-bg-subtle: #2c0b0e; + --bs-light-bg-subtle: #343a40; + --bs-dark-bg-subtle: #1a1d20; + --bs-primary-border-subtle: #084298; + --bs-secondary-border-subtle: #41464b; + --bs-success-border-subtle: #0f5132; + --bs-info-border-subtle: #087990; + --bs-warning-border-subtle: #997404; + --bs-danger-border-subtle: #842029; + --bs-light-border-subtle: #495057; + --bs-dark-border-subtle: #343a40; + --bs-heading-color: inherit; + --bs-link-color: #6ea8fe; + --bs-link-hover-color: #8bb9fe; + --bs-link-color-rgb: 110, 168, 254; + --bs-link-hover-color-rgb: 139, 185, 254; + --bs-code-color: #e685b5; + --bs-highlight-color: #dee2e6; + --bs-highlight-bg: #664d03; + --bs-border-color: #495057; + --bs-border-color-translucent: rgba(255, 255, 255, 0.15); + --bs-form-valid-color: #75b798; + --bs-form-valid-border-color: #75b798; + --bs-form-invalid-color: #ea868f; + --bs-form-invalid-border-color: #ea868f; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +@media (prefers-reduced-motion: no-preference) { + :root { + scroll-behavior: smooth; + } +} + +body { + margin: 0; + font-family: var(--bs-body-font-family); + font-size: var(--bs-body-font-size); + font-weight: var(--bs-body-font-weight); + line-height: var(--bs-body-line-height); + color: var(--bs-body-color); + text-align: var(--bs-body-text-align); + background-color: var(--bs-body-bg); + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} + +hr { + margin: 1rem 0; + color: inherit; + border: 0; + border-top: var(--bs-border-width) solid; + opacity: 0.25; +} + +h6, h5, h4, h3, h2, h1 { + margin-top: 0; + margin-bottom: 0.5rem; + font-weight: 500; + line-height: 1.2; + color: var(--bs-heading-color); +} + +h1 { + font-size: calc(1.375rem + 1.5vw); +} +@media (min-width: 1200px) { + h1 { + font-size: 2.5rem; + } +} + +h2 { + font-size: calc(1.325rem + 0.9vw); +} +@media (min-width: 1200px) { + h2 { + font-size: 2rem; + } +} + +h3 { + font-size: calc(1.3rem + 0.6vw); +} +@media (min-width: 1200px) { + h3 { + font-size: 1.75rem; + } +} + +h4 { + font-size: calc(1.275rem + 0.3vw); +} +@media (min-width: 1200px) { + h4 { + font-size: 1.5rem; + } +} + +h5 { + font-size: 1.25rem; +} + +h6 { + font-size: 1rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +abbr[title] { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + -webkit-text-decoration-skip-ink: none; + text-decoration-skip-ink: none; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul { + padding-left: 2rem; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: 700; +} + +dd { + margin-bottom: 0.5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +b, +strong { + font-weight: bolder; +} + +small { + font-size: 0.875em; +} + +mark { + padding: 0.1875em; + color: var(--bs-highlight-color); + background-color: var(--bs-highlight-bg); +} + +sub, +sup { + position: relative; + font-size: 0.75em; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +a { + color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1)); + text-decoration: underline; +} +a:hover { + --bs-link-color-rgb: var(--bs-link-hover-color-rgb); +} + +a:not([href]):not([class]), a:not([href]):not([class]):hover { + color: inherit; + text-decoration: none; +} + +pre, +code, +kbd, +samp { + font-family: var(--bs-font-monospace); + font-size: 1em; +} + +pre { + display: block; + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + font-size: 0.875em; +} +pre code { + font-size: inherit; + color: inherit; + word-break: normal; +} + +code { + font-size: 0.875em; + color: var(--bs-code-color); + word-wrap: break-word; +} +a > code { + color: inherit; +} + +kbd { + padding: 0.1875rem 0.375rem; + font-size: 0.875em; + color: var(--bs-body-bg); + background-color: var(--bs-body-color); + border-radius: 0.25rem; +} +kbd kbd { + padding: 0; + font-size: 1em; +} + +figure { + margin: 0 0 1rem; +} + +img, +svg { + vertical-align: middle; +} + +table { + caption-side: bottom; + border-collapse: collapse; +} + +caption { + padding-top: 0.5rem; + padding-bottom: 0.5rem; + color: var(--bs-secondary-color); + text-align: left; +} + +th { + text-align: inherit; + text-align: -webkit-match-parent; +} + +thead, +tbody, +tfoot, +tr, +td, +th { + border-color: inherit; + border-style: solid; + border-width: 0; +} + +label { + display: inline-block; +} + +button { + border-radius: 0; +} + +button:focus:not(:focus-visible) { + outline: 0; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +select { + text-transform: none; +} + +[role=button] { + cursor: pointer; +} + +select { + word-wrap: normal; +} +select:disabled { + opacity: 1; +} + +[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator { + display: none !important; +} + +button, +[type=button], +[type=reset], +[type=submit] { + -webkit-appearance: button; +} +button:not(:disabled), +[type=button]:not(:disabled), +[type=reset]:not(:disabled), +[type=submit]:not(:disabled) { + cursor: pointer; +} + +::-moz-focus-inner { + padding: 0; + border-style: none; +} + +textarea { + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + float: left; + width: 100%; + padding: 0; + margin-bottom: 0.5rem; + font-size: calc(1.275rem + 0.3vw); + line-height: inherit; +} +@media (min-width: 1200px) { + legend { + font-size: 1.5rem; + } +} +legend + * { + clear: left; +} + +::-webkit-datetime-edit-fields-wrapper, +::-webkit-datetime-edit-text, +::-webkit-datetime-edit-minute, +::-webkit-datetime-edit-hour-field, +::-webkit-datetime-edit-day-field, +::-webkit-datetime-edit-month-field, +::-webkit-datetime-edit-year-field { + padding: 0; +} + +::-webkit-inner-spin-button { + height: auto; +} + +[type=search] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +/* rtl:raw: +[type="tel"], +[type="url"], +[type="email"], +[type="number"] { + direction: ltr; +} +*/ +::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-color-swatch-wrapper { + padding: 0; +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button; +} + +::file-selector-button { + font: inherit; + -webkit-appearance: button; +} + +output { + display: inline-block; +} + +iframe { + border: 0; +} + +summary { + display: list-item; + cursor: pointer; +} + +progress { + vertical-align: baseline; +} + +[hidden] { + display: none !important; +} + +/*# sourceMappingURL=bootstrap-reboot.css.map */ \ No newline at end of file diff --git a/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map b/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map new file mode 100644 index 0000000..5fe522b --- /dev/null +++ b/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/mixins/_banner.scss","../../scss/_root.scss","../../scss/vendor/_rfs.scss","bootstrap-reboot.css","../../scss/mixins/_color-mode.scss","../../scss/_reboot.scss","../../scss/_variables.scss","../../scss/mixins/_border-radius.scss"],"names":[],"mappings":"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","file":"bootstrap-reboot.css","sourcesContent":["@mixin bsBanner($file) {\n /*!\n * Bootstrap #{$file} v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n}\n",":root,\n[data-bs-theme=\"light\"] {\n // Note: Custom variable values only support SassScript inside `#{}`.\n\n // Colors\n //\n // Generate palettes for full colors, grays, and theme colors.\n\n @each $color, $value in $colors {\n --#{$prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $grays {\n --#{$prefix}gray-#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors-rgb {\n --#{$prefix}#{$color}-rgb: #{$value};\n }\n\n @each $color, $value in $theme-colors-text {\n --#{$prefix}#{$color}-text-emphasis: #{$value};\n }\n\n @each $color, $value in $theme-colors-bg-subtle {\n --#{$prefix}#{$color}-bg-subtle: #{$value};\n }\n\n @each $color, $value in $theme-colors-border-subtle {\n --#{$prefix}#{$color}-border-subtle: #{$value};\n }\n\n --#{$prefix}white-rgb: #{to-rgb($white)};\n --#{$prefix}black-rgb: #{to-rgb($black)};\n\n // Fonts\n\n // Note: Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --#{$prefix}font-sans-serif: #{inspect($font-family-sans-serif)};\n --#{$prefix}font-monospace: #{inspect($font-family-monospace)};\n --#{$prefix}gradient: #{$gradient};\n\n // Root and body\n // scss-docs-start root-body-variables\n @if $font-size-root != null {\n --#{$prefix}root-font-size: #{$font-size-root};\n }\n --#{$prefix}body-font-family: #{inspect($font-family-base)};\n @include rfs($font-size-base, --#{$prefix}body-font-size);\n --#{$prefix}body-font-weight: #{$font-weight-base};\n --#{$prefix}body-line-height: #{$line-height-base};\n @if $body-text-align != null {\n --#{$prefix}body-text-align: #{$body-text-align};\n }\n\n --#{$prefix}body-color: #{$body-color};\n --#{$prefix}body-color-rgb: #{to-rgb($body-color)};\n --#{$prefix}body-bg: #{$body-bg};\n --#{$prefix}body-bg-rgb: #{to-rgb($body-bg)};\n\n --#{$prefix}emphasis-color: #{$body-emphasis-color};\n --#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color)};\n\n --#{$prefix}secondary-color: #{$body-secondary-color};\n --#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color)};\n --#{$prefix}secondary-bg: #{$body-secondary-bg};\n --#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg)};\n\n --#{$prefix}tertiary-color: #{$body-tertiary-color};\n --#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color)};\n --#{$prefix}tertiary-bg: #{$body-tertiary-bg};\n --#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg)};\n // scss-docs-end root-body-variables\n\n --#{$prefix}heading-color: #{$headings-color};\n\n --#{$prefix}link-color: #{$link-color};\n --#{$prefix}link-color-rgb: #{to-rgb($link-color)};\n --#{$prefix}link-decoration: #{$link-decoration};\n\n --#{$prefix}link-hover-color: #{$link-hover-color};\n --#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color)};\n\n @if $link-hover-decoration != null {\n --#{$prefix}link-hover-decoration: #{$link-hover-decoration};\n }\n\n --#{$prefix}code-color: #{$code-color};\n --#{$prefix}highlight-color: #{$mark-color};\n --#{$prefix}highlight-bg: #{$mark-bg};\n\n // scss-docs-start root-border-var\n --#{$prefix}border-width: #{$border-width};\n --#{$prefix}border-style: #{$border-style};\n --#{$prefix}border-color: #{$border-color};\n --#{$prefix}border-color-translucent: #{$border-color-translucent};\n\n --#{$prefix}border-radius: #{$border-radius};\n --#{$prefix}border-radius-sm: #{$border-radius-sm};\n --#{$prefix}border-radius-lg: #{$border-radius-lg};\n --#{$prefix}border-radius-xl: #{$border-radius-xl};\n --#{$prefix}border-radius-xxl: #{$border-radius-xxl};\n --#{$prefix}border-radius-2xl: var(--#{$prefix}border-radius-xxl); // Deprecated in v5.3.0 for consistency\n --#{$prefix}border-radius-pill: #{$border-radius-pill};\n // scss-docs-end root-border-var\n\n --#{$prefix}box-shadow: #{$box-shadow};\n --#{$prefix}box-shadow-sm: #{$box-shadow-sm};\n --#{$prefix}box-shadow-lg: #{$box-shadow-lg};\n --#{$prefix}box-shadow-inset: #{$box-shadow-inset};\n\n // Focus styles\n // scss-docs-start root-focus-variables\n --#{$prefix}focus-ring-width: #{$focus-ring-width};\n --#{$prefix}focus-ring-opacity: #{$focus-ring-opacity};\n --#{$prefix}focus-ring-color: #{$focus-ring-color};\n // scss-docs-end root-focus-variables\n\n // scss-docs-start root-form-validation-variables\n --#{$prefix}form-valid-color: #{$form-valid-color};\n --#{$prefix}form-valid-border-color: #{$form-valid-border-color};\n --#{$prefix}form-invalid-color: #{$form-invalid-color};\n --#{$prefix}form-invalid-border-color: #{$form-invalid-border-color};\n // scss-docs-end root-form-validation-variables\n}\n\n@if $enable-dark-mode {\n @include color-mode(dark, true) {\n color-scheme: dark;\n\n // scss-docs-start root-dark-mode-vars\n --#{$prefix}body-color: #{$body-color-dark};\n --#{$prefix}body-color-rgb: #{to-rgb($body-color-dark)};\n --#{$prefix}body-bg: #{$body-bg-dark};\n --#{$prefix}body-bg-rgb: #{to-rgb($body-bg-dark)};\n\n --#{$prefix}emphasis-color: #{$body-emphasis-color-dark};\n --#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color-dark)};\n\n --#{$prefix}secondary-color: #{$body-secondary-color-dark};\n --#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color-dark)};\n --#{$prefix}secondary-bg: #{$body-secondary-bg-dark};\n --#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg-dark)};\n\n --#{$prefix}tertiary-color: #{$body-tertiary-color-dark};\n --#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color-dark)};\n --#{$prefix}tertiary-bg: #{$body-tertiary-bg-dark};\n --#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg-dark)};\n\n @each $color, $value in $theme-colors-text-dark {\n --#{$prefix}#{$color}-text-emphasis: #{$value};\n }\n\n @each $color, $value in $theme-colors-bg-subtle-dark {\n --#{$prefix}#{$color}-bg-subtle: #{$value};\n }\n\n @each $color, $value in $theme-colors-border-subtle-dark {\n --#{$prefix}#{$color}-border-subtle: #{$value};\n }\n\n --#{$prefix}heading-color: #{$headings-color-dark};\n\n --#{$prefix}link-color: #{$link-color-dark};\n --#{$prefix}link-hover-color: #{$link-hover-color-dark};\n --#{$prefix}link-color-rgb: #{to-rgb($link-color-dark)};\n --#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color-dark)};\n\n --#{$prefix}code-color: #{$code-color-dark};\n --#{$prefix}highlight-color: #{$mark-color-dark};\n --#{$prefix}highlight-bg: #{$mark-bg-dark};\n\n --#{$prefix}border-color: #{$border-color-dark};\n --#{$prefix}border-color-translucent: #{$border-color-translucent-dark};\n\n --#{$prefix}form-valid-color: #{$form-valid-color-dark};\n --#{$prefix}form-valid-border-color: #{$form-valid-border-color-dark};\n --#{$prefix}form-invalid-color: #{$form-invalid-color-dark};\n --#{$prefix}form-invalid-border-color: #{$form-invalid-border-color-dark};\n // scss-docs-end root-dark-mode-vars\n }\n}\n","// stylelint-disable scss/dimension-no-non-numeric-values\n\n// SCSS RFS mixin\n//\n// Automated responsive values for font sizes, paddings, margins and much more\n//\n// Licensed under MIT (https://github.com/twbs/rfs/blob/main/LICENSE)\n\n// Configuration\n\n// Base value\n$rfs-base-value: 1.25rem !default;\n$rfs-unit: rem !default;\n\n@if $rfs-unit != rem and $rfs-unit != px {\n @error \"`#{$rfs-unit}` is not a valid unit for $rfs-unit. Use `px` or `rem`.\";\n}\n\n// Breakpoint at where values start decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n@if $rfs-breakpoint-unit != px and $rfs-breakpoint-unit != em and $rfs-breakpoint-unit != rem {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n}\n\n// Resize values based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != number or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Mode. Possibilities: \"min-media-query\", \"max-media-query\"\n$rfs-mode: min-media-query !default;\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-rfs to false\n$enable-rfs: true !default;\n\n// Cache $rfs-base-value unit\n$rfs-base-value-unit: unit($rfs-base-value);\n\n@function divide($dividend, $divisor, $precision: 10) {\n $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);\n $dividend: abs($dividend);\n $divisor: abs($divisor);\n @if $dividend == 0 {\n @return 0;\n }\n @if $divisor == 0 {\n @error \"Cannot divide by 0\";\n }\n $remainder: $dividend;\n $result: 0;\n $factor: 10;\n @while ($remainder > 0 and $precision >= 0) {\n $quotient: 0;\n @while ($remainder >= $divisor) {\n $remainder: $remainder - $divisor;\n $quotient: $quotient + 1;\n }\n $result: $result * 10 + $quotient;\n $factor: $factor * .1;\n $remainder: $remainder * 10;\n $precision: $precision - 1;\n @if ($precision < 0 and $remainder >= $divisor * 5) {\n $result: $result + 1;\n }\n }\n $result: $result * $factor * $sign;\n $dividend-unit: unit($dividend);\n $divisor-unit: unit($divisor);\n $unit-map: (\n \"px\": 1px,\n \"rem\": 1rem,\n \"em\": 1em,\n \"%\": 1%\n );\n @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {\n $result: $result * map-get($unit-map, $dividend-unit);\n }\n @return $result;\n}\n\n// Remove px-unit from $rfs-base-value for calculations\n@if $rfs-base-value-unit == px {\n $rfs-base-value: divide($rfs-base-value, $rfs-base-value * 0 + 1);\n}\n@else if $rfs-base-value-unit == rem {\n $rfs-base-value: divide($rfs-base-value, divide($rfs-base-value * 0 + 1, $rfs-rem-value));\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == px {\n $rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value));\n}\n\n// Calculate the media query value\n$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit});\n$rfs-mq-property-width: if($rfs-mode == max-media-query, max-width, min-width);\n$rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height);\n\n// Internal mixin used to determine which media query needs to be used\n@mixin _rfs-media-query {\n @if $rfs-two-dimensional {\n @if $rfs-mode == max-media-query {\n @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}), (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n @content;\n }\n }\n @else {\n @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) and (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n @content;\n }\n }\n }\n @else {\n @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) {\n @content;\n }\n }\n}\n\n// Internal mixin that adds disable classes to the selector if needed.\n@mixin _rfs-rule {\n @if $rfs-class == disable and $rfs-mode == max-media-query {\n // Adding an extra class increases specificity, which prevents the media query to override the property\n &,\n .disable-rfs &,\n &.disable-rfs {\n @content;\n }\n }\n @else if $rfs-class == enable and $rfs-mode == min-media-query {\n .enable-rfs &,\n &.enable-rfs {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Internal mixin that adds enable classes to the selector if needed.\n@mixin _rfs-media-query-rule {\n\n @if $rfs-class == enable {\n @if $rfs-mode == min-media-query {\n @content;\n }\n\n @include _rfs-media-query () {\n .enable-rfs &,\n &.enable-rfs {\n @content;\n }\n }\n }\n @else {\n @if $rfs-class == disable and $rfs-mode == min-media-query {\n .disable-rfs &,\n &.disable-rfs {\n @content;\n }\n }\n @include _rfs-media-query () {\n @content;\n }\n }\n}\n\n// Helper function to get the formatted non-responsive value\n@function rfs-value($values) {\n // Convert to list\n $values: if(type-of($values) != list, ($values,), $values);\n\n $val: \"\";\n\n // Loop over each value and calculate value\n @each $value in $values {\n @if $value == 0 {\n $val: $val + \" 0\";\n }\n @else {\n // Cache $value unit\n $unit: if(type-of($value) == \"number\", unit($value), false);\n\n @if $unit == px {\n // Convert to rem if needed\n $val: $val + \" \" + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value);\n }\n @else if $unit == rem {\n // Convert to px if needed\n $val: $val + \" \" + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value);\n } @else {\n // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n $val: $val + \" \" + $value;\n }\n }\n }\n\n // Remove first space\n @return unquote(str-slice($val, 2));\n}\n\n// Helper function to get the responsive value calculated by RFS\n@function rfs-fluid-value($values) {\n // Convert to list\n $values: if(type-of($values) != list, ($values,), $values);\n\n $val: \"\";\n\n // Loop over each value and calculate value\n @each $value in $values {\n @if $value == 0 {\n $val: $val + \" 0\";\n } @else {\n // Cache $value unit\n $unit: if(type-of($value) == \"number\", unit($value), false);\n\n // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $unit or $unit != px and $unit != rem {\n $val: $val + \" \" + $value;\n } @else {\n // Remove unit from $value for calculations\n $value: divide($value, $value * 0 + if($unit == px, 1, divide(1, $rfs-rem-value)));\n\n // Only add the media query if the value is greater than the minimum value\n @if abs($value) <= $rfs-base-value or not $enable-rfs {\n $val: $val + \" \" + if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px);\n }\n @else {\n // Calculate the minimum value\n $value-min: $rfs-base-value + divide(abs($value) - $rfs-base-value, $rfs-factor);\n\n // Calculate difference between $value and the minimum value\n $value-diff: abs($value) - $value-min;\n\n // Base value formatting\n $min-width: if($rfs-unit == rem, #{divide($value-min, $rfs-rem-value)}rem, #{$value-min}px);\n\n // Use negative value if needed\n $min-width: if($value < 0, -$min-width, $min-width);\n\n // Use `vmin` if two-dimensional is enabled\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{divide($value-diff * 100, $rfs-breakpoint)}#{$variable-unit};\n\n // Return the calculated value\n $val: $val + \" calc(\" + $min-width + if($value < 0, \" - \", \" + \") + $variable-width + \")\";\n }\n }\n }\n }\n\n // Remove first space\n @return unquote(str-slice($val, 2));\n}\n\n// RFS mixin\n@mixin rfs($values, $property: font-size) {\n @if $values != null {\n $val: rfs-value($values);\n $fluid-val: rfs-fluid-value($values);\n\n // Do not print the media query if responsive & non-responsive values are the same\n @if $val == $fluid-val {\n #{$property}: $val;\n }\n @else {\n @include _rfs-rule () {\n #{$property}: if($rfs-mode == max-media-query, $val, $fluid-val);\n\n // Include safari iframe resize fix if needed\n min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null);\n }\n\n @include _rfs-media-query-rule () {\n #{$property}: if($rfs-mode == max-media-query, $fluid-val, $val);\n }\n }\n }\n}\n\n// Shorthand helper mixins\n@mixin font-size($value) {\n @include rfs($value);\n}\n\n@mixin padding($value) {\n @include rfs($value, padding);\n}\n\n@mixin padding-top($value) {\n @include rfs($value, padding-top);\n}\n\n@mixin padding-right($value) {\n @include rfs($value, padding-right);\n}\n\n@mixin padding-bottom($value) {\n @include rfs($value, padding-bottom);\n}\n\n@mixin padding-left($value) {\n @include rfs($value, padding-left);\n}\n\n@mixin margin($value) {\n @include rfs($value, margin);\n}\n\n@mixin margin-top($value) {\n @include rfs($value, margin-top);\n}\n\n@mixin margin-right($value) {\n @include rfs($value, margin-right);\n}\n\n@mixin margin-bottom($value) {\n @include rfs($value, margin-bottom);\n}\n\n@mixin margin-left($value) {\n @include rfs($value, margin-left);\n}\n","/*!\n * Bootstrap Reboot v5.3.3 (https://getbootstrap.com/)\n * Copyright 2011-2024 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root,\n[data-bs-theme=light] {\n --bs-blue: #0d6efd;\n --bs-indigo: #6610f2;\n --bs-purple: #6f42c1;\n --bs-pink: #d63384;\n --bs-red: #dc3545;\n --bs-orange: #fd7e14;\n --bs-yellow: #ffc107;\n --bs-green: #198754;\n --bs-teal: #20c997;\n --bs-cyan: #0dcaf0;\n --bs-black: #000;\n --bs-white: #fff;\n --bs-gray: #6c757d;\n --bs-gray-dark: #343a40;\n --bs-gray-100: #f8f9fa;\n --bs-gray-200: #e9ecef;\n --bs-gray-300: #dee2e6;\n --bs-gray-400: #ced4da;\n --bs-gray-500: #adb5bd;\n --bs-gray-600: #6c757d;\n --bs-gray-700: #495057;\n --bs-gray-800: #343a40;\n --bs-gray-900: #212529;\n --bs-primary: #0d6efd;\n --bs-secondary: #6c757d;\n --bs-success: #198754;\n --bs-info: #0dcaf0;\n --bs-warning: #ffc107;\n --bs-danger: #dc3545;\n --bs-light: #f8f9fa;\n --bs-dark: #212529;\n --bs-primary-rgb: 13, 110, 253;\n --bs-secondary-rgb: 108, 117, 125;\n --bs-success-rgb: 25, 135, 84;\n --bs-info-rgb: 13, 202, 240;\n --bs-warning-rgb: 255, 193, 7;\n --bs-danger-rgb: 220, 53, 69;\n --bs-light-rgb: 248, 249, 250;\n --bs-dark-rgb: 33, 37, 41;\n --bs-primary-text-emphasis: #052c65;\n --bs-secondary-text-emphasis: #2b2f32;\n --bs-success-text-emphasis: #0a3622;\n --bs-info-text-emphasis: #055160;\n --bs-warning-text-emphasis: #664d03;\n --bs-danger-text-emphasis: #58151c;\n --bs-light-text-emphasis: #495057;\n --bs-dark-text-emphasis: #495057;\n --bs-primary-bg-subtle: #cfe2ff;\n --bs-secondary-bg-subtle: #e2e3e5;\n --bs-success-bg-subtle: #d1e7dd;\n --bs-info-bg-subtle: #cff4fc;\n --bs-warning-bg-subtle: #fff3cd;\n --bs-danger-bg-subtle: #f8d7da;\n --bs-light-bg-subtle: #fcfcfd;\n --bs-dark-bg-subtle: #ced4da;\n --bs-primary-border-subtle: #9ec5fe;\n --bs-secondary-border-subtle: #c4c8cb;\n --bs-success-border-subtle: #a3cfbb;\n --bs-info-border-subtle: #9eeaf9;\n --bs-warning-border-subtle: #ffe69c;\n --bs-danger-border-subtle: #f1aeb5;\n --bs-light-border-subtle: #e9ecef;\n --bs-dark-border-subtle: #adb5bd;\n --bs-white-rgb: 255, 255, 255;\n --bs-black-rgb: 0, 0, 0;\n --bs-font-sans-serif: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", \"Liberation Sans\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));\n --bs-body-font-family: var(--bs-font-sans-serif);\n --bs-body-font-size: 1rem;\n --bs-body-font-weight: 400;\n --bs-body-line-height: 1.5;\n --bs-body-color: #212529;\n --bs-body-color-rgb: 33, 37, 41;\n --bs-body-bg: #fff;\n --bs-body-bg-rgb: 255, 255, 255;\n --bs-emphasis-color: #000;\n --bs-emphasis-color-rgb: 0, 0, 0;\n --bs-secondary-color: rgba(33, 37, 41, 0.75);\n --bs-secondary-color-rgb: 33, 37, 41;\n --bs-secondary-bg: #e9ecef;\n --bs-secondary-bg-rgb: 233, 236, 239;\n --bs-tertiary-color: rgba(33, 37, 41, 0.5);\n --bs-tertiary-color-rgb: 33, 37, 41;\n --bs-tertiary-bg: #f8f9fa;\n --bs-tertiary-bg-rgb: 248, 249, 250;\n --bs-heading-color: inherit;\n --bs-link-color: #0d6efd;\n --bs-link-color-rgb: 13, 110, 253;\n --bs-link-decoration: underline;\n --bs-link-hover-color: #0a58ca;\n --bs-link-hover-color-rgb: 10, 88, 202;\n --bs-code-color: #d63384;\n --bs-highlight-color: #212529;\n --bs-highlight-bg: #fff3cd;\n --bs-border-width: 1px;\n --bs-border-style: solid;\n --bs-border-color: #dee2e6;\n --bs-border-color-translucent: rgba(0, 0, 0, 0.175);\n --bs-border-radius: 0.375rem;\n --bs-border-radius-sm: 0.25rem;\n --bs-border-radius-lg: 0.5rem;\n --bs-border-radius-xl: 1rem;\n --bs-border-radius-xxl: 2rem;\n --bs-border-radius-2xl: var(--bs-border-radius-xxl);\n --bs-border-radius-pill: 50rem;\n --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);\n --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);\n --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);\n --bs-focus-ring-width: 0.25rem;\n --bs-focus-ring-opacity: 0.25;\n --bs-focus-ring-color: rgba(13, 110, 253, 0.25);\n --bs-form-valid-color: #198754;\n --bs-form-valid-border-color: #198754;\n --bs-form-invalid-color: #dc3545;\n --bs-form-invalid-border-color: #dc3545;\n}\n\n[data-bs-theme=dark] {\n color-scheme: dark;\n --bs-body-color: #dee2e6;\n --bs-body-color-rgb: 222, 226, 230;\n --bs-body-bg: #212529;\n --bs-body-bg-rgb: 33, 37, 41;\n --bs-emphasis-color: #fff;\n --bs-emphasis-color-rgb: 255, 255, 255;\n --bs-secondary-color: rgba(222, 226, 230, 0.75);\n --bs-secondary-color-rgb: 222, 226, 230;\n --bs-secondary-bg: #343a40;\n --bs-secondary-bg-rgb: 52, 58, 64;\n --bs-tertiary-color: rgba(222, 226, 230, 0.5);\n --bs-tertiary-color-rgb: 222, 226, 230;\n --bs-tertiary-bg: #2b3035;\n --bs-tertiary-bg-rgb: 43, 48, 53;\n --bs-primary-text-emphasis: #6ea8fe;\n --bs-secondary-text-emphasis: #a7acb1;\n --bs-success-text-emphasis: #75b798;\n --bs-info-text-emphasis: #6edff6;\n --bs-warning-text-emphasis: #ffda6a;\n --bs-danger-text-emphasis: #ea868f;\n --bs-light-text-emphasis: #f8f9fa;\n --bs-dark-text-emphasis: #dee2e6;\n --bs-primary-bg-subtle: #031633;\n --bs-secondary-bg-subtle: #161719;\n --bs-success-bg-subtle: #051b11;\n --bs-info-bg-subtle: #032830;\n --bs-warning-bg-subtle: #332701;\n --bs-danger-bg-subtle: #2c0b0e;\n --bs-light-bg-subtle: #343a40;\n --bs-dark-bg-subtle: #1a1d20;\n --bs-primary-border-subtle: #084298;\n --bs-secondary-border-subtle: #41464b;\n --bs-success-border-subtle: #0f5132;\n --bs-info-border-subtle: #087990;\n --bs-warning-border-subtle: #997404;\n --bs-danger-border-subtle: #842029;\n --bs-light-border-subtle: #495057;\n --bs-dark-border-subtle: #343a40;\n --bs-heading-color: inherit;\n --bs-link-color: #6ea8fe;\n --bs-link-hover-color: #8bb9fe;\n --bs-link-color-rgb: 110, 168, 254;\n --bs-link-hover-color-rgb: 139, 185, 254;\n --bs-code-color: #e685b5;\n --bs-highlight-color: #dee2e6;\n --bs-highlight-bg: #664d03;\n --bs-border-color: #495057;\n --bs-border-color-translucent: rgba(255, 255, 255, 0.15);\n --bs-form-valid-color: #75b798;\n --bs-form-valid-border-color: #75b798;\n --bs-form-invalid-color: #ea868f;\n --bs-form-invalid-border-color: #ea868f;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n :root {\n scroll-behavior: smooth;\n }\n}\n\nbody {\n margin: 0;\n font-family: var(--bs-body-font-family);\n font-size: var(--bs-body-font-size);\n font-weight: var(--bs-body-font-weight);\n line-height: var(--bs-body-line-height);\n color: var(--bs-body-color);\n text-align: var(--bs-body-text-align);\n background-color: var(--bs-body-bg);\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nhr {\n margin: 1rem 0;\n color: inherit;\n border: 0;\n border-top: var(--bs-border-width) solid;\n opacity: 0.25;\n}\n\nh6, h5, h4, h3, h2, h1 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n font-weight: 500;\n line-height: 1.2;\n color: var(--bs-heading-color);\n}\n\nh1 {\n font-size: calc(1.375rem + 1.5vw);\n}\n@media (min-width: 1200px) {\n h1 {\n font-size: 2.5rem;\n }\n}\n\nh2 {\n font-size: calc(1.325rem + 0.9vw);\n}\n@media (min-width: 1200px) {\n h2 {\n font-size: 2rem;\n }\n}\n\nh3 {\n font-size: calc(1.3rem + 0.6vw);\n}\n@media (min-width: 1200px) {\n h3 {\n font-size: 1.75rem;\n }\n}\n\nh4 {\n font-size: calc(1.275rem + 0.3vw);\n}\n@media (min-width: 1200px) {\n h4 {\n font-size: 1.5rem;\n }\n}\n\nh5 {\n font-size: 1.25rem;\n}\n\nh6 {\n font-size: 1rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title] {\n text-decoration: underline dotted;\n cursor: help;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul {\n padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: 0.5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 0.875em;\n}\n\nmark {\n padding: 0.1875em;\n color: var(--bs-highlight-color);\n background-color: var(--bs-highlight-bg);\n}\n\nsub,\nsup {\n position: relative;\n font-size: 0.75em;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\na {\n color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));\n text-decoration: underline;\n}\na:hover {\n --bs-link-color-rgb: var(--bs-link-hover-color-rgb);\n}\n\na:not([href]):not([class]), a:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: var(--bs-font-monospace);\n font-size: 1em;\n}\n\npre {\n display: block;\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n font-size: 0.875em;\n}\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\ncode {\n font-size: 0.875em;\n color: var(--bs-code-color);\n word-wrap: break-word;\n}\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.1875rem 0.375rem;\n font-size: 0.875em;\n color: var(--bs-body-bg);\n background-color: var(--bs-body-color);\n border-radius: 0.25rem;\n}\nkbd kbd {\n padding: 0;\n font-size: 1em;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg,\nsvg {\n vertical-align: middle;\n}\n\ntable {\n caption-side: bottom;\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n color: var(--bs-secondary-color);\n text-align: left;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n}\n\nlabel {\n display: inline-block;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=button] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\nselect:disabled {\n opacity: 1;\n}\n\n[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {\n display: none !important;\n}\n\nbutton,\n[type=button],\n[type=reset],\n[type=submit] {\n -webkit-appearance: button;\n}\nbutton:not(:disabled),\n[type=button]:not(:disabled),\n[type=reset]:not(:disabled),\n[type=submit]:not(:disabled) {\n cursor: pointer;\n}\n\n::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ntextarea {\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n float: left;\n width: 100%;\n padding: 0;\n margin-bottom: 0.5rem;\n font-size: calc(1.275rem + 0.3vw);\n line-height: inherit;\n}\n@media (min-width: 1200px) {\n legend {\n font-size: 1.5rem;\n }\n}\nlegend + * {\n clear: left;\n}\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n padding: 0;\n}\n\n::-webkit-inner-spin-button {\n height: auto;\n}\n\n[type=search] {\n -webkit-appearance: textfield;\n outline-offset: -2px;\n}\n\n/* rtl:raw:\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n direction: ltr;\n}\n*/\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-color-swatch-wrapper {\n padding: 0;\n}\n\n::file-selector-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\niframe {\n border: 0;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */\n","// scss-docs-start color-mode-mixin\n@mixin color-mode($mode: light, $root: false) {\n @if $color-mode-type == \"media-query\" {\n @if $root == true {\n @media (prefers-color-scheme: $mode) {\n :root {\n @content;\n }\n }\n } @else {\n @media (prefers-color-scheme: $mode) {\n @content;\n }\n }\n } @else {\n [data-bs-theme=\"#{$mode}\"] {\n @content;\n }\n }\n}\n// scss-docs-end color-mode-mixin\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n\n// Root\n//\n// Ability to the value of the root font sizes, affecting the value of `rem`.\n// null by default, thus nothing is generated.\n\n:root {\n @if $font-size-root != null {\n @include font-size(var(--#{$prefix}root-font-size));\n }\n\n @if $enable-smooth-scroll {\n @media (prefers-reduced-motion: no-preference) {\n scroll-behavior: smooth;\n }\n }\n}\n\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Prevent adjustments of font size after orientation changes in iOS.\n// 4. Change the default tap highlight to be completely transparent in iOS.\n\n// scss-docs-start reboot-body-rules\nbody {\n margin: 0; // 1\n font-family: var(--#{$prefix}body-font-family);\n @include font-size(var(--#{$prefix}body-font-size));\n font-weight: var(--#{$prefix}body-font-weight);\n line-height: var(--#{$prefix}body-line-height);\n color: var(--#{$prefix}body-color);\n text-align: var(--#{$prefix}body-text-align);\n background-color: var(--#{$prefix}body-bg); // 2\n -webkit-text-size-adjust: 100%; // 3\n -webkit-tap-highlight-color: rgba($black, 0); // 4\n}\n// scss-docs-end reboot-body-rules\n\n\n// Content grouping\n//\n// 1. Reset Firefox's gray color\n\nhr {\n margin: $hr-margin-y 0;\n color: $hr-color; // 1\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n opacity: $hr-opacity;\n}\n\n\n// Typography\n//\n// 1. Remove top margins from headings\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n\n%heading {\n margin-top: 0; // 1\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-style: $headings-font-style;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: var(--#{$prefix}heading-color);\n}\n\nh1 {\n @extend %heading;\n @include font-size($h1-font-size);\n}\n\nh2 {\n @extend %heading;\n @include font-size($h2-font-size);\n}\n\nh3 {\n @extend %heading;\n @include font-size($h3-font-size);\n}\n\nh4 {\n @extend %heading;\n @include font-size($h4-font-size);\n}\n\nh5 {\n @extend %heading;\n @include font-size($h5-font-size);\n}\n\nh6 {\n @extend %heading;\n @include font-size($h6-font-size);\n}\n\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\n\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n\n// Abbreviations\n//\n// 1. Add the correct text decoration in Chrome, Edge, Opera, and Safari.\n// 2. Add explicit cursor to indicate changed behavior.\n// 3. Prevent the text-decoration to be skipped.\n\nabbr[title] {\n text-decoration: underline dotted; // 1\n cursor: help; // 2\n text-decoration-skip-ink: none; // 3\n}\n\n\n// Address\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\n\n// Lists\n\nol,\nul {\n padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\n// 1. Undo browser default\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // 1\n}\n\n\n// Blockquote\n\nblockquote {\n margin: 0 0 1rem;\n}\n\n\n// Strong\n//\n// Add the correct font weight in Chrome, Edge, and Safari\n\nb,\nstrong {\n font-weight: $font-weight-bolder;\n}\n\n\n// Small\n//\n// Add the correct font size in all browsers\n\nsmall {\n @include font-size($small-font-size);\n}\n\n\n// Mark\n\nmark {\n padding: $mark-padding;\n color: var(--#{$prefix}highlight-color);\n background-color: var(--#{$prefix}highlight-bg);\n}\n\n\n// Sub and Sup\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n\nsub,\nsup {\n position: relative;\n @include font-size($sub-sup-font-size);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n// Links\n\na {\n color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, 1));\n text-decoration: $link-decoration;\n\n &:hover {\n --#{$prefix}link-color-rgb: var(--#{$prefix}link-hover-color-rgb);\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n &,\n &:hover {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n// Code\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-code;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\n// 1. Remove browser default top margin\n// 2. Reset browser default of `1em` to use `rem`s\n// 3. Don't allow content to break outside\n\npre {\n display: block;\n margin-top: 0; // 1\n margin-bottom: 1rem; // 2\n overflow: auto; // 3\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\ncode {\n @include font-size($code-font-size);\n color: var(--#{$prefix}code-color);\n word-wrap: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n\n kbd {\n padding: 0;\n @include font-size(1em);\n font-weight: $nested-kbd-font-weight;\n }\n}\n\n\n// Figures\n//\n// Apply a consistent margin strategy (matches our type styles).\n\nfigure {\n margin: 0 0 1rem;\n}\n\n\n// Images and content\n\nimg,\nsvg {\n vertical-align: middle;\n}\n\n\n// Tables\n//\n// Prevent double borders\n\ntable {\n caption-side: bottom;\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: $table-cell-padding-y;\n padding-bottom: $table-cell-padding-y;\n color: $table-caption-color;\n text-align: left;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n}\n\n\n// Forms\n//\n// 1. Allow labels to use `margin` for spacing.\n\nlabel {\n display: inline-block; // 1\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n// See https://github.com/twbs/bootstrap/issues/24093\n\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\n// 1. Remove the margin in Firefox and Safari\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // 1\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\n// Remove the inheritance of text transform in Firefox\nbutton,\nselect {\n text-transform: none;\n}\n// Set the cursor for non-`