From 5f7be3e5bfe2f316521fdc8e180a7b6b4da5daa4 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 26 Jan 2022 14:38:18 +0100 Subject: [PATCH] Nuovo progetto CORE x API + UI --- GPW.Api.sln | 31 - GPW.CORE.Api/.config/dotnet-tools.json | 5 + .../Controllers/CheckProjController.cs | 82 + GPW.CORE.Api/Controllers/VC19Controller.cs | 130 + GPW.CORE.Api/Data/ApiDataService.cs | 314 + GPW.CORE.Api/GPW.CORE.Api.csproj | 28 + GPW.CORE.Api/NLog.config | 46 + GPW.CORE.Api/Program.cs | 63 + GPW.CORE.Api/Properties/launchSettings.json | 31 + GPW.CORE.Api/VC19Check.cs | 17 + GPW.CORE.Api/appsettings.Development.json | 8 + GPW.CORE.Api/appsettings.json | 43 + GPW.CORE.Api/logs/.placeholder.txt | 1 + GPW.CORE.Data/Controllers/GPWController.cs | 818 + GPW.CORE.Data/DCCDecode.cs | 58 + GPW.CORE.Data/DTO/DailyDataDTO.cs | 71 + GPW.CORE.Data/DTO/PeriodoDTO.cs | 40 + GPW.CORE.Data/DTO/WeekStatDTO.cs | 23 + GPW.CORE.Data/DbModels/AnagClientiModel.cs | 42 + GPW.CORE.Data/DbModels/AnagFasiModel.cs | 53 + GPW.CORE.Data/DbModels/AnagGruppiModel.cs | 27 + GPW.CORE.Data/DbModels/AnagKeyValueModel.cs | 19 + GPW.CORE.Data/DbModels/AnagOrariModel.cs | 44 + GPW.CORE.Data/DbModels/AnagProgettiModel.cs | 41 + GPW.CORE.Data/DbModels/AnagTipoTimbModel.cs | 26 + GPW.CORE.Data/DbModels/CalcOreFasiModel.cs | 51 + .../DbModels/CalcOreProgettiModel.cs | 56 + GPW.CORE.Data/DbModels/CheckVc19Model.cs | 29 + GPW.CORE.Data/DbModels/DipendentiModel.cs | 59 + GPW.CORE.Data/DbModels/ParetoRegAttModel.cs | 24 + .../DbModels/RegAttivitaExplModel.cs | 22 + GPW.CORE.Data/DbModels/RegAttivitaModel.cs | 53 + GPW.CORE.Data/DbModels/RilievoTempModel.cs | 22 + GPW.CORE.Data/DbModels/TimbratureExplModel.cs | 80 + GPW.CORE.Data/DbModels/TimbratureModel.cs | 36 + GPW.CORE.Data/Enum.cs | 32 + GPW.CORE.Data/GPW.CORE.Data.csproj | 23 + GPW.CORE.Data/GPWContext.cs | 744 + GPW.CORE.Data/LiManObj.cs | 220 + GPW.CORE.Data/MailKitEmailSender.cs | 64 + GPW.CORE.Data/MailKitEmailSenderOptions.cs | 36 + GPW.CORE.Data/Utils.cs | 64 + GPW.CORE.Data/WeekData.cs | 98 + GPW.CORE.UI.sln | 37 + GPW.CORE.UI/.config/dotnet-tools.json | 5 + GPW.CORE.UI/App.razor | 14 + GPW.CORE.UI/Components/AddRA.razor | 71 + GPW.CORE.UI/Components/Chart.razor | 62 + GPW.CORE.UI/Components/ChartHist.razor | 82 + GPW.CORE.UI/Components/ChartTS.razor | 90 + GPW.CORE.UI/Components/CmpFooter.razor | 16 + GPW.CORE.UI/Components/DataPager.razor | 56 + GPW.CORE.UI/Components/DataPager.razor.cs | 201 + GPW.CORE.UI/Components/DayAgendaDetail.razor | 35 + GPW.CORE.UI/Components/DayCheckEditor.razor | 121 + .../Components/DayCheckEditor.razor.cs | 129 + GPW.CORE.UI/Components/DayHoriz.razor | 71 + GPW.CORE.UI/Components/DayHoriz.razor.cs | 429 + GPW.CORE.UI/Components/FasiSearch.razor | 71 + GPW.CORE.UI/Components/FasiSearch.razor.cs | 115 + GPW.CORE.UI/Components/LoadingData.razor | 6 + GPW.CORE.UI/Components/LoadingDataSmall.razor | 6 + GPW.CORE.UI/Components/ParetoRA.razor | 143 + GPW.CORE.UI/Components/PeriodoLav.razor | 80 + GPW.CORE.UI/Components/RecFaseStart.razor | 275 + GPW.CORE.UI/Components/RegAtt.razor | 92 + GPW.CORE.UI/Components/RegAtt.razor.cs | 244 + GPW.CORE.UI/Components/RegAttEditor.razor | 140 + GPW.CORE.UI/Components/RegAttEditor.razor.cs | 211 + GPW.CORE.UI/Components/Svg.razor | 45 + GPW.CORE.UI/Components/TimbList.razor | 83 + GPW.CORE.UI/Components/TimbrEditor.razor | 84 + GPW.CORE.UI/Components/TimbrEditor.razor.cs | 187 + GPW.CORE.UI/Components/WeekPlanner.razor | 5 + GPW.CORE.UI/Components/WeekSelector.razor | 72 + GPW.CORE.UI/Components/WeekStat.razor | 164 + GPW.CORE.UI/Data/GpwDataService.cs | 783 + GPW.CORE.UI/Data/LicenseService.cs | 308 + GPW.CORE.UI/Data/MessageService.cs | 210 + GPW.CORE.UI/GPW.CORE.UI.csproj | 39 + GPW.CORE.UI/Pages/Error.cshtml | 42 + GPW.CORE.UI/Pages/Error.cshtml.cs | 27 + GPW.CORE.UI/Pages/FastRec.razor | 189 + GPW.CORE.UI/Pages/ForceReset.razor | 39 + GPW.CORE.UI/Pages/Index.razor | 20 + GPW.CORE.UI/Pages/Planner.razor | 145 + GPW.CORE.UI/Pages/Planner.razor.cs | 498 + GPW.CORE.UI/Pages/Test.razor | 383 + GPW.CORE.UI/Pages/Test.razor.cs | 167 + GPW.CORE.UI/Pages/_Host.cshtml | 10 + GPW.CORE.UI/Pages/_Layout.cshtml | 38 + GPW.CORE.UI/Program.cs | 53 + GPW.CORE.UI/Properties/launchSettings.json | 28 + GPW.CORE.UI/Shared/LoginDisplay.razor | 170 + GPW.CORE.UI/Shared/MainLayout.razor | 23 + GPW.CORE.UI/Shared/MainLayout.razor.css | 77 + GPW.CORE.UI/Shared/NavMenu.razor | 49 + GPW.CORE.UI/Shared/NavMenu.razor.css | 62 + GPW.CORE.UI/_Imports.razor | 11 + GPW.CORE.UI/appsettings.Development.json | 9 + GPW.CORE.UI/appsettings.json | 15 + GPW.CORE.UI/chartJsData.cs | 16 + GPW.CORE.UI/compilerconfig.json | 10 + GPW.CORE.UI/compilerconfig.json.defaults | 61 + GPW.CORE.UI/libman.json | 26 + GPW.CORE.UI/post-build.ps1 | 31 + .../wwwroot/css/bootstrap/bootstrap.min.css | 7 + .../css/bootstrap/bootstrap.min.css.map | 1 + GPW.CORE.UI/wwwroot/css/fonts.css | 30 + GPW.CORE.UI/wwwroot/css/fonts.less | 36 + GPW.CORE.UI/wwwroot/css/fonts.min.css | 1 + .../wwwroot/css/open-iconic/FONT-LICENSE | 86 + .../wwwroot/css/open-iconic/ICON-LICENSE | 21 + GPW.CORE.UI/wwwroot/css/open-iconic/README.md | 114 + .../font/css/open-iconic-bootstrap.min.css | 1 + .../open-iconic/font/fonts/open-iconic.eot | Bin 0 -> 28196 bytes .../open-iconic/font/fonts/open-iconic.otf | Bin 0 -> 20996 bytes .../open-iconic/font/fonts/open-iconic.svg | 543 + .../open-iconic/font/fonts/open-iconic.ttf | Bin 0 -> 28028 bytes .../open-iconic/font/fonts/open-iconic.woff | Bin 0 -> 14984 bytes GPW.CORE.UI/wwwroot/css/site.css | 282 + GPW.CORE.UI/wwwroot/css/site.less | 301 + GPW.CORE.UI/wwwroot/css/site.min.css | 1 + GPW.CORE.UI/wwwroot/favicon.ico | Bin 0 -> 31702 bytes .../wwwroot/fonts/lato-v17-latin-regular.eot | Bin 0 -> 26668 bytes .../wwwroot/fonts/lato-v17-latin-regular.svg | 435 + .../wwwroot/fonts/lato-v17-latin-regular.ttf | Bin 0 -> 60524 bytes .../wwwroot/fonts/lato-v17-latin-regular.woff | Bin 0 -> 28660 bytes .../fonts/lato-v17-latin-regular.woff2 | Bin 0 -> 23484 bytes .../roboto-condensed-v19-latin-regular.eot | Bin 0 -> 17834 bytes .../roboto-condensed-v19-latin-regular.svg | 306 + .../roboto-condensed-v19-latin-regular.ttf | Bin 0 -> 36144 bytes .../roboto-condensed-v19-latin-regular.woff | Bin 0 -> 20156 bytes .../roboto-condensed-v19-latin-regular.woff2 | Bin 0 -> 15720 bytes .../fonts/roboto-v27-latin-regular.eot | Bin 0 -> 17822 bytes .../fonts/roboto-v27-latin-regular.svg | 308 + .../fonts/roboto-v27-latin-regular.ttf | Bin 0 -> 36216 bytes .../fonts/roboto-v27-latin-regular.woff | Bin 0 -> 20332 bytes .../fonts/roboto-v27-latin-regular.woff2 | Bin 0 -> 15688 bytes GPW.CORE.UI/wwwroot/images/LogoBlu.svg | 95 + GPW.CORE.UI/wwwroot/images/LogoEgw.png | Bin 0 -> 3051 bytes GPW.CORE.UI/wwwroot/images/LogoEgwWhite.png | Bin 0 -> 3346 bytes GPW.CORE.UI/wwwroot/images/WorkInProgress.jpg | Bin 0 -> 377683 bytes GPW.CORE.UI/wwwroot/lib/Chart.js/chart.esm.js | 10608 +++++++++++++ .../wwwroot/lib/Chart.js/chart.esm.min.js | 1 + GPW.CORE.UI/wwwroot/lib/Chart.js/chart.js | 13250 ++++++++++++++++ GPW.CORE.UI/wwwroot/lib/Chart.js/chart.min.js | 13 + .../wwwroot/lib/Chart.js/helpers.esm.js | 7 + .../wwwroot/lib/Chart.js/helpers.esm.min.js | 1 + .../lib/bootstrap/css/bootstrap-grid.css | 3872 +++++ .../lib/bootstrap/css/bootstrap-grid.css.map | 1 + .../lib/bootstrap/css/bootstrap-grid.min.css | 7 + .../bootstrap/css/bootstrap-grid.min.css.map | 1 + .../lib/bootstrap/css/bootstrap-reboot.css | 325 + .../bootstrap/css/bootstrap-reboot.css.map | 1 + .../bootstrap/css/bootstrap-reboot.min.css | 8 + .../css/bootstrap-reboot.min.css.map | 1 + .../wwwroot/lib/bootstrap/css/bootstrap.css | 10315 ++++++++++++ .../lib/bootstrap/css/bootstrap.css.map | 1 + .../lib/bootstrap/css/bootstrap.min.css | 7 + .../lib/bootstrap/css/bootstrap.min.css.map | 1 + .../lib/bootstrap/js/bootstrap.bundle.js | 6972 ++++++++ .../lib/bootstrap/js/bootstrap.bundle.js.map | 1 + .../lib/bootstrap/js/bootstrap.bundle.min.js | 7 + .../bootstrap/js/bootstrap.bundle.min.js.map | 1 + .../wwwroot/lib/bootstrap/js/bootstrap.js | 4357 +++++ .../wwwroot/lib/bootstrap/js/bootstrap.js.map | 1 + .../wwwroot/lib/bootstrap/js/bootstrap.min.js | 7 + .../lib/bootstrap/js/bootstrap.min.js.map | 1 + .../wwwroot/lib/bootstrap/scss/_alert.scss | 52 + .../wwwroot/lib/bootstrap/scss/_badge.scss | 54 + .../lib/bootstrap/scss/_breadcrumb.scss | 42 + .../lib/bootstrap/scss/_button-group.scss | 163 + .../wwwroot/lib/bootstrap/scss/_buttons.scss | 142 + .../wwwroot/lib/bootstrap/scss/_card.scss | 286 + .../wwwroot/lib/bootstrap/scss/_carousel.scss | 200 + .../wwwroot/lib/bootstrap/scss/_close.scss | 40 + .../wwwroot/lib/bootstrap/scss/_code.scss | 48 + .../lib/bootstrap/scss/_custom-forms.scss | 526 + .../wwwroot/lib/bootstrap/scss/_dropdown.scss | 192 + .../wwwroot/lib/bootstrap/scss/_forms.scss | 347 + .../lib/bootstrap/scss/_functions.scss | 190 + .../wwwroot/lib/bootstrap/scss/_grid.scss | 73 + .../wwwroot/lib/bootstrap/scss/_images.scss | 42 + .../lib/bootstrap/scss/_input-group.scss | 211 + .../lib/bootstrap/scss/_jumbotron.scss | 17 + .../lib/bootstrap/scss/_list-group.scss | 154 + .../wwwroot/lib/bootstrap/scss/_media.scss | 8 + .../wwwroot/lib/bootstrap/scss/_mixins.scss | 47 + .../wwwroot/lib/bootstrap/scss/_modal.scss | 240 + .../wwwroot/lib/bootstrap/scss/_nav.scss | 120 + .../wwwroot/lib/bootstrap/scss/_navbar.scss | 332 + .../lib/bootstrap/scss/_pagination.scss | 74 + .../wwwroot/lib/bootstrap/scss/_popover.scss | 170 + .../wwwroot/lib/bootstrap/scss/_print.scss | 132 + .../wwwroot/lib/bootstrap/scss/_progress.scss | 47 + .../wwwroot/lib/bootstrap/scss/_reboot.scss | 484 + .../wwwroot/lib/bootstrap/scss/_root.scss | 19 + .../wwwroot/lib/bootstrap/scss/_spinners.scss | 65 + .../wwwroot/lib/bootstrap/scss/_tables.scss | 185 + .../wwwroot/lib/bootstrap/scss/_toasts.scss | 46 + .../wwwroot/lib/bootstrap/scss/_tooltip.scss | 115 + .../lib/bootstrap/scss/_transitions.scss | 20 + .../wwwroot/lib/bootstrap/scss/_type.scss | 125 + .../lib/bootstrap/scss/_utilities.scss | 18 + .../lib/bootstrap/scss/_variables.scss | 1148 ++ .../lib/bootstrap/scss/bootstrap-grid.scss | 30 + .../lib/bootstrap/scss/bootstrap-reboot.scss | 12 + .../wwwroot/lib/bootstrap/scss/bootstrap.scss | 44 + .../lib/bootstrap/scss/mixins/_alert.scss | 13 + .../scss/mixins/_background-variant.scss | 23 + .../lib/bootstrap/scss/mixins/_badge.scss | 17 + .../bootstrap/scss/mixins/_border-radius.scss | 76 + .../bootstrap/scss/mixins/_box-shadow.scss | 20 + .../bootstrap/scss/mixins/_breakpoints.scss | 123 + .../lib/bootstrap/scss/mixins/_buttons.scss | 110 + .../lib/bootstrap/scss/mixins/_caret.scss | 62 + .../lib/bootstrap/scss/mixins/_clearfix.scss | 7 + .../lib/bootstrap/scss/mixins/_deprecate.scss | 10 + .../lib/bootstrap/scss/mixins/_float.scss | 14 + .../lib/bootstrap/scss/mixins/_forms.scss | 195 + .../lib/bootstrap/scss/mixins/_gradients.scss | 45 + .../scss/mixins/_grid-framework.scss | 80 + .../lib/bootstrap/scss/mixins/_grid.scss | 69 + .../lib/bootstrap/scss/mixins/_hover.scss | 37 + .../lib/bootstrap/scss/mixins/_image.scss | 36 + .../bootstrap/scss/mixins/_list-group.scss | 21 + .../lib/bootstrap/scss/mixins/_lists.scss | 7 + .../bootstrap/scss/mixins/_nav-divider.scss | 11 + .../bootstrap/scss/mixins/_pagination.scss | 22 + .../bootstrap/scss/mixins/_reset-text.scss | 17 + .../lib/bootstrap/scss/mixins/_resize.scss | 6 + .../bootstrap/scss/mixins/_screen-reader.scss | 34 + .../lib/bootstrap/scss/mixins/_size.scss | 7 + .../lib/bootstrap/scss/mixins/_table-row.scss | 39 + .../bootstrap/scss/mixins/_text-emphasis.scss | 17 + .../lib/bootstrap/scss/mixins/_text-hide.scss | 11 + .../bootstrap/scss/mixins/_text-truncate.scss | 8 + .../bootstrap/scss/mixins/_transition.scss | 26 + .../bootstrap/scss/mixins/_visibility.scss | 8 + .../lib/bootstrap/scss/utilities/_align.scss | 8 + .../bootstrap/scss/utilities/_background.scss | 19 + .../bootstrap/scss/utilities/_borders.scss | 75 + .../bootstrap/scss/utilities/_clearfix.scss | 3 + .../bootstrap/scss/utilities/_display.scss | 26 + .../lib/bootstrap/scss/utilities/_embed.scss | 39 + .../lib/bootstrap/scss/utilities/_flex.scss | 51 + .../lib/bootstrap/scss/utilities/_float.scss | 11 + .../scss/utilities/_interactions.scss | 5 + .../bootstrap/scss/utilities/_overflow.scss | 5 + .../bootstrap/scss/utilities/_position.scss | 32 + .../scss/utilities/_screenreaders.scss | 11 + .../bootstrap/scss/utilities/_shadows.scss | 6 + .../lib/bootstrap/scss/utilities/_sizing.scss | 20 + .../bootstrap/scss/utilities/_spacing.scss | 73 + .../scss/utilities/_stretched-link.scss | 19 + .../lib/bootstrap/scss/utilities/_text.scss | 72 + .../bootstrap/scss/utilities/_visibility.scss | 13 + .../lib/bootstrap/scss/vendor/_rfs.scss | 228 + GPW.CORE.UI/wwwroot/lib/chartBoot.js | 16 + .../chartjs-adapter-luxon.esm.js | 91 + .../chartjs-adapter-luxon.esm.min.js | 1 + .../chartjs-adapter-luxon.js | 96 + .../chartjs-adapter-luxon.min.js | 7 + .../wwwroot/lib/font-awesome/css/all.css | 4616 ++++++ .../wwwroot/lib/font-awesome/css/all.min.css | 5 + .../wwwroot/lib/font-awesome/css/brands.css | 15 + .../lib/font-awesome/css/brands.min.css | 5 + .../lib/font-awesome/css/fontawesome.css | 4582 ++++++ .../lib/font-awesome/css/fontawesome.min.css | 5 + .../wwwroot/lib/font-awesome/css/regular.css | 15 + .../lib/font-awesome/css/regular.min.css | 5 + .../wwwroot/lib/font-awesome/css/solid.css | 16 + .../lib/font-awesome/css/solid.min.css | 5 + .../lib/font-awesome/css/svg-with-js.css | 371 + .../lib/font-awesome/css/svg-with-js.min.css | 5 + .../wwwroot/lib/font-awesome/css/v4-shims.css | 2172 +++ .../lib/font-awesome/css/v4-shims.min.css | 5 + .../wwwroot/lib/font-awesome/js/all.js | 4466 ++++++ .../wwwroot/lib/font-awesome/js/all.min.js | 5 + .../wwwroot/lib/font-awesome/js/brands.js | 585 + .../wwwroot/lib/font-awesome/js/brands.min.js | 5 + .../lib/font-awesome/js/conflict-detection.js | 998 ++ .../font-awesome/js/conflict-detection.min.js | 5 + .../lib/font-awesome/js/fontawesome.js | 2483 +++ .../lib/font-awesome/js/fontawesome.min.js | 5 + .../wwwroot/lib/font-awesome/js/regular.js | 280 + .../lib/font-awesome/js/regular.min.js | 5 + .../wwwroot/lib/font-awesome/js/solid.js | 1130 ++ .../wwwroot/lib/font-awesome/js/solid.min.js | 5 + .../wwwroot/lib/font-awesome/js/v4-shims.js | 68 + .../lib/font-awesome/js/v4-shims.min.js | 5 + .../lib/font-awesome/sprites/brands.svg | 1378 ++ .../lib/font-awesome/sprites/regular.svg | 463 + .../lib/font-awesome/sprites/solid.svg | 3013 ++++ .../font-awesome/webfonts/fa-brands-400.eot | Bin 0 -> 134294 bytes .../font-awesome/webfonts/fa-brands-400.svg | 3717 +++++ .../font-awesome/webfonts/fa-brands-400.ttf | Bin 0 -> 133988 bytes .../font-awesome/webfonts/fa-brands-400.woff | Bin 0 -> 89988 bytes .../font-awesome/webfonts/fa-brands-400.woff2 | Bin 0 -> 76736 bytes .../font-awesome/webfonts/fa-regular-400.eot | Bin 0 -> 34034 bytes .../font-awesome/webfonts/fa-regular-400.svg | 801 + .../font-awesome/webfonts/fa-regular-400.ttf | Bin 0 -> 33736 bytes .../font-awesome/webfonts/fa-regular-400.woff | Bin 0 -> 16276 bytes .../webfonts/fa-regular-400.woff2 | Bin 0 -> 13224 bytes .../font-awesome/webfonts/fa-solid-900.eot | Bin 0 -> 203030 bytes .../font-awesome/webfonts/fa-solid-900.svg | 5034 ++++++ .../font-awesome/webfonts/fa-solid-900.ttf | Bin 0 -> 202744 bytes .../font-awesome/webfonts/fa-solid-900.woff | Bin 0 -> 101648 bytes .../font-awesome/webfonts/fa-solid-900.woff2 | Bin 0 -> 78268 bytes .../wwwroot/lib/luxon/cjs-browser/luxon.js | 8473 ++++++++++ .../lib/luxon/cjs-browser/luxon.js.map | 1 + .../lib/luxon/cjs-browser/luxon.min.js | 1 + GPW.CORE.UI/wwwroot/lib/luxon/luxon.js | 8478 ++++++++++ GPW.CORE.UI/wwwroot/lib/luxon/luxon.js.map | 1 + GPW.CORE.UI/wwwroot/lib/luxon/luxon.min.js | 1 + .../wwwroot/lib/luxon/luxon.min.js.map | 1 + 317 files changed, 124646 insertions(+), 31 deletions(-) delete mode 100644 GPW.Api.sln create mode 100644 GPW.CORE.Api/.config/dotnet-tools.json create mode 100644 GPW.CORE.Api/Controllers/CheckProjController.cs create mode 100644 GPW.CORE.Api/Controllers/VC19Controller.cs create mode 100644 GPW.CORE.Api/Data/ApiDataService.cs create mode 100644 GPW.CORE.Api/GPW.CORE.Api.csproj create mode 100644 GPW.CORE.Api/NLog.config create mode 100644 GPW.CORE.Api/Program.cs create mode 100644 GPW.CORE.Api/Properties/launchSettings.json create mode 100644 GPW.CORE.Api/VC19Check.cs create mode 100644 GPW.CORE.Api/appsettings.Development.json create mode 100644 GPW.CORE.Api/appsettings.json create mode 100644 GPW.CORE.Api/logs/.placeholder.txt create mode 100644 GPW.CORE.Data/Controllers/GPWController.cs create mode 100644 GPW.CORE.Data/DCCDecode.cs create mode 100644 GPW.CORE.Data/DTO/DailyDataDTO.cs create mode 100644 GPW.CORE.Data/DTO/PeriodoDTO.cs create mode 100644 GPW.CORE.Data/DTO/WeekStatDTO.cs create mode 100644 GPW.CORE.Data/DbModels/AnagClientiModel.cs create mode 100644 GPW.CORE.Data/DbModels/AnagFasiModel.cs create mode 100644 GPW.CORE.Data/DbModels/AnagGruppiModel.cs create mode 100644 GPW.CORE.Data/DbModels/AnagKeyValueModel.cs create mode 100644 GPW.CORE.Data/DbModels/AnagOrariModel.cs create mode 100644 GPW.CORE.Data/DbModels/AnagProgettiModel.cs create mode 100644 GPW.CORE.Data/DbModels/AnagTipoTimbModel.cs create mode 100644 GPW.CORE.Data/DbModels/CalcOreFasiModel.cs create mode 100644 GPW.CORE.Data/DbModels/CalcOreProgettiModel.cs create mode 100644 GPW.CORE.Data/DbModels/CheckVc19Model.cs create mode 100644 GPW.CORE.Data/DbModels/DipendentiModel.cs create mode 100644 GPW.CORE.Data/DbModels/ParetoRegAttModel.cs create mode 100644 GPW.CORE.Data/DbModels/RegAttivitaExplModel.cs create mode 100644 GPW.CORE.Data/DbModels/RegAttivitaModel.cs create mode 100644 GPW.CORE.Data/DbModels/RilievoTempModel.cs create mode 100644 GPW.CORE.Data/DbModels/TimbratureExplModel.cs create mode 100644 GPW.CORE.Data/DbModels/TimbratureModel.cs create mode 100644 GPW.CORE.Data/Enum.cs create mode 100644 GPW.CORE.Data/GPW.CORE.Data.csproj create mode 100644 GPW.CORE.Data/GPWContext.cs create mode 100644 GPW.CORE.Data/LiManObj.cs create mode 100644 GPW.CORE.Data/MailKitEmailSender.cs create mode 100644 GPW.CORE.Data/MailKitEmailSenderOptions.cs create mode 100644 GPW.CORE.Data/Utils.cs create mode 100644 GPW.CORE.Data/WeekData.cs create mode 100644 GPW.CORE.UI.sln create mode 100644 GPW.CORE.UI/.config/dotnet-tools.json create mode 100644 GPW.CORE.UI/App.razor create mode 100644 GPW.CORE.UI/Components/AddRA.razor create mode 100644 GPW.CORE.UI/Components/Chart.razor create mode 100644 GPW.CORE.UI/Components/ChartHist.razor create mode 100644 GPW.CORE.UI/Components/ChartTS.razor create mode 100644 GPW.CORE.UI/Components/CmpFooter.razor create mode 100644 GPW.CORE.UI/Components/DataPager.razor create mode 100644 GPW.CORE.UI/Components/DataPager.razor.cs create mode 100644 GPW.CORE.UI/Components/DayAgendaDetail.razor create mode 100644 GPW.CORE.UI/Components/DayCheckEditor.razor create mode 100644 GPW.CORE.UI/Components/DayCheckEditor.razor.cs create mode 100644 GPW.CORE.UI/Components/DayHoriz.razor create mode 100644 GPW.CORE.UI/Components/DayHoriz.razor.cs create mode 100644 GPW.CORE.UI/Components/FasiSearch.razor create mode 100644 GPW.CORE.UI/Components/FasiSearch.razor.cs create mode 100644 GPW.CORE.UI/Components/LoadingData.razor create mode 100644 GPW.CORE.UI/Components/LoadingDataSmall.razor create mode 100644 GPW.CORE.UI/Components/ParetoRA.razor create mode 100644 GPW.CORE.UI/Components/PeriodoLav.razor create mode 100644 GPW.CORE.UI/Components/RecFaseStart.razor create mode 100644 GPW.CORE.UI/Components/RegAtt.razor create mode 100644 GPW.CORE.UI/Components/RegAtt.razor.cs create mode 100644 GPW.CORE.UI/Components/RegAttEditor.razor create mode 100644 GPW.CORE.UI/Components/RegAttEditor.razor.cs create mode 100644 GPW.CORE.UI/Components/Svg.razor create mode 100644 GPW.CORE.UI/Components/TimbList.razor create mode 100644 GPW.CORE.UI/Components/TimbrEditor.razor create mode 100644 GPW.CORE.UI/Components/TimbrEditor.razor.cs create mode 100644 GPW.CORE.UI/Components/WeekPlanner.razor create mode 100644 GPW.CORE.UI/Components/WeekSelector.razor create mode 100644 GPW.CORE.UI/Components/WeekStat.razor create mode 100644 GPW.CORE.UI/Data/GpwDataService.cs create mode 100644 GPW.CORE.UI/Data/LicenseService.cs create mode 100644 GPW.CORE.UI/Data/MessageService.cs create mode 100644 GPW.CORE.UI/GPW.CORE.UI.csproj create mode 100644 GPW.CORE.UI/Pages/Error.cshtml create mode 100644 GPW.CORE.UI/Pages/Error.cshtml.cs create mode 100644 GPW.CORE.UI/Pages/FastRec.razor create mode 100644 GPW.CORE.UI/Pages/ForceReset.razor create mode 100644 GPW.CORE.UI/Pages/Index.razor create mode 100644 GPW.CORE.UI/Pages/Planner.razor create mode 100644 GPW.CORE.UI/Pages/Planner.razor.cs create mode 100644 GPW.CORE.UI/Pages/Test.razor create mode 100644 GPW.CORE.UI/Pages/Test.razor.cs create mode 100644 GPW.CORE.UI/Pages/_Host.cshtml create mode 100644 GPW.CORE.UI/Pages/_Layout.cshtml create mode 100644 GPW.CORE.UI/Program.cs create mode 100644 GPW.CORE.UI/Properties/launchSettings.json create mode 100644 GPW.CORE.UI/Shared/LoginDisplay.razor create mode 100644 GPW.CORE.UI/Shared/MainLayout.razor create mode 100644 GPW.CORE.UI/Shared/MainLayout.razor.css create mode 100644 GPW.CORE.UI/Shared/NavMenu.razor create mode 100644 GPW.CORE.UI/Shared/NavMenu.razor.css create mode 100644 GPW.CORE.UI/_Imports.razor create mode 100644 GPW.CORE.UI/appsettings.Development.json create mode 100644 GPW.CORE.UI/appsettings.json create mode 100644 GPW.CORE.UI/chartJsData.cs create mode 100644 GPW.CORE.UI/compilerconfig.json create mode 100644 GPW.CORE.UI/compilerconfig.json.defaults create mode 100644 GPW.CORE.UI/libman.json create mode 100644 GPW.CORE.UI/post-build.ps1 create mode 100644 GPW.CORE.UI/wwwroot/css/bootstrap/bootstrap.min.css create mode 100644 GPW.CORE.UI/wwwroot/css/bootstrap/bootstrap.min.css.map create mode 100644 GPW.CORE.UI/wwwroot/css/fonts.css create mode 100644 GPW.CORE.UI/wwwroot/css/fonts.less create mode 100644 GPW.CORE.UI/wwwroot/css/fonts.min.css create mode 100644 GPW.CORE.UI/wwwroot/css/open-iconic/FONT-LICENSE create mode 100644 GPW.CORE.UI/wwwroot/css/open-iconic/ICON-LICENSE create mode 100644 GPW.CORE.UI/wwwroot/css/open-iconic/README.md create mode 100644 GPW.CORE.UI/wwwroot/css/open-iconic/font/css/open-iconic-bootstrap.min.css create mode 100644 GPW.CORE.UI/wwwroot/css/open-iconic/font/fonts/open-iconic.eot create mode 100644 GPW.CORE.UI/wwwroot/css/open-iconic/font/fonts/open-iconic.otf create mode 100644 GPW.CORE.UI/wwwroot/css/open-iconic/font/fonts/open-iconic.svg create mode 100644 GPW.CORE.UI/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf create mode 100644 GPW.CORE.UI/wwwroot/css/open-iconic/font/fonts/open-iconic.woff create mode 100644 GPW.CORE.UI/wwwroot/css/site.css create mode 100644 GPW.CORE.UI/wwwroot/css/site.less create mode 100644 GPW.CORE.UI/wwwroot/css/site.min.css create mode 100644 GPW.CORE.UI/wwwroot/favicon.ico create mode 100644 GPW.CORE.UI/wwwroot/fonts/lato-v17-latin-regular.eot create mode 100644 GPW.CORE.UI/wwwroot/fonts/lato-v17-latin-regular.svg create mode 100644 GPW.CORE.UI/wwwroot/fonts/lato-v17-latin-regular.ttf create mode 100644 GPW.CORE.UI/wwwroot/fonts/lato-v17-latin-regular.woff create mode 100644 GPW.CORE.UI/wwwroot/fonts/lato-v17-latin-regular.woff2 create mode 100644 GPW.CORE.UI/wwwroot/fonts/roboto-condensed-v19-latin-regular.eot create mode 100644 GPW.CORE.UI/wwwroot/fonts/roboto-condensed-v19-latin-regular.svg create mode 100644 GPW.CORE.UI/wwwroot/fonts/roboto-condensed-v19-latin-regular.ttf create mode 100644 GPW.CORE.UI/wwwroot/fonts/roboto-condensed-v19-latin-regular.woff create mode 100644 GPW.CORE.UI/wwwroot/fonts/roboto-condensed-v19-latin-regular.woff2 create mode 100644 GPW.CORE.UI/wwwroot/fonts/roboto-v27-latin-regular.eot create mode 100644 GPW.CORE.UI/wwwroot/fonts/roboto-v27-latin-regular.svg create mode 100644 GPW.CORE.UI/wwwroot/fonts/roboto-v27-latin-regular.ttf create mode 100644 GPW.CORE.UI/wwwroot/fonts/roboto-v27-latin-regular.woff create mode 100644 GPW.CORE.UI/wwwroot/fonts/roboto-v27-latin-regular.woff2 create mode 100644 GPW.CORE.UI/wwwroot/images/LogoBlu.svg create mode 100644 GPW.CORE.UI/wwwroot/images/LogoEgw.png create mode 100644 GPW.CORE.UI/wwwroot/images/LogoEgwWhite.png create mode 100644 GPW.CORE.UI/wwwroot/images/WorkInProgress.jpg create mode 100644 GPW.CORE.UI/wwwroot/lib/Chart.js/chart.esm.js create mode 100644 GPW.CORE.UI/wwwroot/lib/Chart.js/chart.esm.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/Chart.js/chart.js create mode 100644 GPW.CORE.UI/wwwroot/lib/Chart.js/chart.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/Chart.js/helpers.esm.js create mode 100644 GPW.CORE.UI/wwwroot/lib/Chart.js/helpers.esm.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap-grid.css create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap-grid.css.map create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap-grid.min.css create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap-grid.min.css.map create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap-reboot.css create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap-reboot.css.map create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap-reboot.min.css create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap-reboot.min.css.map create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap.css create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap.css.map create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap.min.css create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/css/bootstrap.min.css.map create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/js/bootstrap.bundle.js create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/js/bootstrap.bundle.js.map create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/js/bootstrap.bundle.min.js.map create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/js/bootstrap.js create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/js/bootstrap.js.map create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/js/bootstrap.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/js/bootstrap.min.js.map create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_alert.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_badge.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_breadcrumb.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_button-group.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_buttons.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_card.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_carousel.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_close.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_code.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_custom-forms.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_dropdown.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_forms.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_functions.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_grid.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_images.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_input-group.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_jumbotron.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_list-group.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_media.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_mixins.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_modal.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_nav.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_navbar.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_pagination.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_popover.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_print.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_progress.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_reboot.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_root.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_spinners.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_tables.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_toasts.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_tooltip.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_transitions.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_type.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_utilities.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/_variables.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/bootstrap-grid.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/bootstrap-reboot.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/bootstrap.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_alert.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_background-variant.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_badge.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_border-radius.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_box-shadow.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_breakpoints.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_buttons.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_caret.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_clearfix.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_deprecate.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_float.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_forms.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_gradients.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_grid-framework.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_grid.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_hover.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_image.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_list-group.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_lists.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_nav-divider.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_pagination.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_reset-text.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_resize.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_screen-reader.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_size.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_table-row.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_text-emphasis.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_text-hide.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_text-truncate.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_transition.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/mixins/_visibility.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_align.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_background.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_borders.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_clearfix.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_display.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_embed.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_flex.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_float.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_interactions.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_overflow.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_position.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_screenreaders.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_shadows.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_sizing.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_spacing.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_stretched-link.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_text.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/utilities/_visibility.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/bootstrap/scss/vendor/_rfs.scss create mode 100644 GPW.CORE.UI/wwwroot/lib/chartBoot.js create mode 100644 GPW.CORE.UI/wwwroot/lib/chartjs-adapter-luxon/chartjs-adapter-luxon.esm.js create mode 100644 GPW.CORE.UI/wwwroot/lib/chartjs-adapter-luxon/chartjs-adapter-luxon.esm.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/chartjs-adapter-luxon/chartjs-adapter-luxon.js create mode 100644 GPW.CORE.UI/wwwroot/lib/chartjs-adapter-luxon/chartjs-adapter-luxon.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/all.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/all.min.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/brands.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/brands.min.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/fontawesome.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/fontawesome.min.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/regular.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/regular.min.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/solid.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/solid.min.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/svg-with-js.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/svg-with-js.min.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/v4-shims.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/css/v4-shims.min.css create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/all.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/all.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/brands.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/brands.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/conflict-detection.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/conflict-detection.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/fontawesome.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/fontawesome.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/regular.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/regular.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/solid.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/solid.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/v4-shims.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/js/v4-shims.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/sprites/brands.svg create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/sprites/regular.svg create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/sprites/solid.svg create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-brands-400.eot create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-brands-400.svg create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-brands-400.ttf create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-brands-400.woff create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-brands-400.woff2 create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-regular-400.eot create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-regular-400.svg create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-regular-400.ttf create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-regular-400.woff create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-regular-400.woff2 create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-solid-900.eot create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-solid-900.svg create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-solid-900.ttf create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-solid-900.woff create mode 100644 GPW.CORE.UI/wwwroot/lib/font-awesome/webfonts/fa-solid-900.woff2 create mode 100644 GPW.CORE.UI/wwwroot/lib/luxon/cjs-browser/luxon.js create mode 100644 GPW.CORE.UI/wwwroot/lib/luxon/cjs-browser/luxon.js.map create mode 100644 GPW.CORE.UI/wwwroot/lib/luxon/cjs-browser/luxon.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/luxon/luxon.js create mode 100644 GPW.CORE.UI/wwwroot/lib/luxon/luxon.js.map create mode 100644 GPW.CORE.UI/wwwroot/lib/luxon/luxon.min.js create mode 100644 GPW.CORE.UI/wwwroot/lib/luxon/luxon.min.js.map diff --git a/GPW.Api.sln b/GPW.Api.sln deleted file mode 100644 index de815ec..0000000 --- a/GPW.Api.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31727.386 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPW.Api", "GPW.Api\GPW.Api.csproj", "{EF8D5A17-0D60-4EF0-9262-57AFAC574843}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GPW.Data", "GPW.Data\GPW.Data.csproj", "{E0716E55-CFD3-466E-9919-328B0B7ACD6C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {EF8D5A17-0D60-4EF0-9262-57AFAC574843}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EF8D5A17-0D60-4EF0-9262-57AFAC574843}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EF8D5A17-0D60-4EF0-9262-57AFAC574843}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EF8D5A17-0D60-4EF0-9262-57AFAC574843}.Release|Any CPU.Build.0 = Release|Any CPU - {E0716E55-CFD3-466E-9919-328B0B7ACD6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E0716E55-CFD3-466E-9919-328B0B7ACD6C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E0716E55-CFD3-466E-9919-328B0B7ACD6C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E0716E55-CFD3-466E-9919-328B0B7ACD6C}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {4EA406A5-8A20-49F6-85EE-ADDDBB02833F} - EndGlobalSection -EndGlobal diff --git a/GPW.CORE.Api/.config/dotnet-tools.json b/GPW.CORE.Api/.config/dotnet-tools.json new file mode 100644 index 0000000..b0e38ab --- /dev/null +++ b/GPW.CORE.Api/.config/dotnet-tools.json @@ -0,0 +1,5 @@ +{ + "version": 1, + "isRoot": true, + "tools": {} +} \ No newline at end of file diff --git a/GPW.CORE.Api/Controllers/CheckProjController.cs b/GPW.CORE.Api/Controllers/CheckProjController.cs new file mode 100644 index 0000000..e2a9b7d --- /dev/null +++ b/GPW.CORE.Api/Controllers/CheckProjController.cs @@ -0,0 +1,82 @@ +using GPW.CORE.Api.Data; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Text; + +namespace GPW.CORE.Api.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class CheckProjController : ControllerBase + { + + /// + /// Dataservice x accesso DB + /// + protected ApiDataService dataService { get; set; } + + private readonly ILogger _logger; + + public CheckProjController(ILogger logger, ApiDataService DataService) + { + _logger = logger; + dataService = DataService; + _logger.LogInformation("Avviata classe CheckProj"); + } + + [HttpGet("TryLock")] + public async Task Get() + { + string answ = "ND"; + StringBuilder sbLog = new StringBuilder(); + StringBuilder sbActions = new StringBuilder(); + + // recupero progetti attivi... + var currProj = await dataService.AnagProjActiv(); + sbLog.AppendLine("-----------------------"); + sbLog.AppendLine($"Found {currProj.Count} Active Projects"); + + // leggo fasi attive + var currFasiAct = await dataService.AnagFasiActiv(); + sbLog.AppendLine($"Found {currFasiAct.Count} Active Phases"); + + sbLog.AppendLine("-----------------------"); + // ciclo elenco fasi ancestor di ognuno... + foreach (var itemProj in currProj) + { + // cerco le sue fasi PARENT... + var subsetFasi = currFasiAct + .Where(x => x.IdxProgetto == itemProj.IdxProgetto && x.IdxFaseAncest == 0) + .ToList(); + sbLog.AppendLine("----------"); + string projData = $"[{itemProj.IdxProgetto}] {itemProj.ClienteNav.RagSociale} - {itemProj.NomeProj} | Found {subsetFasi.Count} Phases"; + sbLog.AppendLine(projData); + + // ciclo x ogni fase Parent + foreach (var parentFase in subsetFasi) + { + // se ne trovo valuto le ore impiegate... + var statoFase = await dataService.CalcOreFase(parentFase.IdxFase); + + // se ore usate > (ore budget x %) --> CHIUDO! + if (statoFase != null && statoFase.percUsed >= (decimal)statoFase.percOpen) + { + // x ora LOG... poi chiudo... + string currAction = $"!!! [{parentFase.IdxFase}] Budget exhausted for Phase {parentFase.NomeFase} {statoFase.totOre:N2}h used, {statoFase.percUsed:P1} vs {statoFase.percOpen:P1}"; + sbLog.AppendLine(currAction); + sbActions.AppendLine("----------"); + sbActions.AppendLine(projData); + sbActions.AppendLine(currAction); + } + } + } + + // LOG esteso locale + _logger.LogInformation(sbLog.ToString()); + + // ritorno solo LOG azioni + answ = sbActions.ToString(); + return answ; + } + } +} diff --git a/GPW.CORE.Api/Controllers/VC19Controller.cs b/GPW.CORE.Api/Controllers/VC19Controller.cs new file mode 100644 index 0000000..fe87bec --- /dev/null +++ b/GPW.CORE.Api/Controllers/VC19Controller.cs @@ -0,0 +1,130 @@ +using GPW.CORE.Api.Data; +using GPW.CORE.Data; +using GPW.CORE.Data.DbModels; +using Microsoft.AspNetCore.Mvc; +using NLog; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace GPW.CORE.Api.Controllers +{ + /// + /// Controller interazione VC19 + /// + [Route("api/VC19")] + [ApiController] + public class VC19Controller : ControllerBase + { + #region Private Fields + + /// + /// Classe per logging + /// + private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion Private Fields + + #region Public Constructors + + /// + /// Init generico + /// + /// + public VC19Controller(ApiDataService DataService) + { + _DataService = DataService; + Log.Info("Avviata classe VC19Controller"); + } + + #endregion Public Constructors + + #region Protected Properties + + /// + /// Dataservice x accesso DB + /// + protected ApiDataService _DataService { get; set; } + + #endregion Protected Properties + + #region Public Methods + + /// + /// Recupera ultimi 20 check in ordine cronologico inverso + /// + /// + [HttpGet] + public async Task> Get() + { + var result = await _DataService.ChecksGetLast(20); + return result; + } + + /// + /// Recupera ultimo mese di check x dipendente indicato da ID + /// GET api/VC19/5 + /// + /// + /// + [HttpGet("{id}")] + public async Task> Get(int id) + { + var result = await _DataService.ChecksGetByDip(id); + return result; + } + + /// + /// Invio record decodificato da classe DCC + /// + /// + /// + [HttpPost] + public async Task Post(DCCDecode DecodedData) + { + VC19Check answ = new VC19Check() + { + Result = "KO" + }; + var result = await _DataService.InsertCheck(DecodedData, "10.74.82.255"); + if (result) + { + answ = new VC19Check + { + DTRecord = DateTime.Now, + CheckRecorded = true, + TimbrRecorder = true, + Result = $"OK, Check Recorded for {DecodedData.nam.fn} {DecodedData.nam.gn} {DecodedData.dob:yyyy.MM.dd}" + }; + } + else + { } + return answ; + } + + /// + /// Invio DI TEST record manuale + /// + /// + /// + [HttpPut] + public async Task Put(TestUser id) + { + VC19Check answ = new VC19Check() + { + Result = "KO" + }; + var result = await _DataService.InsertManual((int)id, "10.74.82.255"); + answ = new VC19Check + { + DTRecord = DateTime.Now, + CheckRecorded = true, + TimbrRecorder = true, + Result = $"OK, Check Recorded for id {id}" + }; + return answ; + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.Api/Data/ApiDataService.cs b/GPW.CORE.Api/Data/ApiDataService.cs new file mode 100644 index 0000000..0539f0f --- /dev/null +++ b/GPW.CORE.Api/Data/ApiDataService.cs @@ -0,0 +1,314 @@ +using GPW.CORE.Data.DbModels; +using Newtonsoft.Json; +using NLog; +using Microsoft.AspNetCore.Identity.UI.Services; +using StackExchange.Redis.Extensions.Core.Abstractions; +using System.Diagnostics; +using GPW.CORE.Data; + +namespace GPW.CORE.Api.Data +{ + public class ApiDataService + { + #region Private Fields + + private static IConfiguration _configuration; + + private static ILogger _logger; + + private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); + + private readonly IEmailSender _emailSender; + + //private readonly IDistributedCache distributedCache; + private readonly IRedisCacheClient _redisCacheClient; + + /// + /// Elenco obj in cache + /// + private List cachedDataList = new List(); + + #endregion Private Fields + + #region Protected Fields + + protected const string rKeyProjAct = "Check:ProjAct"; + protected const string rKeyFasiAct = "Check:FasiAct"; + protected const string rKeyCalcOreFase = "Check:OreFasi"; + + + /// + /// TTL da 1 min x cache Redis + /// + protected const int shortTTL = 60 * 1; + + #endregion Protected Fields + + #region Public Fields + + /// + /// Classe Accesso metodi DB + /// + public static CORE.Data.Controllers.GPWController dbController; + + #endregion Public Fields + + #region Public Constructors + + /// + /// Init classe + /// + /// + /// + /// + /// + public ApiDataService(IConfiguration configuration, ILogger logger, IEmailSender emailSender, IRedisCacheClient redisCacheClient) + //public ApiDataService(IConfiguration configuration, ILogger logger, IDistributedCache distributedCache, IEmailSender emailSender, IRedisCacheClient redisCacheClient) + { + _logger = logger; + _configuration = configuration; + _emailSender = emailSender; + _redisCacheClient = redisCacheClient; + + // conf DB + string connStrDB = _configuration.GetConnectionString("GPW.DB"); + if (string.IsNullOrEmpty(connStrDB)) + { + _logger.LogError("ConnString empty!"); + } + else + { + dbController = new CORE.Data.Controllers.GPWController(configuration); + _logger.LogInformation("DbController OK"); + } + } + + #endregion Public Constructors + + #region Protected Methods + + /// + /// Recupero chiave da redis + /// + /// + /// + protected async Task getRSV(string rKey) + { + string answ = await _redisCacheClient.GetDbFromConfiguration().GetAsync(rKey); + return answ; + } + + /// + /// Salvataggio chiave in redis + /// + /// + /// + /// + /// + protected async Task setRSV(string rKey, string rVal, int ttlSec) + { + bool fatto = false; + await _redisCacheClient.GetDbFromConfiguration().AddAsync(rKey, rVal, DateTimeOffset.Now.AddSeconds(ttlSec)); + fatto = true; + return fatto; + } + + /// + /// Salvataggio chiave in redis + /// + /// + /// + /// + /// + protected async Task setRSV(string rKey, int rValInt, int ttlSec) + { + bool fatto = false; + await _redisCacheClient.GetDbFromConfiguration().AddAsync(rKey, rValInt, DateTimeOffset.Now.AddSeconds(ttlSec)); + fatto = true; + return fatto; + } + + /// + /// Registra in cache chiave se non fosse già in elenco + /// + /// + protected void trackCache(string newKey) + { + if (!cachedDataList.Contains(newKey)) + { + cachedDataList.Add(newKey); + } + } + + #endregion Protected Methods + + #region Public Methods + + /// + /// Recupera l'elenco progetti (ATTIVI) + /// + /// + public async Task> AnagProjActiv() + { + List dbResult = new List(); + string cacheKey = $"{rKeyProjAct}"; + trackCache(cacheKey); + string rawData = await getRSV(cacheKey); + if (!string.IsNullOrEmpty(rawData)) + { + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.AnagProjAll(true); + rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + await setRSV(cacheKey, rawData, shortTTL); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB per AnagProjActiv: {ts.TotalMilliseconds} ms"); + } + + return await Task.FromResult(dbResult); + } + + /// + /// Recupera l'elenco fasi (ATTIVE) + /// + /// + public async Task> AnagFasiActiv() + { + List dbResult = new List(); + string cacheKey = $"{rKeyFasiAct}"; + trackCache(cacheKey); + string rawData = await getRSV(cacheKey); + if (!string.IsNullOrEmpty(rawData)) + { + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.AnagFasiAll(true); + rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + await setRSV(cacheKey, rawData, shortTTL); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB per AnagFasiActiv: {ts.TotalMilliseconds} ms"); + } + + return await Task.FromResult(dbResult); + } + + /// + /// Vista dati per FASE (tipicamente master...) con totalizzaizone ore budget/real e stato fase + /// + /// + /// + public async Task CalcOreFase(int idxFase) + { + CalcOreFasiModel? dbResult = new CalcOreFasiModel(); + string cacheKey = $"{rKeyCalcOreFase}:{idxFase}"; + trackCache(cacheKey); + string rawData = await getRSV(cacheKey); + if (!string.IsNullOrEmpty(rawData)) + { + dbResult = JsonConvert.DeserializeObject(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.CalcOreFase(idxFase); + rawData = JsonConvert.SerializeObject(dbResult, Formatting.None, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); + await setRSV(cacheKey, rawData, shortTTL); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB per CalcOreFase: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new CalcOreFasiModel(); + } + return await Task.FromResult(dbResult); + } + + /// + /// invalida tutta la cache in caso di update + /// + /// + public async Task InvalidateAllCache() + { + foreach (var item in cachedDataList) + { + await _redisCacheClient.GetDbFromConfiguration().RemoveAsync(item); + } + cachedDataList = new List(); + } + + + + public async Task> ChecksGetByDip(int idxDip) + { + DateTime dtFine = DateTime.Today.AddDays(1); + List dbResult = new List(); + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.GetChecksVC19Filt(idxDip, dtFine.AddMonths(-1), dtFine); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB per ChecksGetByDip: {ts.TotalMilliseconds} ms"); + + return await Task.FromResult(dbResult); + } + + public async Task> ChecksGetLast(int numRecord) + { + List dbResult = new List(); + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.GetChecksVC19(numRecord); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB per ChecksGetLast: {ts.TotalMilliseconds} ms"); + + return await Task.FromResult(dbResult); + } + + public void Dispose() + { + // Clear database controller + dbController.Dispose(); + } + + public async Task InsertCheck(DCCDecode updItem, string clientIp) + { + bool done = false; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + done = dbController.InsertCheck(updItem, clientIp); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata operazione InsertCheck: {ts.TotalMilliseconds} ms"); + + return await Task.FromResult(done); + } + + public async Task InsertManual(int idxDip, string clientIp) + { + bool done = false; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + done = dbController.InsertManual(idxDip, clientIp); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata operazione InsertManual: {ts.TotalMilliseconds} ms"); + + return await Task.FromResult(done); + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.Api/GPW.CORE.Api.csproj b/GPW.CORE.Api/GPW.CORE.Api.csproj new file mode 100644 index 0000000..116743e --- /dev/null +++ b/GPW.CORE.Api/GPW.CORE.Api.csproj @@ -0,0 +1,28 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + + + + + + + + + + + diff --git a/GPW.CORE.Api/NLog.config b/GPW.CORE.Api/NLog.config new file mode 100644 index 0000000..bd41408 --- /dev/null +++ b/GPW.CORE.Api/NLog.config @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GPW.CORE.Api/Program.cs b/GPW.CORE.Api/Program.cs new file mode 100644 index 0000000..ca211ce --- /dev/null +++ b/GPW.CORE.Api/Program.cs @@ -0,0 +1,63 @@ +using GPW.CORE.Api.Data; +using GPW.CORE.Data; +using Microsoft.AspNetCore.Identity.UI.Services; +using StackExchange.Redis.Extensions.Core.Configuration; +using StackExchange.Redis.Extensions.Newtonsoft; +using System.Text.Json.Serialization; + +var builder = WebApplication.CreateBuilder(args); + +// configuration setup +ConfigurationManager configuration = builder.Configuration; + +// Add services to the container. +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +// abilitazione x email management con MailKit +builder.Services.AddTransient(); +builder.Services.Configure(options => +{ + options.Host_Address = configuration["ExternalProviders:MailKit:SMTP:Address"]; + options.Host_Port = Convert.ToInt32(configuration["ExternalProviders:MailKit:SMTP:Port"]); + options.Host_Username = configuration["ExternalProviders:MailKit:SMTP:Account"]; + options.Host_Password = configuration["ExternalProviders:MailKit:SMTP:Password"]; + options.Sender_EMail = configuration["ExternalProviders:MailKit:SMTP:SenderEmail"]; + options.Sender_Name = configuration["ExternalProviders:MailKit:SMTP:SenderName"]; +}); + +//services.AddStackExchangeRedisCache(options => +//{ +// options.Configuration = Configuration.GetConnectionString("Redis"); +//}); + +builder.Services.AddControllers() + .AddJsonOptions(c => c.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve); + +builder.Services.AddStackExchangeRedisExtensions((options) => +{ + return configuration.GetSection("Redis").Get(); +}); + +builder.Services.AddSingleton(); + + + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/GPW.CORE.Api/Properties/launchSettings.json b/GPW.CORE.Api/Properties/launchSettings.json new file mode 100644 index 0000000..9253c1e --- /dev/null +++ b/GPW.CORE.Api/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:39480", + "sslPort": 44359 + } + }, + "profiles": { + "GPW.CORE.Api": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7178;http://localhost:5178", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/GPW.CORE.Api/VC19Check.cs b/GPW.CORE.Api/VC19Check.cs new file mode 100644 index 0000000..c1a8471 --- /dev/null +++ b/GPW.CORE.Api/VC19Check.cs @@ -0,0 +1,17 @@ +namespace GPW.CORE.Api +{ + /// + /// Esito chiamata VC19 + /// + public class VC19Check + { + #region Public Properties + + public bool CheckRecorded { get; set; } = true; + public DateTime DTRecord { get; set; } = DateTime.Now; + public string Result { get; set; } = ""; + public bool TimbrRecorder { get; set; } = false; + + #endregion Public Properties + } +} diff --git a/GPW.CORE.Api/appsettings.Development.json b/GPW.CORE.Api/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/GPW.CORE.Api/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/GPW.CORE.Api/appsettings.json b/GPW.CORE.Api/appsettings.json new file mode 100644 index 0000000..678dbcd --- /dev/null +++ b/GPW.CORE.Api/appsettings.json @@ -0,0 +1,43 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "GPW.DB": "Server=SQLSTEAM;Database=GPW;User ID=sa;Password=keyhammer;integrated security=False;MultipleActiveResultSets=True;App=LiMan.API;", + "Redis": "localhost:6379,DefaultDatabase=15" + }, + "ExternalProviders": { + "MailKit": { + "SMTP": { + "Address": "smtp.gmail.com", + "Port": "465", + "Account": "steamwarebot@gmail.com", + "Password": "drmfsls16", + "SenderEmail": "steamwarebot@gmail.com", + "SenderName": "Steamware Email BOT" + } + } + }, + "MailDest": { + "Admin": "samuele@steamware.net", + "ProcOp": "ceo@steamware.net" + }, + "Redis": { + "Password": "", + "AllowAdmin": false, + "Ssl": false, + "ConnectTimeout": 6000, + "ConnectRetry": 2, + "Hosts": [ + { + "Host": "localhost", + "Port": "6379" + } + ], + "Database": 15 + } +} diff --git a/GPW.CORE.Api/logs/.placeholder.txt b/GPW.CORE.Api/logs/.placeholder.txt new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/GPW.CORE.Api/logs/.placeholder.txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/GPW.CORE.Data/Controllers/GPWController.cs b/GPW.CORE.Data/Controllers/GPWController.cs new file mode 100644 index 0000000..279bef6 --- /dev/null +++ b/GPW.CORE.Data/Controllers/GPWController.cs @@ -0,0 +1,818 @@ +using GPW.CORE.Data.DbModels; +using GPW.CORE.Data.DTO; +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using NLog; +using Newtonsoft.Json; + +namespace GPW.CORE.Data.Controllers +{ + public class GPWController : IDisposable + { + #region Private Fields + + private static IConfiguration _configuration = null!; + private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion Private Fields + + #region Public Constructors + + public GPWController(IConfiguration configuration) + { + _configuration = configuration; + } + + #endregion Public Constructors + + #region Public Methods + + /// + /// Recupera l'elenco Clienti (tutti) + /// + /// + public List AnagClientiAll() + { + // init dati necessari + List dbResult = new List(); + // cerco su DB recuperando set di dati.... + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + // recupero intero set... + dbResult = localDbCtx + .DbSetAnagClienti + .OrderBy(x => x.RagSociale) + .ToList(); + } + catch (Exception exc) + { + Log.Error($"Errore in AnagClientiAll:{Environment.NewLine}{exc}"); + } + } + return dbResult; + } + + /// + /// Recupera l'elenco delle fasi (tutte) + /// + /// + public List AnagFasiAll(bool onlyActive) + { + // init dati necessari + List dbResult = new List(); + // cerco su DB recuperando set di dati.... + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + // recupero intero set... + dbResult = localDbCtx + .DbSetAnagFasi + .Where(x => ((bool)x.Attivo == true && onlyActive == true) || !onlyActive) + .ToList(); + } + catch (Exception exc) + { + Log.Error($"Errore in AnagFasiAll:{Environment.NewLine}{exc}"); + } + } + return dbResult; + } + + public List AnagGruppiAll() + { + // init dati necessari + List dbResult = new List(); + // cerco su DB recuperando set di dati.... + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + // recupero intero set... + dbResult = localDbCtx + .DbSetAnagGruppi + .ToList(); + } + catch (Exception exc) + { + Log.Error($"Errore in AnagGruppiAll:{Environment.NewLine}{exc}"); + } + } + return dbResult; + } + + public List AnagProjAll(bool onlyActive) + { + // init dati necessari + List dbResult = new List(); + // cerco su DB recuperando set di dati.... + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + // recupero intero set.... + dbResult = localDbCtx + .DbSetAnagProgetti + .Where(x => ((bool)x.Attivo == true && onlyActive == true) || !onlyActive) + .Include(c => c.ClienteNav) + .OrderBy(x => x.NomeProj) + .ToList(); + } + catch (Exception exc) + { + Log.Error($"Errore in AnagProjAll:{Environment.NewLine}{exc}"); + } + } + return dbResult; + } + + /// + /// Vista dati per progetto con totalizzaizone ore budget/real + /// + /// + /// + public CalcOreProgettiModel CalcOreProj(int idxProj) + { + CalcOreProgettiModel dbResult = new CalcOreProgettiModel(); + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + var idxProgetto = new SqlParameter("@idxProgetto", idxProj); + + var rawResult = localDbCtx + .DbSetCalcOreProj + .FromSqlRaw("EXEC stp_AP_getByIdxPrj @idxProgetto", idxProgetto) + .ToList(); + if (rawResult != null && rawResult.Count > 0) + { + dbResult = rawResult[0]; + } + } + return dbResult; + } + + /// + /// Vista dati per FASE con totalizzaizone ore budget/real + /// + /// + /// + public CalcOreFasiModel CalcOreFase(int idxFase) + { + CalcOreFasiModel dbResult = new CalcOreFasiModel(); + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + var parIdxFase = new SqlParameter("@idxFase", idxFase); + + var rawResult = localDbCtx + .DbSetCalcOreFasi + .FromSqlRaw("EXEC stp_AF_getByIdxFase_Child @idxFase", parIdxFase) + .ToList(); + if (rawResult != null && rawResult.Count > 0) + { + dbResult = rawResult[0]; + } + } + return dbResult; + } + + /// + /// Recupera l'elenco dei Rilievi temperatura nel periodo indicato x dipendente + /// + /// Dipendente interessato + /// Data di riferimento (ultima/corrente) + /// NUm settimane precedenti da recuperare + /// + public List CheckVC19List(int idxDipendente, DateTime dtInizio, DateTime dtFine) + { + // init dati necessari + List dbResult = new List(); + // cerco su DB recuperando set di dati.... + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + dbResult = localDbCtx + .DbSetCheckVc19 + .Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DtCheck && x.DtCheck <= dtFine) + .ToList(); + } + return dbResult; + } + + /// + /// Recupera l'elenco dei dettagli giornalieri attività di un dipendente, dato periodo riferimento + /// + /// Dipendente interessato + /// Data di riferimento (ultima/corrente) + /// NUm settimane precedenti da recuperare + /// + public List DailyDetails(int idxDipendente, DateTime dtInizio, DateTime dtFine) + { + // init dati necessari + List dbResult = new List(); + List rawTimbExp = new List(); + List rawTimbr = new List(); + List rawRegAtt = new List(); + List rawRilTemp = new List(); + List rawCheckC19 = new List(); + + // cerco su DB recuperando set di dati.... + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + // recupero intero set dati timbrature e attività.... + rawTimbExp = localDbCtx + .DbSetTimbratureExpl + .Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DataLav && x.DataLav <= dtFine) + .ToList(); + + rawTimbr = localDbCtx + .DbSetTimbrature + .Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DataOra && x.DataOra <= dtFine) + .ToList(); + + rawRegAtt = localDbCtx + .DbSetRegAttivita + .Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.Inizio && x.Inizio <= dtFine) + .Include(a => a.FasiNav).ThenInclude(p => p.ProgettoNav).ThenInclude(c => c.ClienteNav) + .ToList(); + + rawRilTemp = localDbCtx + .DbSetRilievoTemp + .Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DtRilievo && x.DtRilievo <= dtFine) + .ToList(); + + rawCheckC19 = localDbCtx + .DbSetCheckVc19 + .Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DtCheck && x.DtCheck <= dtFine) + .ToList(); + + // calcolo intervallo date... + int numDays = dtFine.Subtract(dtInizio).Days; + + // x ogni giorno scompongo il set di info... + for (int i = 0; i <= numDays; i++) + { + DateTime thisDay = dtInizio.AddDays(i); + DailyDataDTO currDayDto = new DailyDataDTO() + { + IdxDipendente = idxDipendente, + DtRif = thisDay, + ListRA = rawRegAtt + .Where(x => thisDay <= x.Inizio && x.Inizio <= thisDay.AddDays(1)) + .ToList(), + ListTimbr = rawTimbr + .Where(x => thisDay <= x.DataOra && x.DataOra <= thisDay.AddDays(1)) + .ToList(), + TimbrExpl = rawTimbExp + .Where(x => thisDay == x.DataLav) + .FirstOrDefault(), + ListRilTemp = rawRilTemp + .Where(x => thisDay <= x.DtRilievo && x.DtRilievo <= thisDay.AddDays(1)) + .ToList(), + ListCheckC19 = rawCheckC19 + .Where(x => thisDay <= x.DtCheck && x.DtCheck <= thisDay.AddDays(1)) + .ToList() + }; + + dbResult.Add(currDayDto); + } + } + return dbResult; + } + + public bool DbForceMigrate() + { + bool answ = false; + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + localDbCtx.DbForceMigrate(); + answ = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in DbForceMigrate{Environment.NewLine}{exc}"); + } + } + return answ; + } + + public List DipendentiGetAll() + { + List dbResult = new List(); + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + dbResult = localDbCtx + .DbSetDipendenti + .ToList(); + } + return dbResult; + } + + public List AnagKeyValGetAll() + { + List dbResult = new List(); + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + dbResult = localDbCtx + .DbSetAnagKeyValue + .ToList(); + } + return dbResult; + } + + public void Dispose() + { + Log.Info("Dispose di GPWController"); + } + + /// + /// Elenco pareto progetti ordinati da filtro + /// + /// + /// + /// + /// + /// + public List ParetoRegAtt(int idxDip, DateTime dataStart, DateTime dataEnd, int maxResult) + { + List dbResult = new List(); + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + var idxDipendente = new SqlParameter("@idxDipendente", idxDip); + var inizio = new SqlParameter("@inizio", dataStart); + var fine = new SqlParameter("@fine", dataEnd); + var maxRes = new SqlParameter("@maxRes", maxResult); + + dbResult = localDbCtx + .DbSetParetoRegAtt + .FromSqlRaw("EXEC stp_freqProjByDipPeriodo @idxDipendente, @inizio,@fine,@maxRes", idxDipendente, inizio, fine, maxRes) + .ToList(); + } + return dbResult; + } + + public bool RegAttDelete(RegAttivitaModel currItem) + { + bool answ = false; + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + localDbCtx.Remove(currItem); + + localDbCtx.SaveChanges(); + answ = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in RegAttUpdate{Environment.NewLine}{exc}"); + } + } + return answ; + } + + /// + /// Recupera ultima attività dipendente + /// + /// + /// cerca ultima solo tra attive (=true) o tutte (=false) + /// + public RegAttivitaModel RegAttLastByDip(int IdxDipendente, bool onlyActive) + { + RegAttivitaModel dbResult = new RegAttivitaModel(); + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + dbResult = localDbCtx + .DbSetRegAttivita + .Where(x => x.FasiNav.Attivo || !onlyActive) + .OrderByDescending(x => x.Inizio) + .FirstOrDefault(x => x.IdxDipendente == IdxDipendente); + } + catch (Exception exc) + { + Log.Error($"Eccezione in RegAttLastByDip{Environment.NewLine}{exc}"); + } + if (dbResult == null) + { + dbResult = new RegAttivitaModel(); + } + } + return dbResult; + } + + public bool RegAttUpdate(RegAttivitaModel currItem) + { + bool answ = false; + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + var currRec = localDbCtx + .DbSetRegAttivita + .FirstOrDefault(x => x.IdxRa == currItem.IdxRa); + if (currRec != null) + { + currRec.IdxDipendente = currItem.IdxDipendente; + currRec.IdxFase = currItem.IdxFase; + currRec.Inizio = currItem.Inizio; + currRec.Fine = currItem.Fine; + currRec.Descrizione = currItem.Descrizione; + + localDbCtx + .DbSetRegAttivita + .Update(currRec); + } + // altrimenti aggiungo + else + { + localDbCtx + .DbSetRegAttivita + .Update(currItem); + } + localDbCtx.SaveChanges(); + answ = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in RegAttUpdate{Environment.NewLine}{exc}"); + } + } + return answ; + } + + /// + /// Recupera l'elenco dei Rilievi temperatura nel periodo indicato x dipendente + /// + /// Dipendente interessato + /// Data di riferimento (ultima/corrente) + /// NUm settimane precedenti da recuperare + /// + public List RilTempList(int idxDipendente, DateTime dtInizio, DateTime dtFine) + { + // init dati necessari + List dbResult = new List(); + // cerco su DB recuperando set di dati.... + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + dbResult = localDbCtx + .DbSetRilievoTemp + .Where(x => x.IdxDipendente == idxDipendente && dtInizio <= x.DtRilievo && x.DtRilievo <= dtFine) + .ToList(); + } + return dbResult; + } + + public bool RilTempUpdate(RilievoTempModel currItem) + { + bool answ = false; + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + var currRec = localDbCtx + .DbSetRilievoTemp + .FirstOrDefault(x => x.IdxDipendente == currItem.IdxDipendente && x.DtRilievo == currItem.DtRilievo); + if (currRec != null) + { + // aggiorno solo entrata/uscita + currRec.TempRil = currItem.TempRil; + + localDbCtx + .DbSetRilievoTemp + .Update(currRec); + } + // altrimenti aggiungo + else + { + localDbCtx + .DbSetRilievoTemp + .Add(currItem); + } + localDbCtx.SaveChanges(); + answ = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in RilTempUpdate{Environment.NewLine}{exc}"); + } + } + return answ; + } + + /// + /// Annulla modifiche su una specifica entity (cancel update) + /// + /// + /// + public bool rollBackEntity(object item) + { + bool answ = false; + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + if (localDbCtx.Entry(item).State == EntityState.Deleted || localDbCtx.Entry(item).State == EntityState.Modified) + { + localDbCtx.Entry(item).Reload(); + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in rollBackEntity{Environment.NewLine}{exc}"); + } + } + return answ; + } + + public bool TimbratureDelete(TimbratureModel currItem) + { + bool answ = false; + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + localDbCtx.Remove(currItem); + + localDbCtx.SaveChanges(); + answ = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in TimbratureDelete{Environment.NewLine}{exc}"); + } + } + return answ; + } + + public bool TimbratureUpdate(TimbratureModel currItem) + { + bool answ = false; + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + var currRec = localDbCtx + .DbSetTimbrature + .FirstOrDefault(x => x.IdxDipendente == currItem.IdxDipendente && x.DataOra == currItem.DataOra); + if (currRec != null) + { + // aggiorno solo entrata/uscita + currRec.Entrata = currItem.Entrata; + + localDbCtx + .DbSetTimbrature + .Update(currRec); + } + // altrimenti aggiungo + else + { + localDbCtx + .DbSetTimbrature + .Add(currItem); + } + localDbCtx.SaveChanges(); + answ = true; + } + catch (Exception exc) + { + Log.Error($"Eccezione in TimbratureUpdate{Environment.NewLine}{exc}"); + } + } + return answ; + } + + /// + /// Recupera overview di un periodo settimanale x dipendente, data riferimento, numero settimane precedenti + /// + /// Dipendente interessato + /// Data di riferimento (ultima/corrente) + /// NUm settimane precedenti da recuperare + /// + public List WeekOverview(int idxDipendente, DateTime dtRif, int numWeek) + { + // init dati necessari + List dbResult = new List(); + List weekList = new List(); + + // aggiungo sett corrente + quelle richeiste... + for (int i = numWeek; i >= 0; i--) + { + var currWeek = new WeekData(dtRif.AddDays(-i * 7)); + weekList.Add(currWeek); + } + + // cerco su DB settimana x settimana.... + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + foreach (var item in weekList) + { + var totOreTim = localDbCtx + .DbSetTimbratureExpl + .Where(x => x.IdxDipendente == idxDipendente && x.DataLav >= item.inizio && x.DataLav <= item.fine) + .Sum(x => (double)x.HLav); + var totMinLav = localDbCtx + .DbSetRegAttivitaExpl + .Where(x => x.IdxDipendente == idxDipendente && x.DataLav >= item.inizio && x.DataLav <= item.fine) + .Sum(x => (int)x.MinRegAtt); + + // aggiungo alla lista... + var weekData = new WeekStatDTO() + { + IdxDipendente = idxDipendente, + Anno = item.anno, + WeekNumber = item.weekNumber, + Inizio = item.inizio, + Fine = item.fine, + SumOreLav = totOreTim, + SumOreComm = (double)totMinLav / 60, + }; + dbResult.Add(weekData); + } + } + return dbResult; + } + + + public List GetChecksVC19(int maxNum) + { + List dbResult = new List(); + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + int numRec = localDbCtx + .DbSetCheckVc19 + .Count(); + + // se ho meno record che quelli richiesti --> riduco + maxNum = numRec > maxNum ? maxNum : numRec; + + dbResult = localDbCtx + .DbSetCheckVc19 + .OrderByDescending(x => x.DtCheck) + .Take(maxNum) + .ToList(); + } + return dbResult; + } + + public List GetChecksVC19Filt(int idxDip, DateTime dtStart, DateTime dtEnd) + { + List dbResult = new List(); + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + DateTime oggi = DateTime.Today; + dbResult = localDbCtx + .DbSetCheckVc19 + .Where(x => (idxDip == 0 || x.IdxDipendente == idxDip) && (x.DtCheck >= dtStart && x.DtCheck <= dtEnd)) + .OrderByDescending(x => x.DtCheck) + .ToList(); + } + return dbResult; + } + + public bool InsertCheck(DCCDecode updItem, string clientIp) + { + bool done = false; + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + int idxDip = 0; + DipendentiModel currUser = new DipendentiModel() + { + IdxDipendente = 0 + }; + // per prima cosa cerca il dipendente x cognome/nome... + var userList = localDbCtx + .DbSetDipendenti + .Where(x => x.Cognome.ToUpper() == updItem.nam.fn.ToUpper() && x.Nome.ToUpper() == updItem.nam.gn.ToUpper()) + .ToList(); + // se ne ho solo 1 ok... + if (userList.Count > 1) + { + currUser = userList + .Where(x => x.DataNascita != null && updItem.dob.Date == ((DateTime)x.DataNascita).Date) + .FirstOrDefault(); + } + // altrimenti cerco anche con DOB... + else if (userList.Count == 1) + { + // se lo trova inserisce check... + currUser = userList[0]; + } + + if (currUser != null) + { + // fisso dipendente + idxDip = currUser.IdxDipendente; + } + + string rawPayload = JsonConvert.SerializeObject(updItem); + CheckVc19Model newItem = new CheckVc19Model() + { + IdxDipendente = idxDip, + DtCheck = DateTime.Now, + Cognome = updItem.nam.fn.ToUpper(), + Nome = updItem.nam.gn.ToUpper(), + Payload = rawPayload, + Dob = updItem.dob.Date + }; + // aggiungo! + localDbCtx + .DbSetCheckVc19 + .Add(newItem); + + // ora salvo! + localDbCtx.SaveChanges(); + + // se trovato procedo ANCHE x timbratura + if (idxDip > 0) + { + // verifico se ho timbratura ingresso + var listTimbra = localDbCtx + .DbSetTimbrature + .Where(x => x.IdxDipendente == idxDip && x.DataOra.Date == DateTime.Today && x.Entrata == true) + .ToList(); + // se non ci fosse aggiungo + if (listTimbra == null || listTimbra.Count == 0) + { + var newIngresso = new TimbratureModel() + { + IdxDipendente = idxDip, + DataOra = DateTime.Now, + CodTipoTimb = "Web", + Ipv4 = clientIp, + Entrata = true, + Approv = true + }; + + // aggiungo! + localDbCtx + .DbSetTimbrature + .Add(newIngresso); + } + // ora salvo! + localDbCtx.SaveChanges(); + done = true; + } + // altrimenti NON FA NULLA + else + { + Log.Info($"Attenzione, dipendente non trovato: {updItem.nam.fn} {updItem.nam.gn}"); + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in InsertCheck:{Environment.NewLine}{exc}"); + } + } + return done; + } + + public bool InsertManual(int idxDip, string clientIp) + { + bool done = false; + using (GPWContext localDbCtx = new GPWContext(_configuration)) + { + try + { + // se trovato procedo + if (idxDip > 0) + { + string rawPayload = "MANUAL"; + CheckVc19Model newItem = new CheckVc19Model() + { + IdxDipendente = idxDip, + DtCheck = DateTime.Now, + Payload = rawPayload + }; + // aggiungo! + localDbCtx + .DbSetCheckVc19 + .Add(newItem); + + // ora salvo! + localDbCtx.SaveChanges(); + done = true; + } + // altrimenti NON FA NULLA + else + { + Log.Info($"Attenzione, dipendente non trovato: {idxDip}"); + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in InsertManual:{Environment.NewLine}{exc}"); + } + } + return done; + } + + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.Data/DCCDecode.cs b/GPW.CORE.Data/DCCDecode.cs new file mode 100644 index 0000000..33fb5c8 --- /dev/null +++ b/GPW.CORE.Data/DCCDecode.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +// +// This is here so CodeMaid doesn't reorganize this document +// +namespace GPW.CORE.Data +{ + public class DCCDecode + { + public List v { get; set; } + + public userVal nam { get; set; } + public DateTime dob { get; set; } + + + public string ver { get; set; } + + public class certVal + { + + public string @is { get; set; } + public string ci { get; set; } + public string co { get; set; } + public int dn { get; set; } + public string dt { get; set; } + public string ma { get; set; } + public string mp { get; set; } + public int sd { get; set; } + public string tg { get; set; } + public string vp { get; set; } + + } + + public class userVal + { + + /// + /// Cognome + /// + public string fn { get; set; } + + public string fnt { get; set; } + + /// + /// Nome + /// + public string gn { get; set; } + + public string gnt { get; set; } + + } + + } +} diff --git a/GPW.CORE.Data/DTO/DailyDataDTO.cs b/GPW.CORE.Data/DTO/DailyDataDTO.cs new file mode 100644 index 0000000..dfd99d6 --- /dev/null +++ b/GPW.CORE.Data/DTO/DailyDataDTO.cs @@ -0,0 +1,71 @@ +using GPW.CORE.Data.DbModels; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data.DTO +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + public class DailyDataDTO + { + public int IdxDipendente { get; set; } = 0; + public DateTime DtRif { get; set; } = DateTime.Today; + + public List? ListRA { get; set; } + public List? ListTimbr { get; set; } + public TimbratureExplModel? TimbrExpl { get; set; } + public List? ListRilTemp { get; set; } + public List? ListCheckC19 { get; set; } + + public DateTime DtInizio + { + get + { + DateTime answ = DtRif; + if (ListTimbr != null && ListTimbr.Count > 0) + { + answ = ListTimbr + .OrderBy(x => x.DataOra) + .Take(1) + .Select(x => x.DataOra) + .FirstOrDefault(); + } + return answ; + } + } + + public double OreLav + { + get + { + double answ = 0; + if (ListRA != null && ListRA.Count > 0) + { + answ = ListRA + .Sum(x => x.OreTot == null ? 0 : (double)x.OreTot); + } + return answ; + } + } + public double OreComm + { + get + { + double answ = 0; + if (TimbrExpl != null && TimbrExpl.HLav != null) + { + answ = (double)TimbrExpl.HLav; + } + return answ; + } + } + + + + } +} diff --git a/GPW.CORE.Data/DTO/PeriodoDTO.cs b/GPW.CORE.Data/DTO/PeriodoDTO.cs new file mode 100644 index 0000000..ec30bde --- /dev/null +++ b/GPW.CORE.Data/DTO/PeriodoDTO.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data.DTO +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + public class PeriodoDTO + { + public DateTime Inizio { get; set; } + public DateTime Fine { get; set; } + public TipoPeriodo Tipo { get; set; } = TipoPeriodo.ND; + + public bool IsClosed { get; set; } = false; + + public decimal? OreTot { get; set; } + + public TimeSpan Durata + { + get + { + TimeSpan valore = TimeSpan.FromHours(0); + if (OreTot != null) + { + try + { + valore = TimeSpan.FromHours((double)OreTot); + } + catch (Exception exc) + { } + } + return valore; + } + } + } +} diff --git a/GPW.CORE.Data/DTO/WeekStatDTO.cs b/GPW.CORE.Data/DTO/WeekStatDTO.cs new file mode 100644 index 0000000..bd9de8d --- /dev/null +++ b/GPW.CORE.Data/DTO/WeekStatDTO.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data.DTO +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + public class WeekStatDTO + { + public int Anno { get; set; } = DateTime.Today.Year; + public int WeekNumber { get; set; } = 1; + public DateTime Inizio { get; set; } = DateTime.Today; + public DateTime Fine { get; set; } = DateTime.Today.AddDays(1); + + public int IdxDipendente { get; set; } = 0; + public double SumOreLav { get; set; } = 0; + public double SumOreComm { get; set; } = 0; + } +} diff --git a/GPW.CORE.Data/DbModels/AnagClientiModel.cs b/GPW.CORE.Data/DbModels/AnagClientiModel.cs new file mode 100644 index 0000000..49f4f4b --- /dev/null +++ b/GPW.CORE.Data/DbModels/AnagClientiModel.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("AnagClienti")] + public partial class AnagClientiModel + { + public AnagClientiModel() + { + ProgettiNav = new HashSet(); + } + + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int IdxCliente { get; set; } + public string? RagSociale { get; set; } = ""; + public string? Indirizzo { get; set; } = ""; + public string? Cap { get; set; } = ""; + public string? Citta { get; set; } = ""; + public string? Prov { get; set; } = ""; + public string? Tel { get; set; } = ""; + public string? Url { get; set; } = ""; + public string? Email { get; set; } = ""; + public string? PIva { get; set; } = ""; + public string? Cf { get; set; } = ""; + public string? LogoUrl { get; set; } = ""; + public string? Nota { get; set; } = ""; + public int OldIdx { get; set; } = 0; + public bool Attivo { get; set; } = false; + /// + /// codice esterno + /// + public string? CodExt { get; set; } = ""; + + public virtual ICollection ProgettiNav { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/AnagFasiModel.cs b/GPW.CORE.Data/DbModels/AnagFasiModel.cs new file mode 100644 index 0000000..1d03d11 --- /dev/null +++ b/GPW.CORE.Data/DbModels/AnagFasiModel.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("AnagFasi")] + public partial class AnagFasiModel + { + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int IdxFase { get; set; } + public int? IdxProgetto { get; set; } + /// + /// codice fase gerarchico (F.1.2. = Fase 1, sottofase 2) - aggiornare con trigger! + /// + public string CodFase { get; set; } = ""; + /// + /// fase ANCESTOR (contenitore), 0 = è top level + /// + public int IdxFaseAncest { get; set; } = 0; + public string NomeFase { get; set; } = ""; + public string DescrizioneFase { get; set; } = ""; + /// + /// indica se sia abilitata o meno a ricevere assegnazioni di record temporali + /// + public bool EnableTime { get; set; } = true; + /// + /// indica se sia abilitata o meno a ricevere assegnazioni di record di spesa + /// + public bool EnableMoney { get; set; } = false; + public bool Attivo { get; set; } = true; + /// + /// codice univoco + /// + public string CodClasse { get; set; } = ""; + /// + /// codice esterno + /// + public string CodExt { get; set; } = ""; + /// + /// Budget del progetto (in ore) + /// + public decimal BudgetTime { get; set; } = 0; + public decimal BudgetMoney { get; set; } = 0; + + [ForeignKey("IdxProgetto")] + public virtual AnagProgettiModel? ProgettoNav { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/AnagGruppiModel.cs b/GPW.CORE.Data/DbModels/AnagGruppiModel.cs new file mode 100644 index 0000000..1d24595 --- /dev/null +++ b/GPW.CORE.Data/DbModels/AnagGruppiModel.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("AnagGruppi")] + public partial class AnagGruppiModel + { + //public AnagGruppiModel() + //{ + // DipendentiNav = new HashSet(); + //} + public string Gruppo { get; set; } = null!; + public string? DescrGruppo { get; set; } + public string? CodExt { get; set; } + /// + /// determina se sia abilitato x export dati + /// + public bool? ExportEnab { get; set; } + + //public virtual ICollection DipendentiNav { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/AnagKeyValueModel.cs b/GPW.CORE.Data/DbModels/AnagKeyValueModel.cs new file mode 100644 index 0000000..257105b --- /dev/null +++ b/GPW.CORE.Data/DbModels/AnagKeyValueModel.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("AnagKeyValue")] + public partial class AnagKeyValueModel + { + public string NomeVar { get; set; } = null!; + public int? ValInt { get; set; } + public double? ValFloat { get; set; } + public string? ValString { get; set; } + public string? Descrizione { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/AnagOrariModel.cs b/GPW.CORE.Data/DbModels/AnagOrariModel.cs new file mode 100644 index 0000000..96a8f41 --- /dev/null +++ b/GPW.CORE.Data/DbModels/AnagOrariModel.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; + +#nullable disable + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("AnagOrari")] + public partial class AnagOrariModel + { + public AnagOrariModel() + { + DipendentiNav = new HashSet(); + } + + public string CodOrario { get; set; } + public string DescOrario { get; set; } + public double OreLun { get; set; } + public double OreMar { get; set; } + public double OreMer { get; set; } + public double OreGio { get; set; } + public double OreVen { get; set; } + public double OreSab { get; set; } + public double OreDom { get; set; } + public double OreOrdSett { get; set; } + public double OreStraordAss { get; set; } + public bool AutoCompOreOrd { get; set; } + public string TipoCompens { get; set; } + public TimeSpan OraInizio1 { get; set; } + public TimeSpan OraFine1 { get; set; } + public TimeSpan OraInizio2 { get; set; } + public TimeSpan OraFine2 { get; set; } + public TimeSpan OraInizio3 { get; set; } + public TimeSpan OraFine3 { get; set; } + public int ArrotMinuti { get; set; } + public string ChkFun { get; set; } + + public virtual ICollection DipendentiNav { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/AnagProgettiModel.cs b/GPW.CORE.Data/DbModels/AnagProgettiModel.cs new file mode 100644 index 0000000..924c9c8 --- /dev/null +++ b/GPW.CORE.Data/DbModels/AnagProgettiModel.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("AnagProgetti")] + public partial class AnagProgettiModel + { + public AnagProgettiModel() + { + FasiNav = new HashSet(); + } + + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int IdxProgetto { get; set; } + public int IdxCliente { get; set; } + public string NomeProj { get; set; } = ""; + public string DescrProj { get; set; } = ""; + public int OldIdx { get; set; } + public bool? Attivo { get; set; } + /// + /// codice esterno + /// + public string CodExt { get; set; } = ""; + public DateTime Avvio { get; set; } + public DateTime Chiusura { get; set; } + public string Gruppo { get; set; } = ""; + public bool Starred { get; set; } + + [ForeignKey("IdxCliente")] + public virtual AnagClientiModel ClienteNav { get; set; } = null!; + [ForeignKey("Gruppo")] + public virtual AnagGruppiModel GruppiNav { get; set; } = null!; + public virtual ICollection FasiNav { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/AnagTipoTimbModel.cs b/GPW.CORE.Data/DbModels/AnagTipoTimbModel.cs new file mode 100644 index 0000000..cb8c14f --- /dev/null +++ b/GPW.CORE.Data/DbModels/AnagTipoTimbModel.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +#nullable disable + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("AnagTipoTimb")] + public partial class AnagTipoTimbModel + { + public AnagTipoTimbModel() + { + TimbratureNav = new HashSet(); + } + [Key] + public string CodTipoTimb { get; set; } + public string DescrTipoTimb { get; set; } + + public virtual ICollection TimbratureNav { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/CalcOreFasiModel.cs b/GPW.CORE.Data/DbModels/CalcOreFasiModel.cs new file mode 100644 index 0000000..f540336 --- /dev/null +++ b/GPW.CORE.Data/DbModels/CalcOreFasiModel.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + public partial class CalcOreFasiModel + { + + [Key] + public int IdxFase { get; set; } + public int IdxProgetto { get; set; } + public string CodFase { get; set; } = ""; + public int IdxFaseAncest { get; set; } + public string NomeFase { get; set; } = ""; + public string DescrizioneFase { get; set; } = ""; + public bool? EnableTime { get; set; } + public bool? EnableMoney { get; set; } + public bool? Attivo { get; set; } + public decimal budgetTime { get; set; } = 0; + public decimal budgetMoney { get; set; } = 0; + public double percOpen { get; set; } = 1; + public string CodClasse { get; set; } = ""; + public string CodExt { get; set; } = ""; + public decimal totOre { get; set; } = 0; + + [NotMapped] + public decimal percUsed + { + get + { + decimal answ = 0; + decimal denom = budgetTime > 0 ? budgetTime : 1; + answ = totOre / denom; + return answ; + } + } + [NotMapped] + public decimal timeRem + { + get + { + return budgetTime - totOre; + } + } + } +} diff --git a/GPW.CORE.Data/DbModels/CalcOreProgettiModel.cs b/GPW.CORE.Data/DbModels/CalcOreProgettiModel.cs new file mode 100644 index 0000000..0a89e4b --- /dev/null +++ b/GPW.CORE.Data/DbModels/CalcOreProgettiModel.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + public partial class CalcOreProgettiModel + { + + [Key] + public int IdxProgetto { get; set; } + public int IdxCliente { get; set; } + public string NomeProj { get; set; } = ""; + public string DescrProj { get; set; } = ""; + public int OldIdx { get; set; } + public bool? Attivo { get; set; } + /// + /// codice esterno + /// + public string CodExt { get; set; } = ""; + public DateTime Avvio { get; set; } + public DateTime Chiusura { get; set; } + public string Gruppo { get; set; } = ""; + + public string RagSociale { get; set; } = ""; + public decimal budgetTime { get; set; } = 0; + public decimal budgetMoney { get; set; } = 0; + public decimal totOre { get; set; } = 0; + public decimal totOrePrevMont { get; set; } = 0; + public decimal totOreLast30 { get; set; } = 0; + + [NotMapped] + public decimal percUsed + { + get + { + decimal answ = 0; + decimal denom = budgetTime > 0 ? budgetTime : 1; + answ = totOre / denom; + return answ; + } + } + [NotMapped] + public decimal timeRem + { + get + { + return budgetTime - totOre; + } + } + } +} diff --git a/GPW.CORE.Data/DbModels/CheckVc19Model.cs b/GPW.CORE.Data/DbModels/CheckVc19Model.cs new file mode 100644 index 0000000..f3bd3eb --- /dev/null +++ b/GPW.CORE.Data/DbModels/CheckVc19Model.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("CheckVc19")] + public partial class CheckVc19Model + { + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int IdxCheckVc19 { get; set; } + public DateTime DtCheck { get; set; } = DateTime.Now; + public int IdxDipendente { get; set; } + public string Cognome { get; set; } = null!; + public string Nome { get; set; } = null!; + public DateTime Dob { get; set; } + public string Payload { get; set; } = null!; + + /// + /// Navigation property to Dipendente + /// + [ForeignKey("IdxDipendente")] + public virtual DipendentiModel? DipNav { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/DipendentiModel.cs b/GPW.CORE.Data/DbModels/DipendentiModel.cs new file mode 100644 index 0000000..155faaf --- /dev/null +++ b/GPW.CORE.Data/DbModels/DipendentiModel.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("Dipendenti")] + public partial class DipendentiModel + { + public DipendentiModel() + { + RegAttivitaNav = new HashSet(); + RilievoTempNav = new HashSet(); + TimbratureNav = new HashSet(); + } + + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int IdxDipendente { get; set; } + public string? Matricola { get; set; } + public string Cf { get; set; } = null!; + public string? Cognome { get; set; } + public string? Nome { get; set; } + public DateTime? DataNascita { get; set; } + public string? LuogoNascita { get; set; } + public string? ProvNascita { get; set; } + public string? NazNascita { get; set; } + public string CodHw { get; set; } = null!; + public string? CodOrario { get; set; } + public bool? MailLastOp { get; set; } + public bool? MailDay { get; set; } + public bool? MailWeek { get; set; } + public bool? MailMonth { get; set; } + public string Email { get; set; } = null!; + public string AuthKey { get; set; } = null!; + /// + /// numero di impieghi della authKey + /// + public int? NumAuth { get; set; } + public string? WolMac { get; set; } + public string Dominio { get; set; } = null!; + public string Utente { get; set; } = null!; + /// + /// nome/codice dipendente per sistema esterno da importare + /// + public string CodDipendenteExt { get; set; } = null!; + public string? Gruppo { get; set; } + public DateTime? DataAssunzione { get; set; } + public DateTime? DataCessazione { get; set; } + public bool? Attivo { get; set; } + + public virtual ICollection RegAttivitaNav { get; set; } + public virtual ICollection RilievoTempNav { get; set; } + public virtual ICollection TimbratureNav { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/ParetoRegAttModel.cs b/GPW.CORE.Data/DbModels/ParetoRegAttModel.cs new file mode 100644 index 0000000..a2899f0 --- /dev/null +++ b/GPW.CORE.Data/DbModels/ParetoRegAttModel.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + public partial class ParetoRegAttModel + { + [Key] + public long RowNum { get; set; } = 0; + public string nomeComm { get; set; } = ""; + public int idxFaseComm { get; set; } = 0; + public int idxFase { get; set; } = 0; + public string nomeProj { get; set; } = ""; + public string nomeFase { get; set; } = ""; + public decimal freq { get; set; } = 0; + public decimal qty { get; set; } = 0; + public int tot{ get; set; } = 0; + } +} diff --git a/GPW.CORE.Data/DbModels/RegAttivitaExplModel.cs b/GPW.CORE.Data/DbModels/RegAttivitaExplModel.cs new file mode 100644 index 0000000..3a4a042 --- /dev/null +++ b/GPW.CORE.Data/DbModels/RegAttivitaExplModel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("RegAttivitaExpl")] + public partial class RegAttivitaExplModel + { + public DateTime DataLav { get; set; } + public int IdxDipendente { get; set; } + public string? CognomeNome { get; set; } + /// + /// totale dei minuti di attività registrate per la giornata (da trigger suRegAttivita) + /// + public int? MinRegAtt { get; set; } + public string? DescrProj { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/RegAttivitaModel.cs b/GPW.CORE.Data/DbModels/RegAttivitaModel.cs new file mode 100644 index 0000000..f6365ec --- /dev/null +++ b/GPW.CORE.Data/DbModels/RegAttivitaModel.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("RegAttivita")] + public partial class RegAttivitaModel + { + [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int IdxRa { get; set; } + public int IdxDipendente { get; set; } = 0; + public int IdxFase { get; set; } + public DateTime Inizio { get; set; } + public DateTime Fine { get; set; } + public string? Descrizione { get; set; } + /// + /// Ore Attività - prima era ([dbo].[f_hourInterval]([inizio],[fine])) poi sostituita per performance + /// + public decimal? OreTot { get; set; } + + [NotMapped] + public TimeSpan Durata + { + get + { + TimeSpan valore = TimeSpan.FromHours(0); + if (OreTot != null) + { + try + { + valore = TimeSpan.FromHours((double)OreTot); + } + catch (Exception exc) + { } + } + return valore; + } + } + + public decimal? Importo { get; set; } + + [ForeignKey("IdxDipendente")] + public virtual DipendentiModel? DipNav { get; set; } + [ForeignKey("IdxFase")] + public virtual AnagFasiModel? FasiNav { get; set; } + + } +} diff --git a/GPW.CORE.Data/DbModels/RilievoTempModel.cs b/GPW.CORE.Data/DbModels/RilievoTempModel.cs new file mode 100644 index 0000000..142511c --- /dev/null +++ b/GPW.CORE.Data/DbModels/RilievoTempModel.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // This is here so CodeMaid doesn't reorganize this document + // + [Table("RilievoTemp")] + public partial class RilievoTempModel + { + public int IdxDipendente { get; set; } + public DateTime DtRilievo { get; set; } + public decimal TempRil { get; set; } + + /// + /// Navigation property to Dipendente + /// + [ForeignKey("IdxDipendente")] + public virtual DipendentiModel DipNav { get; set; } = null!; + } +} diff --git a/GPW.CORE.Data/DbModels/TimbratureExplModel.cs b/GPW.CORE.Data/DbModels/TimbratureExplModel.cs new file mode 100644 index 0000000..47126a4 --- /dev/null +++ b/GPW.CORE.Data/DbModels/TimbratureExplModel.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("TimbratureExpl")] + public partial class TimbratureExplModel + { + public DateTime DataLav { get; set; } + public int IdxDipendente { get; set; } + public string? CognomeNome { get; set; } + public DateTime? Entrata1 { get; set; } + public DateTime? Uscita1 { get; set; } + public DateTime? Entrata2 { get; set; } + public DateTime? Uscita2 { get; set; } + public DateTime? Entrata3 { get; set; } + public DateTime? Uscita3 { get; set; } + public DateTime? Entrata4 { get; set; } + public DateTime? Uscita4 { get; set; } + public double? HLav { get; set; } + public int? MinLav { get; set; } + public int? MinOrd { get; set; } + /// + /// minuti non lavorati (ovvero se fatti meno di ordinari e senza giustificativi) + /// + public int? MinNonLav { get; set; } + public int? MinStra { get; set; } + public int? MinPerm { get; set; } + public int? MinFer { get; set; } + public int? MinMal { get; set; } + public int? MinFest { get; set; } + /// + /// Minuti di Cassa Integrazione + /// + public int? MinCassa { get; set; } + /// + /// Minuti Permessi per 104 + /// + public int? Min104 { get; set; } + public int? MinMpp { get; set; } + /// + /// DATEDIFF(n, ISNULL(entrata_1,GETDATE()), ISNULL(ISNULL(uscita_4,ISNULL(uscita_3,ISNULL(uscita_2,ISNULL(uscita_1,entrata_1)))),GETDATE())) + /// + public int? MinArcoPres { get; set; } + public bool? IsOkTim { get; set; } + /// + /// dato sintetico x indicare se TUTTE le timbrature componenti siano approvate + /// + public bool? IsOkApp { get; set; } + /// + /// determina se il record sia "bloccato" (archiviazione e blocco mesi precedenti...) + /// + public bool? Block { get; set; } + /// + /// eventuale diagnostica da check function sulla riga indicata (codice) + /// + public string? ChkFunCod { get; set; } + /// + /// eventuale diagnostica da check function sulla riga indicata (spiegazione) + /// + public string? ChkFunRes { get; set; } + public int? IsOk { get; set; } + /// + /// determina se la giornata sia ok (oreLav + giustificativi >= oreOrd) + /// + public int IsOkLav { get; set; } + /// + /// totale ore giustificate + /// + public double? HGiust { get; set; } + /// + /// Temperatura rilevata + /// + public decimal TempRil { get; set; } + } +} diff --git a/GPW.CORE.Data/DbModels/TimbratureModel.cs b/GPW.CORE.Data/DbModels/TimbratureModel.cs new file mode 100644 index 0000000..6fe5a0c --- /dev/null +++ b/GPW.CORE.Data/DbModels/TimbratureModel.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; + +namespace GPW.CORE.Data.DbModels +{ + // + // This is here so CodeMaid doesn't reorganize this document + // + [Table("Timbrature")] + public partial class TimbratureModel + { + public DateTime DataOra { get; set; } + public int IdxDipendente { get; set; } + public bool? Entrata { get; set; } + public string? Ipv4 { get; set; } + public string? CodTipoTimb { get; set; } + /// + /// Approvazioen timbratura (default true...) + /// + public bool? Approv { get; set; } + + + + /// + /// Navigation property to TipoTimb + /// + [ForeignKey("CodTipoTimb")] + public virtual AnagTipoTimbModel CodTipoTimbNav { get; set; } = null!; + /// + /// Navigation property to Dipendente + /// + [ForeignKey("IdxDipendente")] + public virtual DipendentiModel DipNav { get; set; } = null!; + } +} diff --git a/GPW.CORE.Data/Enum.cs b/GPW.CORE.Data/Enum.cs new file mode 100644 index 0000000..a5dc757 --- /dev/null +++ b/GPW.CORE.Data/Enum.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data +{ + public enum TipoPeriodo + { + ND = 0, + Lavoro = 1 + } + public enum TestUser + { + LocatelliSamuele = 1, + SalviMarco = 3, + RottoliGiancarlo = 4, + BaroniMara = 6, + LocatelliMarco = 8, + SassiDario = 10, + SassiEmmanuele = 11, + LanzaRenzo = 12, + MangiaLorenzo = 13, + PerdoncinSara = 14, + PievaniNicola = 15, + Tarri, Selene = 16, + BaronchelliCarlo = 18, + MonchiFilippo = 19, + VivianiCarlo = 20 + } +} diff --git a/GPW.CORE.Data/GPW.CORE.Data.csproj b/GPW.CORE.Data/GPW.CORE.Data.csproj new file mode 100644 index 0000000..2495353 --- /dev/null +++ b/GPW.CORE.Data/GPW.CORE.Data.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + enable + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + diff --git a/GPW.CORE.Data/GPWContext.cs b/GPW.CORE.Data/GPWContext.cs new file mode 100644 index 0000000..bb0fd07 --- /dev/null +++ b/GPW.CORE.Data/GPWContext.cs @@ -0,0 +1,744 @@ +using System; +using System.Collections.Generic; +using GPW.CORE.Data.DbModels; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.Extensions.Configuration; +using NLog; + +namespace GPW.CORE.Data +{ + public partial class GPWContext : DbContext + { + + private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); + + private IConfiguration _configuration = null!; + + public GPWContext() + { + } + + public GPWContext(IConfiguration configuration) + { + _configuration = configuration; + } + + public GPWContext(DbContextOptions options) : base(options) + { + try + { + // se non ci fosse... crea o migra! + Database.Migrate(); + } + catch (Exception exc) + { + Log.Error(exc, "Exception during context initialization 02"); + } + } + + public virtual DbSet DbSetCheckVc19 { get; set; } = null!; + public virtual DbSet DbSetDipendenti { get; set; } = null!; + public virtual DbSet DbSetRegAttivita { get; set; } = null!; + public virtual DbSet DbSetRegAttivitaExpl { get; set; } = null!; + public virtual DbSet DbSetRilievoTemp { get; set; } = null!; + public virtual DbSet DbSetTimbrature { get; set; } = null!; + public virtual DbSet DbSetTimbratureExpl { get; set; } = null!; + public virtual DbSet DbSetAnagClienti { get; set; } = null!; + public virtual DbSet DbSetAnagFasi { get; set; } = null!; + public virtual DbSet DbSetAnagProgetti { get; set; } = null!; + public virtual DbSet DbSetAnagGruppi { get; set; } = null!; + public virtual DbSet DbSetParetoRegAtt { get; set; } = null!; + public virtual DbSet DbSetCalcOreProj { get; set; } = null!; + public virtual DbSet DbSetCalcOreFasi { get; set; } = null!; + public virtual DbSet DbSetAnagKeyValue { get; set; } = null!; + public virtual DbSet DbSetAnagTipoTimb { get; set; } = null!; + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!optionsBuilder.IsConfigured) + { + string connString = _configuration.GetConnectionString("GPW.DB"); + if (!string.IsNullOrEmpty(connString)) + { + optionsBuilder.UseSqlServer(connString); + } + else + { + optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=Sauder_NKC;Trusted_Connection=True;"); + optionsBuilder.UseSqlServer("Server=SQLSTEAM;Database=GPW;Trusted_Connection=True;"); + } + } + } + + public void DbForceMigrate() + { + try + { + // se non ci fosse... crea o migra! + Database.Migrate(); + Log.Info("DbForceMigrate: done!"); + } + catch (Exception exc) + { + Log.Error(exc, "DbForceMigrate: Exception during context initialization 01"); + } + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.UseCollation("Latin1_General_CI_AS"); + + modelBuilder.Entity(entity => + { + entity.Property(e => e.Cognome) + .HasMaxLength(100) + .HasColumnName("cognome") + .HasDefaultValueSql("('')"); + + entity.Property(e => e.Dob) + .HasColumnType("datetime") + .HasColumnName("DOB") + .HasDefaultValueSql("(getdate())"); + + entity.Property(e => e.DtCheck) + .HasColumnType("datetime") + .HasColumnName("dtCheck") + .HasDefaultValueSql("(getdate())"); + + entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente"); + + entity.Property(e => e.Nome) + .HasMaxLength(100) + .HasColumnName("nome") + .HasDefaultValueSql("('')"); + + entity.Property(e => e.Payload) + .HasMaxLength(500) + .HasColumnName("payload") + .HasDefaultValueSql("('')"); + }); + + modelBuilder.Entity(entity => + { + + entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente"); + + entity.Property(e => e.Attivo) + .HasColumnName("attivo") + .HasDefaultValueSql("((1))"); + + entity.Property(e => e.AuthKey) + .HasMaxLength(50) + .HasColumnName("authKey") + .HasDefaultValueSql("('##########')"); + + entity.Property(e => e.Cf) + .HasMaxLength(16) + .HasColumnName("CF") + .HasDefaultValueSql("('0000000000000000')"); + + entity.Property(e => e.CodDipendenteExt) + .HasMaxLength(50) + .HasColumnName("codDipendenteExt") + .HasDefaultValueSql("('')") + .HasComment("nome/codice dipendente per sistema esterno da importare"); + + entity.Property(e => e.CodHw) + .HasMaxLength(50) + .HasColumnName("codHw") + .HasDefaultValueSql("('')"); + + entity.Property(e => e.CodOrario) + .HasMaxLength(50) + .HasColumnName("codOrario"); + + entity.Property(e => e.Cognome).HasMaxLength(50); + + entity.Property(e => e.DataAssunzione) + .HasColumnType("date") + .HasColumnName("dataAssunzione") + .HasDefaultValueSql("('1900-01-01')"); + + entity.Property(e => e.DataCessazione) + .HasColumnType("date") + .HasColumnName("dataCessazione") + .HasDefaultValueSql("('9999-12-31')"); + + entity.Property(e => e.DataNascita) + .HasColumnType("datetime") + .HasColumnName("dataNascita"); + + entity.Property(e => e.Dominio) + .HasMaxLength(50) + .HasColumnName("dominio") + .HasDefaultValueSql("('DOMINIO')"); + + entity.Property(e => e.Email) + .HasMaxLength(250) + .HasColumnName("email") + .HasDefaultValueSql("('')"); + + entity.Property(e => e.Gruppo) + .HasMaxLength(50) + .HasColumnName("gruppo") + .HasDefaultValueSql("('NA')"); + + entity.Property(e => e.LuogoNascita) + .HasMaxLength(50) + .HasColumnName("luogoNascita"); + + entity.Property(e => e.MailDay) + .HasColumnName("mailDay") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.MailLastOp) + .HasColumnName("mailLastOp") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.MailMonth) + .HasColumnName("mailMonth") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.MailWeek) + .HasColumnName("mailWeek") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.Matricola) + .HasMaxLength(50) + .HasColumnName("matricola"); + + entity.Property(e => e.NazNascita) + .HasMaxLength(50) + .HasColumnName("nazNascita"); + + entity.Property(e => e.Nome).HasMaxLength(50); + + entity.Property(e => e.NumAuth) + .HasColumnName("numAuth") + .HasDefaultValueSql("((0))") + .HasComment("numero di impieghi della authKey"); + + entity.Property(e => e.ProvNascita) + .HasMaxLength(50) + .HasColumnName("provNascita"); + + entity.Property(e => e.Utente) + .HasMaxLength(50) + .HasColumnName("utente") + .HasDefaultValueSql("('UTENTE')"); + + entity.Property(e => e.WolMac) + .HasMaxLength(50) + .HasColumnName("WOL_MAC"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => e.Inizio, "ix_RA_inizio"); + + entity.HasIndex(e => new { e.IdxDipendente, e.Inizio }, "ix_idxDip"); + + entity.HasIndex(e => new { e.IdxFase, e.Inizio }, "ix_idxFase") + .HasFillFactor(100); + + entity.HasIndex(e => new { e.Inizio, e.IdxDipendente }, "ix_inizio"); + + entity.Property(e => e.IdxRa).HasColumnName("idxRA"); + + entity.Property(e => e.Descrizione) + .HasMaxLength(500) + .HasColumnName("descrizione"); + + entity.Property(e => e.Fine) + .HasColumnType("datetime") + .HasColumnName("fine"); + + entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente"); + + entity.Property(e => e.IdxFase).HasColumnName("idxFase"); + + entity.Property(e => e.Importo) + .HasColumnType("decimal(19, 4)") + .HasColumnName("importo") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.Inizio) + .HasColumnType("datetime") + .HasColumnName("inizio"); + + entity.Property(e => e.OreTot) + .HasColumnType("decimal(19, 4)") + .HasColumnName("oreTot") + .HasComputedColumnSql("(CONVERT([decimal](19,4),CONVERT([decimal](19,4),datediff(minute,isnull([inizio],'19000101'),isnull([fine],'19000101')),(0))/(60),(0)))", false) + .HasComment("Ore Attività - prima era ([dbo].[f_hourInterval]([inizio],[fine])) poi sostituita per performance"); + + //entity.HasOne(d => d.DipNav) + // .WithMany(p => p.RegAttivitaNav) + // .HasForeignKey(d => d.IdxDipendente) + // .OnDelete(DeleteBehavior.ClientSetNull) + // .HasConstraintName("FK_RegAttivita_Dipendenti"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.IdxDipendente, e.DtRilievo }); + + entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente"); + + entity.Property(e => e.DtRilievo) + .HasColumnType("datetime") + .HasColumnName("dtRilievo"); + + entity.Property(e => e.TempRil) + .HasColumnType("decimal(9, 3)") + .HasColumnName("tempRil"); + + entity.HasOne(d => d.DipNav) + .WithMany(p => p.RilievoTempNav) + .HasForeignKey(d => d.IdxDipendente) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_RilievoTemp_Dipendenti"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.IdxDipendente, e.DataOra }); + + entity.HasIndex(e => new { e.IdxDipendente, e.Entrata }, "ix_Timbrature_IdxDip_Entrata"); + + entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente"); + + entity.Property(e => e.DataOra) + .HasColumnType("datetime") + .HasColumnName("dataOra"); + + entity.Property(e => e.Approv) + .HasDefaultValueSql("((0))") + .HasComment("Approvazioen timbratura (default true...)"); + + entity.Property(e => e.CodTipoTimb) + .HasMaxLength(10) + .HasDefaultValueSql("(N'BC')"); + + entity.Property(e => e.Entrata).HasColumnName("entrata"); + + entity.Property(e => e.Ipv4) + .HasMaxLength(15) + .HasColumnName("IPv4") + .HasDefaultValueSql("(N'0.0.0.0')"); + + entity.HasOne(d => d.DipNav) + .WithMany(p => p.TimbratureNav) + .HasForeignKey(d => d.IdxDipendente) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_Timbrature_Dipendenti"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.DataLav, e.IdxDipendente }); + + entity.ToTable("RegAttivitaExpl"); + + entity.Property(e => e.DataLav) + .HasColumnType("date") + .HasColumnName("dataLav"); + + entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente"); + + entity.Property(e => e.CognomeNome) + .HasMaxLength(100) + .HasDefaultValueSql("('')"); + + entity.Property(e => e.DescrProj) + .HasMaxLength(500) + .HasColumnName("descrProj") + .HasDefaultValueSql("('')"); + + entity.Property(e => e.MinRegAtt) + .HasColumnName("minRegAtt") + .HasDefaultValueSql("((0))") + .HasComment("totale dei minuti di attività registrate per la giornata (da trigger suRegAttivita)"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => new { e.DataLav, e.IdxDipendente }) + .HasName("PK_TimbratureExpl_1"); + + entity.ToTable("TimbratureExpl"); + + entity.HasIndex(e => new { e.CognomeNome, e.DataLav }, "ix_TimbrExpl_CognomeNome_DataLav") + .HasFillFactor(100); + + entity.HasIndex(e => e.IdxDipendente, "ix_idxDip") + .HasFillFactor(100); + + entity.Property(e => e.DataLav) + .HasColumnType("date") + .HasColumnName("dataLav"); + + entity.Property(e => e.IdxDipendente).HasColumnName("idxDipendente"); + + entity.Property(e => e.Block) + .HasColumnName("block") + .HasDefaultValueSql("((0))") + .HasComment("determina se il record sia \"bloccato\" (archiviazione e blocco mesi precedenti...)"); + + entity.Property(e => e.ChkFunCod) + .HasMaxLength(50) + .HasColumnName("chkFunCod") + .HasDefaultValueSql("('')") + .HasComment("eventuale diagnostica da check function sulla riga indicata (codice)"); + + entity.Property(e => e.ChkFunRes) + .HasMaxLength(50) + .HasColumnName("chkFunRes") + .HasDefaultValueSql("('')") + .HasComment("eventuale diagnostica da check function sulla riga indicata (spiegazione)"); + + entity.Property(e => e.CognomeNome).HasMaxLength(100); + + entity.Property(e => e.Entrata1) + .HasColumnType("datetime") + .HasColumnName("entrata_1"); + + entity.Property(e => e.Entrata2) + .HasColumnType("datetime") + .HasColumnName("entrata_2"); + + entity.Property(e => e.Entrata3) + .HasColumnType("datetime") + .HasColumnName("entrata_3"); + + entity.Property(e => e.Entrata4) + .HasColumnType("datetime") + .HasColumnName("entrata_4"); + + entity.Property(e => e.HGiust) + .HasColumnName("h_giust") + .HasComputedColumnSql("(((((((CONVERT([float],[minPerm],(0))+[minFer])+[minMal])+[minFest])+[min104])+[minMpp])+[minCassa])/(60))", false) + .HasComment("totale ore giustificate"); + + entity.Property(e => e.HLav).HasColumnName("h_lav"); + + entity.Property(e => e.IsOk) + .HasColumnName("isOk") + .HasComputedColumnSql("(([isOkTim]&[isOkApp])&case when [minOrd]<=((((((([minLav]+[minPerm])+[minFer])+[minMal])+[minFest])+[minCassa])+[min104])+[minMpp]) then (1) else (0) end)", false); + + entity.Property(e => e.IsOkApp) + .HasColumnName("isOkApp") + .HasDefaultValueSql("((1))") + .HasComment("dato sintetico x indicare se TUTTE le timbrature componenti siano approvate"); + + entity.Property(e => e.IsOkLav) + .HasColumnName("isOkLav") + .HasComputedColumnSql("(case when [minOrd]<=((((((([minLav]+[minPerm])+[minFer])+[minMal])+[minFest])+[minCassa])+[min104])+[minMpp]) then (1) else (0) end)", false) + .HasComment("determina se la giornata sia ok (oreLav + giustificativi >= oreOrd)"); + + entity.Property(e => e.IsOkTim) + .HasColumnName("isOkTim") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.Min104) + .HasColumnName("min104") + .HasDefaultValueSql("((0))") + .HasComment("Minuti Permessi per 104"); + + entity.Property(e => e.MinArcoPres) + .HasColumnName("minArcoPres") + .HasComputedColumnSql("(datediff(minute,isnull([entrata_1],getdate()),isnull(isnull([uscita_4],isnull([uscita_3],isnull([uscita_2],isnull([uscita_1],[entrata_1])))),getdate())))", false) + .HasComment("DATEDIFF(n, ISNULL(entrata_1,GETDATE()), ISNULL(ISNULL(uscita_4,ISNULL(uscita_3,ISNULL(uscita_2,ISNULL(uscita_1,entrata_1)))),GETDATE()))"); + + entity.Property(e => e.MinCassa) + .HasColumnName("minCassa") + .HasDefaultValueSql("((0))") + .HasComment("Minuti di Cassa Integrazione"); + + entity.Property(e => e.MinFer) + .HasColumnName("minFer") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.MinFest) + .HasColumnName("minFest") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.MinLav) + .HasColumnName("minLav") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.MinMal) + .HasColumnName("minMal") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.MinMpp) + .HasColumnName("minMpp") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.MinNonLav) + .HasColumnName("minNonLav") + .HasDefaultValueSql("((0))") + .HasComment("minuti non lavorati (ovvero se fatti meno di ordinari e senza giustificativi)"); + + entity.Property(e => e.MinOrd) + .HasColumnName("minOrd") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.MinPerm) + .HasColumnName("minPerm") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.MinStra) + .HasColumnName("minStra") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.TempRil) + .HasColumnType("decimal(9, 3)") + .HasColumnName("tempRil") + .HasComment("Temperatura rilevata"); + + entity.Property(e => e.Uscita1) + .HasColumnType("datetime") + .HasColumnName("uscita_1"); + + entity.Property(e => e.Uscita2) + .HasColumnType("datetime") + .HasColumnName("uscita_2"); + + entity.Property(e => e.Uscita3) + .HasColumnType("datetime") + .HasColumnName("uscita_3"); + + entity.Property(e => e.Uscita4) + .HasColumnType("datetime") + .HasColumnName("uscita_4"); + }); + + modelBuilder.Entity(entity => + { + entity.Property(e => e.IdxCliente).HasColumnName("idxCliente"); + + entity.Property(e => e.Attivo).HasDefaultValueSql("((1))"); + + entity.Property(e => e.Cap) + .HasMaxLength(5) + .HasColumnName("CAP"); + + entity.Property(e => e.Cf) + .HasMaxLength(20) + .HasColumnName("CF"); + + entity.Property(e => e.Citta) + .HasMaxLength(50) + .HasColumnName("citta"); + + entity.Property(e => e.CodExt) + .HasMaxLength(50) + .HasColumnName("codExt") + .HasDefaultValueSql("('n.d.')") + .HasComment("codice esterno"); + + entity.Property(e => e.Email) + .HasMaxLength(50) + .HasColumnName("email"); + + entity.Property(e => e.Indirizzo) + .HasMaxLength(50) + .HasColumnName("indirizzo"); + + entity.Property(e => e.LogoUrl) + .HasMaxLength(50) + .HasColumnName("logoUrl"); + + entity.Property(e => e.Nota) + .HasMaxLength(500) + .HasColumnName("nota"); + + entity.Property(e => e.OldIdx).HasDefaultValueSql("((-1))"); + + entity.Property(e => e.PIva) + .HasMaxLength(20) + .HasColumnName("pIva"); + + entity.Property(e => e.Prov) + .HasMaxLength(50) + .HasColumnName("prov"); + + entity.Property(e => e.RagSociale).HasMaxLength(250); + + entity.Property(e => e.Tel) + .HasMaxLength(50) + .HasColumnName("tel"); + + entity.Property(e => e.Url) + .HasMaxLength(50) + .HasColumnName("url"); + }); + + modelBuilder.Entity(entity => + { + entity.HasIndex(e => new { e.IdxProgetto, e.Attivo }, "ix_AnagFasi_idxProgetto_Attivo"); + + entity.Property(e => e.IdxFase).HasColumnName("idxFase"); + + entity.Property(e => e.Attivo) + .IsRequired() + .HasDefaultValueSql("((1))"); + + entity.Property(e => e.BudgetMoney) + .HasColumnType("decimal(19, 4)") + .HasColumnName("budgetMoney"); + + entity.Property(e => e.BudgetTime) + .HasColumnType("decimal(19, 4)") + .HasColumnName("budgetTime") + .HasComment("Budget del progetto (in ore)"); + + entity.Property(e => e.CodClasse) + .HasMaxLength(10) + .HasColumnName("codClasse") + .HasComment("codice univoco"); + + entity.Property(e => e.CodExt) + .HasMaxLength(50) + .HasColumnName("codExt") + .HasComment("codice esterno"); + + entity.Property(e => e.CodFase) + .HasMaxLength(250) + .HasColumnName("codFase") + .HasComment("codice fase gerarchico (F.1.2. = Fase 1, sottofase 2) - aggiornare con trigger!"); + + entity.Property(e => e.DescrizioneFase) + .HasMaxLength(250) + .HasColumnName("descrizioneFase"); + + entity.Property(e => e.EnableMoney) + .HasColumnName("enableMoney") + .HasDefaultValueSql("((0))") + .HasComment("indica se sia abilitata o meno a ricevere assegnazioni di record di spesa"); + + entity.Property(e => e.EnableTime) + .HasColumnName("enableTime") + .HasDefaultValueSql("((0))") + .HasComment("indica se sia abilitata o meno a ricevere assegnazioni di record temporali"); + + entity.Property(e => e.IdxFaseAncest) + .HasColumnName("idxFaseAncest") + .HasComment("fase ANCESTOR (contenitore), 0 = è top level"); + + entity.Property(e => e.IdxProgetto).HasColumnName("idxProgetto"); + + entity.Property(e => e.NomeFase) + .HasMaxLength(250) + .HasColumnName("nomeFase"); + + }); + + modelBuilder.Entity(entity => + { + + entity.Property(e => e.IdxProgetto).HasColumnName("idxProgetto"); + + entity.Property(e => e.Attivo) + .IsRequired() + .HasDefaultValueSql("((1))"); + + entity.Property(e => e.Avvio) + .HasColumnType("datetime") + .HasColumnName("avvio") + .HasDefaultValueSql("(getdate())"); + + entity.Property(e => e.Chiusura) + .HasColumnType("datetime") + .HasColumnName("chiusura") + .HasDefaultValueSql("(dateadd(year,(10),getdate()))"); + + entity.Property(e => e.CodExt) + .HasMaxLength(50) + .HasColumnName("codExt") + .HasDefaultValueSql("('')") + .HasComment("codice esterno"); + + entity.Property(e => e.DescrProj) + .HasMaxLength(250) + .HasColumnName("descrProj") + .HasDefaultValueSql("('-')"); + + entity.Property(e => e.Gruppo) + .HasMaxLength(50) + .HasColumnName("gruppo") + .HasDefaultValueSql("('STEAMWARE')"); + + entity.Property(e => e.IdxCliente).HasColumnName("idxCliente"); + + entity.Property(e => e.NomeProj) + .HasMaxLength(50) + .HasColumnName("nomeProj"); + + entity.Property(e => e.Starred).HasColumnName("starred"); + + }); + + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Gruppo); + + entity.ToTable("AnagGruppi"); + + entity.Property(e => e.Gruppo) + .HasMaxLength(50) + .HasColumnName("gruppo"); + + entity.Property(e => e.CodExt) + .HasMaxLength(4) + .HasColumnName("codExt"); + + entity.Property(e => e.DescrGruppo) + .HasMaxLength(50) + .HasColumnName("descrGruppo"); + + entity.Property(e => e.ExportEnab) + .HasColumnName("exportEnab") + .HasDefaultValueSql("((1))") + .HasComment("determina se sia abilitato x export dati"); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.NomeVar); + + entity.ToTable("AnagKeyValue"); + + entity.Property(e => e.NomeVar) + .HasMaxLength(50) + .HasColumnName("nomeVar"); + + entity.Property(e => e.Descrizione) + .HasMaxLength(250) + .HasColumnName("descrizione") + .HasDefaultValueSql("('-')"); + + entity.Property(e => e.ValFloat) + .HasColumnName("valFloat") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.ValInt) + .HasColumnName("valInt") + .HasDefaultValueSql("((0))"); + + entity.Property(e => e.ValString) + .HasMaxLength(250) + .HasColumnName("valString") + .HasDefaultValueSql("('')"); + }); + + + OnModelCreatingPartial(modelBuilder); + } + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); + } +} diff --git a/GPW.CORE.Data/LiManObj.cs b/GPW.CORE.Data/LiManObj.cs new file mode 100644 index 0000000..efedf8f --- /dev/null +++ b/GPW.CORE.Data/LiManObj.cs @@ -0,0 +1,220 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data +{ + public class LiManObj + { + #region Public Enums + + public enum StatoRichiesta + { + ND = 0, + + Richiesta, + + Valutazione, + + Approvata, + + Rifiutata + } + + public enum TipoLicenza + { + ND = 0, + + /// + /// Licenza LEgacy Steamware + /// + GLS, + + /// + /// Master Key License, che ha una data di scadenza globale ed un token = numero di utenti/token massimi associati + /// + MasterKey, + + /// + /// UserKey License (licenza che consuma un token utente della licenza master) - es GPW + /// + UserKey, + + /// + /// Chiave tiupo Checksum basata su licenza masster + checksum MD5 di una serie di dati (child licenses) + /// + CheckSumKey + } + + #endregion Public Enums + + #region Public Classes + + public class ApplicativoDTO + { + #region Public Properties + + public string Chiave { get; set; } = ""; + public string CodApp { get; set; } = ""; + public string CodInst { get; set; } = ""; + public DateTime DataEnigma { get; set; } = DateTime.Today.AddYears(-1); + public string Descrizione { get; set; } = ""; + public string Enigma { get; set; } = ""; + public int IdxLic { get; set; } = 0; + + public bool IsActive + { + get => (Scadenza.Subtract(DateTime.Today).TotalDays > 0); + } + + public bool Locked { get; set; } = false; + public int NumLicenze { get; set; } = 0; + public int NumLicenzeAttive { get; set; } = 0; + public string Payload { get; set; } = ""; + public DateTime Scadenza { get; set; } = DateTime.Today.AddYears(-1); + public TipoLicenza Tipo { get; set; } = TipoLicenza.ND; + + #endregion Public Properties + } + + public class AttivazioneDTO + { + #region Public Properties + + public string Chiave { get; set; } = ""; + public string CodApp { get; set; } = ""; + public string CodImpiego { get; set; } = ""; + public string CodInst { get; set; } = ""; + public string Descrizione { get; set; } = ""; + public int IdxLic { get; set; } = 0; + public int IdxSubLic { get; set; } = 0; + public TipoLicenza Tipo { get; set; } = TipoLicenza.UserKey; + public DateTime VetoUnlock { get; set; } = DateTime.Today.AddMonths(2); + + #endregion Public Properties + } + + public class LicenseCoord + { + #region Public Properties + + public string CodApp { get; set; } = ""; + public string CodInst { get; set; } = ""; + public string Enigma { get; set; } = ""; + public string MasterKey { get; set; } = ""; + + #endregion Public Properties + } + + public class SupportRequest + { + #region Public Properties + + public string CodApp { get; set; } = ""; + public string CodImp { get; set; } = ""; + public string CodInst { get; set; } = ""; + public string ContactEmail { get; set; } = ""; + public string ContactName { get; set; } = ""; + public string ContactPhone { get; set; } = ""; + public int idxSubLic { get; set; } = 0; + + public bool IsValid + { + get => !string.IsNullOrEmpty(MasterKey) && !string.IsNullOrEmpty(ContactName) && !string.IsNullOrEmpty(ContactEmail) && !string.IsNullOrEmpty(CodInst) && !string.IsNullOrEmpty(CodApp); + } + + public string MasterKey { get; set; } = ""; + public string ReqBody { get; set; } = ""; + + #endregion Public Properties + } + + /// + /// Oggetto Ticket + /// + public class TicketDTO + { + #region Public Properties + + /// + /// Codice univoco della sub licenza (opzionale) + /// + public string CodImpiego { get; set; } = ""; + + /// + /// Contatto email del cliente richiedente + /// + public string ContactEmail { get; set; } = ""; + + /// + /// Contatto del cliente richiedente + /// + public string ContactName { get; set; } = ""; + + /// + /// Contatto telefonico del cliente richiedente + /// + public string ContactPhone { get; set; } = ""; + + public DateTime DtReq { get; set; } = DateTime.Now; + + /// + /// IDX licenza master + /// + public int IdxLic { get; set; } = 0; + + /// + /// IDX licenza child (opzionale) + /// + public int IdxSubLic { get; set; } = 0; + + public int IdxTicket { get; set; } = 0; + + /// + /// Motivazione della richiesta + /// + public string ReqBody { get; set; } = ""; + + /// + /// Stato richiesta + /// + public StatoRichiesta Status { get; set; } = StatoRichiesta.ND; + + /// + /// Risposta alla richiesta + /// + public string SupplAnsw { get; set; } = ""; + + /// + /// Email del responsabile dell'azione (interno - supplier) + /// + public string SupplEmail { get; set; } = ""; + + /// + /// Cod dell'user responsabile dell'azione (interno - supplier) + /// + public string SupplUserCode { get; set; } = ""; + + /// + /// Tipologia di licenza gestita + /// + public TipoLicenza Tipo { get; set; } = TipoLicenza.UserKey; + + #endregion Public Properties + } + + public class UserLicenseRequest + { + #region Public Properties + + public string MasterKey { get; set; } = ""; + public Dictionary ParamDict { get; set; } = new Dictionary(); + + #endregion Public Properties + } + + #endregion Public Classes + } +} diff --git a/GPW.CORE.Data/MailKitEmailSender.cs b/GPW.CORE.Data/MailKitEmailSender.cs new file mode 100644 index 0000000..14257ac --- /dev/null +++ b/GPW.CORE.Data/MailKitEmailSender.cs @@ -0,0 +1,64 @@ +using MailKit.Net.Smtp; +using Microsoft.AspNetCore.Identity.UI.Services; +using Microsoft.Extensions.Options; +using MimeKit; +using MimeKit.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data +{ + /// Implementazione interfaccia email con pacchetto MailKIT + /// + /// https://www.ryadel.com/en/asp-net-core-send-email-messages-smtp-mailkit/ + /// + public class MailKitEmailSender : IEmailSender + { + #region Public Constructors + + public MailKitEmailSender(IOptions options) + { + this.Options = options.Value; + } + + #endregion Public Constructors + + #region Public Properties + + public MailKitEmailSenderOptions Options { get; set; } + + #endregion Public Properties + + #region Public Methods + + public Task Execute(string to, string subject, string message) + { + // create message + var email = new MimeMessage(); + email.Sender = MailboxAddress.Parse(Options.Sender_EMail); + if (!string.IsNullOrEmpty(Options.Sender_Name)) + email.Sender.Name = Options.Sender_Name; + email.From.Add(email.Sender); + email.To.Add(MailboxAddress.Parse(to)); + email.Subject = subject; + email.Body = new TextPart(TextFormat.Html) { Text = message }; + + // send email + using (var smtp = new SmtpClient()) + { + smtp.Connect(Options.Host_Address, Options.Host_Port, Options.Host_SecureSocketOptions); + smtp.Authenticate(Options.Host_Username, Options.Host_Password); + smtp.Send(email); + smtp.Disconnect(true); + } + + return Task.FromResult(true); + } + + public Task SendEmailAsync(string email, string subject, string message) + { + return Execute(email, subject, message); + } + + #endregion Public Methods + } +} diff --git a/GPW.CORE.Data/MailKitEmailSenderOptions.cs b/GPW.CORE.Data/MailKitEmailSenderOptions.cs new file mode 100644 index 0000000..838db92 --- /dev/null +++ b/GPW.CORE.Data/MailKitEmailSenderOptions.cs @@ -0,0 +1,36 @@ +using MailKit.Security; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data +{ + public class MailKitEmailSenderOptions + { + #region Public Constructors + + public MailKitEmailSenderOptions() + { + Host_SecureSocketOptions = SecureSocketOptions.Auto; + } + + #endregion Public Constructors + + #region Public Properties + + public string Host_Address { get; set; } + + public string Host_Password { get; set; } + public int Host_Port { get; set; } + + public SecureSocketOptions Host_SecureSocketOptions { get; set; } + public string Host_Username { get; set; } + public string Sender_EMail { get; set; } + + public string Sender_Name { get; set; } + + #endregion Public Properties + } +} diff --git a/GPW.CORE.Data/Utils.cs b/GPW.CORE.Data/Utils.cs new file mode 100644 index 0000000..9ea1889 --- /dev/null +++ b/GPW.CORE.Data/Utils.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data +{ + public class Utils + { + /// + /// Effettua trim di una data al numero di minuti indicato + /// + /// vedere qui: + /// https://stackoverflow.com/questions/1393696/rounding-datetime-objects + /// + /// DataOra originale + /// Minuti di arrotondamento richeisti + /// Arrotondamento x difetto (floor = true) o eccesso (false) + /// + public static DateTime DateRounded(DateTime DateOrig, int roundMin, bool isFloor) + { + long ticks = 0; + roundMin = roundMin <= 0 ? 1 : roundMin; + TimeOnly step = new TimeOnly(0, roundMin); + if (isFloor) + { + ticks= DateOrig.Ticks / step.Ticks; + } + else + { + ticks = (DateOrig.Ticks + step.Ticks - 1) / step.Ticks; + } + DateTime answ = new DateTime(ticks * step.Ticks, DateOrig.Kind); + return answ; + } + /// + /// Effettua arrotondamento di un timespan ad un dato step di minuti + /// + /// vedere qui: + /// https://stackoverflow.com/questions/1393696/rounding-datetime-objects + /// + /// DataOra originale + /// Minuti di arrotondamento richeisti + /// Arrotondamento x difetto (floor = true) o eccesso (false) + /// + public static TimeSpan TSpanRounded(TimeSpan TSpanOrig, int roundMin, bool isFloor) + { + long ticks = 0; + roundMin = roundMin <= 0 ? 1 : roundMin; + TimeOnly step = new TimeOnly(0, roundMin); + if (isFloor) + { + ticks = TSpanOrig.Ticks / step.Ticks; + } + else + { + ticks = (TSpanOrig.Ticks + step.Ticks - 1) / step.Ticks; + } + TimeSpan answ = new TimeSpan(ticks * step.Ticks); + return answ; + } + } +} diff --git a/GPW.CORE.Data/WeekData.cs b/GPW.CORE.Data/WeekData.cs new file mode 100644 index 0000000..625d20b --- /dev/null +++ b/GPW.CORE.Data/WeekData.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GPW.CORE.Data +{ + public class WeekData + { + public int anno { get; set; } = DateTime.Today.Year; + + public DateTime inizio { get; set; } = DateTime.Today; + public DateTime fine { get; set; } = DateTime.Today.AddDays(1); + + public int weekNumber { get; set; } = 1; + + /// + /// Calcola estremi settimana dato un giorno come lunedì-domenica + /// + /// + public WeekData(DateTime dtRif) + { + DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(dtRif); + this.anno = dtRif.Year; + this.weekNumber = GetIso8601WeekOfYear(dtRif); + this.inizio = dtRif.Date.AddDays(1 - (int)day); + this.fine = dtRif.Date.AddDays(7 - (int)day); + } + + /// + /// Calcola estremi settimana dato numero + anno + /// + /// + public WeekData(int year, int numWeek) + { + this.anno = year; + this.weekNumber = numWeek; + DateTime dtRif = FirstDateOfWeekISO8601(year, numWeek); + DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(dtRif); + this.inizio = dtRif.Date.AddDays(1 - (int)day); + this.fine = dtRif.Date.AddDays(7 - (int)day); + } + + /// + /// Calcolo settimana dell'anno ISO 8601 + /// + /// This presumes that weeks start with Monday. + /// Week 1 is the 1st week of the year with a Thursday in it. + /// + /// rif: https://stackoverflow.com/questions/11154673/get-the-correct-week-number-of-a-given-date + /// + /// + /// + public static int GetIso8601WeekOfYear(DateTime time) + { + // Seriously cheat. If its Monday, Tuesday or Wednesday, then it'll + // be the same week# as whatever Thursday, Friday or Saturday are, + // and we always get those right + DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time); + if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday) + { + time = time.AddDays(3); + } + + // Return the week of our adjusted day + return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); + } + + public static DateTime FirstDateOfWeekISO8601(int year, int weekOfYear) + { + DateTime jan1 = new DateTime(year, 1, 1); + int daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek; + + // Use first Thursday in January to get first week of the year as + // it will never be in Week 52/53 + DateTime firstThursday = jan1.AddDays(daysOffset); + var cal = CultureInfo.CurrentCulture.Calendar; + int firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); + + var weekNum = weekOfYear; + // As we're adding days to a date in Week 1, + // we need to subtract 1 in order to get the right date for week #1 + if (firstWeek == 1) + { + weekNum -= 1; + } + + // Using the first Thursday as starting week ensures that we are starting in the right year + // then we add number of weeks multiplied with days + var result = firstThursday.AddDays(weekNum * 7); + + // Subtract 3 days from Thursday to get Monday, which is the first weekday in ISO8601 + return result.AddDays(-3); + } + } +} diff --git a/GPW.CORE.UI.sln b/GPW.CORE.UI.sln new file mode 100644 index 0000000..2bad4bf --- /dev/null +++ b/GPW.CORE.UI.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31912.275 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPW.CORE.UI", "GPW.CORE.UI\GPW.CORE.UI.csproj", "{E4229EE4-ED4F-4507-8058-B01DC3CA1B28}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GPW.CORE.Data", "GPW.CORE.Data\GPW.CORE.Data.csproj", "{718B275D-7573-4CE2-87AF-57FCAAD71BD8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GPW.CORE.Api", "GPW.CORE.Api\GPW.CORE.Api.csproj", "{5204CC6B-88E2-4EFB-9DC8-2C74F32991D0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E4229EE4-ED4F-4507-8058-B01DC3CA1B28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E4229EE4-ED4F-4507-8058-B01DC3CA1B28}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E4229EE4-ED4F-4507-8058-B01DC3CA1B28}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E4229EE4-ED4F-4507-8058-B01DC3CA1B28}.Release|Any CPU.Build.0 = Release|Any CPU + {718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {718B275D-7573-4CE2-87AF-57FCAAD71BD8}.Release|Any CPU.Build.0 = Release|Any CPU + {5204CC6B-88E2-4EFB-9DC8-2C74F32991D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5204CC6B-88E2-4EFB-9DC8-2C74F32991D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5204CC6B-88E2-4EFB-9DC8-2C74F32991D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5204CC6B-88E2-4EFB-9DC8-2C74F32991D0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AE057165-54C4-4678-8617-A03F0E8F6495} + EndGlobalSection +EndGlobal diff --git a/GPW.CORE.UI/.config/dotnet-tools.json b/GPW.CORE.UI/.config/dotnet-tools.json new file mode 100644 index 0000000..b0e38ab --- /dev/null +++ b/GPW.CORE.UI/.config/dotnet-tools.json @@ -0,0 +1,5 @@ +{ + "version": 1, + "isRoot": true, + "tools": {} +} \ No newline at end of file diff --git a/GPW.CORE.UI/App.razor b/GPW.CORE.UI/App.razor new file mode 100644 index 0000000..7431d6a --- /dev/null +++ b/GPW.CORE.UI/App.razor @@ -0,0 +1,14 @@ + + + + + + + + Not found + +

Sorry, there's nothing at this address.

+
+
+
+
diff --git a/GPW.CORE.UI/Components/AddRA.razor b/GPW.CORE.UI/Components/AddRA.razor new file mode 100644 index 0000000..d0c3d24 --- /dev/null +++ b/GPW.CORE.UI/Components/AddRA.razor @@ -0,0 +1,71 @@ +@using CORE.Data.DbModels +@using UI.Data +@inject GpwDataService GDataServ +@inject MessageService AppMServ + +@if (EnableAction) +{ + +} +else +{ +   +} + +@code { + + + [Parameter] + public DateTime InizioPer { get; set; } = DateTime.Today.AddHours(8); + + [Parameter] + public int IdxDip { get; set; } = 0; + + [Parameter] + public EventCallback NewItemCreated { get; set; } + + [Parameter] + public bool EnableAction { get; set; } = true; + + protected bool canPaste + { + get => AppMServ.clonedRA != null; + } + + /// + /// Indico item selezionato + /// + protected async void AddNew() + { + RegAttivitaModel newItem = new RegAttivitaModel(); + TimeSpan durata = new TimeSpan(1, 0, 0); + // se ho un record clonato parto da quello... + if (AppMServ.clonedRA != null && (!GDataServ.VetoInsert || (AppMServ.clonedRA.FasiNav!=null && AppMServ.clonedRA.FasiNav.Attivo))) + { + newItem = AppMServ.clonedRA; + } + else + { + // recupero ultima fase x utente... + newItem = await GDataServ.RegAttLastByDip(AppMServ.IdxDipendente, GDataServ.VetoInsert); + } + // calcolo durata arrotondata ai 5 minuti... + durata = CORE.Data.Utils.TSpanRounded(newItem.Durata, 5, false); + newItem.IdxRa = 0; + newItem.Inizio = InizioPer; + newItem.Fine = InizioPer.AddMinutes(durata.TotalMinutes); + // salvo in AppMS + AppMServ.recordRA = newItem; + await NewItemCreated.InvokeAsync(newItem); + } + +} diff --git a/GPW.CORE.UI/Components/Chart.razor b/GPW.CORE.UI/Components/Chart.razor new file mode 100644 index 0000000..ededce3 --- /dev/null +++ b/GPW.CORE.UI/Components/Chart.razor @@ -0,0 +1,62 @@ +@inject IJSRuntime JSRuntime + + + +@code { + public enum ChartType + { + Pie, + Bar + } + + [Parameter] + public string Id { get; set; } = "MyChart"; + + [Parameter] + public ChartType Type { get; set; } + + [Parameter] + public string[] Data { get; set; } + + [Parameter] + public string[] BackgroundColor { get; set; } + + [Parameter] + public string[] Labels { get; set; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + await InitDefault(); + } + + protected async Task InitDefault() + { + // Here we create an anonymous type with all the options + // that need to be sent to Chart.js + var config = new + { + type = Type.ToString().ToLower(), + options = new + { + responsive = true, + scales = new + { + yAxes = new + { + suggestedMin = 0 + } + } + }, + data = new + { + datasets = new[] + { + new { data = Data, backgroundColor = BackgroundColor} + }, + labels = Labels + } + }; + await JSRuntime.InvokeVoidAsync("setup", Id, config); + } + +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/ChartHist.razor b/GPW.CORE.UI/Components/ChartHist.razor new file mode 100644 index 0000000..047cbf9 --- /dev/null +++ b/GPW.CORE.UI/Components/ChartHist.razor @@ -0,0 +1,82 @@ +@inject IJSRuntime JSRuntime + + + +@code { + + [Parameter] + public string Id { get; set; } = "MyHist"; + + [Parameter] + public string[] Data { get; set; } + [Parameter] + public string[] Labels { get; set; } + + [Parameter] + public string lineColor { get; set; } + [Parameter] + public string backColor { get; set; } + + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + //if (!firstRender) + //{ + await renderChart(); + //} + } + + + /// + /// Inizializzazione rendering componente + /// + /// partendo da qui: + /// https://www.williamleme.com/posts/2020/003-chartjs-blazor/ + /// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/ + /// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type + /// + /// + /// + protected async Task renderChart() + { + // creazione di un oggetto anonymous type con tutte le opzioni da passare a chart.js + var config = new + { + type = "bar", + options = new + { + responsive = true, + scales = new + { + yAxes = new + { + suggestedMin = 0, + display = true, + ticks = new + { + beginAtZero = true, + maxTicksLimit = 10 + } + } + } + }, + data = new + { + datasets = new[] + { + new + { + data = Data, + borderColor = lineColor, + backgroundColor = backColor, + borderWidth = 1, + label= "Freq. Osservate" + } + }, + labels = Labels + } + }; + await JSRuntime.InvokeVoidAsync("setup", Id, config); + } + +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/ChartTS.razor b/GPW.CORE.UI/Components/ChartTS.razor new file mode 100644 index 0000000..ccbefc1 --- /dev/null +++ b/GPW.CORE.UI/Components/ChartTS.razor @@ -0,0 +1,90 @@ +@inject IJSRuntime JSRuntime + + + +@code { + + [Parameter] + public string Id { get; set; } = "MyTs"; + + [Parameter] + public List DataTS { get; set; } + + [Parameter] + public string lineColor { get; set; } + [Parameter] + public string backColor { get; set; } + + /// + /// Inizializzazione rendering componente + /// + /// partendo da qui: + /// https://www.williamleme.com/posts/2020/003-chartjs-blazor/ + /// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/ + /// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type + /// + /// + /// + protected override async Task OnAfterRenderAsync(bool firstRender) + { + //if (!firstRender) + //{ + await renderChart(); + //} + } + + /// + /// Inizializzazione rendering componente + /// + /// partendo da qui: + /// https://www.williamleme.com/posts/2020/003-chartjs-blazor/ + /// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/ + /// https://www.tutorialsteacher.com/csharp/csharp-anonymous-type + /// + /// + /// + protected async Task renderChart() + { + // creazione di un oggetto anonymous type con tutte le opzioni da passare a chart.js + var config = new + { + type = "line", + options = new + { + responsive = true, + scales = new + { + yAxes = new + { + display = true, + ticks = new + { + maxTicksLimit = 10 + } + }, + xAxes = new + { + type = "timeseries", + distribution = "linear", + } + } + }, + data = new + { + datasets = new[] + { + new + { + data = DataTS, + borderColor= lineColor, + backgroundColor= backColor, + lineTension= 0, + stepped= true, + label= "Temperatura Rilevata" + } + } + } + }; + await JSRuntime.InvokeVoidAsync("setup", Id, config); + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/CmpFooter.razor b/GPW.CORE.UI/Components/CmpFooter.razor new file mode 100644 index 0000000..9abe221 --- /dev/null +++ b/GPW.CORE.UI/Components/CmpFooter.razor @@ -0,0 +1,16 @@ +
+
+ GPW.CORE.Logger v.@version +
+
+ @adesso + Egalware +
+
+ +@code { + protected DateTime adesso = DateTime.Now; + + Version version = typeof(Program).Assembly.GetName().Version; + +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/DataPager.razor b/GPW.CORE.UI/Components/DataPager.razor new file mode 100644 index 0000000..619e271 --- /dev/null +++ b/GPW.CORE.UI/Components/DataPager.razor @@ -0,0 +1,56 @@ +
+
+
+
+ @if (totalCount > 0) + { +
    +
  • +
  • + @for (int i = @startPage; i <= endPage; ++i) + { + var pageNum = i; +
  • + } +
  • +
  • +
+ } +
+
+
+
+ @if (showLoading) + { +
+
+
+ } +
+
+
+
+
+
+ @if (!showLoading) + { + @totalCount records + } +
+
+ @if (totalCount > 0) + { +
+ +
+ } +
+
+
+
\ No newline at end of file diff --git a/GPW.CORE.UI/Components/DataPager.razor.cs b/GPW.CORE.UI/Components/DataPager.razor.cs new file mode 100644 index 0000000..39a9324 --- /dev/null +++ b/GPW.CORE.UI/Components/DataPager.razor.cs @@ -0,0 +1,201 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using System.Net.Http; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Components.Forms; +using Microsoft.AspNetCore.Components.Routing; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Components.Web.Virtualization; +using Microsoft.JSInterop; +using GPW.CORE.UI; +using GPW.CORE.UI.Shared; + +namespace GPW.CORE.UI.Components +{ + public partial class DataPager : ComponentBase + { + #region Protected Fields + + protected bool _showLoading = false; + + #endregion Protected Fields + + #region Private Properties + + private int endPage + { + get + { + int answ = (int)(currPage / numPages) * numPages + numPages; + answ = answ < LastPage ? answ : LastPage; + return answ; + } + } + + private int LastPage + { + get + { + return Math.Max((int)Math.Ceiling(totalCount / (double)PageSize), 1); + } + } + + private int nextBlock + { + get + { + int answ = currPage + numPages; + answ = answ < LastPage ? answ : LastPage; + return answ; + } + } + + private int numPages { get; set; } = 10; + + private int prevBlock + { + get + { + int answ = currPage - numPages; + answ = answ > 0 ? answ : 1; + return answ; + } + } + + // calcola un set 1 .. numPages centrato sulla pagina corrente... + private int startPage + { + get + { + int answ = (int)(currPage / numPages) * numPages; + answ = answ > 0 ? answ : 1; + return answ; + } + } + + #endregion Private Properties + + #region Protected Properties + + protected int _numPage { get; set; } = 1; + + protected int _numRecord { get; set; } = 10; + + protected int percLoading { get; set; } = 0; + + #endregion Protected Properties + + #region Public Properties + + [Parameter] + public int currPage + { + get + { + return _numPage; + } + set + { + bool doReport = !_numPage.Equals(value); + if (doReport) + { + _numPage = value; + reportChangePage(); + } + } + } + + [Parameter] + public EventCallback numPageChanged { get; set; } + + [Parameter] + public EventCallback numRecordChanged { get; set; } + + [Parameter] + public int PageSize + { + get + { + return _numRecord; + } + set + { + bool doReport = !_numRecord.Equals(value); + if (doReport) + { + _numRecord = value; + reportChange(); + } + } + } + + [Parameter] + public bool showLoading + { + get + { + return _showLoading; + } + set + { + if (value) + { + Random random = new Random(); + percLoading = random.Next(30, 90); + } + else + { + percLoading = 5; + } + _showLoading = value; + } + } + + [Parameter] + public int totalCount { get; set; } = 0; + + #endregion Public Properties + + #region Private Methods + + private void reportChange() + { + numRecordChanged.InvokeAsync(PageSize); + } + + private void reportChangePage() + { + numPageChanged.InvokeAsync(currPage); + } + + #endregion Private Methods + + #region Protected Methods + + protected string cssActive(int numPage) + { + string answ = ""; + if (numPage == currPage) + { + answ = "active"; + } + return answ; + } + + protected override async Task OnInitializedAsync() + { + await Task.Run(() => showLoading = false); + } + + protected void PaginationItemClick(int page) + { + currPage = page; + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/DayAgendaDetail.razor b/GPW.CORE.UI/Components/DayAgendaDetail.razor new file mode 100644 index 0000000..278fd43 --- /dev/null +++ b/GPW.CORE.UI/Components/DayAgendaDetail.razor @@ -0,0 +1,35 @@ +@if (CurrDay == DayOfWeek.Saturday) +{ + @if ((Ora - 8) % 2 == 0) + { + + DayAgendaDetail + + } +} +else if (CurrDay == DayOfWeek.Sunday) +{ + @if ((Ora - 8) % 4 == 0) + { + + DayAgendaDetail + + } +} +else +{ + + DayAgendaDetail + + +} + +@code { + [Parameter] + public DayOfWeek CurrDay { get; set; } = DayOfWeek.Sunday; + + + + [Parameter] + public int Ora { get; set; } = 0; +} diff --git a/GPW.CORE.UI/Components/DayCheckEditor.razor b/GPW.CORE.UI/Components/DayCheckEditor.razor new file mode 100644 index 0000000..39905e2 --- /dev/null +++ b/GPW.CORE.UI/Components/DayCheckEditor.razor @@ -0,0 +1,121 @@ +@using CORE.Data.DbModels +@using UI.Data + +@inject IJSRuntime JSRuntime +@inject GpwDataService GDataServ +@inject MessageService AppMServ + +
+
+
+
+

Daily Cheks

+
+
+ +
+
+
+
+
+
+ @if (listRilTemp != null) + { + + + } + else + { + + } +
+
+
+
+ @TargetDate.ToString("dddd dd/MM/yyyy") +
+
+ @if (currRecord != null) + { + +
+
+ + + +
+ +
+ +
+
+ } + else + { + + } +
+ +
+
+
+ @if (listVC19 != null) + { +

Check C19

+ + + + + + + + + + + @foreach (var record in listVC19) + { + + + + + + + } + +
CheckCognomeNomeData Nascita
+ @record.DtCheck.ToString("dd/MM/yy HH:mm") + + @record.Cognome + + @record.Nome + + @record.Dob.ToShortDateString() +
+ } + else + { + + } +
+
+
+
+ + diff --git a/GPW.CORE.UI/Components/DayCheckEditor.razor.cs b/GPW.CORE.UI/Components/DayCheckEditor.razor.cs new file mode 100644 index 0000000..95edf0c --- /dev/null +++ b/GPW.CORE.UI/Components/DayCheckEditor.razor.cs @@ -0,0 +1,129 @@ +using GPW.CORE.Data.DbModels; +using Microsoft.AspNetCore.Components; + +namespace GPW.CORE.UI.Components +{ + public partial class DayCheckEditor + { + #region Protected Fields + + protected int _numDays = 30; + + #endregion Protected Fields + + #region Private Properties + + private int numDays + { + get + { + return _numDays; + } + + set + { + _numDays = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + + #endregion Private Properties + + #region Protected Properties + + protected DateTime _targetDate { get; set; } = DateTime.Today; + + protected RilievoTempModel? currRecord { get; set; } = null; + + protected string[]? histData { get; set; } = null; + + protected string[]? histLabel { get; set; } = null; + + protected List? listRilTemp { get; set; } = null; + + protected List? listVC19 { get; set; } = null; + + #endregion Protected Properties + + #region Public Properties + + [Parameter] + public EventCallback CloseReq { get; set; } + + [Parameter] + public DateTime TargetDate + { + get + { + return _targetDate; + } + + set + { + _targetDate = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + + #endregion Public Properties + + #region Protected Methods + + /// + /// Indico item selezionato + /// + protected async void DoClose() + { + await CloseReq.InvokeAsync(true); + } + + /// + /// Effettua salvataggio misurazione temperatura + /// + protected async void DoSave() + { + // chiamo classe gestione che salva e resetta cache dati... + if (currRecord != null) + { + await GDataServ.RilTempUpdate(currRecord); + } + + // chiamo chiusura! + await CloseReq.InvokeAsync(true); + } + + protected async Task ReloadData() + { + DateTime inizio = TargetDate.AddDays(1 - numDays); + DateTime fine = TargetDate.AddDays(1); + // recupero dati completi... + var rawVC19 = await GDataServ.CheckVC19List(AppMServ.IdxDipendente, fine.AddDays(-15), fine); + var rawData = await GDataServ.RilTempList(AppMServ.IdxDipendente, inizio, fine); + + // calcolo dati derivati + listVC19 = rawVC19.OrderByDescending(x => x.DtCheck).ToList(); + listRilTemp = rawData.Select(r => new chartJsData.chartJsTSerie() + { x = r.DtRilievo, y = r.TempRil }).ToList(); + + // calcolo hist frequenza con EFCore: https://entityframeworkcore.com/knowledge-base/60871048/group-by-and-to-dictionary-in-ef-core-3-1 + var histDict = rawData.GroupBy(r => r.TempRil.ToString("N1")).Select(g => new + { + g.Key, + Count = g.Count() + }).OrderBy(d => d.Key).ToDictionary(x => x.Key, x => x.Count.ToString()); + histData = histDict.Values.ToArray(); + histLabel = histDict.Keys.ToArray(); + // cerco se c' dato odierno della temperatura... + currRecord = rawData.Where(x => x.DtRilievo == TargetDate).FirstOrDefault(); + if (currRecord == null) + { + currRecord = new RilievoTempModel() + { IdxDipendente = AppMServ.IdxDipendente, DtRilievo = DateTime.Today, TempRil = 0 }; + } + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/DayHoriz.razor b/GPW.CORE.UI/Components/DayHoriz.razor new file mode 100644 index 0000000..93aa88b --- /dev/null +++ b/GPW.CORE.UI/Components/DayHoriz.razor @@ -0,0 +1,71 @@ + + +
+
+ @if (IsTitle) + { + DAY + } + else + { +
@DayDTO.DtRif.ToString("ddd")
+
@DayDTO.DtRif.ToString("dd.MM")
+ } +
+
+ @if (IsTitle) + { +
+ @for (int i = StartHour; i <= EndHour; i++) + { +
+ @i.ToString("00") +
+ } +
+ } + else + { + +
+ @if (@DayDTO != null && @DayDTO.ListTimbr != null) + { + @foreach (var item in ListTimb()) + { + + } + } +
+ +
+ @if (@noData) + { + + } + else if (@DayDTO != null && @DayDTO.ListRA != null) + { + @foreach (var item in ListRegAtt()) + { + + } + } +
+ } +
+
+ @if (IsTitle) + { +
Timb
+
Lavo
+ } + else + { +
@TotLav
+
@TotComm
+
+ } +
+
+ + + diff --git a/GPW.CORE.UI/Components/DayHoriz.razor.cs b/GPW.CORE.UI/Components/DayHoriz.razor.cs new file mode 100644 index 0000000..a3920ad --- /dev/null +++ b/GPW.CORE.UI/Components/DayHoriz.razor.cs @@ -0,0 +1,429 @@ +using GPW.CORE.Data.DbModels; +using GPW.CORE.Data.DTO; +using Microsoft.AspNetCore.Components; + +namespace GPW.CORE.UI.Components +{ + public partial class DayHoriz + { + #region Protected Fields + + /// + /// record prima timbratura x + /// + protected DateTime FirstTimb = DateTime.Now; + + #endregion Protected Fields + + #region Private Properties + + private bool noData { get => DayDTO == null || DayDTO.ListRA == null || DayDTO.ListRA.Count == 0; } + + private bool OkTemp + { + get + { + bool answ = false; + if (DayDTO != null && DayDTO.ListRilTemp != null) + { + answ = DayDTO.ListRilTemp.Count > 0; + } + return answ; + } + } + + private bool OkVC19 + { + get + { + bool answ = false; + if (DayDTO != null && DayDTO.ListCheckC19 != null) + { + answ = DayDTO.ListCheckC19.Count > 0; + } + return answ; + } + } + + private Double oreComm + { + get + { + double answ = 0; + if (DayDTO != null && DayDTO.ListRA != null) + { + answ = (double)DayDTO.ListRA.Sum(x => x.OreTot); + } + return answ; + } + } + + private Double oreLav + { + get + { + double answ = 0; + if (DayDTO != null && DayDTO.TimbrExpl != null && DayDTO.TimbrExpl.HLav != null) + { + answ = (double)DayDTO.TimbrExpl.HLav; + if (DayDTO.DtRif == DateTime.Today) + { + if (DayDTO.ListTimbr != null) + { + // aggiungo ultima timb fino ad adesso... + var lastIn = DayDTO.ListTimbr.Where(x => x.Entrata == true).OrderByDescending(x => x.DataOra).FirstOrDefault(); + var lastOut = DayDTO.ListTimbr.Where(x => x.Entrata == false).OrderByDescending(x => x.DataOra).FirstOrDefault(); + // se MANCA timb uscita finale... + if (lastIn != null) + { + if (lastOut == null || lastOut.DataOra < lastIn.DataOra) + { + DateTime adesso = DateTime.Now; + answ += adesso.Subtract(lastIn.DataOra).TotalHours; + } + } + } + } + } + return answ; + } + } + + private int periodo + { + get + { + int answ = 1; + if (DayDTO != null) + { + answ = EndHour - StartHour; + } + + return answ; + } + } + + private decimal tempRil + { + get + { + decimal answ = 0; + if (OkTemp) + { + answ = DayDTO.ListRilTemp[0].TempRil; + } + return answ; + } + } + + private string TotComm + { + get + { + TimeSpan tSpan = TimeSpan.FromHours(oreComm); + return $"{tSpan.Hours}h {tSpan.Minutes}'"; + } + } + + private string TotLav + { + get + { + TimeSpan tSpan = TimeSpan.FromHours(oreLav); + return $"{tSpan.Hours}h {tSpan.Minutes}'"; + } + } + + #endregion Private Properties + + #region Public Properties + + public string cssBadgeLav + { + get + { + string bCtr = "btn"; + string answ = $"{bCtr}-light"; + var deltaComm = oreComm - oreLav; + if (Math.Abs(deltaComm) < 0.5) + { + answ = $"{bCtr}-info"; + } + else if (Math.Abs(deltaComm) < 1) + { + answ = $"{bCtr}-warning"; + } + else + { + answ = $"{bCtr}-danger"; + } + return answ; + } + } + + public string cssCheck + { + get => OkVC19 ? "text-success" : "text-secondary"; + } + + public string cssThermo + { + get + { + string answ = ""; + // verifico in base a ok temp o meno... + if (OkTemp) + { + // colore in base al valore... + var currTemp = tempRil; + if (currTemp != null) + { + if (currTemp >= (decimal)37.5) + { + answ = "text-danger"; + } + else if (currTemp >= 37) + { + answ = "text-warning"; + } + else + { + answ = "text-success"; + } + } + } + else + { + answ = "text-secondary"; + } + return answ; + } + } + + [Parameter] + public DailyDataDTO? DayDTO { get; set; } + + [Parameter] + public bool EnableActionMenu { get; set; } = true; + + [Parameter] + public int EndHour { get; set; } + + [Parameter] + public int IdxDipSel { get; set; } = 0; + + [Parameter] + public bool IsTitle { get; set; } = false; + + [Parameter] + public EventCallback ItemSelected { get; set; } + + [Parameter] + public EventCallback ItemUpdated { get; set; } + + [Parameter] + public List ListFasi { get; set; } = null!; + + [Parameter] + public EventCallback?> PeriodSelected { get; set; } + + [Parameter] + public EventCallback ReqTempList { get; set; } + + [Parameter] + public int StartHour { get; set; } + + #endregion Public Properties + + #region Private Methods + + private List ListRegAtt() + { + // init + DateTime currHour = DayDTO.DtRif.AddHours(StartHour); + DateTime lastHour = DayDTO.DtRif.AddHours(EndHour); + List result = new List(); + // ciclo partendo dal primo evento ed aggiungendo eventuali periodi in testa / coda / intermedi + foreach (var item in DayDTO.ListRA) + { + // se evento > ora corrente --> aggiungo vuoto... + if (item.Inizio > currHour) + { + CORE.Data.DbModels.RegAttivitaModel? newItem = new CORE.Data.DbModels.RegAttivitaModel() + { + Inizio = currHour, + IdxFase = 0, + Descrizione = "-", + Fine = item.Inizio, + OreTot = (decimal)item.Inizio.Subtract(currHour).TotalHours + }; + result.Add(newItem); + } + + // ...altrimenti parto con lui... + result.Add(item); + currHour = item.Fine; + } + // se non sono in fondo --> aggiungo! + if (currHour < lastHour) + { + CORE.Data.DbModels.RegAttivitaModel? newItem = new CORE.Data.DbModels.RegAttivitaModel() + { + Inizio = currHour, + IdxFase = 0, + Descrizione = "-", + Fine = lastHour, + OreTot = (decimal)lastHour.Subtract(currHour).TotalHours + }; + result.Add(newItem); + } + + return result; + } + + private List ListTimb() + { + // init + List result = new List(); + if (DayDTO != null) + { + // limiti estremi visualizzazione + DateTime currHour = DayDTO.DtRif.AddHours(StartHour); + DateTime lastHour = DayDTO.DtRif.AddHours(EndHour); + int idxTimb = 0; + if (DayDTO.ListTimbr != null) + { + // divido tra ingressi e uscite + var timbIN = DayDTO.ListTimbr.Where(x => x.Entrata == true).ToList(); + var timbOUT = DayDTO.ListTimbr.Where(x => x.Entrata == false).ToList(); + DateTime fineLav = currHour; + + // sistemo la prima timbratura + if (timbIN.Count > 0) + { + var firstRec = timbIN.OrderBy(x => x.DataOra).FirstOrDefault(); + if (firstRec != null) + { + FirstTimb = CORE.Data.Utils.DateRounded(firstRec.DataOra, 5, false); + } + } + + // ciclo partendo dal primo evento timbratura IN ed aggiungendo eventuali periodi in testa / coda / intermedi + foreach (var item in timbIN) + { + bool isClosed = true; + // se evento > ora corrente --> aggiungo vuoto... + if (item.DataOra > currHour) + { + PeriodoDTO emptyPeriod = new PeriodoDTO() + { + Inizio = currHour, + Fine = item.DataOra, + Tipo = CORE.Data.TipoPeriodo.ND, + OreTot = (decimal)item.DataOra.Subtract(currHour).TotalHours, + IsClosed = true + }; + result.Add(emptyPeriod); + } + + // ...processo cercando uscita relativa oppure NOW + if (timbOUT.Count > idxTimb) + { + fineLav = timbOUT[idxTimb].DataOra; + } + else + { + DateTime adesso = DateTime.Now; + int minRound = ((int)Math.Floor((double)adesso.Minute / 5)) * 5; + fineLav = DateTime.Today.AddHours(adesso.Hour).AddMinutes(minRound); + isClosed = false; + } + PeriodoDTO workPeriod = new PeriodoDTO() + { + Inizio = item.DataOra, + Fine = fineLav, + Tipo = CORE.Data.TipoPeriodo.Lavoro, + OreTot = (decimal)fineLav.Subtract(item.DataOra).TotalHours, + IsClosed = isClosed + }; + result.Add(workPeriod); + idxTimb++; + currHour = fineLav; + } + // se non sono in fondo --> aggiungo! + if (currHour < lastHour) + { + PeriodoDTO emptyPeriod = new PeriodoDTO() + { + Inizio = currHour, + Fine = lastHour, + Tipo = CORE.Data.TipoPeriodo.ND, + OreTot = (decimal)lastHour.Subtract(currHour).TotalHours, + IsClosed = true + }; + result.Add(emptyPeriod); + } + } + } + + return result; + } + + #endregion Private Methods + + #region Protected Methods + + /// + /// Indico item selezionato + /// + protected async void PeriodoSelected(PeriodoDTO selPeriodo) + { + if (DayDTO != null) + { + await PeriodSelected.InvokeAsync(DayDTO.ListTimbr); + } + } + + /// + /// Indico item selezionato + /// + protected async void ReportCloned() + { + await ItemSelected.InvokeAsync(null); + } + + /// + /// Indico item selezionato + /// + protected async void ReportSelected(RegAttivitaModel selRecord) + { + await ItemSelected.InvokeAsync(selRecord); + } + + /// + /// Indico item aggiornato + /// + protected async void ReportUpdated() + { + await ItemUpdated.InvokeAsync(null); + } + + protected async void SelTemperature() + { + if (DayDTO != null) + { + await ReqTempList.InvokeAsync(DayDTO.DtRif); + } + } + + protected async void SelTimbrature() + { + if (DayDTO != null) + { + await PeriodSelected.InvokeAsync(DayDTO.ListTimbr); + } + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/FasiSearch.razor b/GPW.CORE.UI/Components/FasiSearch.razor new file mode 100644 index 0000000..15d4272 --- /dev/null +++ b/GPW.CORE.UI/Components/FasiSearch.razor @@ -0,0 +1,71 @@ + +
+
+ +
+
+ + + +
+ +
+ @if (!string.IsNullOrEmpty(gruppoSel)) + { + +
+
+ + + +
+ +
+ } + @if (idxProj > 0) + { + +
+
+ + + +
+ +
+ } +
+
+
+
+ @if (idxFase > 0) + { + + } +
+
+ + diff --git a/GPW.CORE.UI/Components/FasiSearch.razor.cs b/GPW.CORE.UI/Components/FasiSearch.razor.cs new file mode 100644 index 0000000..db9efcc --- /dev/null +++ b/GPW.CORE.UI/Components/FasiSearch.razor.cs @@ -0,0 +1,115 @@ +using GPW.CORE.Data.DbModels; +using GPW.CORE.UI.Data; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace GPW.CORE.UI.Components +{ + public partial class FasiSearch + { + #region Protected Fields + + protected string _gruppoSel = ""; + + protected int _idxProj = 0; + + protected bool vetoUpd = false; + + #endregion Protected Fields + + #region Public Fields + + public int idxFase = 0; + + #endregion Public Fields + + #region Private Properties + + [Inject] + private MessageService AppMServ { get; set; } + + [Inject] + private IJSRuntime JSRuntime { get; set; } + + #endregion Private Properties + + #region Protected Properties + + protected List fasiList { get; set; } = new List(); + + [Inject] + protected GpwDataService GDataServ { get; set; } + + protected List gruppiList { get; set; } = new List(); + + protected List projList { get; set; } = new List(); + + #endregion Protected Properties + + #region Public Properties + + public string gruppoSel + { + get + { + return _gruppoSel; + } + + set + { + _gruppoSel = value; + if (!vetoUpd) + { + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + } + + public int idxProj + { + get + { + return _idxProj; + } + + set + { + _idxProj = value; + if (!vetoUpd) + { + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + } + + [Parameter] + public EventCallback ItemSelected { get; set; } + + #endregion Public Properties + + #region Protected Methods + + protected override async Task OnInitializedAsync() + { + await ReloadData(); + } + + protected async Task ReloadData() + { + gruppiList = await GDataServ.AnagGruppiAll(); + var allProj = await GDataServ.AnagProjAll(); + projList = allProj.Where(x => x.Attivo == true && x.Gruppo == gruppoSel).OrderBy(x => x.ClienteNav.RagSociale).ThenBy(x => x.NomeProj).ToList(); + var allFasi = await GDataServ.AnagFasiAll(); + fasiList = allFasi.Where(x => x.IdxProgetto == idxProj && x.Attivo == true).ToList(); + } + + protected async Task SelectRecord() + { + await ItemSelected.InvokeAsync(idxFase); + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/LoadingData.razor b/GPW.CORE.UI/Components/LoadingData.razor new file mode 100644 index 0000000..354d765 --- /dev/null +++ b/GPW.CORE.UI/Components/LoadingData.razor @@ -0,0 +1,6 @@ +
+
+

loading data

+ +
+
\ No newline at end of file diff --git a/GPW.CORE.UI/Components/LoadingDataSmall.razor b/GPW.CORE.UI/Components/LoadingDataSmall.razor new file mode 100644 index 0000000..8362fbb --- /dev/null +++ b/GPW.CORE.UI/Components/LoadingDataSmall.razor @@ -0,0 +1,6 @@ +
+
+ loading data + +
+
\ No newline at end of file diff --git a/GPW.CORE.UI/Components/ParetoRA.razor b/GPW.CORE.UI/Components/ParetoRA.razor new file mode 100644 index 0000000..9f1aa9a --- /dev/null +++ b/GPW.CORE.UI/Components/ParetoRA.razor @@ -0,0 +1,143 @@ +@using GPW.CORE.Data.DbModels +@using CORE.Data.DbModels +@using UI.Data + +@inject IJSRuntime JSRuntime +@inject GpwDataService GDataServ +@inject MessageService AppMServ + +@if (ListRecords == null) +{ + +} +else +{ + + + + + + + + + + + @foreach (var item in ListRecords) + { + + + + + + } + +
Progettooresel
+
+
+ (@item.RowNum.ToString("00")) +
+
+ @item.nomeProj | @item.nomeComm - @item.nomeFase +
+
+
@item.qty.ToString("N2")
+} +
+
+ +
+
+ # days +
+ +
+
+
+ +
+
+ # res +
+ +
+
+
+ +@code { + + private int _maxSugg = 10; + private int _ggPrec = 60; + private int idxFaseSel = 0; + + + [Parameter] + public EventCallback ItemSelected { get; set; } + [Parameter] + public int idxFase + { + get + { + return idxFaseSel; + } + set + { + idxFaseSel = value; + } + } + + private int maxSugg + { + get + { + return _maxSugg; + } + set + { + _maxSugg = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + private int ggPrec + { + get + { + return _ggPrec; + } + set + { + _ggPrec = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + + protected List? ListRecords { get; set; } = null; + + protected string cssRiga(int idxFase) + { + string answ = ""; + if (idxFase == idxFaseSel) + { + answ = "bg-info text-light"; + } + return answ; + } + + protected override async Task OnInitializedAsync() + { + await ReloadData(); + } + + protected async Task ReloadData() + { + idxFaseSel = 0; + ListRecords = await GDataServ.ParetoRegAtt(AppMServ.IdxDipendente, ggPrec, maxSugg); + } + + protected async Task SelectRecord(int idxFase) + { + idxFaseSel = idxFase; + await ItemSelected.InvokeAsync(idxFase); + } +} diff --git a/GPW.CORE.UI/Components/PeriodoLav.razor b/GPW.CORE.UI/Components/PeriodoLav.razor new file mode 100644 index 0000000..30a5fbf --- /dev/null +++ b/GPW.CORE.UI/Components/PeriodoLav.razor @@ -0,0 +1,80 @@ +@using CORE.Data.DbModels +@using CORE.Data.DTO +@using UI.Data +@inject GpwDataService GDataServ +@inject MessageService AppMServ +@inject IJSRuntime JSRuntime + +
+ @if (CurrPeriodo.Tipo != CORE.Data.TipoPeriodo.ND) + { + +
+
+ @CurrPeriodo.Inizio.ToString("HH:mm") +
+ @if (CurrPeriodo.IsClosed) + { + @if ((double)CurrPeriodo.OreTot >= 1.25) + { +
+ +
+ } + @if ((double)CurrPeriodo.OreTot >= 1) + { +
+ @CurrPeriodo.Fine.ToString("HH:mm") +
+ } + } + else + { +
+ +
+ } +
+ } +
+ +@code { + + [Parameter] + public PeriodoDTO CurrPeriodo { get; set; } = null!; + [Parameter] + public double Periodo { get; set; } = 1; + + [Parameter] + public EventCallback ItemSelected { get; set; } + + private string widthPerc + { + get + { + string answ = "1%"; + if (CurrPeriodo != null) + { + double num = CurrPeriodo.OreTot != null ? (double)CurrPeriodo.OreTot : 0; + answ = $"{num / Periodo:P2}".Replace(",", "."); + } + + return answ; + } + } + + + private string blockCss + { + get + { + string answ = CurrPeriodo.Tipo == CORE.Data.TipoPeriodo.ND ? "" : " border border-success bg-dark text-light rounded "; + return answ; + } + } + + private async void Edit() + { + await ItemSelected.InvokeAsync(CurrPeriodo); + } +} diff --git a/GPW.CORE.UI/Components/RecFaseStart.razor b/GPW.CORE.UI/Components/RecFaseStart.razor new file mode 100644 index 0000000..07a3077 --- /dev/null +++ b/GPW.CORE.UI/Components/RecFaseStart.razor @@ -0,0 +1,275 @@ +@using CORE.Data.DbModels +@using UI.Data + +@inject IJSRuntime JSRuntime +@inject GpwDataService GDataServ +@inject MessageService AppMServ + + +@if (CalcOreFasi == null) +{ + +} +else +{ +
+
+
+
+ @currProj.Gruppo +
+
+ @currProj.ClienteNav.RagSociale +
+
+
+
+ @currProj.NomeProj +
+
+
+
+
+
+ Budget: @CalcOreFasi.budgetTime.ToString("N2") +
+
+ consumate: @CalcOreFasi.percUsed.ToString("P1") +
+
+
+
+ Caricate: @CalcOreFasi.totOre.ToString("N2") +
+
+ rimanenti: @CalcOreFasi.timeRem.ToString("N0") +
+
+ @if (!(bool)CalcOreFasi.Attivo || VetoProj) + { + if (VetoInsert) + { +
+ Attenzione!: impossibile caricare altre ore nel progetto, verificare l'attivazione e le ore a budget con amministrazione prima di procedere! +
+ } + else + { +
+ Attenzione!: progetto inattivo: verificare con amministrazione prima di procedere! +
+ + } + } +
+
+
+
+ @if (currFase != null) + { +
+
+ @ancestFase.NomeFase +
+
+ @currFase.NomeFase +
+
+ } +
+
+
+
+ +
+ + +
+
+
+ +
+
+ Min +
+ +
+
+
+ +
+
+ +
+ +
+
+
+ +
+
+ @if (AppMServ.PayloadOk) + { + if (CalcOreFasi != null) + { + if (buttonEnabled) + { + + } + } + } +
+
+ +
+
+
+
+} + +@code { + private int _idxFase = 0; + private int idxProj = 0; + private int minDur = 30; + private bool doClose = true; + + private string descrizione = ""; + + private string cssCheckOre = ""; + + private CalcOreFasiModel? CalcOreFasi { get; set; } = null; + private AnagFasiModel? currFase { get; set; } = null; + private AnagFasiModel? ancestFase { get; set; } = null; + private AnagProgettiModel? currProj { get; set; } = null; + + [Parameter] + public int idxFase + { + get + { + return _idxFase; + } + set + { + _idxFase = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + + [Parameter] + public EventCallback RecStarted { get; set; } + + private bool buttonEnabled + { + get + { + bool answ = !VetoProj; + if (CalcOreFasi != null) + { + if (!(bool)CalcOreFasi.Attivo) + { + if (VetoInsert) + { + answ = false; + } + else + { + answ = true; + } + } + } + return answ; + } + } + + private bool VetoInsert + { + get => GDataServ.VetoInsert; + } + private bool VetoProj + { + get + { + bool answ = false; + if (currProj != null) + { + var projAttivo = true; + _ = bool.TryParse($"{currProj.Attivo}", out projAttivo); + answ = !projAttivo; + } + return answ; + } + } + + private async Task StartRecord() + { + // calcolo dataora chiusura... + DateTime newInizio = CORE.Data.Utils.DateRounded(DateTime.Now, 5, true); + + // chiudo attività precedente (se c'è) odierna + if (doClose) + { + var lastRA = await GDataServ.RegAttLastByDip(AppMServ.IdxDipendente, false); + if (lastRA != null && lastRA.Inizio.Date == DateTime.Today) + { + lastRA.Fine = newInizio; + await GDataServ.RegAttUpdate(lastRA); + } + } + // registro nuova attività + RegAttivitaModel newItem = new RegAttivitaModel() + { + IdxDipendente = AppMServ.IdxDipendente, + Inizio = newInizio, + Fine = newInizio.AddMinutes(minDur), + IdxFase = idxFase, + Descrizione = descrizione + }; + await GDataServ.RegAttUpdate(newItem); + // segnalo fatto + await RecStarted.InvokeAsync(false); + } + + private async Task ClosePage() + { + await RecStarted.InvokeAsync(false); + } + + protected async Task ReloadData() + { + // recupero dati fase completi... + currFase = await GDataServ.AnagFasiSearch(idxFase); + ancestFase = await GDataServ.AnagFasiSearch(currFase.IdxFaseAncest); + currProj = await GDataServ.AnagProjSearch((int)currFase.IdxProgetto); + if (currFase != null) + { + int idxFaseTgt = currFase.IdxFaseAncest == 0 ? currFase.IdxFase : currFase.IdxFaseAncest; + CalcOreFasi = await GDataServ.CalcOreFase(idxFaseTgt); + cssCheckOre = "text-success"; + if (CalcOreFasi.percUsed > 1) + { + cssCheckOre = "text-danger"; + } + else if (CalcOreFasi.percUsed * 100 > 80) + { + cssCheckOre = "text-warning"; + } + //if (currFase.IdxProgetto != null) + //{ + // int idxProj = (int)currFase.IdxProgetto; + // CalcOreProj = await GDataServ.CalcOreProj(idxProj); + // cssCheckOre = "text-success"; + // if (CalcOreProj.percUsed > 1) + // { + // cssCheckOre = "text-danger"; + // } + // else if (CalcOreProj.percUsed * 100 > 80) + // { + // cssCheckOre = "text-warning"; + // } + //} + } + } + +} diff --git a/GPW.CORE.UI/Components/RegAtt.razor b/GPW.CORE.UI/Components/RegAtt.razor new file mode 100644 index 0000000..2b581c7 --- /dev/null +++ b/GPW.CORE.UI/Components/RegAtt.razor @@ -0,0 +1,92 @@ +@using CORE.Data.DbModels +@using UI.Data +@inject GpwDataService GDataServ +@inject MessageService AppMServ +@inject IJSRuntime JSRuntime + +
+
+ @if (@CurrData.IdxFase > 0) + { + +
+
@(trimLine($"{CurrData.FasiNav?.ProgettoNav?.ClienteNav?.RagSociale}",65)) - @(trimLine($"{CurrData.FasiNav?.ProgettoNav?.NomeProj}",75))
+
@(trimLine($"{CurrData.FasiNav?.DescrizioneFase}",130))
+
@(trimLine($"{CurrData.Descrizione}",250))
+
+ } + else + { +
+ +
+ } +
+
+ + + + diff --git a/GPW.CORE.UI/Components/RegAtt.razor.cs b/GPW.CORE.UI/Components/RegAtt.razor.cs new file mode 100644 index 0000000..e043dcc --- /dev/null +++ b/GPW.CORE.UI/Components/RegAtt.razor.cs @@ -0,0 +1,244 @@ +using GPW.CORE.Data.DbModels; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace GPW.CORE.UI.Components +{ + public partial class RegAtt + { + #region Protected Fields + + protected bool isSelected = false; + + #endregion Protected Fields + + #region Private Properties + + private string blockCss + { + get + { + string answ = CurrData.IdxFase == 0 ? "" : " border border-info rounded"; + return answ; + } + } + + private bool dropActionTop + + { + get + { + bool answ = false; + switch (CurrData.Inizio.DayOfWeek) + { + case DayOfWeek.Sunday: + case DayOfWeek.Saturday: + case DayOfWeek.Friday: + answ = true; + break; + + default: + break; + } + return answ; + } + } + + private string widthPerc + { + get + { + string answ = "1%"; + if (CurrData != null) + { + double num = CurrData.OreTot != null ? (double)CurrData.OreTot : 0; + answ = $"{num / Periodo:P2}".Replace(",", "."); + } + + return answ; + } + } + + private bool VetoInsert + { + get => GDataServ.VetoInsert; + } + + #endregion Private Properties + + #region Protected Properties + + protected string buttonCss + { + get => !IsClipboard ? "dropbtn" : ""; + } + + protected string cssSelected + { + get => isSelected ? "table-info" : ""; + } + + protected string cssDropContent + { + get => dropActionTop ? "dropdown-content-top" : "dropdown-content"; + } + + #endregion Protected Properties + + #region Public Properties + + [Parameter] + public RegAttivitaModel CurrData { get; set; } = null!; + + [Parameter] + public bool EnableActionMenu { get; set; } = true; + + [Parameter] + public int IdxDipSel { get; set; } = 0; + + [Parameter] + public bool IsClipboard { get; set; } = false; + + [Parameter] + public EventCallback ItemCloned { get; set; } + + [Parameter] + public EventCallback ItemSelected { get; set; } + + [Parameter] + public EventCallback ItemUpdated { get; set; } + + [Parameter] + public List ListFasi { get; set; } = null!; + + [Parameter] + public double Periodo { get; set; } = 1; + + #endregion Public Properties + + #region Private Methods + + /// + /// Verifico coerenza date (inizio < fine) + /// + /// indica se la data modificata sia l'inizio + private void checkCoerenzaDate(bool modInizio) + { + // verifica presenza errori + bool inError = CurrData.Inizio >= CurrData.Fine; + if (inError) + { + // se ho mod inizio --> tengo ferma fine, inizio 1/2 h prima + if (modInizio) + { + CurrData.Inizio = CurrData.Fine.AddMinutes(-30); + } + else + { + CurrData.Fine = CurrData.Inizio.AddMinutes(30); + } + } + } + + #endregion Private Methods + + #region Protected Methods + + protected async void AddTime(bool isEnd, int deltaMin) + { + // verifico checkbox IsEnd + if (isEnd) + { + // modifico fine... + CurrData.Fine = CurrData.Fine.AddMinutes(deltaMin); + checkCoerenzaDate(false); + } + else + { + // modifico inizio... + CurrData.Inizio = CurrData.Inizio.AddMinutes(deltaMin); + checkCoerenzaDate(true); + } + // salvo + await GDataServ.RegAttUpdate(CurrData); + await ItemUpdated.InvokeAsync(CurrData); + } + + /// + /// Indico item selezionato + /// + protected async void Clone() + { + AppMServ.clonedRA = CurrData; + await ItemCloned.InvokeAsync(CurrData); + } + + /// + /// Indico item selezionato + /// + protected async void Delete() + { + // chiedo verifica + if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler eliminare il record selezionato??")) + return; + + // aggiorno + await GDataServ.RegAttDelete(CurrData); + // registro fatto + await ItemUpdated.InvokeAsync(null); + } + + /// + /// Indico item selezionato + /// + protected async void Edit() + { + // SOLO SE non una copia clipboard... + //if (!IsClipboard) + //{ + isSelected = true; + await ItemSelected.InvokeAsync(CurrData); + //} + } + + protected override void OnInitialized() + { + isSelected = false; + } + + /// + /// Indico item selezionato + /// + protected async void ReportSelect(RegAttivitaModel selRecord) + { + await ItemSelected.InvokeAsync(selRecord); + } + + /// + /// Trim linea di testo secondo regole + /// + /// Stringa origiale + /// Fattore di moltiplicazione (std: 130) + /// + protected string trimLine(object stringOrig, int multFact = 130) + { + double num = 1; + if (CurrData.OreTot != null) + { + num = (double)CurrData.OreTot; + } + + double perc = num / Periodo; + int maxLenght = (int)(perc * multFact); + string answ = $"{stringOrig}"; + if (answ.Length > maxLenght) + { + answ = $"{answ.Substring(0, maxLenght)}..."; + } + + return answ; + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/RegAttEditor.razor b/GPW.CORE.UI/Components/RegAttEditor.razor new file mode 100644 index 0000000..d0dd6ec --- /dev/null +++ b/GPW.CORE.UI/Components/RegAttEditor.razor @@ -0,0 +1,140 @@ +@using CORE.Data.DbModels +@using UI.Data + + + +
+
+
+
+

Modifica # @currRecord.IdxRa

+
+
+
+
+ + + +
+ + @foreach (var item in gruppiList) + { + + } + +
+
+
+
+
+ + +
+
+ +
+
+ + + +
+ + @foreach (var item in projList) + { + + } + +
+ +
+
+ + + +
+ + @foreach (var item in fasiList) + { + if (@item.EnableTime) + { + if (item.Attivo) + { + + } + else + { + + } + } + else + { + if (item.Attivo) + { + + } + else + { + + } + } + } + +
+
+
+ +
+
+
+
+ + + +
+ +
+
+
+
+
+ + + +
+ +
+
+
+ + +
+
+ + + +
+ +
+
+
+
+ +
+
+ + + diff --git a/GPW.CORE.UI/Components/RegAttEditor.razor.cs b/GPW.CORE.UI/Components/RegAttEditor.razor.cs new file mode 100644 index 0000000..74b1cd7 --- /dev/null +++ b/GPW.CORE.UI/Components/RegAttEditor.razor.cs @@ -0,0 +1,211 @@ +using GPW.CORE.Data.DbModels; +using GPW.CORE.UI.Data; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace GPW.CORE.UI.Components +{ + public partial class RegAttEditor + { + #region Protected Fields + + protected string _gruppoSel = ""; + protected int _idxProj = 0; + protected bool vetoUpd = false; + + #endregion Protected Fields + + #region Private Properties + + [Inject] + private MessageService AppMServ { get; set; } + + [Inject] + private IJSRuntime JSRuntime { get; set; } + + private bool VetoInsert + { + get => GDataServ.VetoInsert; + } + + #endregion Private Properties + + #region Protected Properties + + protected List fasiList { get; set; } = new List(); + + [Inject] + protected GpwDataService GDataServ { get; set; } + + protected List gruppiList { get; set; } = new List(); + protected List projList { get; set; } = new List(); + + #endregion Protected Properties + + #region Public Properties + + [Parameter] + public RegAttivitaModel currRecord + { + get + { + return AppMServ.recordRA; + } + set + { + AppMServ.recordRA = value; + vetoUpd = true; + if (value.FasiNav != null && value.FasiNav.ProgettoNav != null) + { + gruppoSel = value.FasiNav.ProgettoNav.Gruppo; + idxProj = value.FasiNav.IdxProgetto != null ? (int)value.FasiNav.IdxProgetto : 0; + } + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + vetoUpd = false; + } + } + + public string gruppoSel + { + get + { + return _gruppoSel; + } + set + { + _gruppoSel = value; + if (!vetoUpd) + { + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + } + + public int idxProj + { + get + { + return _idxProj; + } + set + { + _idxProj = value; + if (!vetoUpd) + { + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + } + + [Parameter] + public EventCallback ItemReset { get; set; } + + [Parameter] + public EventCallback ItemUpdated { get; set; } + + #endregion Public Properties + + #region Private Methods + + private void arrotondaMinuti() + { + // arrotondo ai 5 min... + currRecord.Inizio = CORE.Data.Utils.DateRounded(currRecord.Inizio.AddMinutes(2), 5, true); + // arrotondo ai 5 min... + currRecord.Fine = CORE.Data.Utils.DateRounded(currRecord.Fine.AddMinutes(2), 5, true); + checkCoerenzaDate(true); + } + + /// + /// Verifico coerenza date (inizio < fine) + /// + /// indica se la data modificata sia l'inizio + private void checkCoerenzaDate(bool modInizio) + { + // verifica presenza errori + bool inError = currRecord.Inizio >= currRecord.Fine; + if (inError) + { + // se ho mod inizio --> tengo ferma fine, inizio 1/2 h prima + if (modInizio) + { + currRecord.Inizio = currRecord.Fine.AddMinutes(-30); + } + else + { + currRecord.Fine = currRecord.Inizio.AddMinutes(30); + } + } + } + + #endregion Private Methods + + #region Protected Methods + + /// + /// Salvo in MService record clonato + /// + protected async void DoClone() + { + AppMServ.clonedRA = currRecord; + await ItemReset.InvokeAsync(true); + } + + /// + /// Elimino record + /// + protected async void DoDelete() + { + // chiedo verifica + if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler eliminare il record selezionato??")) + return; + + // aggiorno + await GDataServ.RegAttDelete(currRecord); + // registro fatto + await ItemUpdated.InvokeAsync(true); + } + + /// + /// Indico item selezionato + /// + protected async void DoReset() + { + await ItemReset.InvokeAsync(true); + } + + /// + /// Aggiorno e riporto update + /// + protected async void DoUpdate() + { + arrotondaMinuti(); + // aggiorno + await GDataServ.RegAttUpdate(currRecord); + // resetto clone e record corrente... + AppMServ.clonedRA = null; + // registro fatto + await ItemUpdated.InvokeAsync(true); + } + + protected async Task ReloadData() + { + gruppiList = await GDataServ.AnagGruppiAll(); + var allProj = await GDataServ.AnagProjAll(); + projList = allProj + .Where(x => x.Attivo == true && x.Gruppo == gruppoSel) + .OrderBy(x => x.ClienteNav.RagSociale) + .ThenBy(x => x.NomeProj) + .ToList(); + var allFasi = await GDataServ.AnagFasiAll(); + fasiList = allFasi + .Where(x => x.IdxProgetto == idxProj) + .ToList(); + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/Svg.razor b/GPW.CORE.UI/Components/Svg.razor new file mode 100644 index 0000000..783d56c --- /dev/null +++ b/GPW.CORE.UI/Components/Svg.razor @@ -0,0 +1,45 @@ +

Test

+ +@*Vedere link +https://www.dallaskostna.ca/2021/03/13/scalable-vector-graphics-svg-and-blazor/ +*@ + + + + + + + + + + + + + + + + + + + + + + +@code { + string testclass1 = "regionnotclicked"; + string testclass2 = "regionnotclicked"; + string testclass3 = "regionnotclicked"; + + private void test1() + { + testclass1 = "regionclicked"; + } + private void test2() + { + testclass2 = "regionclicked"; + } + private void test3() + { + testclass3 = "regionclicked"; + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/TimbList.razor b/GPW.CORE.UI/Components/TimbList.razor new file mode 100644 index 0000000..421bf24 --- /dev/null +++ b/GPW.CORE.UI/Components/TimbList.razor @@ -0,0 +1,83 @@ +@using CORE.Data.DbModels +@using UI.Data + +@inject IJSRuntime JSRuntime +@inject GpwDataService GDataServ +@inject MessageService AppMServ + + + + + + + + + + + + + @foreach (var item in ListTimb) + { + + + + + + + + + } + +
Scambio
@item.DataOra.ToString("dd/MM - HH:mm") + @if (@item.Entrata == true) + { + + } + + + + @if (@item.Entrata == false) + { + + } + + +
+ +@code { + + private List _ListTimb { get; set; } = new List(); + + [Parameter] + public List ListTimb + { + get + { + return _ListTimb.OrderByDescending(x => x.DataOra).ToList(); + } + set + { + _ListTimb = value; + InvokeAsync(() => + { + StateHasChanged(); + }); + } + } + + [Parameter] + public EventCallback ReqDelete { get; set; } + + [Parameter] + public EventCallback ReqUpdate { get; set; } + + protected async void Delete(TimbratureModel currRecord) + { + await ReqDelete.InvokeAsync(currRecord); + } + + protected async void ScambioInOut(TimbratureModel currRecord) + { + await ReqUpdate.InvokeAsync(currRecord); + } +} diff --git a/GPW.CORE.UI/Components/TimbrEditor.razor b/GPW.CORE.UI/Components/TimbrEditor.razor new file mode 100644 index 0000000..244642a --- /dev/null +++ b/GPW.CORE.UI/Components/TimbrEditor.razor @@ -0,0 +1,84 @@ +@using CORE.Data.DbModels +@using UI.Data + + +
+
+
+
+

Timbrature

+
+
+ +
+
+
+
+
+
+
+
+
+ Timbrature Approvate +
+
+
+ @if (ListTimbAppr != null) + { + + } + else + { + + } +
+
+ +
+
+
+
+
+ Mancate timbrature +
+
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+ Richieste in corso +
+
+
+ @if (ListTimbRich != null) + { + + } + else + { + + } +
+
+
+
+
+
+ diff --git a/GPW.CORE.UI/Components/TimbrEditor.razor.cs b/GPW.CORE.UI/Components/TimbrEditor.razor.cs new file mode 100644 index 0000000..ebd719c --- /dev/null +++ b/GPW.CORE.UI/Components/TimbrEditor.razor.cs @@ -0,0 +1,187 @@ +using GPW.CORE.Data.DbModels; +using GPW.CORE.UI.Data; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace GPW.CORE.UI.Components +{ + public partial class TimbrEditor + { + #region Protected Fields + + protected bool vetoUpd = false; + + #endregion Protected Fields + + #region Private Properties + + [Inject] + private MessageService AppMServ { get; set; } + + [Inject] + private IHttpContextAccessor httpContextAccessor { get; set; } + + [Inject] + private IJSRuntime JSRuntime { get; set; } + + #endregion Private Properties + + #region Protected Properties + + + [Inject] + protected GpwDataService GDataServ { get; set; } + + protected bool IsUscita { get; set; } = false; + + protected List? ListTimbAppr { get; set; } + + protected List? ListTimbRich { get; set; } + + protected string txtMsgInOut + { + get => IsUscita ? "Uscita" : "Entrata"; + } + + #endregion Protected Properties + + #region Public Properties + + [Parameter] + public EventCallback CloseReq { get; set; } + + [Parameter] + public DateTime DataRif { get; set; } + + [Parameter] + public EventCallback ItemReset { get; set; } + + [Parameter] + public EventCallback ItemUpdated { get; set; } + + [Parameter] + public List ListTimb { get; set; } = new List(); + + #endregion Public Properties + + #region Private Methods + + private async Task ReloadData() + { + DateTime adesso = DateTime.Now; + ListTimb = (ListTimb == null) ? new List() : ListTimb; + + // prendo primo record timbrature o oggi... + if (ListTimb.Count > 0) + { + DataRif = ListTimb.FirstOrDefault().DataOra.Date.AddHours(adesso.Hour).AddMinutes(Math.Ceiling((double)adesso.Minute / 5) * 5); + } + else + { + DataRif = DateTime.Today.AddHours(adesso.Hour).AddMinutes(Math.Ceiling((double)adesso.Minute / 5) * 5); + } + await Task.Delay(1); + if (ListTimb != null) + { + ListTimbAppr = ListTimb.Where(x => x.Approv == true).OrderByDescending(x => x.DataOra).ToList(); + ListTimbRich = ListTimb.Where(x => x.Approv == false).OrderByDescending(x => x.DataOra).ToList(); + } + } + + #endregion Private Methods + + #region Protected Methods + + protected async void DoAdd() + { + var remoteIp = httpContextAccessor.HttpContext.Connection?.RemoteIpAddress.ToString(); + TimbratureModel currRecord = new TimbratureModel() + { + Entrata = !IsUscita, + Approv = false, + CodTipoTimb = "NoTim", + DataOra = DataRif, + IdxDipendente = AppMServ.IdxDipendente, + Ipv4 = $"{remoteIp}" + }; + + // aggiungo alla lista... + ListTimb.Add(currRecord); + ListTimbRich.Add(currRecord); + + + // aggiorno + await GDataServ.TimbratureUpdate(currRecord); + + await Task.Delay(10); + + await ReloadData(); + } + + /// + /// Indico item selezionato + /// + protected async void DoClose() + { + await CloseReq.InvokeAsync(true); + } + + /// + /// Aggiorno e riporto update + /// + protected async void DoDelete(TimbratureModel currRecord) + { + // chiedo verifica + if (!await JSRuntime.InvokeAsync("confirm", "Sicuro di voler eliminare la richiesta selezionata??")) + return; + + // elimino dalla lista... + ListTimb.Remove(currRecord); + if (ListTimbAppr.Contains(currRecord)) + { + ListTimbAppr.Remove(currRecord); + } + + if (ListTimbRich.Contains(currRecord)) + { + ListTimbRich.Remove(currRecord); + } + + // aggiorno + await GDataServ.TimbratureDelete(currRecord); + + await Task.Delay(10); + + await ReloadData(); + + await ItemUpdated.InvokeAsync(true); + } + + /// + /// Aggiorno e riporto update + /// + protected async void DoUpdate(TimbratureModel currRecord) + { + // elimino da lista + ListTimb.Remove(currRecord); + + // scambio + currRecord.Entrata = !currRecord.Entrata; + + // aggiorno + await GDataServ.TimbratureUpdate(currRecord); + + // ri-aggiungo in lista... + ListTimb.Add(currRecord); + + await ReloadData(); + } + + protected override async Task OnInitializedAsync() + { + await ReloadData(); + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Components/WeekPlanner.razor b/GPW.CORE.UI/Components/WeekPlanner.razor new file mode 100644 index 0000000..c56bd75 --- /dev/null +++ b/GPW.CORE.UI/Components/WeekPlanner.razor @@ -0,0 +1,5 @@ +

WeekPlanner

+ +@code { + +} diff --git a/GPW.CORE.UI/Components/WeekSelector.razor b/GPW.CORE.UI/Components/WeekSelector.razor new file mode 100644 index 0000000..98a1902 --- /dev/null +++ b/GPW.CORE.UI/Components/WeekSelector.razor @@ -0,0 +1,72 @@ +@using CORE.Data.DbModels +@using UI.Data + +@inject MessageService AppMServ + +
+
+
+
+

Selezione Data Riferimento

+
+
+ Selezionare la data desiderata +
+
+
+
+
+
+
+
+ Data Target +
+ +
+
+
+ +
+
+ +
+
+
+
+@code { + + [Parameter] + public EventCallback CloseReq { get; set; } + + + [Parameter] + public EventCallback WeekSelected { get; set; } + + /// + /// Indico item selezionato + /// + protected async void DoClose() + { + await CloseReq.InvokeAsync(true); + } + + /// + /// Indico item selezionato + /// + protected async void DoSelection() + { + await WeekSelected.InvokeAsync(true); + } + + protected DateTime TargetDate + { + get + { + return AppMServ.targetDate; + } + set + { + AppMServ.targetDate = value; + } + } +} diff --git a/GPW.CORE.UI/Components/WeekStat.razor b/GPW.CORE.UI/Components/WeekStat.razor new file mode 100644 index 0000000..77a7eb3 --- /dev/null +++ b/GPW.CORE.UI/Components/WeekStat.razor @@ -0,0 +1,164 @@ +@using GPW.CORE.Data + +
+
+ +
+
+
+
+
+
+ +
+ @currData?.SumOreLav.ToString("N2") +
+
+
+
+
+ +
+ @currData?.SumOreComm.ToString("N2") +
+
+
+
+
+
+
+
+
+
+
+
+
+ + @code { + + public class WeekArg + { + public int Year { get; set; } + public int Week { get; set; } + } + + + [Parameter] + public CORE.Data.DTO.WeekStatDTO? currData { get; set; } + + [Parameter] + public int WeekSel { get; set; } = 0; + + + [Parameter] + public EventCallback weekSelected { get; set; } + + protected int currWeekNum + { + get + { + int answ = 0; + if (currData != null) + { + answ = currData.WeekNumber; + } + return answ; + } + } + protected int currYearNum + { + get + { + int answ = 0; + if (currData != null) + { + answ = currData.Anno; + } + return answ; + } + } + + protected void reportSelect() + { + weekSelected.InvokeAsync(new WeekData(currYearNum, currWeekNum)); + } + + protected string selStyle + { + get + { + string currCss = "bg-secondary"; + if (currData != null) + { + currCss = currData.WeekNumber == WeekSel ? "btn-primary" : "btn-secondary"; + } + return currCss; + } + } + + protected double denom + { + get + { + double answ = 40; + // cerco massimo tra ore lav e commesse... + if (currData.SumOreLav > answ) + { + answ = currData.SumOreLav; + } + if (currData.SumOreComm > answ) + { + answ = currData.SumOreComm; + } + return answ; + } + } + + protected string styleLav + { + get + { + double valPerc = 0; + if (currData != null) + { + try + { + valPerc = currData.SumOreLav / denom; + } + catch + { } + } + return $"width: {valPerc:P0};"; + } + } + protected string styleCom + { + get + { + double valPerc = 0; + if (currData != null) + { + try + { + valPerc = currData.SumOreComm / denom; + } + catch + { } + } + return $"width: {valPerc:P0};"; + } + } + + } diff --git a/GPW.CORE.UI/Data/GpwDataService.cs b/GPW.CORE.UI/Data/GpwDataService.cs new file mode 100644 index 0000000..070a944 --- /dev/null +++ b/GPW.CORE.UI/Data/GpwDataService.cs @@ -0,0 +1,783 @@ +using GPW.CORE.Data.DbModels; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Caching.Memory; +using Newtonsoft.Json; +using NLog; +using System.Diagnostics; +using System.Text; + +namespace GPW.CORE.UI.Data +{ + public class GpwDataService : IDisposable + { + #region Private Fields + + private static IConfiguration _configuration = null!; + private static ILogger _logger = null!; + private static JsonSerializerSettings? JSSettings; + + private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); + + //private readonly IEmailSender _emailSender; + //private readonly UserManager _userManager; + private readonly IDistributedCache distributedCache; + + private readonly IMemoryCache memoryCache; + private List cachedDataList = new List(); + + /// + /// Durata assoluta massima della cache IN SECONDI + /// + private int chAbsExp = 60 * 5; + + /// + /// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa + /// NON estende oltre il tempo massimo di validità della cache (chAbsExp) + /// + private int chSliExp = 60 * 1; + + #endregion Private Fields + + #region Protected Fields + + protected const string rKeyAKV = "Cache:AKV"; + protected const string rKeyCalcOreFase = "Cache:CalcOreFase"; + protected const string rKeyCalcOreProj = "Cache:CalcOreProj"; + protected const string rKeyCliAll = "Cache:CliAll"; + protected const string rKeyDailyData = "Cache:DailyData"; + protected const string rKeyDipendenti = "Cache:Dipendenti"; + protected const string rKeyFasiAll = "Cache:FasiAll"; + protected const string rKeyGrpAll = "Cache:GrpAll"; + protected const string rKeyParetoRegAtt = "Cache:ParetoRegAtt"; + protected const string rKeyProjAll = "Cache:ProjAll"; + protected const string rKeyRilTemp = "Cache:RilTemp"; + protected const string rKeyVC19 = "Cache:VC19"; + protected const string rKeyVetoIns = "Cache:VetoInsert"; + protected const string rKeyWeekStats = "Cache:WeekStats"; + protected static string connStringBBM = ""; + + #endregion Protected Fields + + #region Public Fields + + public static CORE.Data.Controllers.GPWController dbController = null!; + + public bool VetoInsert = false; + + #endregion Public Fields + + #region Public Constructors + + public GpwDataService(IConfiguration configuration, ILogger logger, IMemoryCache memoryCache, IDistributedCache distributedCache) + { + _logger = logger; + _configuration = configuration; + // conf cache + this.memoryCache = memoryCache; + this.distributedCache = distributedCache; + + // json serializer... + // FIX errore loop circolare + // https://www.ryadel.com/en/jsonserializationexception-self-referencing-loop-detected-error-fix-entity-framework-asp-net-core/ + JSSettings = new JsonSerializerSettings() + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }; + // cod app + CodApp = _configuration["CodApp"]; + var strVeto = _configuration["VetoIns"]; + _ = bool.TryParse(strVeto, out VetoInsert); + // conf DB + string connStr = _configuration.GetConnectionString("GPW.DB"); + if (string.IsNullOrEmpty(connStr)) + { + _logger.LogError("ConnString empty!"); + } + else + { + dbController = new CORE.Data.Controllers.GPWController(configuration); + } + } + + #endregion Public Constructors + + #region Public Properties + + public string CodApp { get; set; } = ""; + + #endregion Public Properties + + #region Private Methods + + private DistributedCacheEntryOptions cacheOpt(bool fastCache) + { + var numSecAbsExp = fastCache ? chAbsExp : chAbsExp * 10; + var numSecSliExp = fastCache ? chSliExp : chSliExp * 10; + return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp)); + } + + private DistributedCacheEntryOptions cacheOpt(int multFact) + { + var numSecAbsExp = chAbsExp * multFact; + var numSecSliExp = chSliExp * multFact; + return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp)); + } + + #endregion Private Methods + + #region Protected Methods + + /// + /// Registra in cache chiave se non fosse già in elenco + /// + /// + protected void trackCache(string newKey) + { + if (!cachedDataList.Contains(newKey)) + { + cachedDataList.Add(newKey); + } + } + + #endregion Protected Methods + + #region Public Methods + + /// + /// Elenco AKV + /// + public async Task> AKVList() + { + List dbResult = new List(); + // cerco da cache + string currKey = rKeyAKV; + trackCache(currKey); + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.AnagKeyValGetAll(); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(500)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per AKVList: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + /// + /// Recupera l'elenco fasi (tutte) + /// + /// + public async Task> AnagClientiAll() + { + List? dbResult = new List(); + string currKey = $"{rKeyCliAll}"; + + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.AnagClientiAll(); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per AnagClientiAll: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + /// + /// Recupera l'elenco fasi (tutte) + /// + /// + public async Task> AnagFasiAll() + { + List? dbResult = new List(); + string currKey = $"{rKeyFasiAll}"; + + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.AnagFasiAll(false); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per AnagFasiAll: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + /// + /// Recupera info x una specifica FASE + /// + /// + public async Task AnagFasiSearch(int idxFase) + { + AnagFasiModel dbResult = new AnagFasiModel(); + var rawData = await AnagFasiAll(); + if (rawData != null) + { + dbResult = rawData.FirstOrDefault(x => x.IdxFase == idxFase); + } + + return await Task.FromResult(dbResult); + } + + /// + /// Recupera l'elenco gruppi (tutti) + /// + /// + public async Task> AnagGruppiAll() + { + List? dbResult = new List(); + string currKey = $"{rKeyGrpAll}"; + + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.AnagGruppiAll(); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per AnagGruppiAll: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + /// + /// Recupera l'elenco progetti (tutti) + /// + /// + public async Task> AnagProjAll() + { + List? dbResult = new List(); + string currKey = $"{rKeyProjAll}"; + + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.AnagProjAll(false); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per AnagProjAll: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + /// + /// Recupera info x uno specifico PROJ + /// + /// + public async Task AnagProjSearch(int idxProj) + { + AnagProgettiModel dbResult = new AnagProgettiModel(); + var rawData = await AnagProjAll(); + if (rawData != null) + { + dbResult = rawData.FirstOrDefault(x => x.IdxProgetto == idxProj); + } + + return await Task.FromResult(dbResult); + } + + /// + /// Vista dati per FASE (tipicamente master...) con totalizzaizone ore budget/real e stato fase + /// + /// + /// + public async Task CalcOreFase(int idxFase) + { + CalcOreFasiModel? dbResult = new CalcOreFasiModel(); + string currKey = $"{rKeyCalcOreFase}:{idxFase}"; + trackCache(currKey); + + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.CalcOreFase(idxFase); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per CalcOreFase: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new CalcOreFasiModel(); + } + return await Task.FromResult(dbResult); + } + + /// + /// Vista dati per progetto con totalizzaizone ore budget/real + /// + /// + /// + public async Task CalcOreProj(int idxProj) + { + CalcOreProgettiModel? dbResult = new CalcOreProgettiModel(); + string currKey = $"{rKeyCalcOreProj}:{idxProj}"; + trackCache(currKey); + + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.CalcOreProj(idxProj); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per CalcOreProj: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new CalcOreProgettiModel(); + } + return await Task.FromResult(dbResult); + } + + /// + /// Recupera l'elenco dei controlli VC19 nel periodo indicato x dipendente + /// + /// Dipendente interessato + /// Data di riferimento (ultima/corrente) + /// NUm settimane precedenti da recuperare + /// + public async Task> CheckVC19List(int idxDipendente, DateTime dtInizio, DateTime dtFine) + { + List? dbResult = new List(); + string currKey = $"{rKeyVC19}:{dtInizio:yyyyMMdd}:{dtFine:yyyMMdd}"; + trackCache(currKey); + + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.CheckVC19List(idxDipendente, dtInizio, dtFine); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per CheckVC19List: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + /// + /// Recupera l'elenco dei dettagli giornalieri attività di un dipendente, dato periodo riferimento + /// + /// Dipendente interessato + /// Data di riferimento (ultima/corrente) + /// NUm settimane precedenti da recuperare + /// + public async Task> DailyDetails(int idxDipendente, DateTime dtInizio, DateTime dtFine) + { + List? dbResult = new List(); + string currKey = $"{rKeyDailyData}:{idxDipendente}:{dtInizio.ToString("yyyy-MM-dd")}:{dtFine.ToString("yyyy-MM-dd")}"; + trackCache(currKey); + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.DailyDetails(idxDipendente, dtInizio, dtFine); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per DailyDetails: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + public async Task> DipendentiGetAll() + { + List? dbResult = new List(); + string rawData; + var redisDataList = await distributedCache.GetAsync(rKeyDipendenti); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.DipendentiGetAll(); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(rKeyDipendenti, redisDataList, cacheOpt(false)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per DipendentiGetAll: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + public void Dispose() + { + // Clear database controller + dbController.Dispose(); + } + + /// + /// invalida tutta la cache in caso di update + /// + /// + public async Task InvalidateAllCache() + { + await distributedCache.RemoveAsync(rKeyDipendenti); + await distributedCache.RemoveAsync(rKeyFasiAll); + foreach (var item in cachedDataList) + { + await distributedCache.RemoveAsync(item); + } + cachedDataList = new List(); + } + + /// + /// Invalida la cache corrispondente al apttern fornito + /// + /// + public async Task InvalidateCache(string cachePattern) + { + foreach (var item in cachedDataList) + { + if (item.Contains(cachePattern)) + { + await distributedCache.RemoveAsync(item); + } + } + } + + /// + /// Statistiche ultime settimane + /// + /// + /// + /// + /// + public async Task> LastWeeks(int idxDipendente, DateTime dtRif, int numWeek) + { + List? dbResult = new List(); + string currKey = $"{rKeyWeekStats}:{idxDipendente}:{dtRif.ToString("yyyy-MM-dd")}:{numWeek}"; + trackCache(currKey); + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.WeekOverview(idxDipendente, dtRif, numWeek); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per LastWeeks: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + /// + /// Elenco pareto progetti ordinati da filtro + /// + /// + /// + /// + /// + public async Task> ParetoRegAtt(int idxDip, int numDayPrev, int maxResult) + { + List? dbResult = new List(); + string currKey = $"{rKeyParetoRegAtt}:{idxDip}:{numDayPrev}:{maxResult}"; + + DateTime dataFine = DateTime.Today.AddDays(1); + DateTime dataInizio = dataFine.AddDays(-numDayPrev); + + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.ParetoRegAtt(idxDip, dataInizio, dataFine, maxResult); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per ParetoRegAtt: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + public async Task RegAttDelete(RegAttivitaModel currItem) + { + bool answ = false; + try + { + dbController.RegAttDelete(currItem); + // invalido la cache... + await InvalidateAllCache(); + answ = true; + } + catch + { } + return answ; + } + + /// + /// Recupera ultima attività dipendente + /// + /// + /// cerca ultima solo tra attive (=true) o tutte (=false) + /// + public async Task RegAttLastByDip(int IdxDipendente, bool onlyActive) + { + RegAttivitaModel dbResult = dbController.RegAttLastByDip(IdxDipendente, onlyActive); + return await Task.FromResult(dbResult); + } + + public async Task RegAttUpdate(RegAttivitaModel currItem) + { + bool answ = false; + try + { + dbController.RegAttUpdate(currItem); + // invalido la cache... + await InvalidateAllCache(); + answ = true; + } + catch + { } + return answ; + } + + /// + /// Recupera l'elenco dei Rilievi temperatura nel periodo indicato x dipendente + /// + /// Dipendente interessato + /// Data di riferimento (ultima/corrente) + /// NUm settimane precedenti da recuperare + /// + public async Task> RilTempList(int idxDipendente, DateTime dtInizio, DateTime dtFine) + { + List? dbResult = new List(); + string currKey = $"{rKeyRilTemp}:{dtInizio:yyyyMMdd}:{dtFine:yyyMMdd}"; + trackCache(currKey); + + string rawData; + var redisDataList = await distributedCache.GetAsync(currKey); + if (redisDataList != null) + { + rawData = Encoding.UTF8.GetString(redisDataList); + dbResult = JsonConvert.DeserializeObject>(rawData); + } + else + { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + dbResult = dbController.RilTempList(idxDipendente, dtInizio, dtFine); + rawData = JsonConvert.SerializeObject(dbResult, JSSettings); + redisDataList = Encoding.UTF8.GetBytes(rawData); + await distributedCache.SetAsync(currKey, redisDataList, cacheOpt(true)); + stopWatch.Stop(); + TimeSpan ts = stopWatch.Elapsed; + Log.Trace($"Effettuata lettura da DB + caching per RilTempList: {ts.TotalMilliseconds} ms"); + } + if (dbResult == null) + { + dbResult = new List(); + } + return await Task.FromResult(dbResult); + } + + public async Task RilTempUpdate(RilievoTempModel currItem) + { + bool answ = false; + try + { + dbController.RilTempUpdate(currItem); + // invalido la cache... + await InvalidateCache(rKeyRilTemp); + //await InvalidateCache($"{rKeyWeekStats}:{currItem.IdxDipendente}"); + await InvalidateCache($"{rKeyDailyData}:{currItem.IdxDipendente}"); + answ = true; + } + catch + { } + return answ; + } + + public void rollBackEdit(object item) + { + dbController.rollBackEntity(item); + } + + public async Task TimbratureDelete(TimbratureModel currItem) + { + bool answ = false; + try + { + dbController.TimbratureDelete(currItem); + // invalido la cache... + await InvalidateAllCache(); + answ = true; + } + catch + { } + return answ; + } + + public async Task TimbratureUpdate(TimbratureModel currItem) + { + bool answ = false; + try + { + dbController.TimbratureUpdate(currItem); + // invalido la cache... + await InvalidateAllCache(); + answ = true; + } + catch + { } + return answ; + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Data/LicenseService.cs b/GPW.CORE.UI/Data/LicenseService.cs new file mode 100644 index 0000000..739c83e --- /dev/null +++ b/GPW.CORE.UI/Data/LicenseService.cs @@ -0,0 +1,308 @@ +using GPW.CORE.Data; +using GPW.CORE.Data.DbModels; +using Microsoft.Extensions.Caching.Distributed; +using Newtonsoft.Json; +using RestSharp; +using System.Diagnostics; +using System.Text; +using System.Web; + +namespace GPW.CORE.UI.Data +{ + /// + /// Servizi e dati condivisi a livello applicazione + /// + public class LicenseService + { + #region Private Fields + + private static ILogger _logger; + private static IConfiguration _configuration; + private readonly IDistributedCache distributedCache; + + /// + /// Chiave redis x attivazioni della licenza + /// + protected const string rKeyAttByLic = "LongCache:AttByLic"; + + /// + /// Durata assoluta massima della cache IN SECONDI + /// + private int chAbsExp = 60 * 5; + + /// + /// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa + /// NON estende oltre il tempo massimo di validità della cache (chAbsExp) + /// + private int chSliExp = 60 * 1; + + /// + /// Fattorte conversione cache sliding --> 1 h + /// + private int cacheFact = 12; + + /// + /// Opzioni cache con moltiplicatore durata risp durata base (1/5 minuti) + /// + /// + /// + private DistributedCacheEntryOptions cacheOpt(int multFact) + { + var numSecAbsExp = chAbsExp * multFact; + var numSecSliExp = chSliExp * multFact; + return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp)); + } + + /// + /// Elenco obj in cache + /// + private List cachedDataList = new List(); + + /// + /// Init classe + /// + /// + /// + /// + public LicenseService(IConfiguration configuration, ILogger logger, IDistributedCache distributedCache) + { + _logger = logger; + _configuration = configuration; + this.distributedCache = distributedCache; + } + + /// + /// Recupero chiave da redis + /// + /// + /// + protected async Task getRSV(string rKey) + { + string answ = ""; + var redisDataList = await distributedCache.GetAsync(rKey); + if (redisDataList != null) + { + answ = Encoding.UTF8.GetString(redisDataList); + } + return answ; + } + + /// + /// Salvataggio chiave in redis + /// + /// + /// + /// + /// + protected async Task setRSV(string rKey, string rVal, int cacheMult) + { + bool fatto = false; + var redisDataList = Encoding.UTF8.GetBytes(rVal); + await distributedCache.SetAsync(rKey, redisDataList, cacheOpt(cacheMult)); + fatto = true; + return fatto; + } + + /// + /// Salvataggio chiave in redis + /// + /// + /// + /// + /// + protected async Task setRSV(string rKey, int rValInt, int cacheMult) + { + bool fatto = false; + var redisDataList = Encoding.UTF8.GetBytes($"{rValInt}"); + await distributedCache.SetAsync(rKey, redisDataList, cacheOpt(cacheMult)); + fatto = true; + return fatto; + } + /// + /// Registra in cache chiave se non fosse già in elenco + /// + /// + protected void trackCache(string newKey) + { + if (!cachedDataList.Contains(newKey)) + { + cachedDataList.Add(newKey); + } + } + + #endregion Private Fields + + #region Public Events + + public event Action EA_InfoUpdated = null!; + + public List ActivList { get; set; } = new List(); + + #endregion Public Events + + #region Public Properties + + public async Task> ActivListCache() + { + List dbResult = new List(); + string cacheKey = $"{rKeyAttByLic}:{MasterKey}"; + trackCache(cacheKey); + string rawData = await getRSV(cacheKey); + if (!string.IsNullOrEmpty(rawData)) + { + dbResult = JsonConvert.DeserializeObject>(rawData); + } + return await Task.FromResult(dbResult); + } + public async Task setActivList(List newActList, int numDays) + { + bool fatto = false; + string cacheKey = $"{rKeyAttByLic}:{MasterKey}"; + var rawData = JsonConvert.SerializeObject(newActList); + await setRSV(cacheKey, rawData, numDays * cacheFact * 24); + fatto = true; + if (EA_InfoUpdated != null) + { + EA_InfoUpdated?.Invoke(); + } + return fatto; + } + + public List AKVList { get; set; } = new List(); + + public string Installazione { get; set; } = ""; + public string Applicazione { get; set; } = ""; + public string MasterKey { get; set; } = ""; + + public bool ValidData + { + get + { + // controllo valori string base + bool checkData = !string.IsNullOrEmpty(Installazione) && !string.IsNullOrEmpty(Applicazione) && !string.IsNullOrEmpty(MasterKey); + return checkData; + } + } + + public bool HasActivData + { + get + { + bool answ = ValidData; + // se ok controllo che ci siano attivazioni + if (answ) + { + // provo classe locale... + answ = ActivList != null && ActivList.Count > 0; + // se non le avessi carico! + if (!answ) + { + var pUpd = Task.Run(async () => + { + ActivList = await ActivListCache(); + }); + pUpd.Wait(); + } + + } + return answ; + } + } + + public DateTime infoExpiry { get; set; } = DateTime.Today.AddDays(1); + + #endregion Public Properties + + #region Private Methods + + private void ReportUpdated() + { + if (EA_InfoUpdated != null) + { + EA_InfoUpdated?.Invoke(); + } + } + + /// + /// Cerca di recuperare valore string da elenco AKV + /// + /// Chiave AKV richiesta + /// + protected string getAVKStr(string varReq) + { + string answ = ""; + if (AKVList != null && AKVList.Count > 0) + { + var currRec = AKVList.Where(x => x.NomeVar == varReq).FirstOrDefault(); + if (currRec != null) + { + answ = $"{currRec.ValString}"; + } + } + return answ; + } + + /// + /// Init della classe con variabili di base da Redis/DB + /// + public bool InitAkv() + { + bool fatto = false; + Installazione = getAVKStr("installazione"); + MasterKey = getAVKStr(Installazione); + fatto = !string.IsNullOrEmpty($"{Installazione}{MasterKey}"); + return fatto; + } + + /// + /// Init della classe con variabili di base da Redis/DB + /// + public async Task RefreshLicense() + { + bool fatto = false; + var onlineAct = await OnlineActivationList(); + if (onlineAct != null) + { + if (onlineAct.Count > 0) + { + // scadenza info a 15 gg... + int numDays = 15; + infoExpiry = DateTime.Now.AddDays(numDays); + ActivList = onlineAct; + fatto = await setActivList(onlineAct, numDays); + } + } + await Task.Delay(1); + return fatto; + } + + /// + /// URL dell'API x chiamate gestione licenze + /// + private static string apiUrl = "https://liman.egalware.com/ELM.API/"; + + /// + /// Elenco attivazioni attuali + /// + private async Task> OnlineActivationList() + { + List answ = new List(); + // cerco online + RestClient client = new RestClient(apiUrl); + //client.Authenticator = new HttpBasicAuthenticator("username", "password"); + string MKeyEnc = HttpUtility.UrlEncode(MasterKey); + var request = new RestRequest($"/api/attivazioni/?chiave={MKeyEnc}", Method.Get); + var response = await client.GetAsync(request); + // controllo risposta + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + // salvo in redis contenuto serializzato + string rawData = response.Content; + answ = JsonConvert.DeserializeObject>(rawData); + } + return await Task.FromResult(answ); + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Data/MessageService.cs b/GPW.CORE.UI/Data/MessageService.cs new file mode 100644 index 0000000..66a0c3a --- /dev/null +++ b/GPW.CORE.UI/Data/MessageService.cs @@ -0,0 +1,210 @@ +using GPW.CORE.Data; +using GPW.CORE.Data.DbModels; +using System.Security.Cryptography; +using System.Text; + +namespace GPW.CORE.UI.Data +{ + public class MessageService + { + + #region Private Fields + + private string _pageIcon = ""; + + private string _pageName = ""; + + private string _searchVal = ""; + + private DipendentiModel _rigaDip; + + private bool showSearch; + + #endregion Private Fields + + #region Public Events + + public event Action EA_HideSearch = null!; + + public event Action EA_PageUpdated = null!; + + public event Action EA_SearchUpdated = null!; + + public event Action EA_ShowSearch = null!; + + #endregion Public Events + + #region Public Properties + + public string PageIcon + { + get => _pageIcon; + set + { + if (_pageIcon != value) + { + _pageIcon = value; + ReportPageUpd(); + } + } + } + + public string PageName + { + get => _pageName; + set + { + if (_pageName != value) + { + _pageName = value; + ReportPageUpd(); + } + } + } + + public string SearchVal + { + get => _searchVal; + set + { + if (_searchVal != value) + { + _searchVal = value; + + if (EA_SearchUpdated != null) + { + EA_SearchUpdated?.Invoke(); + } + } + } + } + + public DipendentiModel? RigaDip + { + get => _rigaDip; + set + { + if (_rigaDip != value) + { + _rigaDip = value; + + if (EA_SearchUpdated != null) + { + EA_SearchUpdated?.Invoke(); + } + } + } + } + + public int IdxDipendente + { + get + { + int answ = 0; + if (_rigaDip != null) + { + answ = _rigaDip.IdxDipendente; + } + return answ; + } + } + + public bool IsActive + { + get + { + bool answ = false; + if (_rigaDip != null) + { + answ = (bool)_rigaDip.Attivo; + } + return answ; + } + } + public bool PayloadOk { get; set; } = false; + + /// + /// Calcola HASH del codice impiego = payload utente + /// + /// + /// + public string HashDip + { + get + { + string hash = ""; + string answ = ""; + if (_rigaDip != null) + { + answ = $"{_rigaDip.IdxDipendente}|{_rigaDip.Cognome}.{_rigaDip.Nome}|{_rigaDip.Cf}|{_rigaDip.DataAssunzione:yyyyMMdd}|{_rigaDip.Email}|{_rigaDip.Matricola}"; + } + // hashing! + using (var md5 = MD5.Create()) + { + byte[] InputBytes = Encoding.UTF8.GetBytes(answ); + var byteHash = md5.ComputeHash(InputBytes); + hash = BitConverter.ToString(byteHash).Replace("-", "").ToLowerInvariant(); + } + return hash; + } + } + + public bool ShowSearch + { + get => showSearch; + set + { + if (showSearch != value) + { + showSearch = value; + if (showSearch) + { + if (EA_ShowSearch != null) + { + EA_ShowSearch?.Invoke(); + } + } + else + { + if (EA_HideSearch != null) + { + EA_HideSearch?.Invoke(); + } + } + } + } + } + + public RegAttivitaModel? recordRA { get; set; } = null; + public RegAttivitaModel? clonedRA { get; set; } = null; + + + public int selWeekNum { get; set; } = 0; + public int selYear { get; set; } = DateTime.Today.Year; + + public DateTime targetDate { get; set; } = DateTime.Today; + + + #endregion Public Properties + + #region Private Methods + + private void ReportPageUpd() + { + if (EA_PageUpdated != null) + { + EA_PageUpdated?.Invoke(); + } + } + + private void ReportSearch() + { + if (EA_SearchUpdated != null) + { + EA_SearchUpdated?.Invoke(); + } + } + + #endregion Private Methods + } +} diff --git a/GPW.CORE.UI/GPW.CORE.UI.csproj b/GPW.CORE.UI/GPW.CORE.UI.csproj new file mode 100644 index 0000000..87f30dc --- /dev/null +++ b/GPW.CORE.UI/GPW.CORE.UI.csproj @@ -0,0 +1,39 @@ + + + + net6.0 + 3.0.2201.2614 + enable + enable + + + + + + + + <_WebToolingArtifacts Remove="Properties\PublishProfiles\IIS02.pubxml" /> + <_WebToolingArtifacts Remove="Properties\PublishProfiles\W2019-IIS-DEV.pubxml" /> + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GPW.CORE.UI/Pages/Error.cshtml b/GPW.CORE.UI/Pages/Error.cshtml new file mode 100644 index 0000000..0ad849b --- /dev/null +++ b/GPW.CORE.UI/Pages/Error.cshtml @@ -0,0 +1,42 @@ +@page +@model GPW.CORE.UI.Pages.ErrorModel + + + + + + + + Error + + + + + +
+
+

Error.

+

An error occurred while processing your request.

+ + @if (Model.ShowRequestId) + { +

+ Request ID: @Model.RequestId +

+ } + +

Development Mode

+

+ Swapping to the Development environment displays detailed information about the error that occurred. +

+

+ The Development environment shouldn't be enabled for deployed applications. + It can result in displaying sensitive information from exceptions to end users. + For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development + and restarting the app. +

+
+
+ + + diff --git a/GPW.CORE.UI/Pages/Error.cshtml.cs b/GPW.CORE.UI/Pages/Error.cshtml.cs new file mode 100644 index 0000000..1b622d8 --- /dev/null +++ b/GPW.CORE.UI/Pages/Error.cshtml.cs @@ -0,0 +1,27 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using System.Diagnostics; + +namespace GPW.CORE.UI.Pages +{ + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + [IgnoreAntiforgeryToken] + public class ErrorModel : PageModel + { + public string? RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + + private readonly ILogger _logger; + + public ErrorModel(ILogger logger) + { + _logger = logger; + } + + public void OnGet() + { + RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; + } + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Pages/FastRec.razor b/GPW.CORE.UI/Pages/FastRec.razor new file mode 100644 index 0000000..0b0a8b2 --- /dev/null +++ b/GPW.CORE.UI/Pages/FastRec.razor @@ -0,0 +1,189 @@ +@page "/FastRec" +@attribute [Authorize] + +@using GPW.CORE.UI +@using GPW.CORE.UI.Components +@using CORE.Data.DbModels +@using CORE.Data.DTO +@using UI.Data + +@inject IJSRuntime JSRuntime +@inject GpwDataService GDataServ +@inject MessageService AppMServ + +
+
+
+
+

Fast Recording

+
+
+
+
+ + + +
+ +
+
+
+
+
+
+
+ @if (@TipoSearch == 0) + { + + } + else if (@TipoSearch == 1) + { + + } +
+
+ @if (idxFaseSel > 0) + { + + } + else + { +
+

Attesa selezione

+ Selezionare una Fase per attivare la registrazione attività +
+ } +
+
+ + @foreach (var currItem in ListRecords) + { + + } +
+
+
+
+ + + +@code { + + private List ListFasi = new List(); + private List ListRecords = new List(); + private int _tipoSearch = 0; + + public int TipoSearch + { + get + { + return _tipoSearch; + } + set + { + if (!_tipoSearch.Equals(value)) + { + _tipoSearch = value; + idxFaseSel = 0; + } + } + } + + protected int startHour = 7; + protected int endHour = 21; + protected bool isLoading = false; + private int idxFaseSel = 0; + + private int idxDipendente + { + get => AppMServ.IdxDipendente; + } + + private void SelFase(int idxFase) + { + idxFaseSel = idxFase; + } + + private void RecDone(bool fatto) + { + idxFaseSel = 0; + } + + private async Task ReloadData() + { + isLoading = true; + DateTime oggi = DateTime.Today; + var rawData=await GDataServ.DailyDetails(idxDipendente, oggi, oggi.AddDays(1)); + ListRecords = rawData.Where(x=> x.DtRif==oggi).ToList(); + await Task.Delay(100); + checkHourRange(); + await Task.Delay(100); + isLoading = false; + } + + protected override async Task OnInitializedAsync() + { + await ReloadData(); + } + + private void checkHourRange() + { + int minHour = 9; + int maxHour = 18; + if (ListRecords != null) + { + int roundMin = 15; + // per ogni giornata + foreach (var giornata in ListRecords) + { + var minRecTimb = giornata.ListTimbr + .Where(x => x.Entrata == true) + .OrderBy(x => x.DataOra) + .FirstOrDefault(); + if (minRecTimb != null) + { + if (minHour > minRecTimb.DataOra.AddMinutes(-roundMin).Hour) + { + minHour = minRecTimb.DataOra.AddMinutes(-roundMin).Hour; + } + } + var minRecRa = giornata.ListRA + .OrderBy(x => x.Inizio) + .FirstOrDefault(); + if (minRecRa != null) + { + if (minHour > minRecRa.Inizio.AddMinutes(-roundMin).Hour) + { + minHour = minRecRa.Inizio.AddMinutes(-roundMin).Hour; + } + } + var maxRecTimb = giornata.ListTimbr + .Where(x => x.Entrata == false) + .OrderByDescending(x => x.DataOra) + .FirstOrDefault(); + if (maxRecTimb != null) + { + if (maxHour < maxRecTimb.DataOra.AddMinutes(roundMin).Hour + 1) + { + maxHour = maxRecTimb.DataOra.AddMinutes(roundMin).Hour + 1; + } + } + var maxRecRa = giornata.ListRA + .OrderByDescending(x => x.Fine) + .FirstOrDefault(); + if (maxRecRa != null) + { + if (maxHour < maxRecRa.Fine.AddMinutes(roundMin).Hour + 1) + { + maxHour = maxRecRa.Fine.AddMinutes(roundMin).Hour + 1; + } + } + } + } + startHour = minHour; + endHour = maxHour; + } +} diff --git a/GPW.CORE.UI/Pages/ForceReset.razor b/GPW.CORE.UI/Pages/ForceReset.razor new file mode 100644 index 0000000..8b48768 --- /dev/null +++ b/GPW.CORE.UI/Pages/ForceReset.razor @@ -0,0 +1,39 @@ +@page "/ForceReset" +@attribute [Authorize] + +@using CORE.Data.DbModels +@using UI.Data +@inject GpwDataService GDataServ +@inject NavigationManager NavManager +@inject MessageService AppMServ + + +
+
+ Data Reset +
+
+

@message

+ +
+
+ +@code { + protected string message = "Resetting Cache!"; + protected override async Task OnInitializedAsync() + { + await GDataServ.InvalidateAllCache(); + + AppMServ.clonedRA = null; + AppMServ.recordRA = null; + //AppMServ.RigaDip = null; + message = "Reset done!"; + + // attendo 500 msec + await Task.Delay(500); + + // passo a pagina home + NavManager.NavigateTo("Planner"); + } + +} diff --git a/GPW.CORE.UI/Pages/Index.razor b/GPW.CORE.UI/Pages/Index.razor new file mode 100644 index 0000000..eed2d15 --- /dev/null +++ b/GPW.CORE.UI/Pages/Index.razor @@ -0,0 +1,20 @@ +@page "/" + +GPW + + +
+
+

GPW - Log Commesse

+
+
+ + Egalware + +
+
+
+ Gestione commesse utente GPW, visualizzazione formato planner settimanale +
+
+
\ No newline at end of file diff --git a/GPW.CORE.UI/Pages/Planner.razor b/GPW.CORE.UI/Pages/Planner.razor new file mode 100644 index 0000000..50a2b38 --- /dev/null +++ b/GPW.CORE.UI/Pages/Planner.razor @@ -0,0 +1,145 @@ +@page "/Planner" +@attribute [Authorize] +@using GPW.CORE.UI.Components + +@if (selPeriod) +{ + + + +} +else if (showTemp) +{ + + + +} +else if (currRecord != null) +{ + + + +} +else if (ListTimbr != null) +{ + + + +} + +
+
+
+
+ +
+ +
+
+ + + +
+
+
+ @if (weekStatList != null) + { +
+ @foreach (var item in weekStatList) + { +
+ +
+ } +
+ } + else + { + + } +
+
+
+
+ @if (ListRecords == null) + { + + } + else + { + +
+
+ +
+ @foreach (var currItem in ListRecords) + { +
+ +
+ } +
+ } +
+ +
+ + + + diff --git a/GPW.CORE.UI/Pages/Planner.razor.cs b/GPW.CORE.UI/Pages/Planner.razor.cs new file mode 100644 index 0000000..967171c --- /dev/null +++ b/GPW.CORE.UI/Pages/Planner.razor.cs @@ -0,0 +1,498 @@ +using GPW.CORE.Data; +using GPW.CORE.Data.DbModels; +using GPW.CORE.Data.DTO; +using GPW.CORE.UI.Data; +using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; + +namespace GPW.CORE.UI.Pages +{ + /// + /// Gestione pagina principale del planner + /// + /// modale: vedere qui: https://gist.github.com/conficient/ba98d1662c659e170ec16650acea05c8 + /// + //[Authorize(Roles = "SuperAdmin, Admin")] + public partial class Planner : IDisposable + { + #region Private Fields + + private int _endHour = 19; + private int _startHour = 8; + + private RegAttivitaModel currRecord = null; + private List ListFasi = new List(); + private List ListRecords = new List(); + private List ListTimbr = null; + private bool selPeriod = false; + private List weekStatList = new List(); + private bool showTemp = false; + private DateTime DtRifTempRil = DateTime.Today; + + #endregion Private Fields + + #region Private Properties + + private int _currPage { get; set; } = 1; + + private int _numRecord { get; set; } = 10; + + private int _selPlantId { get; set; } = 0; + + private int _selSuppId { get; set; } = 0; + + private int _selTraspId { get; set; } = 0; + + private int currPage + { + get => _currPage; + set + { + if (_currPage != value) + { + _currPage = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + } + + private int endHour + { + get => _endHour; + set + { + // fix --> max 24... + _endHour = _endHour > 24 ? 24 : _endHour; + if (_endHour != value) + { + _endHour = value; + } + } + } + + private bool isLoading { get; set; } = false; + + private int numRecord + { + get => _numRecord; + set + { + if (_numRecord != value) + { + _numRecord = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + } + + private double periodoClonato + { + get + { + double answ = 8; + // se ho record clkonato --> uso quello + if (clonedRA != null) + { + answ = clonedRA.Durata.TotalHours; + } + else + { + answ = endHour - startHour; + } + return answ; + } + } + + private int startHour + { + get => _startHour; + set + { + // fix --> MIN 0... + _startHour = _startHour < 0 ? 0 : _startHour; + + if (_startHour != value) + { + _startHour = value; + } + } + } + + #endregion Private Properties + + #region Protected Properties + + protected string actionCss + { + get => isLoading ? "disabled" : ""; + } + + [Inject] + protected MessageService AppMServ { get; set; } + + protected int currWeekNum + { + get + { + return AppMServ.selWeekNum; + } + set + { + AppMServ.selWeekNum = value; + } + } + + protected WeekData currWeekSel + { + get + { + return new WeekData(currYear, currWeekNum); + } + } + + protected int currYear + { + get + { + return AppMServ.selYear; + } + set + { + AppMServ.selYear = value; + } + } + + [Inject] + protected GpwDataService DataService { get; set; } + + /// + /// Dipendente corrente + /// + protected int IdxDipendente + { + get + { + return AppMServ.IdxDipendente; + } + } + + [Inject] + protected IJSRuntime JSRuntime { get; set; } + + [Inject] + protected NavigationManager NavManager { get; set; } + + protected DateTime TargetDate + { + get + { + return AppMServ.targetDate; + } + set + { + AppMServ.targetDate = value; + } + } + + #endregion Protected Properties + + #region Public Properties + + public RegAttivitaModel clonedRA + { + get + { + return AppMServ.clonedRA; + } + set + { + AppMServ.clonedRA = value; + } + } + + #endregion Public Properties + + #region Private Methods + + private void checkHourRange() + { + int minHour = 9; + int maxHour = 18; + if (ListRecords != null) + { + int roundMin = 15; + // per ogni giornata + foreach (var giornata in ListRecords) + { + var minRecTimb = giornata.ListTimbr + .Where(x => x.Entrata == true) + .OrderBy(x => x.DataOra) + .FirstOrDefault(); + if (minRecTimb != null) + { + if (minHour > minRecTimb.DataOra.AddMinutes(-roundMin).Hour) + { + minHour = minRecTimb.DataOra.AddMinutes(-roundMin).Hour; + } + } + var minRecRa = giornata.ListRA + .OrderBy(x => x.Inizio) + .FirstOrDefault(); + if (minRecRa != null) + { + if (minHour > minRecRa.Inizio.AddMinutes(-roundMin).Hour) + { + minHour = minRecRa.Inizio.AddMinutes(-roundMin).Hour; + } + } + var maxRecTimb = giornata.ListTimbr + .Where(x => x.Entrata == false) + .OrderByDescending(x => x.DataOra) + .FirstOrDefault(); + if (maxRecTimb != null) + { + if (maxHour < maxRecTimb.DataOra.AddMinutes(roundMin).Hour + 1) + { + maxHour = maxRecTimb.DataOra.AddMinutes(roundMin).Hour + 1; + } + } + var maxRecRa = giornata.ListRA + .OrderByDescending(x => x.Fine) + .FirstOrDefault(); + if (maxRecRa != null) + { + if (maxHour < maxRecRa.Fine.AddMinutes(roundMin).Hour + 1) + { + maxHour = maxRecRa.Fine.AddMinutes(roundMin).Hour + 1; + } + } + } + } + startHour = minHour; + endHour = maxHour; + } + + /// + /// Reinit dei dati + /// + /// + /// + private async Task InitData(bool dateReset) + { + isLoading = true; + if (dateReset) + { + TargetDate = DateTime.Today; + } + weekStatList = await DataService.LastWeeks(IdxDipendente, TargetDate, 4); + currWeekNum = weekStatList.Last().WeekNumber; + isLoading = false; + } + + private async Task ReloadData() + { + isLoading = true; + ListRecords = await DataService.DailyDetails(IdxDipendente, currWeekSel.inizio, currWeekSel.fine); + await Task.Delay(100); + checkHourRange(); + await Task.Delay(100); + lastRefresh = DateTime.Now; + isLoading = false; + } + + #endregion Private Methods + + #region Protected Methods + + protected async Task MoveWeek(int numWeek) + { + isLoading = true; + TargetDate = TargetDate.AddDays(numWeek * 7); + await Task.Delay(100); + await InitData(false); + await Task.Delay(100); + await ReloadData(); + } + + protected override async Task OnInitializedAsync() + { + await InitData(true); + await ReloadData(); + } + + /// + /// Indico item selezionato + /// + protected async void PeriodoSelect(List newList) + { + // salvo periodo selezionato + ListTimbr = newList; + } + + /// + /// Indico item selezionato + /// + protected async void ShowTempRil(DateTime dataRif) + { + // salvo data + DtRifTempRil = dataRif; + showTemp = true; + } + + /// + /// Timer per refresh dati + /// + /// https://stackoverflow.com/questions/63060065/blazor-timer-call-async-api-task-to-update-ui + /// https://www.janduniec.blog/index.php/100/timers-in-blazor/ + /// + protected System.Timers.Timer UITimer; + + protected DateTime lastRefresh = DateTime.Now; + + protected override void OnInitialized() + { + // avvio un timer infinito x refresh pagina COMUNQUE ogni 60 sec anche non succedesse nulla... + UITimer = new System.Timers.Timer + { + Interval = 1000 * 60, + AutoReset = true, + Enabled = true + }; + UITimer.Elapsed += async (s, ea) => await TryReload(); + } + public void Dispose() + { + UITimer?.Dispose(); + } + + /// + /// Gestione refresh condizionale + /// + /// + protected async Task TryReload() + { + await Task.Delay(1); + // effettuo reload SOLO SE no ho editing in corso... + if (!modeEdit) + { + await ReloadData(); + await InvokeAsync(StateHasChanged); + } + } + + protected bool modeEdit + { + get => (currRecord != null || ListTimbr != null || showTemp); + //get => (selPeriod || showTemp || currRecord != null || weekStatList != null || ListTimbr != null); + } + + protected async Task ReloadPeriodo() + { + selPeriod = false; + showTemp = false; + weekStatList = null; + currRecord = null; + ListTimbr = null; + await Task.Delay(50); + await InitData(false); + await Task.Delay(50); + await ReloadData(); + } + + /// + /// Indico item selezionato + /// + protected async void ReportSelect(RegAttivitaModel selRecord) + { + // recupero attivit selezionata in curr record + currRecord = selRecord; + } + + protected void ResetClone() + { + clonedRA = null; + } + + protected async Task ResetData() + { + currRecord = null; + ListTimbr = null; + await InitData(true); + await ReloadData(); + } + + protected async Task ResetSelPeriodo() + { + selPeriod = false; + showTemp = false; + currRecord = null; + ListTimbr = null; + await InitData(true); + await ReloadData(); + } + + protected async Task ResetDayCheck() + { + selPeriod = false; + showTemp = false; + currRecord = null; + ListTimbr = null; + await InitData(true); + await ReloadData(); + } + + protected async Task ResetTimbData() + { + currRecord = null; + ListTimbr = null; + await ReloadData(); + } + + protected async Task ResetWeek() + { + isLoading = true; + TargetDate = DateTime.Today; + await Task.Delay(100); + await InitData(false); + await Task.Delay(100); + await ReloadData(); + } + + protected async Task setWeekNumber(WeekData wData) + { + isLoading = true; + // seleziono settimana! + currYear = wData.anno; + currWeekNum = wData.weekNumber; + // resetto currRecord... + currRecord = null; + await ReloadData(); + } + + protected async Task ShowSelPeriodo() + { + selPeriod = true; + } + + protected async Task UpdRegAttData() + { + isLoading = true; + currRecord = null; + ListTimbr = null; + await Task.Delay(100); + await ReloadData(); + } + + protected async Task UpdTimbData() + { + isLoading = true; + currRecord = null; + await Task.Delay(100); + await ReloadData(); + } + + #endregion Protected Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Pages/Test.razor b/GPW.CORE.UI/Pages/Test.razor new file mode 100644 index 0000000..413406a --- /dev/null +++ b/GPW.CORE.UI/Pages/Test.razor @@ -0,0 +1,383 @@ +@page "/Test" +@attribute [AllowAnonymous] + +@using GPW.CORE.UI.Components + +Test - Fasi + +
+
+ +
+
+ +
+
+ +
+
+ +@*
+
+
+
+ +
+
St... - OR...
+
Mail
+
-
+
+
+
+
+ +
+
SteamSW - GPW
+
sviluppo
+
Continuo sviluppo editing
+
+
+
+
+ +
+
SteamSW - GPW
+
sviluppo
+
Continuo sviluppo editing
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
St... - OR...
+
Mail
+
-
+
+
+
+
+
+ +
+
SteamSW - GPW
+
sviluppo
+
Continuo sviluppo editing
+
+
+
+
+ +
+
SteamSW - GPW
+
sviluppo
+
Continuo sviluppo editing
+
+
+
+
+
*@ + + + +
+
Testo 1
+
Testo 2
+
Testo 3
+
Testo 4
+
+ + +@*
+
+

Fasi

+
+
+ @if (ListRecords == null) + { + + } + else if (totalCount == 0) + { +
No Record Found
+ } + else + { +
+
+ + + + + + + + + + + @foreach (var record in ListRecords) + { + + + + + + + } + +
IDCodNomeDescrizione
+ P@record.IdxProgetto | @record.IdxFase (← @record.IdxFaseAncest) + + @record.CodFase + + @record.NomeFase + + @record.DescrizioneFase +
+
+
+ } +
+ +
*@ \ No newline at end of file diff --git a/GPW.CORE.UI/Pages/Test.razor.cs b/GPW.CORE.UI/Pages/Test.razor.cs new file mode 100644 index 0000000..46e9440 --- /dev/null +++ b/GPW.CORE.UI/Pages/Test.razor.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using System.Net.Http; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Components.Authorization; +using Microsoft.AspNetCore.Components.Forms; +using Microsoft.AspNetCore.Components.Routing; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Components.Web.Virtualization; +using Microsoft.JSInterop; +using GPW.CORE.UI; +using GPW.CORE.UI.Shared; +using GPW.CORE.UI.Components; +using GPW.CORE.Data.DbModels; +using GPW.CORE.UI.Data; + +namespace GPW.CORE.UI.Pages +{ + public partial class Test : ComponentBase, IDisposable + { + #region Private Fields + + private List ListRecords = null!; + private List SearchRecords = null!; + + #endregion Private Fields + + #region Private Properties + + private int _currPage { get; set; } = 1; + + private int _numRecord { get; set; } = 10; + + private int currPage + { + get => _currPage; + set + { + if (_currPage != value) + { + _currPage = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + } + + private bool isLoading { get; set; } = false; + + private int IdxDipSel = 0; + + [Inject] + private NavigationManager NavManager { get; set; } = null!; + + private int numRecord + { + get => _numRecord; + set + { + if (_numRecord != value) + { + _numRecord = value; + var pUpd = Task.Run(async () => await ReloadData()); + pUpd.Wait(); + } + } + } + + #endregion Private Properties + + #region Protected Properties + + [Inject] + + protected MessageService AppMService { get; set; } = null!; + + [Inject] + protected GpwDataService DataService { get; set; } = null!; + + [Inject] + protected IJSRuntime JSRuntime { get; set; } = null!; + + protected int totalCount + { + get + { + int answ = 0; + if (SearchRecords != null) + { + answ = SearchRecords.Count; + } + return answ; + } + } + + protected List getTsData() + { + List answ = new List(); + DateTime dtCurs = DateTime.Now.AddDays(-120); + Random rnd = new Random(); + + for (int i = 0; i < 60; i++) + { + answ.Add(new chartJsData.chartJsTSerie() { x = dtCurs, y = (decimal)(360 + rnd.Next(-5, 12)) / 10 }); + dtCurs = dtCurs.AddDays(rnd.Next(1,4)); + } + return answ; + } + + #endregion Protected Properties + + #region Private Methods + + private async Task ReloadData() + { + isLoading = true; + SearchRecords = await DataService.AnagFasiAll(); + ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); + isLoading = false; + } + + #endregion Private Methods + + #region Protected Methods + + protected void ForceReload(int newNum) + { + numRecord = newNum; + } + + protected void ForceReloadPage(int newNum) + { + currPage = newNum; + } + + protected override async Task OnInitializedAsync() + { + await ReloadData(); + } + + protected void ResetData() + { + //DataService.rollBackEdit(currRecord); + } + + protected void Select(DipendentiModel selRecord) + { + IdxDipSel = selRecord.IdxDipendente; + //// rimando a remnants + //NavManager.NavigateTo($"Remnants"); + } + + #endregion Protected Methods + + #region Public Methods + + public void Dispose() + { + //AppMService.EA_SearchUpdated -= OnSeachUpdated; + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Pages/_Host.cshtml b/GPW.CORE.UI/Pages/_Host.cshtml new file mode 100644 index 0000000..6b24341 --- /dev/null +++ b/GPW.CORE.UI/Pages/_Host.cshtml @@ -0,0 +1,10 @@ +@page "/" +@namespace GPW.CORE.UI.Pages +@using Microsoft.AspNetCore.Authorization +@attribute [AllowAnonymous] +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@{ + Layout = "_Layout"; +} + + diff --git a/GPW.CORE.UI/Pages/_Layout.cshtml b/GPW.CORE.UI/Pages/_Layout.cshtml new file mode 100644 index 0000000..7d72848 --- /dev/null +++ b/GPW.CORE.UI/Pages/_Layout.cshtml @@ -0,0 +1,38 @@ +@using Microsoft.AspNetCore.Components.Web +@namespace GPW.CORE.UI.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers + + + + + + + + + + + + + + + + @RenderBody() + +
+ + An error has occurred. This application may no longer respond until reloaded. + + + An unhandled exception has occurred. See browser dev tools for details. + + Reload + 🗙 +
+ + + + + + + + diff --git a/GPW.CORE.UI/Program.cs b/GPW.CORE.UI/Program.cs new file mode 100644 index 0000000..74e69f8 --- /dev/null +++ b/GPW.CORE.UI/Program.cs @@ -0,0 +1,53 @@ +using GPW.CORE.UI.Data; +using Microsoft.AspNetCore.Authentication.Negotiate; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddAuthentication(NegotiateDefaults.AuthenticationScheme) + .AddNegotiate(); + +builder.Services.AddAuthorization(options => +{ + // By default, all incoming requests will be authorized according to the default policy. + options.FallbackPolicy = options.DefaultPolicy; +}); + +builder.Services.AddStackExchangeRedisCache(options => +{ + options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions() { KeepAlive = 180, DefaultDatabase = 15, EndPoints = { { "localhost", 6379 } } }; + options.InstanceName = "GPW-CORE:"; +}); + +builder.Services.AddRazorPages(); +builder.Services.AddServerSideBlazor(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddScoped(); +builder.Services.AddHttpContextAccessor(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); +} + +app.UseHttpsRedirection(); + +app.UseStaticFiles(); + +app.UseRouting(); + +app.UseAuthentication(); +app.UseAuthorization(); + +app.MapBlazorHub(); +app.MapFallbackToPage("/_Host"); + +app.Run(); diff --git a/GPW.CORE.UI/Properties/launchSettings.json b/GPW.CORE.UI/Properties/launchSettings.json new file mode 100644 index 0000000..0eddfb9 --- /dev/null +++ b/GPW.CORE.UI/Properties/launchSettings.json @@ -0,0 +1,28 @@ +{ + "iisSettings": { + "windowsAuthentication": true, + "anonymousAuthentication": false, + "iisExpress": { + "applicationUrl": "http://localhost:46448", + "sslPort": 44369 + } + }, + "profiles": { + "GPW.CORE.UI": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7211;http://localhost:5211", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/GPW.CORE.UI/Shared/LoginDisplay.razor b/GPW.CORE.UI/Shared/LoginDisplay.razor new file mode 100644 index 0000000..b0f8593 --- /dev/null +++ b/GPW.CORE.UI/Shared/LoginDisplay.razor @@ -0,0 +1,170 @@ +@using CORE.Data.DbModels +@using UI.Data +@using Microsoft.AspNetCore.Identity +@inject MessageService AppMServ +@inject LicenseService LicServ +@inject GpwDataService GDataServ +@inject AuthenticationStateProvider AuthenticationStateProvider + + +
+
@userName
+
+ +
+
+ +
+
+
+ +@code { + + [Inject] + private NavigationManager NavManager { get; set; } = null!; + + private string userName = ""; + + protected override async Task OnInitializedAsync() + { + //effettuo eventuale recupero dati dipendente + if (AppMServ.RigaDip == null) + { + await LoadUtente(); + } + // verifica attivazione + await VerifyActiv(); + } + + protected async Task DoReloadUtente() + { + AppMServ.RigaDip = null; + await Task.Delay(250); + await LoadUtente(); + // verifico attivazione dipendente... + await checkUserLicense(); + } + + protected async Task DoVerifyActiv() + { + AppMServ.PayloadOk = false; + await Task.Delay(250); + await VerifyActiv(); + } + + protected async Task LoadUtente() + { + var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); + var user = authState.User; + // verifico se ho utente loggato... + if (user.Identity != null && user.Identity.IsAuthenticated) + { + userName = $"{user.Identity.Name}"; + // cerco su DB + var listaDip = await GDataServ.DipendentiGetAll(); + DipendentiModel? rigaDip = listaDip + .Where(x => $"{x.Dominio}\\{x.Utente}".ToLower() == userName.ToLower()) + .FirstOrDefault(); + if (rigaDip != null) + { + // salvo riga info dipendente + AppMServ.RigaDip = rigaDip; + userName = $"{rigaDip.Cognome} {rigaDip.Nome}"; + } + } + else + { + userName = "N.A."; + } + } + + protected async Task VerifyActiv() + { + // preliminarmente verifica shared info + await checkSharedInfo(); + // refresh attivazioni se necessario + await checkActivations(); + // verifico e salvo dati attivazione dipendente... + await checkUserLicense(); + } + + /// + /// Verifica informazioni condivise applicazione + /// + /// + protected async Task checkSharedInfo() + { + bool allOk = false; + if (!LicServ.ValidData) + { + // salvo cod app da conf... + LicServ.Applicazione = GDataServ.CodApp; + // effettuo lettura dati preliminari da AKV (eventualmente in cache...) + List rawAkvList = await GDataServ.AKVList(); + if (rawAkvList != null) + { + LicServ.AKVList = rawAkvList; + allOk = LicServ.InitAkv(); + } + } + await Task.Delay(1); + return allOk; + } + + /// + /// Verifica informazioni condivise applicazione + /// + /// + protected async Task checkActivations() + { + bool allOk = false; + if (LicServ.ValidData) + { + // se non fosse tutto ok + if (!LicServ.HasActivData) + { + // chiamo refresh licenze da remoto + allOk = await LicServ.RefreshLicense(); + } + } + await Task.Delay(1); + return allOk; + } + + /// + /// Verifica info specifiche utente + /// + /// + protected async Task checkUserLicense() + { + bool answ = false; + // verifico utente attivo + answ = AppMServ.IsActive; + if (answ) + { + var rawActList = LicServ.ActivList; + // recupero hash utente + string hashImpiego = AppMServ.HashDip; + // confronto con elenco attivazioni dello shared service... + var foundRec = rawActList.Where(x => x.CodImpiego == hashImpiego); + answ = foundRec.Count() > 0; + // salvo status payloadOk + AppMServ.PayloadOk = answ; + } + await Task.Delay(1); + return answ; + } + + protected string cssActive + { + get => AppMServ.IsActive ? "text-success" : "text-danger"; + } + protected string cssLicOk + { + get => AppMServ.PayloadOk ? "text-success" : "text-danger"; + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/Shared/MainLayout.razor b/GPW.CORE.UI/Shared/MainLayout.razor new file mode 100644 index 0000000..4d8a797 --- /dev/null +++ b/GPW.CORE.UI/Shared/MainLayout.razor @@ -0,0 +1,23 @@ +@inherits LayoutComponentBase + +GPW.CORE.UI + +
+ + +
+
+ + + +
+
+ @Body +
+
+ +
+
+
diff --git a/GPW.CORE.UI/Shared/MainLayout.razor.css b/GPW.CORE.UI/Shared/MainLayout.razor.css new file mode 100644 index 0000000..8abb9e2 --- /dev/null +++ b/GPW.CORE.UI/Shared/MainLayout.razor.css @@ -0,0 +1,77 @@ +.page { + position: relative; + display: flex; + flex-direction: column; +} + +main { + flex: 1; +} + +.sidebar { + background-image: linear-gradient(180deg, rgb(5, 39, 103) 20%, #3aa6ff 90%); +} + +.top-row { + background-color: #f7f7f7; + border-bottom: 1px solid #d6d5d5; + justify-content: flex-end; + height: 3.5rem; + display: flex; + align-items: center; +} + + .top-row ::deep a, .top-row .btn-link { + white-space: nowrap; + margin-left: 1.5rem; + } + + .top-row a:first-child { + overflow: hidden; + text-overflow: ellipsis; + } + +.bottom-row { + color: #dedede; + background-color: #000000; + height: 2rem; + align-items: center; +} + +@media (max-width: 640.98px) { + .top-row:not(.auth) { + display: none; + } + + .top-row.auth { + justify-content: space-between; + } + + .top-row a, .top-row .btn-link { + margin-left: 0; + } +} + +@media (min-width: 641px) { + .page { + flex-direction: row; + } + + .sidebar { + width: 250px; + height: 100vh; + position: sticky; + top: 0; + } + + .top-row { + position: sticky; + top: 0; + z-index: 1; + } + + .top-row, article { + padding-left: 2rem !important; + padding-right: 1.5rem !important; + } +} diff --git a/GPW.CORE.UI/Shared/NavMenu.razor b/GPW.CORE.UI/Shared/NavMenu.razor new file mode 100644 index 0000000..65b9030 --- /dev/null +++ b/GPW.CORE.UI/Shared/NavMenu.razor @@ -0,0 +1,49 @@ + + +
+ +
+ +@code { + private bool collapseNavMenu = true; + + private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null; + + private void ToggleNavMenu() + { + collapseNavMenu = !collapseNavMenu; + } +} diff --git a/GPW.CORE.UI/Shared/NavMenu.razor.css b/GPW.CORE.UI/Shared/NavMenu.razor.css new file mode 100644 index 0000000..75cac5d --- /dev/null +++ b/GPW.CORE.UI/Shared/NavMenu.razor.css @@ -0,0 +1,62 @@ +.navbar-toggler { + background-color: rgba(255, 255, 255, 0.1); +} + +.top-row { + height: 3.5rem; + background-color: rgba(0,0,0,0.4); +} + +.navbar-brand { + font-size: 1.1rem; +} + +.oi { + width: 2rem; + font-size: 1.1rem; + vertical-align: text-top; + top: -2px; +} + +.nav-item { + font-size: 0.9rem; + padding-bottom: 0.5rem; +} + + .nav-item:first-of-type { + padding-top: 1rem; + } + + .nav-item:last-of-type { + padding-bottom: 1rem; + } + + .nav-item ::deep a { + color: #d7d7d7; + border-radius: 4px; + height: 3rem; + display: flex; + align-items: center; + line-height: 3rem; + } + + .nav-item ::deep a.active { + background-color: rgba(255,255,255,0.25); + color: white; + } + + .nav-item ::deep a:hover { + background-color: rgba(255,255,255,0.1); + color: white; + } + +@media (min-width: 641px) { + .navbar-toggler { + display: none; + } + + .collapse { + /* Never collapse the sidebar for wide screens */ + display: block; + } +} diff --git a/GPW.CORE.UI/_Imports.razor b/GPW.CORE.UI/_Imports.razor new file mode 100644 index 0000000..d85cc3b --- /dev/null +++ b/GPW.CORE.UI/_Imports.razor @@ -0,0 +1,11 @@ +@using System.Net.Http +@using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components.Authorization +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop +@using GPW.CORE.UI +@using GPW.CORE.UI.Shared +@using GPW.CORE.UI.Components diff --git a/GPW.CORE.UI/appsettings.Development.json b/GPW.CORE.UI/appsettings.Development.json new file mode 100644 index 0000000..770d3e9 --- /dev/null +++ b/GPW.CORE.UI/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "DetailedErrors": true, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/GPW.CORE.UI/appsettings.json b/GPW.CORE.UI/appsettings.json new file mode 100644 index 0000000..5be4960 --- /dev/null +++ b/GPW.CORE.UI/appsettings.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "CodApp": "GPW", + "ConnectionStrings": { + "GPW.DB": "Server=SQLSTEAM;Database=GPW; User ID=sa;Password=keyhammer; integrated security=False; MultipleActiveResultSets=True; App=GPW.CORE.UI;", + "Redis": "localhost:6379" + }, + "VetoIns": "true" +} diff --git a/GPW.CORE.UI/chartJsData.cs b/GPW.CORE.UI/chartJsData.cs new file mode 100644 index 0000000..41a9495 --- /dev/null +++ b/GPW.CORE.UI/chartJsData.cs @@ -0,0 +1,16 @@ +namespace GPW.CORE.UI +{ + public class chartJsData + { + public class chartJsTSerie + { + public DateTime x { get; set; } + public decimal y { get; set; } + } + public class chartJsXY + { + public decimal x { get; set; } + public decimal y { get; set; } + } + } +} diff --git a/GPW.CORE.UI/compilerconfig.json b/GPW.CORE.UI/compilerconfig.json new file mode 100644 index 0000000..caa3f6e --- /dev/null +++ b/GPW.CORE.UI/compilerconfig.json @@ -0,0 +1,10 @@ +[ + { + "outputFile": "wwwroot/css/site.css", + "inputFile": "wwwroot/css/site.less" + }, + { + "outputFile": "wwwroot/css/fonts.css", + "inputFile": "wwwroot/css/fonts.less" + } +] \ No newline at end of file diff --git a/GPW.CORE.UI/compilerconfig.json.defaults b/GPW.CORE.UI/compilerconfig.json.defaults new file mode 100644 index 0000000..3b42415 --- /dev/null +++ b/GPW.CORE.UI/compilerconfig.json.defaults @@ -0,0 +1,61 @@ +{ + "compilers": { + "less": { + "autoPrefix": "", + "cssComb": "none", + "ieCompat": true, + "math": null, + "strictMath": false, + "strictUnits": false, + "relativeUrls": true, + "rootPath": "", + "sourceMapRoot": "", + "sourceMapBasePath": "", + "sourceMap": false + }, + "sass": { + "autoPrefix": "", + "loadPaths": [], + "style": 0, + "precision": 10, + "quiet": true, + "quietDeps": true, + "sourceMap": false + }, + "stylus": { + "sourceMap": false + }, + "babel": { + "sourceMap": false + }, + "coffeescript": { + "bare": false, + "runtimeMode": "node", + "sourceMap": false + }, + "handlebars": { + "root": "", + "noBOM": false, + "name": "", + "namespace": "", + "knownHelpersOnly": false, + "forcePartial": false, + "knownHelpers": [], + "commonjs": "", + "amd": false, + "sourceMap": false + } + }, + "minifiers": { + "css": { + "enabled": true, + "termSemicolons": true, + "gzip": false + }, + "javascript": { + "enabled": true, + "termSemicolons": true, + "gzip": false + } + } +} \ No newline at end of file diff --git a/GPW.CORE.UI/libman.json b/GPW.CORE.UI/libman.json new file mode 100644 index 0000000..1fd66e9 --- /dev/null +++ b/GPW.CORE.UI/libman.json @@ -0,0 +1,26 @@ +{ + "version": "1.0", + "defaultProvider": "cdnjs", + "libraries": [ + { + "library": "font-awesome@5.15.4", + "destination": "wwwroot/lib/font-awesome/" + }, + { + "library": "bootstrap@4.6.1", + "destination": "wwwroot/lib/bootstrap/" + }, + { + "library": "Chart.js@3.7.0", + "destination": "wwwroot/lib/Chart.js/" + }, + { + "library": "chartjs-adapter-luxon@1.1.0", + "destination": "wwwroot/lib/chartjs-adapter-luxon/" + }, + { + "library": "luxon@2.3.0", + "destination": "wwwroot/lib/luxon/" + } + ] +} \ No newline at end of file diff --git a/GPW.CORE.UI/post-build.ps1 b/GPW.CORE.UI/post-build.ps1 new file mode 100644 index 0000000..fcf5a81 --- /dev/null +++ b/GPW.CORE.UI/post-build.ps1 @@ -0,0 +1,31 @@ +param([string]$ProjectDir, [string]$ProjectPath); + +$FileVers="..\Resources\VersNum.txt" +$FileManIn="..\Resources\manifest-original.xml" +$FileManOut="..\Resources\manifest.xml" +$FileCLogIn="..\Resources\ChangeLog-original.html" +$FileCLogOut="..\Resources\ChangeLog.html" +$MajMin="3.0." +$currentDate = get-date -format yyMM; +$currentTime = get-date -format ddHH; +$find = "(.|\n)*?"; +$currRelNum=$MajMin + $currentDate +"." + $currentTime +$replace = "" + $MajMin + $currentDate +"." + $currentTime + ""; +$csproj = Get-Content $ProjectPath +$csprojUpdated = $csproj -replace $find, $replace + +Set-Content -Path $ProjectPath -Value $csprojUpdated +Set-Content -Path $FileVers -Value $currRelNum + +# replace x manifest +$manData = Get-Content $FileManIn +$manData = $manData -replace "1.0.0.0", $currRelNum +$manData = $manData -replace "{{DIRNAME}}", "GWMS" +$manData = $manData -replace "{{BRANCHNAME}}", "stable/0" +$manData = $manData -replace "{{PACKNAME}}", "GWMS.UI" +Set-Content -Path $FileManOut -Value $manData + +# replace x ChangeLog +$clogData = Get-Content $FileCLogIn +$clogData = $clogData -replace "{{CURRENT-REL}}", $currRelNum +Set-Content -Path $FileCLogOut -Value $clogData diff --git a/GPW.CORE.UI/wwwroot/css/bootstrap/bootstrap.min.css b/GPW.CORE.UI/wwwroot/css/bootstrap/bootstrap.min.css new file mode 100644 index 0000000..02ae65b --- /dev/null +++ b/GPW.CORE.UI/wwwroot/css/bootstrap/bootstrap.min.css @@ -0,0 +1,7 @@ +@charset "UTF-8";/*! + * Bootstrap v5.1.0 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root{--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-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-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-rgb:33,37,41;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",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-bg:#fff}*,::after,::before{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:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],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}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,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]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button: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:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-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}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x,.75rem);padding-left:var(--bs-gutter-x,.75rem);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}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x) * -.5);margin-left:calc(var(--bs-gutter-x) * -.5)}.row>*{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.3333333333%}.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.6666666667%}.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.3333333333%}.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.6666666667%}.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.3333333333%}.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.6666666667%}.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.3333333333%}.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.6666666667%}.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.3333333333%}.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.6666666667%}.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.3333333333%}.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.6666666667%}.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}}.table{--bs-table-bg:transparent;--bs-table-accent-bg:transparent;--bs-table-striped-color:#212529;--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:#212529;--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:#212529;--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:#212529;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:last-child)>:last-child>*{border-bottom-color:currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-striped>tbody>tr:nth-of-type(odd){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg:#cfe2ff;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:#000;border-color:#bacbe6}.table-secondary{--bs-table-bg:#e2e3e5;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:#000;border-color:#cbccce}.table-success{--bs-table-bg:#d1e7dd;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:#000;border-color:#bcd0c7}.table-info{--bs-table-bg:#cff4fc;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:#000;border-color:#badce3}.table-warning{--bs-table-bg:#fff3cd;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:#000;border-color:#e6dbb9}.table-danger{--bs-table-bg:#f8d7da;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:#000;border-color:#dfc2c4}.table-light{--bs-table-bg:#f8f9fa;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:#000;border-color:#dfe0e1}.table-dark{--bs-table-bg:#212529;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:#fff;border-color:#373b3e}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#6c757d}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#212529;background-color:#fff;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + .5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:auto;padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.5em;border-radius:.25rem}.form-control-color::-webkit-color-swatch{height:1.5em;border-radius:.25rem}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #212529}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .75rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .75rem}.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#198754}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(25,135,84,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#198754;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#198754}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#198754}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#198754}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#198754}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group .form-control.is-valid,.input-group .form-select.is-valid,.was-validated .input-group .form-control:valid,.was-validated .input-group .form-select:valid{z-index:1}.input-group .form-control.is-valid:focus,.input-group .form-select.is-valid:focus,.was-validated .input-group .form-control:valid:focus,.was-validated .input-group .form-select:valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#dc3545}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#dc3545}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#dc3545}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group .form-control.is-invalid,.input-group .form-select.is-invalid,.was-validated .input-group .form-control:invalid,.was-validated .input-group .form-select:invalid{z-index:2}.input-group .form-control.is-invalid:focus,.input-group .form-select.is-invalid:focus,.was-validated .input-group .form-control:invalid:focus,.was-validated .input-group .form-select:invalid:focus{z-index:3}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-primary{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-primary:hover{color:#fff;background-color:#0b5ed7;border-color:#0a58ca}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#fff;background-color:#0b5ed7;border-color:#0a58ca;box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-check:active+.btn-primary,.btn-check:checked+.btn-primary,.btn-primary.active,.btn-primary:active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0a58ca;border-color:#0a53be}.btn-check:active+.btn-primary:focus,.btn-check:checked+.btn-primary:focus,.btn-primary.active:focus,.btn-primary:active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5c636a;border-color:#565e64}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#5c636a;border-color:#565e64;box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-check:active+.btn-secondary,.btn-check:checked+.btn-secondary,.btn-secondary.active,.btn-secondary:active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#565e64;border-color:#51585e}.btn-check:active+.btn-secondary:focus,.btn-check:checked+.btn-secondary:focus,.btn-secondary.active:focus,.btn-secondary:active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-success{color:#fff;background-color:#198754;border-color:#198754}.btn-success:hover{color:#fff;background-color:#157347;border-color:#146c43}.btn-check:focus+.btn-success,.btn-success:focus{color:#fff;background-color:#157347;border-color:#146c43;box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-check:active+.btn-success,.btn-check:checked+.btn-success,.btn-success.active,.btn-success:active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#146c43;border-color:#13653f}.btn-check:active+.btn-success:focus,.btn-check:checked+.btn-success:focus,.btn-success.active:focus,.btn-success:active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#198754;border-color:#198754}.btn-info{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-info:hover{color:#000;background-color:#31d2f2;border-color:#25cff2}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#31d2f2;border-color:#25cff2;box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-check:active+.btn-info,.btn-check:checked+.btn-info,.btn-info.active,.btn-info:active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#3dd5f3;border-color:#25cff2}.btn-check:active+.btn-info:focus,.btn-check:checked+.btn-info:focus,.btn-info.active:focus,.btn-info:active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-info.disabled,.btn-info:disabled{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-warning{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#000;background-color:#ffca2c;border-color:#ffc720}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#ffca2c;border-color:#ffc720;box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-check:active+.btn-warning,.btn-check:checked+.btn-warning,.btn-warning.active,.btn-warning:active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#ffcd39;border-color:#ffc720}.btn-check:active+.btn-warning:focus,.btn-check:checked+.btn-warning:focus,.btn-warning.active:focus,.btn-warning:active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#bb2d3b;border-color:#b02a37}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#fff;background-color:#bb2d3b;border-color:#b02a37;box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-check:active+.btn-danger,.btn-check:checked+.btn-danger,.btn-danger.active,.btn-danger:active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#b02a37;border-color:#a52834}.btn-check:active+.btn-danger:focus,.btn-check:checked+.btn-danger:focus,.btn-danger.active:focus,.btn-danger:active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-light{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:focus+.btn-light,.btn-light:focus{color:#000;background-color:#f9fafb;border-color:#f9fafb;box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-check:active+.btn-light,.btn-check:checked+.btn-light,.btn-light.active,.btn-light:active,.show>.btn-light.dropdown-toggle{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:active+.btn-light:focus,.btn-check:checked+.btn-light:focus,.btn-light.active:focus,.btn-light:active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-light.disabled,.btn-light:disabled{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-dark{color:#fff;background-color:#212529;border-color:#212529}.btn-dark:hover{color:#fff;background-color:#1c1f23;border-color:#1a1e21}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#1c1f23;border-color:#1a1e21;box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-check:active+.btn-dark,.btn-check:checked+.btn-dark,.btn-dark.active,.btn-dark:active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1a1e21;border-color:#191c1f}.btn-check:active+.btn-dark:focus,.btn-check:checked+.btn-dark:focus,.btn-dark.active:focus,.btn-dark:active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#212529;border-color:#212529}.btn-outline-primary{color:#0d6efd;border-color:#0d6efd}.btn-outline-primary:hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-check:active+.btn-outline-primary,.btn-check:checked+.btn-outline-primary,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show,.btn-outline-primary:active{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-check:active+.btn-outline-primary:focus,.btn-check:checked+.btn-outline-primary:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus,.btn-outline-primary:active:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#0d6efd;background-color:transparent}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-check:active+.btn-outline-secondary,.btn-check:checked+.btn-outline-secondary,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show,.btn-outline-secondary:active{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:active+.btn-outline-secondary:focus,.btn-check:checked+.btn-outline-secondary:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus,.btn-outline-secondary:active:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-success{color:#198754;border-color:#198754}.btn-outline-success:hover{color:#fff;background-color:#198754;border-color:#198754}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-check:active+.btn-outline-success,.btn-check:checked+.btn-outline-success,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show,.btn-outline-success:active{color:#fff;background-color:#198754;border-color:#198754}.btn-check:active+.btn-outline-success:focus,.btn-check:checked+.btn-outline-success:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus,.btn-outline-success:active:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#198754;background-color:transparent}.btn-outline-info{color:#0dcaf0;border-color:#0dcaf0}.btn-outline-info:hover{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-check:active+.btn-outline-info,.btn-check:checked+.btn-outline-info,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show,.btn-outline-info:active{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-check:active+.btn-outline-info:focus,.btn-check:checked+.btn-outline-info:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus,.btn-outline-info:active:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#0dcaf0;background-color:transparent}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-check:active+.btn-outline-warning,.btn-check:checked+.btn-outline-warning,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show,.btn-outline-warning:active{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-check:active+.btn-outline-warning:focus,.btn-check:checked+.btn-outline-warning:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus,.btn-outline-warning:active:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-check:active+.btn-outline-danger,.btn-check:checked+.btn-outline-danger,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show,.btn-outline-danger:active{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-check:active+.btn-outline-danger:focus,.btn-check:checked+.btn-outline-danger:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus,.btn-outline-danger:active:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-check:active+.btn-outline-light,.btn-check:checked+.btn-outline-light,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show,.btn-outline-light:active{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:active+.btn-outline-light:focus,.btn-check:checked+.btn-outline-light:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus,.btn-outline-light:active:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-dark{color:#212529;border-color:#212529}.btn-outline-dark:hover{color:#fff;background-color:#212529;border-color:#212529}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-check:active+.btn-outline-dark,.btn-check:checked+.btn-outline-dark,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show,.btn-outline-dark:active{color:#fff;background-color:#212529;border-color:#212529}.btn-check:active+.btn-outline-dark:focus,.btn-check:checked+.btn-outline-dark:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus,.btn-outline-dark:active:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#212529;background-color:transparent}.btn-link{font-weight:400;color:#0d6efd;text-decoration:underline}.btn-link:hover{color:#0a58ca}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropend,.dropstart,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:.5rem 0;margin:0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid rgba(0,0,0,.15)}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#212529;text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#1e2125;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#0d6efd}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#212529}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:focus,.dropdown-menu-dark .dropdown-item:hover{color:#fff;background-color:rgba(255,255,255,.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:#fff;background-color:#0d6efd}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem;color:#0d6efd;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:#0a58ca}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;background:0 0;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6;isolation:isolate}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:0 0;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#0d6efd}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem;transition:box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 .25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-bottom,.navbar-expand-sm .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-bottom,.navbar-expand-md .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-bottom,.navbar-expand-lg .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-bottom,.navbar-expand-xl .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-bottom,.navbar-expand-xxl .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;visibility:visible!important;background-color:transparent;border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-bottom,.navbar-expand .offcanvas-top{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.55);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.55)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.55)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.55);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.55)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.5rem 1rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.5rem;margin-bottom:-.5rem;margin-left:-.5rem;border-bottom:0}.card-header-pills{margin-right:-.5rem;margin-left:-.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-group>.card{margin-bottom:.75rem}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:1rem;color:#212529;text-align:left;background-color:#fff;border:0;border-radius:0;overflow-anchor:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:#0c63e4;background-color:#e7f1ff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.125)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform .2s ease-in-out}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:#fff;border:1px solid rgba(0,0,0,.125)}.accordion-item:first-of-type{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.accordion-item:first-of-type .accordion-button{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:1rem;list-style:none}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#0d6efd;text-decoration:none;background-color:#fff;border:1px solid #dee2e6;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:#0a58ca;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;color:#0a58ca;background-color:#e9ecef;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item.active .page-link{z-index:3;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;background-color:#fff;border-color:#dee2e6}.page-link{padding:.375rem .75rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{color:#084298;background-color:#cfe2ff;border-color:#b6d4fe}.alert-primary .alert-link{color:#06357a}.alert-secondary{color:#41464b;background-color:#e2e3e5;border-color:#d3d6d8}.alert-secondary .alert-link{color:#34383c}.alert-success{color:#0f5132;background-color:#d1e7dd;border-color:#badbcc}.alert-success .alert-link{color:#0c4128}.alert-info{color:#055160;background-color:#cff4fc;border-color:#b6effb}.alert-info .alert-link{color:#04414d}.alert-warning{color:#664d03;background-color:#fff3cd;border-color:#ffecb5}.alert-warning .alert-link{color:#523e02}.alert-danger{color:#842029;background-color:#f8d7da;border-color:#f5c2c7}.alert-danger .alert-link{color:#6a1a21}.alert-light{color:#636464;background-color:#fefefe;border-color:#fdfdfe}.alert-light .alert-link{color:#4f5050}.alert-dark{color:#141619;background-color:#d3d3d4;border-color:#bcbebf}.alert-dark .alert-link{color:#101214}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#0d6efd;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#084298;background-color:#cfe2ff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#084298;background-color:#bacbe6}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#084298;border-color:#084298}.list-group-item-secondary{color:#41464b;background-color:#e2e3e5}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#41464b;background-color:#cbccce}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#41464b;border-color:#41464b}.list-group-item-success{color:#0f5132;background-color:#d1e7dd}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#0f5132;background-color:#bcd0c7}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#0f5132;border-color:#0f5132}.list-group-item-info{color:#055160;background-color:#cff4fc}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#055160;background-color:#badce3}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#055160;border-color:#055160}.list-group-item-warning{color:#664d03;background-color:#fff3cd}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#664d03;background-color:#e6dbb9}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#664d03;border-color:#664d03}.list-group-item-danger{color:#842029;background-color:#f8d7da}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#842029;background-color:#dfc2c4}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#842029;border-color:#842029}.list-group-item-light{color:#636464;background-color:#fefefe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#636464;background-color:#e5e5e5}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#636464;border-color:#636464}.list-group-item-dark{color:#141619;background-color:#d3d3d4}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#141619;background-color:#bebebf}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#141619;border-color:#141619}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#000;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:#000;text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{width:350px;max-width:100%;font-size:.875rem;pointer-events:auto;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15);border-radius:.25rem}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:.75rem}.toast-header{display:flex;align-items:center;padding:.5rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-header .btn-close{margin-right:-.375rem;margin-left:.75rem}.toast-body{padding:.75rem;word-wrap:break-word}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[data-popper-placement^=right],.bs-tooltip-end{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[data-popper-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[data-popper-placement^=left],.bs-tooltip-start{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1070;display:block;max-width:276px;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f0f0f0}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f0f0f0;border-bottom:1px solid rgba(0,0,0,.2);border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.offcanvas{position:fixed;bottom:0;z-index:1045;display:flex;flex-direction:column;max-width:100%;visibility:hidden;background-color:#fff;background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1rem}.offcanvas-header .btn-close{padding:.5rem .5rem;margin-top:-.5rem;margin-right:-.5rem;margin-bottom:-.5rem}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:1rem 1rem;overflow-y:auto}.offcanvas-start{top:0;left:0;width:400px;border-right:1px solid rgba(0,0,0,.2);transform:translateX(-100%)}.offcanvas-end{top:0;right:0;width:400px;border-left:1px solid rgba(0,0,0,.2);transform:translateX(100%)}.offcanvas-top{top:0;right:0;left:0;height:30vh;max-height:100%;border-bottom:1px solid rgba(0,0,0,.2);transform:translateY(-100%)}.offcanvas-bottom{right:0;left:0;height:30vh;max-height:100%;border-top:1px solid rgba(0,0,0,.2);transform:translateY(100%)}.offcanvas.show{transform:none}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentColor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{-webkit-animation:placeholder-glow 2s ease-in-out infinite;animation:placeholder-glow 2s ease-in-out infinite}@-webkit-keyframes placeholder-glow{50%{opacity:.2}}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;-webkit-animation:placeholder-wave 2s linear infinite;animation:placeholder-wave 2s linear infinite}@-webkit-keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#0d6efd}.link-primary:focus,.link-primary:hover{color:#0a58ca}.link-secondary{color:#6c757d}.link-secondary:focus,.link-secondary:hover{color:#565e64}.link-success{color:#198754}.link-success:focus,.link-success:hover{color:#146c43}.link-info{color:#0dcaf0}.link-info:focus,.link-info:hover{color:#3dd5f3}.link-warning{color:#ffc107}.link-warning:focus,.link-warning:hover{color:#ffcd39}.link-danger{color:#dc3545}.link-danger:focus,.link-danger:hover{color:#b02a37}.link-light{color:#f8f9fa}.link-light:focus,.link-light:hover{color:#f9fafb}.link-dark{color:#212529}.link-dark:focus,.link-dark:hover{color:#1a1e21}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio:calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio:calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display: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}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:1px solid #dee2e6!important}.border-0{border:0!important}.border-top{border-top:1px solid #dee2e6!important}.border-top-0{border-top:0!important}.border-end{border-right:1px solid #dee2e6!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:1px solid #dee2e6!important}.border-start-0{border-left:0!important}.border-primary{border-color:#0d6efd!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#198754!important}.border-info{border-color:#0dcaf0!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#212529!important}.border-white{border-color:#fff!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!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}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!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}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:#6c757d!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:.25rem!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:.2rem!important}.rounded-2{border-radius:.25rem!important}.rounded-3{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-end{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-start{border-bottom-left-radius:.25rem!important;border-top-left-radius:.25rem!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.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-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}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!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}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.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-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}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!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}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.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-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}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!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}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.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-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}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!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}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.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-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}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!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}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!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-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.min.css.map */ \ No newline at end of file diff --git a/GPW.CORE.UI/wwwroot/css/bootstrap/bootstrap.min.css.map b/GPW.CORE.UI/wwwroot/css/bootstrap/bootstrap.min.css.map new file mode 100644 index 0000000..afcd9e3 --- /dev/null +++ b/GPW.CORE.UI/wwwroot/css/bootstrap/bootstrap.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/bootstrap.scss","../../scss/_root.scss","../../scss/_reboot.scss","dist/css/bootstrap.css","../../scss/vendor/_rfs.scss","../../scss/mixins/_border-radius.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/_containers.scss","../../scss/mixins/_container.scss","../../scss/mixins/_breakpoints.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/_tables.scss","../../scss/mixins/_table-variants.scss","../../scss/forms/_labels.scss","../../scss/forms/_form-text.scss","../../scss/forms/_form-control.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_gradients.scss","../../scss/forms/_form-select.scss","../../scss/forms/_form-check.scss","../../scss/forms/_form-range.scss","../../scss/forms/_floating-labels.scss","../../scss/forms/_input-group.scss","../../scss/mixins/_forms.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/_button-group.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_accordion.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/mixins/_backdrop.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/_offcanvas.scss","../../scss/_placeholders.scss","../../scss/helpers/_colored-links.scss","../../scss/helpers/_ratio.scss","../../scss/helpers/_position.scss","../../scss/helpers/_stacks.scss","../../scss/helpers/_visually-hidden.scss","../../scss/mixins/_visually-hidden.scss","../../scss/helpers/_stretched-link.scss","../../scss/helpers/_text-truncation.scss","../../scss/mixins/_text-truncate.scss","../../scss/helpers/_vr.scss","../../scss/mixins/_utilities.scss","../../scss/utilities/_api.scss"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Bootstrap v5.1.0 (https://getbootstrap.com/)\n * Copyright 2011-2021 The Bootstrap Authors\n * Copyright 2011-2021 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n// scss-docs-start import-stack\n// Configuration\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"utilities\";\n\n// Layout & components\n@import \"root\";\n@import \"reboot\";\n@import \"type\";\n@import \"images\";\n@import \"containers\";\n@import \"grid\";\n@import \"tables\";\n@import \"forms\";\n@import \"buttons\";\n@import \"transitions\";\n@import \"dropdown\";\n@import \"button-group\";\n@import \"nav\";\n@import \"navbar\";\n@import \"card\";\n@import \"accordion\";\n@import \"breadcrumb\";\n@import \"pagination\";\n@import \"badge\";\n@import \"alert\";\n@import \"progress\";\n@import \"list-group\";\n@import \"close\";\n@import \"toasts\";\n@import \"modal\";\n@import \"tooltip\";\n@import \"popover\";\n@import \"carousel\";\n@import \"spinners\";\n@import \"offcanvas\";\n@import \"placeholders\";\n\n// Helpers\n@import \"helpers\";\n\n// Utilities\n@import \"utilities/api\";\n// scss-docs-end import-stack\n",":root {\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 --#{$variable-prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $grays {\n --#{$variable-prefix}gray-#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$variable-prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors-rgb {\n --#{$variable-prefix}#{$color}-rgb: #{$value};\n }\n\n --#{$variable-prefix}white-rgb: #{to-rgb($white)};\n --#{$variable-prefix}black-rgb: #{to-rgb($black)};\n --#{$variable-prefix}body-rgb: #{to-rgb($body-color)};\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 --#{$variable-prefix}font-sans-serif: #{inspect($font-family-sans-serif)};\n --#{$variable-prefix}font-monospace: #{inspect($font-family-monospace)};\n --#{$variable-prefix}gradient: #{$gradient};\n\n // Root and body\n // stylelint-disable custom-property-empty-line-before\n // scss-docs-start root-body-variables\n @if $font-size-root != null {\n --#{$variable-prefix}root-font-size: #{$font-size-root};\n }\n --#{$variable-prefix}body-font-family: #{$font-family-base};\n --#{$variable-prefix}body-font-size: #{$font-size-base};\n --#{$variable-prefix}body-font-weight: #{$font-weight-base};\n --#{$variable-prefix}body-line-height: #{$line-height-base};\n --#{$variable-prefix}body-color: #{$body-color};\n @if $body-text-align != null {\n --#{$variable-prefix}body-text-align: #{$body-text-align};\n }\n --#{$variable-prefix}body-bg: #{$body-bg};\n // scss-docs-end root-body-variables\n // stylelint-enable custom-property-empty-line-before\n}\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 font-size: var(--#{$variable-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(--#{$variable-prefix}body-font-family);\n @include font-size(var(--#{$variable-prefix}body-font-size));\n font-weight: var(--#{$variable-prefix}body-font-weight);\n line-height: var(--#{$variable-prefix}body-line-height);\n color: var(--#{$variable-prefix}body-color);\n text-align: var(--#{$variable-prefix}body-text-align);\n background-color: var(--#{$variable-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// 2. Set correct height and prevent the `size` attribute to make the `hr` look like an input field\n\nhr {\n margin: $hr-margin-y 0;\n color: $hr-color; // 1\n background-color: currentColor;\n border: 0;\n opacity: $hr-opacity;\n}\n\nhr:not([size]) {\n height: $hr-height; // 2\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: $headings-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. Duplicate behavior to the data-bs-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-bs-original-title] { // 1\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n text-decoration-skip-ink: none; // 4\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 background-color: $mark-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: $link-color;\n text-decoration: $link-decoration;\n\n &:hover {\n color: $link-hover-color;\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 direction: ltr #{\"/* rtl:ignore */\"};\n unicode-bidi: bidi-override;\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: $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-`