From 706e0674fb7fe45e16427ce0cf5c6c9892216dd8 Mon Sep 17 00:00:00 2001 From: Yinyin Liu Date: Mon, 30 Mar 2026 14:36:50 +0200 Subject: [PATCH] a lot of fixes to report system --- csharp/App/Backend/Controller.cs | 150 ++-- csharp/App/Backend/DataTypes/ReportSummary.cs | 18 +- .../Services/ReportAggregationService.cs | 132 +++- .../Backend/Services/ReportEmailService.cs | 106 ++- csharp/App/Backend/Services/WeatherService.cs | 82 +- .../Backend/Services/WeeklyReportService.cs | 77 +- .../images/inesco_logo_for_dark_bg.png | Bin 0 -> 65560 bytes .../SodiohomeInstallations/DailySection.tsx | 49 +- .../SodiohomeInstallations/WeeklyReport.tsx | 748 ++++++++---------- typescript/frontend-marios2/src/lang/de.json | 23 +- typescript/frontend-marios2/src/lang/en.json | 23 +- typescript/frontend-marios2/src/lang/fr.json | 23 +- typescript/frontend-marios2/src/lang/it.json | 23 +- 13 files changed, 827 insertions(+), 627 deletions(-) create mode 100644 typescript/frontend-marios2/src/Resources/images/inesco_logo_for_dark_bg.png diff --git a/csharp/App/Backend/Controller.cs b/csharp/App/Backend/Controller.cs index 28f1e1b3a..ca7015c11 100644 --- a/csharp/App/Backend/Controller.cs +++ b/csharp/App/Backend/Controller.cs @@ -961,6 +961,46 @@ public class Controller : ControllerBase // ── Weekly Performance Report ────────────────────────────────────── + private async Task FetchWeeklyReportAsync( + Int64 installationId, String installationName, String lang, + DateOnly? weekStartDate = null, Boolean forceRegenerate = false) + { + DateOnly periodStart, periodEnd; + if (weekStartDate.HasValue) + { + periodStart = weekStartDate.Value; + periodEnd = weekStartDate.Value.AddDays(6); + } + else + { + (periodStart, periodEnd) = WeeklyReportService.LastCalendarWeek(); + } + + var periodStartStr = periodStart.ToString("yyyy-MM-dd"); + var periodEndStr = periodEnd.ToString("yyyy-MM-dd"); + + if (!forceRegenerate) + { + var cached = Db.GetWeeklyReportForWeek(installationId, periodStartStr, periodEndStr); + if (cached != null) + { + var cachedResponse = await ReportAggregationService.ToWeeklyReportResponseAsync(cached, lang); + if (cachedResponse != null) + { + Console.WriteLine($"[WeeklyReport] Serving cached report for installation {installationId}, period {periodStartStr}–{periodEndStr}, language={lang}"); + return cachedResponse; + } + } + } + + Console.WriteLine($"[WeeklyReport] Generating fresh report for installation {installationId}, period {periodStartStr}–{periodEndStr}"); + var report = await WeeklyReportService.GenerateReportAsync( + installationId, installationName, lang, weekStartDate); + + ReportAggregationService.SaveWeeklySummary(installationId, report, lang); + return report; + } + /// /// Returns a weekly performance report. Serves from cache if available; /// generates fresh on first request or when forceRegenerate is true. @@ -991,43 +1031,9 @@ public class Controller : ControllerBase { var lang = language ?? user.Language ?? "en"; - // Compute target week dates for cache lookup - DateOnly periodStart, periodEnd; - if (weekStartDate.HasValue) - { - periodStart = weekStartDate.Value; - periodEnd = weekStartDate.Value.AddDays(6); - } - else - { - (periodStart, periodEnd) = WeeklyReportService.LastCalendarWeek(); - } - - var periodStartStr = periodStart.ToString("yyyy-MM-dd"); - var periodEndStr = periodEnd.ToString("yyyy-MM-dd"); - - // Cache-first: check if a cached report exists for this week - if (!forceRegenerate) - { - var cached = Db.GetWeeklyReportForWeek(installationId, periodStartStr, periodEndStr); - if (cached != null) - { - var cachedResponse = await ReportAggregationService.ToWeeklyReportResponseAsync(cached, lang); - if (cachedResponse != null) - { - Console.WriteLine($"[GetWeeklyReport] Serving cached report for installation {installationId}, period {periodStartStr}–{periodEndStr}, language={lang}"); - return Ok(cachedResponse); - } - } - } - - // Cache miss or forceRegenerate: generate fresh - Console.WriteLine($"[GetWeeklyReport] Generating fresh report for installation {installationId}, period {periodStartStr}–{periodEndStr}"); - var report = await WeeklyReportService.GenerateReportAsync( - installationId, installation.Name, lang, weekStartDate); - - // Persist weekly summary and seed AiInsightCache for this language - ReportAggregationService.SaveWeeklySummary(installationId, report, lang); + var report = await FetchWeeklyReportAsync(installationId, installation.Name, lang, weekStartDate, forceRegenerate); + if (report == null) + return BadRequest("Failed to generate report."); return Ok(report); } @@ -1134,6 +1140,46 @@ public class Controller : ControllerBase return Ok(reports); } + [HttpGet(nameof(GetCurrentMonthPreview))] + public async Task> GetCurrentMonthPreview( + Int64 installationId, Token authToken, String? language = null) + { + var user = Db.GetSession(authToken)?.User; + if (user == null) + return Unauthorized(); + + var installation = Db.GetInstallationById(installationId); + if (installation is null || !user.HasAccessTo(installation)) + return Unauthorized(); + + var lang = language ?? user.Language ?? "en"; + var preview = await ReportAggregationService.GetCurrentMonthPreviewAsync(installationId, lang); + if (preview == null) + return NotFound("No daily data for the current month."); + + return Ok(preview); + } + + [HttpGet(nameof(GetCurrentYearPreview))] + public async Task> GetCurrentYearPreview( + Int64 installationId, Token authToken, String? language = null) + { + var user = Db.GetSession(authToken)?.User; + if (user == null) + return Unauthorized(); + + var installation = Db.GetInstallationById(installationId); + if (installation is null || !user.HasAccessTo(installation)) + return Unauthorized(); + + var lang = language ?? user.Language ?? "en"; + var preview = await ReportAggregationService.GetCurrentYearPreviewAsync(installationId, lang); + if (preview == null) + return NotFound("No monthly reports for the current year."); + + return Ok(preview); + } + /// /// Manually trigger monthly aggregation for an installation. /// Computes monthly report from daily records for the specified year/month. @@ -1514,7 +1560,9 @@ public class Controller : ControllerBase // ── Report HTML (for PDF download) ───────────────────────────── [HttpGet(nameof(GetWeeklyReportHtml))] - public async Task GetWeeklyReportHtml(Int64 installationId, Token authToken, String? language = null) + public async Task GetWeeklyReportHtml( + Int64 installationId, Token authToken, + String? language = null, String? weekStart = null, String source = "email") { var user = Db.GetSession(authToken)?.User; if (user == null) return Unauthorized(); @@ -1522,14 +1570,26 @@ public class Controller : ControllerBase var installation = Db.GetInstallationById(installationId); if (installation is null || !user.HasAccessTo(installation)) return Unauthorized(); - var lang = language ?? user.Language ?? "en"; - var report = await WeeklyReportService.GenerateReportAsync(installationId, installation.Name, lang); - var html = ReportEmailService.BuildHtmlEmail(report, lang); + var lang = language ?? user.Language ?? "en"; + + DateOnly? weekStartDate = null; + if (!String.IsNullOrEmpty(weekStart)) + { + if (!DateOnly.TryParseExact(weekStart, "yyyy-MM-dd", out var parsed)) + return BadRequest("weekStart must be in yyyy-MM-dd format."); + weekStartDate = parsed; + } + + var report = await FetchWeeklyReportAsync(installationId, installation.Name, lang, weekStartDate); + if (report == null) + return BadRequest("Failed to generate report."); + + var html = ReportEmailService.BuildHtmlEmail(report, lang, source: source); return Content(html, "text/html"); } [HttpGet(nameof(GetMonthlyReportHtml))] - public async Task GetMonthlyReportHtml(Int64 installationId, Int32 year, Int32 month, Token authToken, String? language = null) + public async Task GetMonthlyReportHtml(Int64 installationId, Int32 year, Int32 month, Token authToken, String? language = null, String source = "email") { var user = Db.GetSession(authToken)?.User; if (user == null) return Unauthorized(); @@ -1548,12 +1608,12 @@ public class Controller : ControllerBase report.TotalPvProduction, report.TotalConsumption, report.TotalGridImport, report.TotalGridExport, report.TotalBatteryCharged, report.TotalBatteryDischarged, report.TotalEnergySaved, report.TotalSavingsCHF, report.SelfSufficiencyPercent, report.BatteryEfficiencyPercent, report.AiInsight, - $"{report.WeekCount} {s.CountLabel}", s); + $"{report.WeekCount} {s.CountLabel}", s, source: source); return Content(html, "text/html"); } [HttpGet(nameof(GetYearlyReportHtml))] - public async Task GetYearlyReportHtml(Int64 installationId, Int32 year, Token authToken, String? language = null) + public async Task GetYearlyReportHtml(Int64 installationId, Int32 year, Token authToken, String? language = null, String source = "email") { var user = Db.GetSession(authToken)?.User; if (user == null) return Unauthorized(); @@ -1572,7 +1632,7 @@ public class Controller : ControllerBase report.TotalPvProduction, report.TotalConsumption, report.TotalGridImport, report.TotalGridExport, report.TotalBatteryCharged, report.TotalBatteryDischarged, report.TotalEnergySaved, report.TotalSavingsCHF, report.SelfSufficiencyPercent, report.BatteryEfficiencyPercent, report.AiInsight, - $"{report.MonthCount} {s.CountLabel}", s); + $"{report.MonthCount} {s.CountLabel}", s, source: source); return Content(html, "text/html"); } diff --git a/csharp/App/Backend/DataTypes/ReportSummary.cs b/csharp/App/Backend/DataTypes/ReportSummary.cs index 3a17c4117..cba7d1d97 100644 --- a/csharp/App/Backend/DataTypes/ReportSummary.cs +++ b/csharp/App/Backend/DataTypes/ReportSummary.cs @@ -94,6 +94,11 @@ public class MonthlyReportSummary public Int32 WeekCount { get; set; } public String AiInsight { get; set; } = ""; public String CreatedAt { get; set; } = ""; + + // Preview-only fields (not stored in DB) + [Ignore] public Boolean IsPreview { get; set; } + [Ignore] public Int32 DaysAvailable { get; set; } + [Ignore] public Int32 DaysInMonth { get; set; } } /// @@ -137,19 +142,22 @@ public class YearlyReportSummary public Int32 MonthCount { get; set; } public String AiInsight { get; set; } = ""; public String CreatedAt { get; set; } = ""; + + // Preview-only fields (not stored in DB) + [Ignore] public Boolean IsPreview { get; set; } } // ── DTOs for pending aggregation queries (not stored in DB) ── public class PendingMonth { - public Int32 Year { get; set; } - public Int32 Month { get; set; } - public Int32 WeekCount { get; set; } + public Int32 Year { get; set; } + public Int32 Month { get; set; } + public Int32 WeekCount { get; set; } } public class PendingYear { - public Int32 Year { get; set; } - public Int32 MonthCount { get; set; } + public Int32 Year { get; set; } + public Int32 MonthCount { get; set; } } diff --git a/csharp/App/Backend/Services/ReportAggregationService.cs b/csharp/App/Backend/Services/ReportAggregationService.cs index bec798b34..ec71be1b2 100644 --- a/csharp/App/Backend/Services/ReportAggregationService.cs +++ b/csharp/App/Backend/Services/ReportAggregationService.cs @@ -382,8 +382,8 @@ public static class ReportAggregationService InstallationId = installationId, Year = year, Month = month, - PeriodStart = first.ToString("yyyy-MM-dd"), - PeriodEnd = last.ToString("yyyy-MM-dd"), + PeriodStart = days.Min(d => d.Date), // actual first data day, not calendar month start + PeriodEnd = days.Max(d => d.Date), // actual last data day, not calendar month end TotalPvProduction = totalPv, TotalConsumption = totalConsump, TotalGridImport = totalGridIn, @@ -881,4 +881,132 @@ Rules: Write in {langName}. Write for a homeowner. No asterisks or formatting ma return "AI insight could not be generated at this time."; } + + // ── Current-Period Previews (not saved to DB) ───────────────────── + + public static async Task GetCurrentMonthPreviewAsync(Int64 installationId, String language = "en") + { + var now = DateTime.UtcNow; + var year = now.Year; + var month = now.Month; + var first = new DateOnly(year, month, 1); + var last = first.AddMonths(1).AddDays(-1); + var days = Db.GetDailyRecords(installationId, first, last); + + if (days.Count == 0) + return null; + + var totalPv = Math.Round(days.Sum(d => d.PvProduction), 1); + var totalConsump = Math.Round(days.Sum(d => d.LoadConsumption), 1); + var totalGridIn = Math.Round(days.Sum(d => d.GridImport), 1); + var totalGridOut = Math.Round(days.Sum(d => d.GridExport), 1); + var totalBattChg = Math.Round(days.Sum(d => d.BatteryCharged), 1); + var totalBattDis = Math.Round(days.Sum(d => d.BatteryDischarged), 1); + + var energySaved = Math.Round(totalConsump - totalGridIn, 1); + var savingsCHF = Math.Round(energySaved * ElectricityPriceCHF, 0); + var selfSufficiency = totalConsump > 0 ? Math.Round((totalConsump - totalGridIn) / totalConsump * 100, 1) : 0; + var selfConsumption = totalPv > 0 ? Math.Round((totalPv - totalGridOut) / totalPv * 100, 1) : 0; + var batteryEff = totalBattChg > 0 ? Math.Round(totalBattDis / totalBattChg * 100, 1) : 0; + var gridDependency = totalConsump > 0 ? Math.Round(totalGridIn / totalConsump * 100, 1) : 0; + + var installation = Db.GetInstallationById(installationId); + var installationName = installation?.Name ?? $"Installation {installationId}"; + var monthName = new DateTime(year, month, 1).ToString("MMMM yyyy"); + var weatherCity = !string.IsNullOrWhiteSpace(installation?.City) ? installation.City : installation?.Location; + var weatherRegion = !string.IsNullOrWhiteSpace(installation?.Canton) ? installation.Canton : installation?.Region; + + var aiInsight = await GenerateMonthlyAiInsightAsync( + installationName, monthName, days.Count, + totalPv, totalConsump, totalGridIn, totalGridOut, + totalBattChg, totalBattDis, energySaved, savingsCHF, + selfSufficiency, batteryEff, language, + weatherCity, installation?.Country, weatherRegion); + + var firstDataDay = days.Min(d => d.Date); + var lastDataDay = days.Max(d => d.Date); + + return new MonthlyReportSummary + { + InstallationId = installationId, + Year = year, + Month = month, + PeriodStart = firstDataDay, + PeriodEnd = lastDataDay, + TotalPvProduction = totalPv, + TotalConsumption = totalConsump, + TotalGridImport = totalGridIn, + TotalGridExport = totalGridOut, + TotalBatteryCharged = totalBattChg, + TotalBatteryDischarged = totalBattDis, + TotalEnergySaved = energySaved, + TotalSavingsCHF = savingsCHF, + SelfSufficiencyPercent = selfSufficiency, + SelfConsumptionPercent = selfConsumption, + BatteryEfficiencyPercent = batteryEff, + GridDependencyPercent = gridDependency, + WeekCount = days.Count, + AiInsight = aiInsight, + CreatedAt = DateTime.UtcNow.ToString("o"), + IsPreview = true, + DaysAvailable = days.Count, + DaysInMonth = last.Day, + }; + } + + public static async Task GetCurrentYearPreviewAsync(Int64 installationId, String language = "en") + { + var year = DateTime.UtcNow.Year; + var monthlies = Db.GetMonthlyReportsForYear(installationId, year); + + if (monthlies.Count == 0) + return null; + + var totalPv = Math.Round(monthlies.Sum(m => m.TotalPvProduction), 1); + var totalConsump = Math.Round(monthlies.Sum(m => m.TotalConsumption), 1); + var totalGridIn = Math.Round(monthlies.Sum(m => m.TotalGridImport), 1); + var totalGridOut = Math.Round(monthlies.Sum(m => m.TotalGridExport), 1); + var totalBattChg = Math.Round(monthlies.Sum(m => m.TotalBatteryCharged), 1); + var totalBattDis = Math.Round(monthlies.Sum(m => m.TotalBatteryDischarged), 1); + + var energySaved = Math.Round(totalConsump - totalGridIn, 1); + var savingsCHF = Math.Round(energySaved * ElectricityPriceCHF, 0); + var selfSufficiency = totalConsump > 0 ? Math.Round((totalConsump - totalGridIn) / totalConsump * 100, 1) : 0; + var selfConsumption = totalPv > 0 ? Math.Round((totalPv - totalGridOut) / totalPv * 100, 1) : 0; + var batteryEff = totalBattChg > 0 ? Math.Round(totalBattDis / totalBattChg * 100, 1) : 0; + var gridDependency = totalConsump > 0 ? Math.Round(totalGridIn / totalConsump * 100, 1) : 0; + + var installation = Db.GetInstallationById(installationId); + var installationName = installation?.Name ?? $"Installation {installationId}"; + + var aiInsight = await GenerateYearlyAiInsightAsync( + installationName, year, monthlies.Count, + totalPv, totalConsump, totalGridIn, totalGridOut, + totalBattChg, totalBattDis, energySaved, savingsCHF, + selfSufficiency, batteryEff, language); + + return new YearlyReportSummary + { + InstallationId = installationId, + Year = year, + PeriodStart = monthlies.Min(m => m.PeriodStart), + PeriodEnd = monthlies.Max(m => m.PeriodEnd), + TotalPvProduction = totalPv, + TotalConsumption = totalConsump, + TotalGridImport = totalGridIn, + TotalGridExport = totalGridOut, + TotalBatteryCharged = totalBattChg, + TotalBatteryDischarged = totalBattDis, + TotalEnergySaved = energySaved, + TotalSavingsCHF = savingsCHF, + SelfSufficiencyPercent = selfSufficiency, + SelfConsumptionPercent = selfConsumption, + BatteryEfficiencyPercent = batteryEff, + GridDependencyPercent = gridDependency, + MonthCount = monthlies.Count, + AiInsight = aiInsight, + CreatedAt = DateTime.UtcNow.ToString("o"), + IsPreview = true, + }; + } } diff --git a/csharp/App/Backend/Services/ReportEmailService.cs b/csharp/App/Backend/Services/ReportEmailService.cs index 1399b6a66..3826026fa 100644 --- a/csharp/App/Backend/Services/ReportEmailService.cs +++ b/csharp/App/Backend/Services/ReportEmailService.cs @@ -9,8 +9,10 @@ namespace InnovEnergy.App.Backend.Services; public static class ReportEmailService { - // inesco logo (dark background variant, SVG) embedded as base64 data URI for emails and PDF reports - private const string LogoBase64 = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIGlkPSJf0KHQu9C+0LlfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNjY2LjMzIDIzNy44MyI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmY7fS5jbHMtMntmaWxsOiMwMGIwNTA7fTwvc3R5bGU+PC9kZWZzPjxwYXRoIGNsYXNzPSJjbHMtMiIgZD0ibTUuMDksMzIuMjJDMS43LDI4LjgzLDAsMjQuMzEsMCwxOC42NVMxLjcsOC40OCw1LjA5LDUuMDlDOC40OCwxLjcsMTMuMjQsMCwxOS4zOCwwczEwLjY2LDEuNywxNC4wNSw1LjA5YzMuMzksMy4zOSw1LjA5LDcuOTEsNS4wOSwxMy41NnMtMS43LDEwLjE3LTUuMDksMTMuNTdjLTMuMzksMy4zOS04LjA4LDUuMDktMTQuMDUsNS4wOXMtMTAuOS0xLjctMTQuMjktNS4wOVoiLz48cmVjdCBjbGFzcz0iY2xzLTEiIHg9IjIuNjYiIHk9IjUzLjc4IiB3aWR0aD0iMzMuNDMiIGhlaWdodD0iMTIzLjc4Ii8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJtNjMuMTcsMTc3LjU2VjYxLjUzYzE2LjYzLTcuMTEsMzQuODgtMTAuNjYsNTQuNzUtMTAuNjYsMTcuNzYsMCwzMS40OSw0LjI4LDQxLjE4LDEyLjg0LDkuNjksOC41NiwxNC41NCwyMC44MywxNC41NCwzNi44MnY3Ny4wM2gtMzMuNDN2LTc0LjYxYzAtMTYuMzEtNy41MS0yNC40Ny0yMi41My0yNC40Ny03LjkxLDAtMTUuMDIsMS40NS0yMS4zMiw0LjM2djk0LjcyaC0zMy4xOVoiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Im0zMDUuNDEsMTA1Ljg2YzAsNS44MS0uMzMsMTEuOTUtLjk3LDE4LjQxaC03Ni41NWMzLjA3LDE4Ljc0LDE0LjM3LDI4LjEsMzMuOTEsMjguMSwxMS4zLDAsMjIuNTMtMi4zNCwzMy42Ny03LjAzbDUuMzMsMjYuODljLTEyLjExLDUuNDktMjYuMjUsOC4yNC00Mi4zOSw4LjI0LTE5LjcsMC0zNS41Ny01Ljg1LTQ3LjYtMTcuNTYtMTIuMDMtMTEuNzEtMTguMDUtMjcuNDktMTguMDUtNDcuMzZzNS41Ny0zNC44LDE2LjcxLTQ2Ljc1YzExLjE0LTExLjk1LDI1LjU5LTE3LjkyLDQzLjM2LTE3LjkyLDE1LjgyLDAsMjguNTQsNS4wOSwzOC4xNSwxNS4yNiw5LjYxLDEwLjE3LDE0LjQxLDIzLjQyLDE0LjQxLDM5LjczWm0tMzEuOTgtMS45NHYtMi45MWMwLTYuOTQtMS44Mi0xMi42LTUuNDUtMTYuOTYtMy42My00LjM2LTguNjgtNi41NC0xNS4xNC02LjU0LTYuOTUsMC0xMi42NCwyLjM0LTE3LjA4LDcuMDItNC40NCw0LjY5LTcuMjMsMTEuMTQtOC4zNiwxOS4zOGg0Ni4wM1oiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Im00MDMuNTYsODUuMDJjLTE0LjM3LTQuMzYtMjUuNi02LjU0LTMzLjY3LTYuNTQtMTEuMywwLTE2Ljk2LDMuMzEtMTYuOTYsOS45MywwLDMuMzksMS4zNyw1LjkzLDQuMTIsNy42MywyLjc0LDEuNyw4LjA3LDMuNjcsMTUuOTksNS45MywxNC42OSw0LjA0LDI1LjIzLDguOTIsMzEuNjEsMTQuNjYsNi4zOCw1Ljc0LDkuNTcsMTQuMDEsOS41NywyNC44MywwLDEyLjYtNC42NCwyMi4yNS0xMy45MywyOC45NS05LjI5LDYuNy0yMS42LDEwLjA1LTM2Ljk0LDEwLjA1LTE2Ljk2LDAtMzEuNTctMi42Ny00My44NS04bDQuNi0yNy4zN2MxMy40LDUuMTcsMjYuMjQsNy43NSwzOC41Miw3Ljc1LDUuNjUsMCwxMC4yMS0uOTMsMTMuNjktMi43OSwzLjQ3LTEuODUsNS4yMS00LjQ4LDUuMjEtNy44NywwLTMuNzEtMS42Ni02LjUtNC45Ny04LjM2LTMuMzEtMS44NS0xMC4yOS00LjMyLTIwLjk1LTcuMzktMTEuNzktMy4wNy0yMC42Ny03LjUxLTI2LjY1LTEzLjMyLTUuOTgtNS44MS04Ljk2LTEzLjgxLTguOTYtMjMuOTgsMC0xMi4yNyw0LjE2LTIxLjcyLDEyLjQ4LTI4LjM0LDguMzItNi42MiwxOS45LTkuOTMsMzQuNzYtOS45M3MyOC4xOCwyLjM0LDM5Ljk3LDcuMDJsLTMuNjMsMjcuMTNaIi8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJtNTIzLjYzLDU4LjE0bC02LjMsMjYuNGMtOS41My00LjAzLTE4LjY1LTYuMDYtMjcuMzctNi4wNi05LjY5LDAtMTcuMTYsMy4yMy0yMi40MSw5LjY5LTUuMjUsNi40Ni03Ljg3LDE1LjQyLTcuODcsMjYuODksMCwyNS4xOSwxMC42NiwzNy43OSwzMS45OCwzNy43OSw4LjU2LDAsMTcuNTItMi4xLDI2Ljg5LTYuM2w1LjMzLDI2Ljg5Yy05LjM3LDQuNjgtMjEsNy4wMy0zNC44OCw3LjAzLTIwLjAzLDAtMzUuNjEtNS43Ny00Ni43NS0xNy4zMi0xMS4xNC0xMS41NC0xNi43MS0yNy4yNS0xNi43MS00Ny4xMnM1LjQ5LTM1LjY5LDE2LjQ3LTQ3LjQ4YzEwLjk4LTExLjc5LDI2LTE3LjY4LDQ1LjA2LTE3LjY4LDEzLjg5LDAsMjYuMDgsMi40MiwzNi41OCw3LjI3WiIvPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0ibTYxOS4yNiwxMzkuNTRjLTEyLjQ1LDkuNDQtMzAuMjcsOC40OS00MS42My0yLjg3LTExLjM2LTExLjM2LTEyLjMxLTI5LjE3LTIuODctNDEuNjNsLTI0LjUtMjQuNWMtMjIuODUsMjYuMDMtMjEuODcsNjUuNjksMi45OCw5MC41MywyNC44NCwyNC44NCw2NC41LDI1LjgzLDkwLjUzLDIuOThsLTI0LjUxLTI0LjUxWiIvPjxyZWN0IGNsYXNzPSJjbHMtMiIgeD0iNTYzLjI1IiB5PSI2Mi4yNyIgd2lkdGg9IjQuMzciIGhlaWdodD0iMzQuNTEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwOS4zNyA0MjMuMTEpIHJvdGF0ZSgtNDUpIi8+PHJlY3QgY2xhc3M9ImNscy0yIiB4PSI1NjkuOCIgeT0iNTYuNzgiIHdpZHRoPSI0LjM3IiBoZWlnaHQ9IjM0LjUxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2MS4wMSAzNDEuNTMpIHJvdGF0ZSgtMzUuMDEpIi8+PHJlY3QgY2xhc3M9ImNscy0yIiB4PSI1NzcuMiIgeT0iNTIuNTEiIHdpZHRoPSI0LjM3IiBoZWlnaHQ9IjM0LjUxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNC44NyAyNTEuNjEpIHJvdGF0ZSgtMjUuMDIpIi8+PHJlY3QgY2xhc3M9ImNscy0yIiB4PSI1ODUuMjMiIHk9IjQ5LjU5IiB3aWR0aD0iNC4zNyIgaGVpZ2h0PSIzNC41MSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMi43MyAxNTQuNDIpIHJvdGF0ZSgtMTUuMDEpIi8+PHJlY3QgY2xhc3M9ImNscy0yIiB4PSI1OTMuNjUiIHk9IjQ4LjEiIHdpZHRoPSI0LjM3IiBoZWlnaHQ9IjM0LjUxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMy40MyA1Mi4yMSkgcm90YXRlKC01KSIvPjxyZWN0IGNsYXNzPSJjbHMtMiIgeD0iNTg3LjEyIiB5PSI2My4xNyIgd2lkdGg9IjM0LjUxIiBoZWlnaHQ9IjQuMzciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ4Ni41NSA2NjEuNzMpIHJvdGF0ZSgtODUpIi8+PHJlY3QgY2xhc3M9ImNscy0yIiB4PSI1OTUuNTQiIHk9IjY0LjY2IiB3aWR0aD0iMzQuNTEiIGhlaWdodD0iNC4zNyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzg5LjY0IDY0MS40Nikgcm90YXRlKC03NSkiLz48cmVjdCBjbGFzcz0iY2xzLTIiIHg9IjYwMy41NyIgeT0iNjcuNTgiIHdpZHRoPSIzNC41MSIgaGVpZ2h0PSI0LjM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyOTUuMjkgNjAyLjk4KSByb3RhdGUoLTY1LjAxKSIvPjxyZWN0IGNsYXNzPSJjbHMtMiIgeD0iNjEwLjk3IiB5PSI3MS44NSIgd2lkdGg9IjM0LjUxIiBoZWlnaHQ9IjQuMzciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDIwNy4zIDU0Ni4yMykgcm90YXRlKC01NS4wMSkiLz48cmVjdCBjbGFzcz0iY2xzLTIiIHg9IjYxNy41MiIgeT0iNzcuMzUiIHdpZHRoPSIzNC41MSIgaGVpZ2h0PSI0LjM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMjkuNjEgNDcyLjA1KSByb3RhdGUoLTQ0Ljk5KSIvPjxyZWN0IGNsYXNzPSJjbHMtMiIgeD0iNjIzLjAxIiB5PSI4My44OSIgd2lkdGg9IjM0LjUxIiBoZWlnaHQ9IjQuMzciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDY2LjM0IDM4Mi42NSkgcm90YXRlKC0zNC45OCkiLz48cmVjdCBjbGFzcz0iY2xzLTIiIHg9IjYyNy4yOCIgeT0iOTEuMjkiIHdpZHRoPSIzNC41MSIgaGVpZ2h0PSI0LjM2IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMC45MyAyODEuMykgcm90YXRlKC0yNS4wMSkiLz48cmVjdCBjbGFzcz0iY2xzLTIiIHg9IjYzMC4yMSIgeT0iOTkuMzMiIHdpZHRoPSIzNC41MSIgaGVpZ2h0PSI0LjM2IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNC4yMSAxNzEuMDgpIHJvdGF0ZSgtMTUpIi8+PHJlY3QgY2xhc3M9ImNscy0yIiB4PSI2MzEuNjkiIHk9IjEwNy43NCIgd2lkdGg9IjM0LjUxIiBoZWlnaHQ9IjQuMzciIHRyYW5zZm9ybT0idHJhbnNsYXRlKC03LjEgNTYuODYpIHJvdGF0ZSgtNC45OSkiLz48cmVjdCBjbGFzcz0iY2xzLTIiIHg9IjY0Ni43NiIgeT0iMTAxLjIyIiB3aWR0aD0iNC4zNyIgaGVpZ2h0PSIzNC41MSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDc0LjQ3IDc1NC42NSkgcm90YXRlKC04NS4wMSkiLz48cmVjdCBjbGFzcz0iY2xzLTIiIHg9IjY0NS4yOCIgeT0iMTA5LjYzIiB3aWR0aD0iNC4zNyIgaGVpZ2h0PSIzNC41MSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzU3LjMgNzE5LjQzKSByb3RhdGUoLTc1KSIvPjxyZWN0IGNsYXNzPSJjbHMtMiIgeD0iNjQyLjM2IiB5PSIxMTcuNjYiIHdpZHRoPSI0LjM2IiBoZWlnaHQ9IjM0LjUxIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNDkuNzIgNjYxLjk0KSByb3RhdGUoLTY0Ljk4KSIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtMiIgcG9pbnRzPSI2MjcuMzkgMTMwLjYzIDYyNC44OCAxMzQuMjEgNjUzLjE1IDE1NCA2NTUuNjUgMTUwLjQzIDYyNy4zOSAxMzAuNjMiLz48cG9seWdvbiBjbGFzcz0iY2xzLTIiIHBvaW50cz0iNjI0LjEyIDEzNS4xMiA2MjEuMDMgMTM4LjIxIDY0NS40MyAxNjIuNjEgNjQ4LjUxIDE1OS41MyA2MjQuMTIgMTM1LjEyIi8+PHBvbHlnb24gY2xhc3M9ImNscy0xIiBwb2ludHM9IjkuMTEgMjI0LjY3IDIzLjc4IDIyNC42NyAyMy43OCAyMTcuNzkgOS4xMSAyMTcuNzkgOS4xMSAyMTIuODEgMzQuMjggMjEyLjgxIDM0LjI4IDIwNS43OCAwIDIwNS43OCAwIDIzNy44MyAzNC42NCAyMzcuODMgMzQuNjQgMjMwLjU5IDkuMTEgMjMwLjU5IDkuMTEgMjI0LjY3Ii8+PHBvbHlnb24gY2xhc3M9ImNscy0xIiBwb2ludHM9IjE1Mi4xNiAyMjUuMTIgMTI3LjQ1IDIwNS43OCAxMjEuMjUgMjA1Ljc4IDEyMS4yNSAyMzcuODMgMTI5LjU3IDIzNy44MyAxMjkuNTcgMjE4LjIxIDE1NC4wNCAyMzcuNjUgMTU0LjI2IDIzNy44MyAxNjAuNDggMjM3LjgzIDE2MC40OCAyMDUuNzggMTUyLjE2IDIwNS43OCAxNTIuMTYgMjI1LjEyIi8+PHBvbHlnb24gY2xhc3M9ImNscy0xIiBwb2ludHM9IjI1Ni4yMSAyMjQuNjcgMjcwLjg3IDIyNC42NyAyNzAuODcgMjE3Ljc5IDI1Ni4yMSAyMTcuNzkgMjU2LjIxIDIxMi44MSAyODEuMzcgMjEyLjgxIDI4MS4zNyAyMDUuNzggMjQ3LjEgMjA1Ljc4IDI0Ny4xIDIzNy44MyAyODEuNzMgMjM3LjgzIDI4MS43MyAyMzAuNTkgMjU2LjIxIDIzMC41OSAyNTYuMjEgMjI0LjY3Ii8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJtMzk2LjU1LDIyNi4zMmMyLjY2LDAsNC41OC0uNDksNS44OS0xLjUsMS4zNi0xLjA0LDIuMDQtMi43OCwyLjA0LTUuMTR2LTcuMTljMC0yLjQxLS42OS00LjE3LTIuMDQtNS4yMS0xLjMxLTEuMDEtMy4yNC0xLjUtNS44OS0xLjVoLTI4LjIxdjMyLjA1aDguOTd2LTExLjVoNS44NGwxMi43MywxMS41aDEzLjI5bC0xNC40NS0xMS41aDEuODNabS0xOS4yNC0xMy42NmgxNi4wOGMxLjE5LDAsMS44Mi4yLDIuMTMuMzcuMjkuMTYuNDQuNTguNDQsMS4yNnYzLjUyYzAsLjY4LS4xNSwxLjEtLjQ0LDEuMjYtLjMxLjE3LS45My4zNy0yLjEzLjM3aC0xNi4wOHYtNi43OFoiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Im01MzMuMTIsMjA3LjMxYy0xLjM2LTEuMDMtMy41Mi0xLjUzLTYuNjEtMS41M2gtMjJjLTEuNTMsMC0yLjg1LjExLTMuOTEuMzQtMS4xNC4yNC0yLjA4LjY4LTIuOCwxLjI5LS43NS42My0xLjI4LDEuNTEtMS41OSwyLjU5LS4yOSwxLjAxLS40MywyLjI1LS40MywzLjc4djE2LjAzYzAsMS41My4xNCwyLjc2LjQzLDMuNzUuMywxLjA1LjgyLDEuOTIsMS41MiwyLjU3LjcxLjY1LDEuNjUsMS4xLDIuNzksMS4zNSwxLjA2LjIzLDIuNC4zNCwzLjk4LjM0aDIyYzEuNTMsMCwyLjg2LS4xMSwzLjk0LS4zNCwxLjE3LS4yNCwyLjEyLS43LDIuODMtMS4zNS43MS0uNjUsMS4yMi0xLjUyLDEuNTItMi41Ny4yOC0uOTguNDMtMi4yNC40My0zLjc1di0xMS4zMWgtMjAuOTd2Ny4wM2gxMi4wOHY0Ljg0aC0yMS41MnYtMTcuMzVoMjEuNTJ2My4zOGw4Ljg5LTEuNXYtMS40OGMwLTMuMDMtLjY5LTUuMDMtMi4xMi02LjExWiIvPjxwb2x5Z29uIGNsYXNzPSJjbHMtMSIgcG9pbnRzPSI2NTUuMzIgMjA1Ljc4IDY0NC42NiAyMTYuNzggNjM0LjE1IDIwNS43OCA2MjEuODUgMjA1Ljc4IDYzOS42IDIyMy42OSA2MzkuNiAyMzcuODMgNjQ4LjY0IDIzNy44MyA2NDguNjQgMjIzLjU0IDY2Ni4zMyAyMDUuNzggNjU1LjMyIDIwNS43OCIvPjwvc3ZnPg=="; + // inesco logo (dark background variant, PNG) embedded as base64 for CID attachment in emails + private static readonly byte[] LogoPngBytes = Convert.FromBase64String("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"); + private const string LogoCid = "inesco-logo"; + private const string LogoDataUri = "data:image/png;base64,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"; // NOTE: old PNG constant removed — using SVG dark-bg variant (data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUAAAACECAYAAADhnvK8AAAx/UlEQVR4Xu99B3xU6XWv7cRJHLes7dgvrnF7ifPecxw/97zEz7G3eNdrpS29twUhOkh0hCiiCERdQKIXUQXqHaGCGgjUu1BBAgkk1FAvnHz/I2aR7oymXM0dDTvf379jFqG58917v/u/p59PkISEhISD4hPKH0hISEg4CiQBSkhIOCwkAUpISDgsJAFKSEg4LCQBSkhIOCwkAUpISDgsJAFKSEg4LCQBSkhIOCwkAUpISDgsJAFKSEg4LCQBSkhIOCwkAUpISDgsJAFKSEg4LCQBSkhIOCwkAUpISDgsNCfAnue91NjVQpVttSzPutupl54rf01CQkLC5tCEALuf91Dhs4e0uySA3k3eQj+KdqbvRMxh+X7kPPpVnCttKbxCRS3V1PtckqGEhMTwwOoE2NLTTpeqbtG/3VxGnw4YTZ/yH0mfuD5igHzy+kj6S/FvXwmbQucr44U+KElQQkLC9rAqAbb3dtG1Ryn0zfBZeqQ3mIAgoQ32ClNZQkJCwpawGgFCi8trrqSfxa7UIzmj4v8evRYyiZLrC5WHlJCQkNAUViPAtp5O8iz2p08aMHlNiv8ImnHvAAdMJCQkJGwFqxFgQ1cLvZu8VZ/czJT/dWMhPe18pjyshISEhGawGgHWdDTQdyPn6hGbufL5oPFU1vpYeVgJCQkJzWA1AnzY/pS+YUHwQyl/GziWilseKQ8rISEhoRmsRoCPOxrpe1EfsD9PSW7myJdCJlG51AAlJCRsCKsRIHyAf0rerEds5sl79E/RTlTdUa88rISEhIRmsBoBIgq8q/g6p7XoE5wJEVqjU8ZhmQsoISFhU1iNAJEHWNTykP7t5lJ9gjMhMH+T62QeoISEhG1hNQIEOnq76ToqQSJm0af8R+kRnSH5YvBE2ljgK7U/CQkJm8OqBAig24tvVRz9Jn4VvRYymf7CABGi/O0LwRM498+rJICau9ugQkpISEjYFFYnQADdYHKbK8ijyI/GpXnS726tp1/ErqSfxa6g38S50shUD9qQ70t3G+5TT6/U/CQkJIYHmhCgDvALtvR0UElLNaXWF1FyfQFlNJZSfVeL7AAjISEx7NCUACUkJCTsGZIAJSQkHBaSACUkJEzgpbuqv+MKbqxX3ZElCVBCQkIPyMxo7+3k/wbNeRRdpV/Hu1L443T+WUdvF7kXXKJRqdvpXuN9/hn8/fVdr1ZHJ4chwM6uLqqta6Ci+w/oXlYB3Ui4TReuR9ChE1do9+Fz5LH/FG3xOkabdh8jj32nxc/O0+nLIRQclUC3UjOopOwBtba1Kw9rp3hO9fWNVFhSQSlp2eTrF0ZeR31FeZ0U53ictu09QV5HztN58fOIm8mUmVNMz5610nM7mc/S3NJCZQ+qKD2nkEKib9HhU1dp58MW+zmP9vZOelj9hDJziygiNoWO+QaQ54fnxHmcpM07xH3wOkG7Dp6lI+L8LgdEUXTcbbqTnkePntRRd0+38nA2Q0jNXfp53Eqak36IylufEPbT0uwT3LBkb3EQ/w7S3ZDq9sOo+ZTX/IB/Fl+XQ78Un3PO9KbajsZ+R7RfWJUA29vbxUZMp+uhNy2Sa0Iam1qUh7MY3T091NbeQU3NLVRa/pBuxN8m7zPXadWWAzR1oRu9PXEJ/WHMAlXy5tiFNHL6SlrhtpfOXA6mvKJSanrWQl1d3TTcz1uPOG+Qc2FpBV/PlZv20YhpK/TOwZjozs3XL5wqHz0Wx2uj3l7tT6y3t5faOzroQVU1k7G7pw9NmLeW3hjrrLfGP4xxMvn3dycvo0lO65nsL/pHUoYg0abmZ7wvsD+0Ap+H+I6qh4953+H7Zy7eTG+NW2TgPIyJE709YTGNm7OG1m07ROeuhlFu4X3xfDyjjo5Oqw8RQxPispbHdKEygZKe5rO2d1dodL9P3MBVXakvOrUfKQunL4ZMpBXZJ/nvTd2tXPDwz9HOVNVexxrhyYpoHoexKvcM/3u3OHZoTRqFPb7Hf7dHWJUAa+vqael6LwM31bRUPrS8Ewze9O1iU9Q+baDi0gf8AG0Rb1ZsvDfeN/QAWUP6Hjps0nkrPVgDKSmvolax+W0NaLXVj+tYm1295SD9Uaypb31KYjBHXnxutBP9SZDIhh2H6U5GLtU3NCm/1ipA/mejIKa7WflCKzpLo2e49FuHcm2Wiu4Yfec0ZuYrG7E5u92J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRPcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJUdSIH5m6Ax9Auh+WFAOnJBNbvmaFmFFlro/LIg8wh9L2ou9xL8IP0wd4o5Vh7FZPuPEXO5HA85iJ4l/jwmF0EQRIfB6D3iT2usxRgkAVoI+AIPHr9ssZaEVAr0c0NlhzEg9UX5WdPiRGu2HaKnVujdh7SVucu3GviOwQVdXSJikoXJqq+x1Tc2v2h5pf85YwLfGwJX6Nrd14rLdoSCgBcakirXZErgGjnvF85kZGtUVFVWcuVT5LuDxc3Q/Q/bIq5WGHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/xcYFme1Rp8LV+808B1GZPQC8g+NM9ijDj9COoreZ8wUaCgjpq3kEjZr9PEzB/uQQ2fhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRNcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJUdSIH5m6Ax9Auh+WFAOnJBNbvmaFmFFlro/LIg8wh9L2ou9xL8IP0wd4o5Vh7FZPuPEXO5HA85iJ4l/jwmF0EQRIfB6D3iT2usxRgkAVoI+AIPHr9ssZaEVAr0c0NlhzEg9UX5WdPiRGu2HaKnVujdh7SVucu3GviOwQVdXSJikoXJqq+x1Tc2v2h5pf85YwLfGwJX6Nrd14rLdoSCgBcakirXZErgGjnvF85kZGtUVFVWcuVT5LuDxc3Q/Q/bIq5WGHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/xcYFme1Rp8LV+808B1GZPQC8g+NM9ijDj9COoreZ8wUaCgjpq3kEjZr9PEzB/uQQ2fhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRNcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJUdSIH5m6Ax9Auh+WFAOnJBNbvmaFmFFlro/LIg8wh9L2ou9xL8IP0wd4o5Vh7FZPuPEXO5HA85iJ4l/jwmF0EQRIfB6D3iT2usxRgkAVoI+AIPHr9ssZaEVAr0c0NlhzEg9UX5WdPiRGu2HaKnVujdh7SVucu3GviOwQVdXSJikoXJqq+x1Tc2v2h5pf85YwLfGwJX6Nrd14rLdoSCgBcakirXZErgGjnvF85kZGtUVFVWcuVT5LuDxc3Q/Q/bIq5WGHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/xcYFme1Rp8LV+808B1GZPQC8g+NM9ijDj9COoreZ8wUaCgjpq3kEjZr9PEzB/uQQ2fhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRPcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJcKkdZ3NHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/xcYFme1Rp8LV+808B1GZPQC8g+NM9ijDj9COoreZ8wUaCgjpq3kEjZr9PEzB/uQQ2fhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRNcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJUdSIH5m6Ax9Auh+WFAOnJBNbvmaFmFFlro/LIg8wh9L2ou9xL8IP0wd4o5Vh7FZPuPEXO5HA85iJ4l/jwmF0EQRIfB6D3iT2usxRgkAVoI+AIPHr9ssZaEVAr0c0NlhzEg9UX5WdPiRGu2HaKnVujdh7SVucu3GviOwQVdXSJikoXJqq+x1Tc2v2h5pf85YwLfGwJX6Nrd14rLdoSCgBcakirXZErgGjnvF85kZGtUVFVWcuVT5LuDxc3Q/Q/bIq5WGHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/xcYFme1Rp8LV+808B1GZPQC8g+NM9ijDj9COoreZ8wUaCgjpq3kEjZr9PEzB/uQQ2fhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRPcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJcKkdZ3NHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/xcYFme1Rp8LV+808B1GZPQC8g+NM9ijDj9COoreZ8wUaCgjpq3kEjZr9PEzB/uQQ2fhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRPcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJUdSIH5m6Ax9Auh+WFAOnJBNbvmaFmFFlro/LIg8wh9L2ou9xL8IP0wd4o5Vh7FZPuPEXO5HA85iJ4l/jwmF0EQRIfB6D3iT2usxRgkAVoI+AIPHr9ssZaEVAr0c0NlhzEg9UX5WdPiRGu2HaKnVujdh7SVucu3GviOwQVdXSJikoXJqq+x1Tc2v2h5pf85YwLfGwJX6Nrd14rLdoSCgBcakirXZErgGjnvF85kZGtUVFVWcuVT5LuDxc3Q/Q/bIq5WGHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/xcYFme1Rp8LV+808B1GZPQC8g+NM9ijDj9COoreZ8wUaCgjpq3kEjZr9PEzB/uQQ2fhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRPcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJcKkdZ3NHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/BXhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRPcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJUdSIH5m6Ax9Auh+WFAOnJBNbvmaFmFFlro/LIg8wh9L2ou9xL8IP0wd4o5Vh7FZPuPEXO5HA85iJ4l/jwmF0EQRIfB6D3iT2usxRgkAVoI+AIPHr9ssZaEVAr0c0NlhzEg9UX5WdPiRGu2HaKnVujdh7SVucu3GviOwQVdXSJikoXJqq+x1Tc2v2h5pf85YwLfGwJX6Nrd14rLdoSCgBcakirXZErgGjnvF85kZGtUVFVWcuVT5LuDxc3Q/Q/bIq5WGHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/xcYFme1Rp8LV+808B1GZPQC8g+NM9ijDj9COoreZ8wUaCgjpq3kEjZr9PEzB/uQQ2fhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRPcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJcKkdZ3NHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/xcYFme1Rp8LV+808B1GZPQC8g+NM9ijDj9COoreZ8wUaCgjpq3kEjZr9PEzB/uQQ2fhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRPcSDAY3hba2Dg60rHTfp4FPcHBBU4OVm/ZSlokmESl3c3juivLzpmQ4CRA9AjH3WLkmU/LOxKW05/B5s+ujhwIMWUKN709iltBv4l15FslbiZtoapoXD1vfXHCJ9gtt73hFFHeIxhzhvOYHPH+ko1cb8xeQBKgCWhHgNUEiryIBoioGmp2580/wwOF+n7oYzJUdSIH5m6Ax9Auh+WFAOnJBNbvmaFmFFlro/LIg8wh9L2ou9xL8IP0wd4o5Vh7FZPuPEXO5HA85iJ4l/jwmF0EQRIfB6D3iT2usxRgkAVoI+AIPHr9ssZaEVAr0c0NlhzEg9UX5WdPiRGu2HaKnVujdh7SVucu3GviOwQVdXSJikoXJqq+x1Tc2v2h5pf85YwLfGwJX6Nrd14rLdoSCgBcakirXZErgGjnvF85kZGtUVFVWcuVT5LuDxc3Q/Q/bIq5WGHBLS/Qp4g/H+HhQm8regqB1ZeC55Enw4YTb+KdaETFdHsA0TuH4IgFa1P6NrDZK5DRq4gmiqg+7RWkASoAogqWvqmhew6dMZEHedzYf7CvLbc/xcYFme1Rp8LV+808B1GZPQC8g+NM9ijDj9COoreZ8wUaCgjpq3kEjZr9PEzB/uQQ2fhCw4yY/EmLpkzFazQAhjzgACYck3myKT567iZsBZAGywkSH8/6gOuIvl80ASuNY6uzeCI75OOJtYK0ZoLM0c+FzyOPuU/gj4p5Avid11zTnMvQa0gCVAFYGogv0v5HabEFAEiTcZSHw4EZIzZH32Rwt4hC5LDza2u0Ak0tYE5bn1AZPLYOX9VmolSkNqBhqZILbmdnsM5c/hORHatRTmt4nibdx97kfysvwZjAr+hpZ1arAHcMzTHfU9F0AbXdJOnN6d6aYPnnC4DM/edlM1cfYIkaO/ySPYRfjfiAy7P+6wwhb8SOoX7ByIpG5pjwbMqNqW1hCRAFUC1iJoIoSkCRJqMGtML1RLwLyamZlLynawhC6pHlN9hSqAVI9VECWhDaOD6suW9dQQPLipRkPOGHEZcuyd19UOOHD+urWdz0NKkdxA8gh/WSnuxBIje+5y7bnH0HoL9FhKVoDykVdHa08mNESbc8eSE6r8OGENfDJ7A/QJ/Ikzi92/vYlP3XmMp1wrrgPQa1AZrOXxTEqAKnLsSqgkBJqSmq0qxeSm6kQDWEOWxjQuGTzUMkmSMc8ZEN2togQOlb60wk8fOWU0bdh6l4Khb3HoLpKAmEIHGDfNdthv4LuMCkxlasCkfrxaoefKUnwk1923Osq1m56cOBduKrtBPY5Zyd5kxqTs4DeZcZSx3lq5sq6X8Z5UcBEmpL6T4ulwev3nlYSL5VsVxuZxuhom1IQlQBbQiQDQMHY428daQ4+cDeMiRIaDcEJUpatKHLBMnLnmc77qdDp/2Ey+UDIuHOmXlFzMp6B/buKB+F+Q7HKk7qG9GpYilBAgt2nXzAR5ToDVS64toUdYxFtT+rs09R0uzTpBzhjdNFybv28nu9Ks4V+5E8/3IefQlYQ5/OnA0R4mRV9jWo+9ftgYkAaqAVgQIU+7NV5QAz14NNXpuCIbA0Y7GBsrPaiF4uCc7beC9glI9c4kpLSOPZi7ZrHc8UzJziTunApnbq8+aeFhdSx77LC+dhLWBJHZbaK0obUOiM3oAoiECGrGiHdb/vrGIS+jeTHTjxqiz7x3i8juXnDOckO11P5Aym8r6UmM0gCRAFdCKAP2CYozUcNq3oM+eqWFQCFggxQRkYam2olbgF5u52J1TkCqqTM8zQf2xmq7PiMDeEeQ5HED9L7rJKNdkSpDKtfeoL/tptQZaYW3I9+VyO9Qco10WJs2h1A4lb6gPLm19TNUdDfS08xlPjdOK9PpDEqAKaEWAlwOjXlkCRPcSDcb7xXVt7J3XfpYPKzJsd/h8kNQeJz6j6OFoefCZqa4PWI1v3n6K2tg7+X0dHJ8Uk3eWWavYGa+w7U4L0HoWlFRwUg6qhGbuPWNWYhHeA+z3SdUd2Uu3YrJdlNBqAkQKCTYTfIEPHtsHVsMvFRLwLoiC8v7Mak/aEh1eBYzjIVq/u5e1t13nTjRnbVCbGtF2QZu9iMXbOJprsdNyp4F3hPDOvO/QG38Yn0IjN+zizOBH+jT1Bg2h6PJzYR3HhxCHQm8FKDvhtfaxqPjVxhVMHXYfpq6lST5uKafP1efPzYvGC6FmjS9lPjWqYj3Gt2VJWjobq6qbqZSpseU/nzNA0ooGhTa6+bXrk7pLf3Ukllt1lJLH5IAVcDuCVBCQkLCSpAEKCEh4bCQBCghIeGwkAQoISHhsJAEKCEh4bCQBCghIeGwkAQoISHhsJAEKCEh4bCQBCghIeGwkAQoISHhsJAEKCEh4bCQBCghIeGwkAQoISHhsJAEKCEh4bCQBCghIeGw+G/m/9/qNB0E2gAAAABJRU5ErkJggg=="; @@ -23,7 +25,7 @@ public static class ReportEmailService var strings = GetStrings(language); var installSegment = !string.IsNullOrWhiteSpace(report.InstallationName) ? $" — {report.InstallationName}" : ""; var subject = $"{strings.Title}{installSegment} ({report.PeriodStart} to {report.PeriodEnd})"; - var html = BuildHtmlEmail(report, strings, customerName); + var html = BuildHtmlEmail(report, strings, customerName, $"cid:{LogoCid}"); var config = await ReadMailerConfig(); @@ -35,9 +37,10 @@ public static class ReportEmailService From = { from }, To = { to }, Subject = subject, - Body = new TextPart("html") { Text = html } }; + msg.Body = BuildMultipartBodyWithLogo(html); + Console.WriteLine($"[ReportEmailService] SMTP: {config.SmtpUsername}@{config.SmtpServerUrl}:{config.SmtpPort}"); using var smtp = new SmtpClient(); @@ -220,11 +223,12 @@ public static class ReportEmailService // ── HTML email template ───────────────────────────────────────────── - public static string BuildHtmlEmail(WeeklyReportResponse r, string language = "en", string customerName = null) - => BuildHtmlEmail(r, GetStrings(language), customerName); + public static string BuildHtmlEmail(WeeklyReportResponse r, string language = "en", string customerName = null, string logoSrc = null, string source = "email") + => BuildHtmlEmail(r, GetStrings(language), customerName, logoSrc, source); - private static string BuildHtmlEmail(WeeklyReportResponse r, EmailStrings s, string customerName = null) + private static string BuildHtmlEmail(WeeklyReportResponse r, EmailStrings s, string customerName = null, string logoSrc = null, string source = "email") { + logoSrc ??= LogoDataUri; var cur = r.CurrentWeek; var prev = r.PreviousWeek; @@ -328,19 +332,30 @@ public static class ReportEmailService {s.Change}" : $@"{s.ThisWeek}"; + var footerHtml = source == "web" ? "" : $@" + + + + {s.Footer} + + + "; + + var bgColor = source == "web" ? "transparent" : "#f4f4f4"; + return $@" - - + +
@@ -480,7 +489,7 @@ public static class ReportEmailService report.TotalPvProduction, report.TotalConsumption, report.TotalGridImport, report.TotalGridExport, report.TotalBatteryCharged, report.TotalBatteryDischarged, report.TotalEnergySaved, report.TotalSavingsCHF, report.SelfSufficiencyPercent, report.BatteryEfficiencyPercent, report.AiInsight, - $"{report.WeekCount} {s.CountLabel}", s, customerName); + $"{report.WeekCount} {s.CountLabel}", s, customerName, $"cid:{LogoCid}"); await SendHtmlEmailAsync(subject, html, recipientEmail); } @@ -499,7 +508,7 @@ public static class ReportEmailService report.TotalPvProduction, report.TotalConsumption, report.TotalGridImport, report.TotalGridExport, report.TotalBatteryCharged, report.TotalBatteryDischarged, report.TotalEnergySaved, report.TotalSavingsCHF, report.SelfSufficiencyPercent, report.BatteryEfficiencyPercent, report.AiInsight, - $"{report.MonthCount} {s.CountLabel}", s, customerName); + $"{report.MonthCount} {s.CountLabel}", s, customerName, $"cid:{LogoCid}"); await SendHtmlEmailAsync(subject, html, recipientEmail); } @@ -515,9 +524,10 @@ public static class ReportEmailService From = { from }, To = { to }, Subject = subject, - Body = new TextPart("html") { Text = html } }; + msg.Body = BuildMultipartBodyWithLogo(html); + using var smtp = new SmtpClient(); await smtp.ConnectAsync(config.SmtpServerUrl, config.SmtpPort, SecureSocketOptions.StartTls); await smtp.AuthenticateAsync(config.SmtpUsername, config.SmtpPassword); @@ -527,6 +537,25 @@ public static class ReportEmailService Console.WriteLine($"[ReportEmailService] Report sent to {recipientEmail}"); } + private static MimeEntity BuildMultipartBodyWithLogo(string html) + { + var htmlPart = new TextPart("html") { Text = html }; + + var logoPart = new MimePart("image", "png") + { + Content = new MimeContent(new MemoryStream(LogoPngBytes)), + ContentId = LogoCid, + ContentDisposition = new ContentDisposition(ContentDisposition.Inline), + ContentTransferEncoding = ContentEncoding.Base64, + }; + + var related = new MultipartRelated(); + related.Add(htmlPart); + related.Add(logoPart); + + return related; + } + // ── Aggregated report translation strings ───────────────────────────── public record AggregatedEmailStrings( @@ -604,8 +633,9 @@ public static class ReportEmailService // ── Daily Report HTML ──────────────────────────────────────────── public static string BuildDailyHtmlEmail( - DailyEnergyRecord record, string installationName, string language = "en") + DailyEnergyRecord record, string installationName, string language = "en", string logoSrc = null) { + logoSrc ??= LogoDataUri; var s = GetAggregatedStrings(language, "monthly"); // reuse monthly strings for metric labels var dailyTitle = language switch @@ -637,7 +667,7 @@ public static class ReportEmailService + + "; + + var bgColor = source == "web" ? "transparent" : "#f4f4f4"; + return $@" - -
- +
- - - - + {footerHtml}
- +
{s.Title}
{r.InstallationName}
{r.PeriodStart} — {r.PeriodEnd}
@@ -404,13 +419,7 @@ public static class ReportEmailService
- {s.Footer} - -
- +
{dailyTitle}
{installationName}
{record.Date}
@@ -697,8 +727,9 @@ public static class ReportEmailService double pvProduction, double consumption, double gridImport, double gridExport, double batteryCharged, double batteryDischarged, double energySaved, double savingsCHF, double selfSufficiency, double batteryEfficiency, string aiInsight, - string countLabel, AggregatedEmailStrings s, string customerName = null) + string countLabel, AggregatedEmailStrings s, string customerName = null, string logoSrc = null, string source = "email") { + logoSrc ??= LogoDataUri; var insightLines = aiInsight .Split('\n', StringSplitOptions.RemoveEmptyEntries) .Select(l => System.Text.RegularExpressions.Regex.Replace(l.Trim(), @"^[\d]+[.)]\s*|^[-*]\s*", "").Replace("**", "")) @@ -711,19 +742,30 @@ public static class ReportEmailService "" : $"

{FormatInsightLine(aiInsight)}

"; + var footerHtml = source == "web" ? "" : $@" + +
+ {s.Footer} + +
+ +
diff --git a/csharp/App/Backend/Services/WeatherService.cs b/csharp/App/Backend/Services/WeatherService.cs index d90e7c3fb..1c393ff7b 100644 --- a/csharp/App/Backend/Services/WeatherService.cs +++ b/csharp/App/Backend/Services/WeatherService.cs @@ -40,6 +40,33 @@ public static class WeatherService } } + /// + /// Returns historical weather for a date range, or null on any failure. + /// Uses Open-Meteo's archive API for past weather data. + /// + public static async Task?> GetHistoricalAsync( + string? city, string? country, string? region, + DateOnly startDate, DateOnly endDate) + { + if (string.IsNullOrWhiteSpace(city)) + return null; + + try + { + var coords = await GeocodeAsync(city, region); + if (coords == null) + return null; + + var (lat, lon) = coords.Value; + return await FetchHistoricalAsync(lat, lon, startDate, endDate); + } + catch (Exception ex) + { + Console.Error.WriteLine($"[WeatherService] Error fetching historical weather for '{city}': {ex.Message}"); + return null; + } + } + /// /// Formats a forecast list into a compact text block for AI prompt injection. /// @@ -52,7 +79,22 @@ public static class WeatherService return $"- {dayName}: {d.TempMin:F0}–{d.TempMax:F0}°C, {d.Description}, {d.SunshineHours:F1}h sunshine, {d.PrecipitationMm:F0}mm rain"; }); - return "WEATHER FORECAST (next 7 days):\n" + string.Join("\n", lines); + return "WEATHER FORECAST (coming 7 days):\n" + string.Join("\n", lines); + } + + /// + /// Formats historical weather into a compact text block for AI prompt injection. + /// + public static string FormatHistoricalForPrompt(List historical) + { + var lines = historical.Select(d => + { + var date = DateTime.Parse(d.Date); + var dayName = date.ToString("ddd dd MMM"); + return $"- {dayName}: {d.TempMin:F0}–{d.TempMax:F0}°C, {d.Description}, {d.SunshineHours:F1}h sunshine, {d.PrecipitationMm:F0}mm rain"; + }); + + return "ACTUAL WEATHER (during reporting week):\n" + string.Join("\n", lines); } /// @@ -145,6 +187,44 @@ public static class WeatherService return forecast; } + private static async Task?> FetchHistoricalAsync(double lat, double lon, DateOnly startDate, DateOnly endDate) + { + var url = $"https://archive-api.open-meteo.com/v1/archive" + + $"?latitude={lat}&longitude={lon}" + + $"&start_date={startDate:yyyy-MM-dd}&end_date={endDate:yyyy-MM-dd}" + + "&daily=temperature_2m_max,temperature_2m_min,sunshine_duration,precipitation_sum,weathercode" + + "&timezone=Europe/Zurich"; + + var json = await url.GetStringAsync(); + var data = JsonConvert.DeserializeObject(json); + + if (data?.daily == null) + return null; + + var dates = data.daily.time; + var tempMax = data.daily.temperature_2m_max; + var tempMin = data.daily.temperature_2m_min; + var sun = data.daily.sunshine_duration; + var precip = data.daily.precipitation_sum; + var codes = data.daily.weathercode; + + var historical = new List(); + for (int i = 0; i < dates.Count; i++) + { + historical.Add(new DailyWeather( + Date: (string)dates[i], + TempMin: (double)tempMin[i], + TempMax: (double)tempMax[i], + SunshineHours: Math.Round((double)sun[i] / 3600.0, 1), + PrecipitationMm: (double)precip[i], + Description: WeatherCodeToDescription((int)codes[i]) + )); + } + + Console.WriteLine($"[WeatherService] Fetched {historical.Count}-day historical weather ({startDate:yyyy-MM-dd} to {endDate:yyyy-MM-dd})."); + return historical; + } + private static string WeatherCodeToDescription(int code) => code switch { 0 => "Clear sky", diff --git a/csharp/App/Backend/Services/WeeklyReportService.cs b/csharp/App/Backend/Services/WeeklyReportService.cs index 67c1b07b3..9d141ddac 100644 --- a/csharp/App/Backend/Services/WeeklyReportService.cs +++ b/csharp/App/Backend/Services/WeeklyReportService.cs @@ -274,7 +274,8 @@ public static class WeeklyReportService var aiInsight = await GetAiInsightAsync( currentWeekDays, currentSummary, previousSummary, selfSufficiency, totalEnergySaved, totalSavingsCHF, - behavior, installationName, language, location, country, region); + behavior, installationName, language, + weekStart, weekEnd, location, country, region); // Compute data availability — which days of the week are missing var availableDates = currentWeekDays.Select(d => d.Date).ToHashSet(); @@ -356,6 +357,8 @@ public static class WeeklyReportService BehavioralPattern behavior, string installationName, string language = "en", + DateOnly? periodStart = null, + DateOnly? periodEnd = null, string? location = null, string? country = null, string? region = null) @@ -367,7 +370,23 @@ public static class WeeklyReportService return "AI insight unavailable (API key not configured)."; } - // Fetch weather forecast for the installation's location + // Date labels for prompt clarity + var today = DateOnly.FromDateTime(DateTime.UtcNow); + var periodLabel = periodStart.HasValue && periodEnd.HasValue + ? $"{periodStart.Value:MMM dd}–{periodEnd.Value:MMM dd}" + : "the reporting week"; + + // Fetch historical weather for the report week (actual conditions) + List? historical = null; + var historicalBlock = ""; + if (periodStart.HasValue && periodEnd.HasValue) + { + historical = await WeatherService.GetHistoricalAsync(location, country, region, periodStart.Value, periodEnd.Value); + historicalBlock = historical != null ? "\n" + WeatherService.FormatHistoricalForPrompt(historical) + "\n" : ""; + Console.WriteLine($"[WeeklyReportService] Historical weather: {(historical != null ? $"{historical.Count} days fetched" : "SKIPPED (no location or API error)")}"); + } + + // Fetch weather forecast for the coming week var forecast = await WeatherService.GetForecastAsync(location, country, region); var weatherBlock = forecast != null ? "\n" + WeatherService.FormatForPrompt(forecast) + "\n" : ""; Console.WriteLine($"[WeeklyReportService] Weather forecast: {(forecast != null ? $"{forecast.Count} days fetched" : "SKIPPED (no location or API error)")}"); @@ -399,22 +418,29 @@ public static class WeeklyReportService var battDepleteLine = hasBattery ? (behavior.AvgBatteryDepletedHour >= 0 ? $"Battery typically depletes below 20% during {FormatHourSlot(behavior.AvgBatteryDepletedHour)}." - : "Battery stayed above 20% SoC every night this week.") + : $"Battery stayed above 20% SoC every night during {periodLabel}.") : ""; var weekdayWeekendLine = behavior.WeekendAvgDailyLoad > 0 ? $"Weekday avg load: {behavior.WeekdayAvgDailyLoad} kWh/day. Weekend avg: {behavior.WeekendAvgDailyLoad} kWh/day." : $"Weekday avg load: {behavior.WeekdayAvgDailyLoad} kWh/day."; + // Look up actual weather for best/worst solar days (if historical data available) + var bestDayWeather = historical?.FirstOrDefault(w => w.Date == bestDay.Date); + var worstDayWeather = historical?.FirstOrDefault(w => w.Date == worstDay.Date); + + var bestDayWeatherNote = bestDayWeather != null ? $" (actual weather: {bestDayWeather.Description}, {bestDayWeather.SunshineHours:F1}h sunshine)" : ""; + var worstDayWeatherNote = worstDayWeather != null ? $" (actual weather: {worstDayWeather.Description}, {worstDayWeather.SunshineHours:F1}h sunshine)" : ""; + // Build conditional fact lines var pvDailyFact = hasPv - ? $"- PV: total {current.TotalPvProduction:F1} kWh this week. Best day: {bestDayName} ({bestDay.PvProduction:F1} kWh), worst: {worstDayName} ({worstDay.PvProduction:F1} kWh). Solar covered {selfSufficiency}% of consumption." + ? $"- PV: total {current.TotalPvProduction:F1} kWh for {periodLabel}. Best day: {bestDayName} ({bestDay.PvProduction:F1} kWh){bestDayWeatherNote}, worst: {worstDayName} ({worstDay.PvProduction:F1} kWh){worstDayWeatherNote}. Solar covered {selfSufficiency}% of consumption." : ""; var battDailyFact = hasBattery ? $"- Battery: {current.TotalBatteryCharged:F1} kWh charged, {current.TotalBatteryDischarged:F1} kWh discharged. Most active day: {topBattDayName} ({topBattDay.BatteryCharged:F1} kWh charged)." : ""; var gridDailyFact = hasGrid - ? $"- Grid import: {current.TotalGridImport:F1} kWh total this week." + ? $"- Grid import: {current.TotalGridImport:F1} kWh total for {periodLabel}." : ""; // Behavioral section — only include when hourly data exists @@ -432,7 +458,7 @@ public static class WeeklyReportService var battBehaviorLine = !string.IsNullOrEmpty(battDepleteLine) ? $"- {battDepleteLine}" : ""; behavioralSection = $@" -BEHAVIORAL PATTERN (from hourly data this week): +BEHAVIORAL PATTERN (from hourly data for {periodLabel}): - Peak household load: {FormatHourSlot(behavior.PeakLoadHour)}, avg {behavior.AvgPeakLoadKwh} kWh during that hour - {weekdayWeekendLine}{pvBehaviorLines} {gridBehaviorLine} @@ -440,12 +466,15 @@ BEHAVIORAL PATTERN (from hourly data this week): } // Build conditional instructions - var instruction1 = $"1. Energy savings: Write 1–2 sentences. Say that this week, thanks to sodistore home, the customer avoided buying {totalEnergySaved} kWh from the grid, saving {totalSavingsCHF} CHF (at {ElectricityPriceCHF} CHF/kWh). Use these exact numbers — do not recalculate or change them."; + var instruction1 = $"1. Energy savings: Write 1–2 sentences. Say that during {periodLabel}, thanks to sodistore home, the customer avoided buying {totalEnergySaved} kWh from the grid, saving {totalSavingsCHF} CHF (at {ElectricityPriceCHF} CHF/kWh). Use these exact numbers — do not recalculate or change them."; + var hasHistorical = historical != null && historical.Count > 0; var instruction2 = hasPv - ? $"2. Solar performance: Comment on the best and worst solar day this week and the likely weather reason." + ? hasHistorical + ? $"2. Solar performance: Comment on the best and worst solar day during {periodLabel}. Use the ACTUAL WEATHER data provided above to explain why — do NOT guess the weather. Reference the real conditions (sunshine hours, weather description) from the historical weather data." + : $"2. Solar performance: Comment on the best and worst solar day during {periodLabel}. Only state the production numbers — do NOT speculate about weather reasons if no weather data is provided." : hasGrid - ? $"2. Grid usage: Comment on the {current.TotalGridImport:F1} kWh drawn from the grid this week." + ? $"2. Grid usage: Comment on the {current.TotalGridImport:F1} kWh drawn from the grid during {periodLabel}." : "2. Consumption pattern: Comment on the weekday vs weekend load pattern."; var instruction3 = hasBattery @@ -455,19 +484,24 @@ BEHAVIORAL PATTERN (from hourly data this week): // Instruction 4 — adapts based on whether we have behavioral data string instruction4; if (hasBehavior && hasPv) - instruction4 = $"4. Smart action for next week: Write exactly 2 sentences. Sentence 1: point out the timing mismatch using exact numbers — peak household load is during {FormatHourSlot(behavior.PeakLoadHour)} ({behavior.AvgPeakLoadKwh} kWh) but solar peaks during {FormatHourSlot(behavior.PeakSolarHour)} ({behavior.AvgPeakSolarKwh} kWh), with solar active from {peakSolarWindow}. Sentence 2: suggest shifting energy-intensive appliances (such as washing machine, dishwasher, heat pump, or EV charger if applicable) to run during the solar window {peakSolarWindow} — do not assume which specific device the customer has."; + instruction4 = $"4. Smart action for the coming week: Write exactly 2 sentences. Sentence 1: point out the timing mismatch using exact numbers — peak household load is during {FormatHourSlot(behavior.PeakLoadHour)} ({behavior.AvgPeakLoadKwh} kWh) but solar peaks during {FormatHourSlot(behavior.PeakSolarHour)} ({behavior.AvgPeakSolarKwh} kWh), with solar active from {peakSolarWindow}. Sentence 2: suggest shifting energy-intensive appliances (such as washing machine, dishwasher, heat pump, or EV charger if applicable) to run during the solar window {peakSolarWindow} — do not assume which specific device the customer has."; else if (hasBehavior && hasGrid) - instruction4 = $"4. Smart action for next week: Write exactly 2 sentences. Sentence 1: state that the peak grid-import hour is {FormatHourSlot(behavior.HighestGridImportHour)} ({behavior.AvgGridImportAtPeakHour} kWh avg). Sentence 2: suggest one action to reduce grid use during that hour — shifting energy-intensive appliances (washing machine, dishwasher, heat pump, EV charger) away from that time."; + instruction4 = $"4. Smart action for the coming week: Write exactly 2 sentences. Sentence 1: state that the peak grid-import hour is {FormatHourSlot(behavior.HighestGridImportHour)} ({behavior.AvgGridImportAtPeakHour} kWh avg). Sentence 2: suggest one action to reduce grid use during that hour — shifting energy-intensive appliances (washing machine, dishwasher, heat pump, EV charger) away from that time."; else - instruction4 = "4. Smart action for next week: Based on this week's daily energy patterns, suggest one practical tip to maximize self-consumption and reduce grid dependency."; + instruction4 = $"4. Smart action for the coming week: Based on the energy patterns from {periodLabel}, suggest one practical tip to maximize self-consumption and reduce grid dependency."; // Instruction 5 — weather outlook with pattern-based predictions var hasWeather = forecast != null; var bulletCount = hasWeather ? 5 : 4; + // Forecast date range label for prompt + var forecastLabel = forecast != null && forecast.Count > 0 + ? $"{DateTime.Parse(forecast.First().Date):MMM dd}–{DateTime.Parse(forecast.Last().Date):MMM dd}" + : "the coming days"; + var instruction5 = ""; if (hasWeather && hasPv) { - // Compute avg daily PV production this week for reference + // Compute avg daily PV production for the reporting week as reference var avgDailyPv = currentWeek.Count > 0 ? Math.Round(currentWeek.Average(d => d.PvProduction), 1) : 0; var bestDayPv = Math.Round(bestDay.PvProduction, 1); var worstDayPv = Math.Round(worstDay.PvProduction, 1); @@ -477,36 +511,39 @@ BEHAVIORAL PATTERN (from hourly data this week): var cloudyDays = forecast.Where(d => d.SunshineHours < 3).Select(d => DateTime.Parse(d.Date).ToString("dddd")).ToList(); var totalForecastSunshine = Math.Round(forecast.Sum(d => d.SunshineHours), 1); - var patternContext = $"This week the installation averaged {avgDailyPv} kWh/day PV (best: {bestDayPv} kWh on {bestDayName}, worst: {worstDayPv} kWh on {worstDayName}). "; + var patternContext = $"During {periodLabel} the installation averaged {avgDailyPv} kWh/day PV (best: {bestDayPv} kWh on {bestDayName}, worst: {worstDayPv} kWh on {worstDayName}). "; if (sunnyDays.Count > 0) - patternContext += $"Next week, sunny days ({string.Join(", ", sunnyDays)}) should produce above average (~{avgDailyPv}+ kWh/day). "; + patternContext += $"In the coming days ({forecastLabel}), sunny days ({string.Join(", ", sunnyDays)}) should produce above average (~{avgDailyPv}+ kWh/day). "; if (cloudyDays.Count > 0) patternContext += $"Cloudy/rainy days ({string.Join(", ", cloudyDays)}) will likely produce below average (~{worstDayPv} kWh/day or less). "; - patternContext += $"Total forecast sunshine next week: {totalForecastSunshine}h."; + patternContext += $"Total forecast sunshine for {forecastLabel}: {totalForecastSunshine}h."; - instruction5 = $@"5. Weather outlook: {patternContext} Write 2-3 concise sentences. (1) Name the best solar days next week and estimate production based on this week's pattern. (2) Recommend which specific days are best for running energy-heavy appliances (washing machine, dishwasher, EV charging) to maximize free solar energy. (3) If rainy days follow sunny days, suggest front-loading heavy usage onto the sunny days before the rain arrives. IMPORTANT: Do NOT suggest ""reducing consumption"" in the evening — people need electricity for cooking, lighting, and daily life. Instead, focus on SHIFTING discretionary loads (laundry, dishwasher, EV) to the best solar days. The battery system handles grid charging automatically — do not tell the customer to manage battery charging."; + instruction5 = $@"5. Weather outlook: {patternContext} Write 2-3 concise sentences. (1) Name the best solar days in the coming days ({forecastLabel}) and estimate production based on the reporting week's pattern. (2) Recommend which specific days are best for running energy-heavy appliances (washing machine, dishwasher, EV charging) to maximize free solar energy. (3) If rainy days follow sunny days, suggest front-loading heavy usage onto the sunny days before the rain arrives. IMPORTANT: Do NOT suggest ""reducing consumption"" in the evening — people need electricity for cooking, lighting, and daily life. Instead, focus on SHIFTING discretionary loads (laundry, dishwasher, EV) to the best solar days. The battery system handles grid charging automatically — do not tell the customer to manage battery charging."; } else if (hasWeather) { - instruction5 = @"5. Weather outlook: Summarize the coming week's weather in 1-2 sentences. Mention which days have the most sunshine and suggest those as the best days to run energy-heavy appliances (laundry, dishwasher). Do NOT suggest reducing evening consumption — focus on shifting discretionary loads to sunny days."; + instruction5 = $@"5. Weather outlook: Summarize the weather for the coming days ({forecastLabel}) in 1-2 sentences. Mention which days have the most sunshine and suggest those as the best days to run energy-heavy appliances (laundry, dishwasher). Do NOT suggest reducing evening consumption — focus on shifting discretionary loads to sunny days."; } var prompt = $@"You are an energy advisor for a sodistore home installation: ""{installationName}"". +Today is {today:yyyy-MM-dd} ({today:dddd}). This report covers the week of {periodLabel}. Write {bulletCount} bullet points (each on its own line starting with ""- ""). No bold markers, no asterisks, no markdown — plain text only. IMPORTANT FORMAT RULE: Each bullet MUST start with a short title followed by a colon, then the description. Example: ""- Title label: Description text here."" Translate the title label into {LanguageName(language)} but always keep the ""Title: description"" structure. CRITICAL: All numbers below are pre-calculated. Use these values as-is — do not recalculate, round differently, or change any number. +CRITICAL: Use explicit date references. Say ""during {periodLabel}"" for the reporting week. Say ""the coming days ({forecastLabel})"" for the forecast period. NEVER use ambiguous terms like ""this week"" or ""next week"". SYSTEM COMPONENTS: PV={hasPv}, Battery={hasBattery}, Grid={hasGrid} -DAILY FACTS: -- Total consumption: {current.TotalConsumption:F1} kWh this week. Self-sufficiency: {selfSufficiency}%. +DAILY FACTS (for {periodLabel}): +- Total consumption: {current.TotalConsumption:F1} kWh. Self-sufficiency: {selfSufficiency}%. {pvDailyFact} {battDailyFact} {gridDailyFact} {behavioralSection} +{historicalBlock} {weatherBlock} INSTRUCTIONS: {instruction1} diff --git a/typescript/frontend-marios2/src/Resources/images/inesco_logo_for_dark_bg.png b/typescript/frontend-marios2/src/Resources/images/inesco_logo_for_dark_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..acfffcd031053c0d9d07d7191f4ced3938a5bf56 GIT binary patch literal 65560 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 WjeIz|H4`)mIb~p~pL@db#(x1t6GA8e literal 0 HcmV?d00001 diff --git a/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/DailySection.tsx b/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/DailySection.tsx index 6fd5d28d5..c71ed26a8 100644 --- a/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/DailySection.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/DailySection.tsx @@ -56,19 +56,6 @@ interface HourlyEnergyRecord { // ── Date Helpers ───────────────────────────────────────────── -/** - * Returns the Monday of the current week. - */ -function getCurrentMonday(): Date { - const today = new Date(); - today.setHours(0, 0, 0, 0); - const dow = today.getDay(); // 0=Sun - const offset = dow === 0 ? 6 : dow - 1; // Mon=0 offset - const monday = new Date(today); - monday.setDate(today.getDate() - offset); - return monday; -} - function formatDateISO(d: Date): string { const y = d.getFullYear(); const m = String(d.getMonth() + 1).padStart(2, '0'); @@ -77,19 +64,20 @@ function formatDateISO(d: Date): string { } /** - * Returns current week Mon→yesterday. Today excluded because - * S3 aggregated file is not available until end of day. + * Returns the last 7 days ending yesterday. + * Today is excluded because S3 aggregated file is not available until ~01:00 UTC the next day. */ -function getCurrentWeekDays(currentMonday: Date): Date[] { +function getLast7Days(): Date[] { const yesterday = new Date(); yesterday.setHours(0, 0, 0, 0); yesterday.setDate(yesterday.getDate() - 1); + const days: Date[] = []; - - for (let d = new Date(currentMonday); d <= yesterday; d.setDate(d.getDate() + 1)) { - days.push(new Date(d)); + for (let i = 6; i >= 0; i--) { + const d = new Date(yesterday); + d.setDate(yesterday.getDate() - i); + days.push(d); } - return days; } @@ -105,7 +93,6 @@ export default function DailySection({ onPeriodChange?: (date: string) => void; }) { const intl = useIntl(); - const currentMonday = useMemo(() => getCurrentMonday(), []); const yesterday = useMemo(() => { const d = new Date(); d.setHours(0, 0, 0, 0); @@ -125,11 +112,8 @@ export default function DailySection({ const [loadingWeek, setLoadingWeek] = useState(false); const [noData, setNoData] = useState(false); - // Current week Mon→yesterday only - const weekDays = useMemo( - () => getCurrentWeekDays(currentMonday), - [currentMonday] - ); + // Rolling 7-day window ending yesterday + const weekDays = useMemo(() => getLast7Days(), []); // Fetch data for current week days useEffect(() => { @@ -193,7 +177,7 @@ export default function DailySection({ return ( <> - {/* Day Strip — current week Mon→yesterday */} + {/* Day Strip — last 7 days ending yesterday */} @@ -388,13 +372,14 @@ function IntradayChart({ const hourMap = new Map(hourlyData.map((h) => [h.hour, h])); - const pvData = HOUR_LABELS.map((_, i) => hourMap.get(i)?.pvKwh ?? null); - const loadData = HOUR_LABELS.map((_, i) => hourMap.get(i)?.loadKwh ?? null); + const getHour = (i: number) => hourMap.get(i === 24 ? 23 : i); + const pvData = HOUR_LABELS.map((_, i) => getHour(i)?.pvKwh ?? null); + const loadData = HOUR_LABELS.map((_, i) => getHour(i)?.loadKwh ?? null); const batteryData = HOUR_LABELS.map((_, i) => { - const h = hourMap.get(i); + const h = getHour(i); return h ? h.batteryDischargedKwh - h.batteryChargedKwh : null; }); - const socData = HOUR_LABELS.map((_, i) => hourMap.get(i)?.battSoC ?? null); + const socData = HOUR_LABELS.map((_, i) => getHour(i)?.battSoC ?? null); const chartData = { labels: HOUR_LABELS, diff --git a/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/WeeklyReport.tsx b/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/WeeklyReport.tsx index ff662d40f..289f0514f 100644 --- a/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/WeeklyReport.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/SodiohomeInstallations/WeeklyReport.tsx @@ -26,6 +26,7 @@ import SendIcon from '@mui/icons-material/Send'; import DownloadIcon from '@mui/icons-material/Download'; import SaveIcon from '@mui/icons-material/Save'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import RefreshIcon from '@mui/icons-material/Refresh'; import axiosConfig from 'src/Resources/axiosConfig'; import DailySection from './DailySection'; @@ -104,6 +105,9 @@ interface MonthlyReport extends ReportSummary { avgPeakSolarHour: number; avgWeekdayDailyLoad: number; avgWeekendDailyLoad: number; + isPreview?: boolean; + daysAvailable?: number; + daysInMonth?: number; } interface YearlyReport extends ReportSummary { @@ -113,17 +117,7 @@ interface YearlyReport extends ReportSummary { avgPeakSolarHour: number; avgWeekdayDailyLoad: number; avgWeekendDailyLoad: number; -} - -interface PendingMonth { - year: number; - month: number; - weekCount: number; -} - -interface PendingYear { - year: number; - monthCount: number; + isPreview?: boolean; } interface WeeklyReportSummaryRecord { @@ -151,6 +145,49 @@ interface WeeklyReportSummaryRecord { createdAt: string; } +function ReportHtmlFrame({ html }: { html: string }) { + const iframeRef = useRef(null); + const [height, setHeight] = useState(600); + + useEffect(() => { + const iframe = iframeRef.current; + if (!iframe) return; + + const updateHeight = () => { + try { + const doc = iframe.contentDocument || iframe.contentWindow?.document; + if (doc?.body) { + const newHeight = doc.body.scrollHeight + 20; + if (newHeight > 50) setHeight(newHeight); + } + } catch { /* cross-origin safety */ } + }; + + iframe.addEventListener('load', updateHeight); + const timers = [300, 800, 1500].map(ms => setTimeout(updateHeight, ms)); + + return () => { + iframe.removeEventListener('load', updateHeight); + timers.forEach(clearTimeout); + }; + }, [html]); + + return ( +
- +
- - - - + {footerHtml}
- +
{s.Title}
{installationName}
{periodStart} — {periodEnd}
@@ -774,13 +816,7 @@ public static class ReportEmailService
- {s.Footer} - -