diff --git a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/AgentSelfMetricsCollector.cs b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/AgentSelfMetricsCollector.cs index d8d63c5f..df421429 100644 --- a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/AgentSelfMetricsCollector.cs +++ b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/AgentSelfMetricsCollector.cs @@ -13,17 +13,10 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors /// and HTTP network traffic. Emits agent_metrics_snapshot events via the standard event pipeline. /// No WMI, no PerformanceCounters — only Process properties and Interlocked counters. /// - public class AgentSelfMetricsCollector : IDisposable + public class AgentSelfMetricsCollector : CollectorBase { - private readonly AgentLogger _logger; - private readonly string _sessionId; - private readonly string _tenantId; private readonly string _agentVersion; - private readonly Action _onEventCollected; private readonly NetworkMetrics _networkMetrics; - private readonly int _intervalSeconds; - - private Timer _pollTimer; // Previous sample for delta calculations private TimeSpan _prevCpuTime; @@ -38,20 +31,14 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors AgentLogger logger, string agentVersion = "unknown", int intervalSeconds = 60) + : base(sessionId, tenantId, onEventCollected, logger, intervalSeconds) { - _sessionId = sessionId ?? throw new ArgumentNullException(nameof(sessionId)); - _tenantId = tenantId ?? throw new ArgumentNullException(nameof(tenantId)); - _onEventCollected = onEventCollected ?? throw new ArgumentNullException(nameof(onEventCollected)); _networkMetrics = networkMetrics ?? throw new ArgumentNullException(nameof(networkMetrics)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _agentVersion = string.IsNullOrWhiteSpace(agentVersion) ? "unknown" : agentVersion; - _intervalSeconds = intervalSeconds; } - public void Start() + protected override void OnBeforeStart() { - _logger.Info($"Starting AgentSelfMetrics collector (interval: {_intervalSeconds}s)"); - // Prime the baseline for delta calculations try { @@ -61,123 +48,97 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors } catch (Exception ex) { - _logger.Warning($"Failed to prime CPU baseline: {ex.Message}"); + Logger.Warning($"Failed to prime CPU baseline: {ex.Message}"); _prevCpuTime = TimeSpan.Zero; _prevWallTime = DateTime.UtcNow; } _prevNetSnapshot = _networkMetrics.GetSnapshot(); - - _pollTimer = new Timer( - _ => CollectMetrics(), - null, - TimeSpan.FromSeconds(_intervalSeconds), // first tick after one full interval - TimeSpan.FromSeconds(_intervalSeconds) - ); } - public void Stop() + protected override void Collect() { - _logger.Info("Stopping AgentSelfMetrics collector"); - _pollTimer?.Dispose(); - _pollTimer = null; - } + var data = new Dictionary + { + { "agent_version", _agentVersion } + }; + var now = DateTime.UtcNow; - private void CollectMetrics() - { + // --- Process metrics (no WMI, no PerformanceCounter) --- try { - var data = new Dictionary + var proc = Process.GetCurrentProcess(); + proc.Refresh(); // ensure fresh values + + // CPU %: (delta CPU time) / (delta wall time) / cores * 100 + var currentCpuTime = proc.TotalProcessorTime; + var cpuDelta = currentCpuTime - _prevCpuTime; + var wallDelta = now - _prevWallTime; + + if (wallDelta.TotalMilliseconds > 0) { - { "agent_version", _agentVersion } - }; - var now = DateTime.UtcNow; - - // --- Process metrics (no WMI, no PerformanceCounter) --- - try - { - var proc = Process.GetCurrentProcess(); - proc.Refresh(); // ensure fresh values - - // CPU %: (delta CPU time) / (delta wall time) / cores * 100 - var currentCpuTime = proc.TotalProcessorTime; - var cpuDelta = currentCpuTime - _prevCpuTime; - var wallDelta = now - _prevWallTime; - - if (wallDelta.TotalMilliseconds > 0) - { - var cpuPercent = cpuDelta.TotalMilliseconds / wallDelta.TotalMilliseconds - / Environment.ProcessorCount * 100.0; - data["agent_cpu_percent"] = Math.Round(cpuPercent, 2); - } - - _prevCpuTime = currentCpuTime; - _prevWallTime = now; - - // Memory - data["agent_working_set_mb"] = Math.Round(proc.WorkingSet64 / (1024.0 * 1024), 1); - data["agent_private_bytes_mb"] = Math.Round(proc.PrivateMemorySize64 / (1024.0 * 1024), 1); - - // Threads & handles - data["agent_thread_count"] = proc.Threads.Count; - data["agent_handle_count"] = proc.HandleCount; - } - catch (Exception ex) - { - _logger.Debug($"Process metrics read failed: {ex.Message}"); + var cpuPercent = cpuDelta.TotalMilliseconds / wallDelta.TotalMilliseconds + / Environment.ProcessorCount * 100.0; + data["agent_cpu_percent"] = Math.Round(cpuPercent, 2); } - // --- Network delta --- - try - { - var currentNet = _networkMetrics.GetSnapshot(); - var delta = currentNet.DeltaFrom(_prevNetSnapshot); - _prevNetSnapshot = currentNet; + _prevCpuTime = currentCpuTime; + _prevWallTime = now; - data["net_requests"] = delta.Requests; - data["net_failures"] = delta.Failures; - data["net_bytes_up"] = delta.BytesUp; - data["net_bytes_down"] = delta.BytesDown; - data["net_avg_latency_ms"] = Math.Round(delta.AvgLatencyMs, 1); + // Memory + data["agent_working_set_mb"] = Math.Round(proc.WorkingSet64 / (1024.0 * 1024), 1); + data["agent_private_bytes_mb"] = Math.Round(proc.PrivateMemorySize64 / (1024.0 * 1024), 1); - // Cumulative totals for easy "total cost of this session" view - data["net_total_bytes_up"] = currentNet.TotalBytesUp; - data["net_total_bytes_down"] = currentNet.TotalBytesDown; - data["net_total_requests"] = currentNet.RequestCount; - } - catch (Exception ex) - { - _logger.Debug($"Network metrics read failed: {ex.Message}"); - } - - if (data.Count > 0) - { - _onEventCollected(new EnrollmentEvent - { - SessionId = _sessionId, - TenantId = _tenantId, - Timestamp = now, - EventType = "agent_metrics_snapshot", - Severity = EventSeverity.Debug, - Source = "AgentSelfMetricsCollector", - Phase = EnrollmentPhase.Unknown, - Message = $"Agent CPU: {(data.ContainsKey("agent_cpu_percent") ? data["agent_cpu_percent"] : "?")}%, " + - $"WS: {(data.ContainsKey("agent_working_set_mb") ? data["agent_working_set_mb"] : "?")} MB, " + - $"Net: {(data.ContainsKey("net_requests") ? data["net_requests"] : "?")} req, " + - $"↑{(data.ContainsKey("net_bytes_up") ? data["net_bytes_up"] : "?")} B, " + - $"↓{(data.ContainsKey("net_bytes_down") ? data["net_bytes_down"] : "?")} B", - Data = data - }); - } + // Threads & handles + data["agent_thread_count"] = proc.Threads.Count; + data["agent_handle_count"] = proc.HandleCount; } catch (Exception ex) { - _logger.Warning($"AgentSelfMetrics collection failed: {ex.Message}"); + Logger.Debug($"Process metrics read failed: {ex.Message}"); } - } - public void Dispose() - { - Stop(); + // --- Network delta --- + try + { + var currentNet = _networkMetrics.GetSnapshot(); + var delta = currentNet.DeltaFrom(_prevNetSnapshot); + _prevNetSnapshot = currentNet; + + data["net_requests"] = delta.Requests; + data["net_failures"] = delta.Failures; + data["net_bytes_up"] = delta.BytesUp; + data["net_bytes_down"] = delta.BytesDown; + data["net_avg_latency_ms"] = Math.Round(delta.AvgLatencyMs, 1); + + // Cumulative totals for easy "total cost of this session" view + data["net_total_bytes_up"] = currentNet.TotalBytesUp; + data["net_total_bytes_down"] = currentNet.TotalBytesDown; + data["net_total_requests"] = currentNet.RequestCount; + } + catch (Exception ex) + { + Logger.Debug($"Network metrics read failed: {ex.Message}"); + } + + if (data.Count > 0) + { + EmitEvent(new EnrollmentEvent + { + SessionId = SessionId, + TenantId = TenantId, + Timestamp = now, + EventType = "agent_metrics_snapshot", + Severity = EventSeverity.Debug, + Source = "AgentSelfMetricsCollector", + Phase = EnrollmentPhase.Unknown, + Message = $"Agent CPU: {(data.ContainsKey("agent_cpu_percent") ? data["agent_cpu_percent"] : "?")}%, " + + $"WS: {(data.ContainsKey("agent_working_set_mb") ? data["agent_working_set_mb"] : "?")} MB, " + + $"Net: {(data.ContainsKey("net_requests") ? data["net_requests"] : "?")} req, " + + $"\u2191{(data.ContainsKey("net_bytes_up") ? data["net_bytes_up"] : "?")} B, " + + $"\u2193{(data.ContainsKey("net_bytes_down") ? data["net_bytes_down"] : "?")} B", + Data = data + }); + } } } } diff --git a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/CollectorBase.cs b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/CollectorBase.cs new file mode 100644 index 00000000..b845b15c --- /dev/null +++ b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/CollectorBase.cs @@ -0,0 +1,84 @@ +using System; +using System.Threading; +using AutopilotMonitor.Agent.Core.Logging; +using AutopilotMonitor.Shared.Models; + +namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors +{ + /// + /// Abstract base for interval-based event collectors. + /// Handles Timer lifecycle (Start/Stop/Dispose) so subclasses only implement Collect(). + /// + public abstract class CollectorBase : IDisposable + { + protected readonly string SessionId; + protected readonly string TenantId; + protected readonly Action EmitEvent; + protected readonly AgentLogger Logger; + + private readonly int _intervalSeconds; + private Timer _timer; + private bool _disposed; + + protected CollectorBase( + string sessionId, + string tenantId, + Action emitEvent, + AgentLogger logger, + int intervalSeconds) + { + SessionId = sessionId ?? throw new ArgumentNullException(nameof(sessionId)); + TenantId = tenantId ?? throw new ArgumentNullException(nameof(tenantId)); + EmitEvent = emitEvent ?? throw new ArgumentNullException(nameof(emitEvent)); + Logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _intervalSeconds = intervalSeconds; + } + + /// Starts the collection interval timer. + public void Start() + { + if (_disposed) return; + OnBeforeStart(); + var interval = TimeSpan.FromSeconds(_intervalSeconds); + _timer = new Timer(_ => CollectSafe(), null, GetInitialDelay(), interval); + Logger.Info($"[{GetType().Name}] Started (interval={_intervalSeconds}s)"); + } + + /// Stops the collection timer without disposing the collector. + public void Stop() + { + _timer?.Dispose(); + _timer = null; + Logger.Info($"[{GetType().Name}] Stopped"); + OnAfterStop(); + } + + public void Dispose() + { + if (_disposed) return; + _disposed = true; + Stop(); + } + + /// Override to perform collection. Called on each timer tick. + protected abstract void Collect(); + + /// + /// Override to return the initial delay before the first tick. + /// Default: one full interval (same as the repeat interval). + /// + protected virtual TimeSpan GetInitialDelay() => TimeSpan.FromSeconds(_intervalSeconds); + + /// Optional hook called before the timer starts (e.g. to initialise counters). + protected virtual void OnBeforeStart() { } + + /// Optional hook called after the timer stops (e.g. to dispose counters). + protected virtual void OnAfterStop() { } + + private void CollectSafe() + { + try { Collect(); } + catch (Exception ex) { Logger.Error($"[{GetType().Name}] Collection error: {ex.Message}", ex); } + } + } +} diff --git a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/PerformanceCollector.cs b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/PerformanceCollector.cs index 4e242cca..40cb9d4d 100644 --- a/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/PerformanceCollector.cs +++ b/src/Agent/AutopilotMonitor.Agent.Core/Monitoring/Collectors/PerformanceCollector.cs @@ -11,18 +11,11 @@ using AutopilotMonitor.Shared.Models; namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors { /// - /// Collects system performance metrics (CPU, memory, disk) on a configurable interval - /// Optional collector - toggled on/off via remote config + /// Collects system performance metrics (CPU, memory, disk) on a configurable interval. + /// Optional collector - toggled on/off via remote config. /// - public class PerformanceCollector : IDisposable + public class PerformanceCollector : CollectorBase { - private readonly AgentLogger _logger; - private readonly string _sessionId; - private readonly string _tenantId; - private readonly Action _onEventCollected; - private readonly int _intervalSeconds; - private Timer _pollTimer; - private PerformanceCounter _cpuCounter; private PerformanceCounter _diskQueueCounter; @@ -36,18 +29,15 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors public PerformanceCollector(string sessionId, string tenantId, Action onEventCollected, AgentLogger logger, int intervalSeconds = 60) + : base(sessionId, tenantId, onEventCollected, logger, intervalSeconds) { - _sessionId = sessionId ?? throw new ArgumentNullException(nameof(sessionId)); - _tenantId = tenantId ?? throw new ArgumentNullException(nameof(tenantId)); - _onEventCollected = onEventCollected ?? throw new ArgumentNullException(nameof(onEventCollected)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _intervalSeconds = intervalSeconds; } - public void Start() - { - _logger.Info($"Starting Performance collector (interval: {_intervalSeconds}s)"); + /// Use a 5-second warm-up delay so counters are primed before first read. + protected override TimeSpan GetInitialDelay() => TimeSpan.FromSeconds(5); + protected override void OnBeforeStart() + { try { _cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); @@ -58,7 +48,7 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors } catch (Exception ex) { - _logger.Warning($"Failed to initialize performance counters: {ex.Message}"); + Logger.Warning($"Failed to initialize performance counters: {ex.Message}"); } // Initialize network throughput baseline @@ -74,209 +64,195 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors _prevBytesReceived = stats.BytesReceived; _prevNetSampleTime = DateTime.UtcNow; _networkInitialized = true; - _logger.Debug($"Network throughput tracking initialized on: {_activeNicName}"); + Logger.Debug($"Network throughput tracking initialized on: {_activeNicName}"); } else { - _logger.Debug("No active network interface found for throughput tracking"); + Logger.Debug("No active network interface found for throughput tracking"); } } catch (Exception ex) { - _logger.Debug($"Failed to initialize network throughput baseline: {ex.Message}"); + Logger.Debug($"Failed to initialize network throughput baseline: {ex.Message}"); } - - // Start with an initial delay, then poll on interval - _pollTimer = new Timer( - _ => CollectMetrics(), - null, - TimeSpan.FromSeconds(5), // Initial delay to let counters warm up - TimeSpan.FromSeconds(_intervalSeconds) - ); } - public void Stop() + protected override void OnAfterStop() { - _logger.Info("Stopping Performance collector"); - _pollTimer?.Dispose(); - _pollTimer = null; + _cpuCounter?.Dispose(); + _cpuCounter = null; + _diskQueueCounter?.Dispose(); + _diskQueueCounter = null; } - private void CollectMetrics() + protected override void Collect() { + var data = new Dictionary(); + + // CPU usage try { - var data = new Dictionary(); + var cpuPercent = _cpuCounter?.NextValue() ?? 0; + data["cpu_percent"] = Math.Round(cpuPercent, 1); + } + catch (Exception ex) + { + Logger.Debug($"CPU counter read failed: {ex.Message}"); + } - // CPU usage - try + // Memory info via WMI + try + { + using (var searcher = new ManagementObjectSearcher("SELECT FreePhysicalMemory, TotalVisibleMemorySize FROM Win32_OperatingSystem")) { - var cpuPercent = _cpuCounter?.NextValue() ?? 0; - data["cpu_percent"] = Math.Round(cpuPercent, 1); - } - catch (Exception ex) - { - _logger.Debug($"CPU counter read failed: {ex.Message}"); - } - - // Memory info via WMI - try - { - using (var searcher = new ManagementObjectSearcher("SELECT FreePhysicalMemory, TotalVisibleMemorySize FROM Win32_OperatingSystem")) + foreach (ManagementObject obj in searcher.Get()) { - foreach (ManagementObject obj in searcher.Get()) - { - var freeKb = Convert.ToDouble(obj["FreePhysicalMemory"]); - var totalKb = Convert.ToDouble(obj["TotalVisibleMemorySize"]); - data["memory_available_mb"] = Math.Round(freeKb / 1024, 0); - data["memory_total_mb"] = Math.Round(totalKb / 1024, 0); - data["memory_used_percent"] = Math.Round((1 - freeKb / totalKb) * 100, 1); - } + var freeKb = Convert.ToDouble(obj["FreePhysicalMemory"]); + var totalKb = Convert.ToDouble(obj["TotalVisibleMemorySize"]); + data["memory_available_mb"] = Math.Round(freeKb / 1024, 0); + data["memory_total_mb"] = Math.Round(totalKb / 1024, 0); + data["memory_used_percent"] = Math.Round((1 - freeKb / totalKb) * 100, 1); } } - catch (Exception ex) - { - _logger.Debug($"Memory WMI query failed: {ex.Message}"); - } - - // Disk queue length - try - { - var diskQueue = _diskQueueCounter?.NextValue() ?? 0; - data["disk_queue_length"] = Math.Round(diskQueue, 1); - } - catch (Exception ex) - { - _logger.Debug($"Disk queue counter read failed: {ex.Message}"); - } - - // Disk free space on system drive - try - { - var systemDrive = Path.GetPathRoot(Environment.SystemDirectory); - var driveInfo = new DriveInfo(systemDrive); - data["disk_free_gb"] = Math.Round(driveInfo.AvailableFreeSpace / (1024.0 * 1024 * 1024), 1); - data["disk_total_gb"] = Math.Round(driveInfo.TotalSize / (1024.0 * 1024 * 1024), 1); - } - catch (Exception ex) - { - _logger.Debug($"Disk space query failed: {ex.Message}"); - } - - // Network throughput (bytes sent/received delta + rate) - try - { - if (_networkInitialized) - { - // Re-find the NIC by cached ID - NetworkInterface currentNic = null; - try - { - foreach (var nic in NetworkInterface.GetAllNetworkInterfaces()) - { - if (nic.Id == _activeNicId) - { - currentNic = nic; - break; - } - } - } - catch { /* swallow */ } - - // If cached NIC is gone, try to find a new active one - if (currentNic == null || currentNic.OperationalStatus != OperationalStatus.Up) - { - currentNic = FindActiveNetworkInterface(); - if (currentNic != null) - { - _activeNicId = currentNic.Id; - _activeNicName = currentNic.Description; - var freshStats = currentNic.GetIPStatistics(); - _prevBytesSent = freshStats.BytesSent; - _prevBytesReceived = freshStats.BytesReceived; - _prevNetSampleTime = DateTime.UtcNow; - _logger.Debug($"Network throughput tracking switched to: {_activeNicName}"); - } - else - { - _networkInitialized = false; - _logger.Debug("Active network interface lost, throughput tracking paused"); - } - } - - if (currentNic != null && currentNic.OperationalStatus == OperationalStatus.Up) - { - var stats = currentNic.GetIPStatistics(); - var now = DateTime.UtcNow; - var elapsedSeconds = (now - _prevNetSampleTime).TotalSeconds; - - if (elapsedSeconds > 0) - { - var deltaSent = stats.BytesSent - _prevBytesSent; - var deltaReceived = stats.BytesReceived - _prevBytesReceived; - - // Guard against counter reset (adapter reconnect) - if (deltaSent < 0) deltaSent = 0; - if (deltaReceived < 0) deltaReceived = 0; - - data["net_adapter"] = _activeNicName; - data["net_bytes_sent_delta"] = deltaSent; - data["net_bytes_received_delta"] = deltaReceived; - data["net_send_rate_kbps"] = Math.Round(deltaSent * 8.0 / 1000.0 / elapsedSeconds, 1); - data["net_receive_rate_kbps"] = Math.Round(deltaReceived * 8.0 / 1000.0 / elapsedSeconds, 1); - } - - _prevBytesSent = stats.BytesSent; - _prevBytesReceived = stats.BytesReceived; - _prevNetSampleTime = now; - } - } - else - { - // Try to re-initialize (e.g., network came up after boot) - var activeNic = FindActiveNetworkInterface(); - if (activeNic != null) - { - _activeNicId = activeNic.Id; - _activeNicName = activeNic.Description; - var stats = activeNic.GetIPStatistics(); - _prevBytesSent = stats.BytesSent; - _prevBytesReceived = stats.BytesReceived; - _prevNetSampleTime = DateTime.UtcNow; - _networkInitialized = true; - _logger.Debug($"Network throughput tracking re-initialized on: {_activeNicName}"); - } - } - } - catch (Exception ex) - { - _logger.Debug($"Network throughput collection failed: {ex.Message}"); - } - - if (data.Count > 0) - { - _onEventCollected(new EnrollmentEvent - { - SessionId = _sessionId, - TenantId = _tenantId, - Timestamp = DateTime.UtcNow, - EventType = "performance_snapshot", - Severity = EventSeverity.Debug, - Source = "PerformanceCollector", - Phase = EnrollmentPhase.Unknown, - Message = $"CPU: {(data.ContainsKey("cpu_percent") ? data["cpu_percent"] : "?")}%, " + - $"Memory: {(data.ContainsKey("memory_used_percent") ? data["memory_used_percent"] : "?")}%, " + - $"Disk Free: {(data.ContainsKey("disk_free_gb") ? data["disk_free_gb"] : "?")} GB" + - (data.ContainsKey("net_receive_rate_kbps") - ? $", Net: ↓{data["net_receive_rate_kbps"]} / ↑{data["net_send_rate_kbps"]} kbps" - : ""), - Data = data - }); - } } catch (Exception ex) { - _logger.Warning($"Performance collection failed: {ex.Message}"); + Logger.Debug($"Memory WMI query failed: {ex.Message}"); + } + + // Disk queue length + try + { + var diskQueue = _diskQueueCounter?.NextValue() ?? 0; + data["disk_queue_length"] = Math.Round(diskQueue, 1); + } + catch (Exception ex) + { + Logger.Debug($"Disk queue counter read failed: {ex.Message}"); + } + + // Disk free space on system drive + try + { + var systemDrive = Path.GetPathRoot(Environment.SystemDirectory); + var driveInfo = new DriveInfo(systemDrive); + data["disk_free_gb"] = Math.Round(driveInfo.AvailableFreeSpace / (1024.0 * 1024 * 1024), 1); + data["disk_total_gb"] = Math.Round(driveInfo.TotalSize / (1024.0 * 1024 * 1024), 1); + } + catch (Exception ex) + { + Logger.Debug($"Disk space query failed: {ex.Message}"); + } + + // Network throughput (bytes sent/received delta + rate) + try + { + if (_networkInitialized) + { + // Re-find the NIC by cached ID + NetworkInterface currentNic = null; + try + { + foreach (var nic in NetworkInterface.GetAllNetworkInterfaces()) + { + if (nic.Id == _activeNicId) + { + currentNic = nic; + break; + } + } + } + catch { /* swallow */ } + + // If cached NIC is gone, try to find a new active one + if (currentNic == null || currentNic.OperationalStatus != OperationalStatus.Up) + { + currentNic = FindActiveNetworkInterface(); + if (currentNic != null) + { + _activeNicId = currentNic.Id; + _activeNicName = currentNic.Description; + var freshStats = currentNic.GetIPStatistics(); + _prevBytesSent = freshStats.BytesSent; + _prevBytesReceived = freshStats.BytesReceived; + _prevNetSampleTime = DateTime.UtcNow; + Logger.Debug($"Network throughput tracking switched to: {_activeNicName}"); + } + else + { + _networkInitialized = false; + Logger.Debug("Active network interface lost, throughput tracking paused"); + } + } + + if (currentNic != null && currentNic.OperationalStatus == OperationalStatus.Up) + { + var stats = currentNic.GetIPStatistics(); + var now = DateTime.UtcNow; + var elapsedSeconds = (now - _prevNetSampleTime).TotalSeconds; + + if (elapsedSeconds > 0) + { + var deltaSent = stats.BytesSent - _prevBytesSent; + var deltaReceived = stats.BytesReceived - _prevBytesReceived; + + // Guard against counter reset (adapter reconnect) + if (deltaSent < 0) deltaSent = 0; + if (deltaReceived < 0) deltaReceived = 0; + + data["net_adapter"] = _activeNicName; + data["net_bytes_sent_delta"] = deltaSent; + data["net_bytes_received_delta"] = deltaReceived; + data["net_send_rate_kbps"] = Math.Round(deltaSent * 8.0 / 1000.0 / elapsedSeconds, 1); + data["net_receive_rate_kbps"] = Math.Round(deltaReceived * 8.0 / 1000.0 / elapsedSeconds, 1); + } + + _prevBytesSent = stats.BytesSent; + _prevBytesReceived = stats.BytesReceived; + _prevNetSampleTime = now; + } + } + else + { + // Try to re-initialize (e.g., network came up after boot) + var activeNic = FindActiveNetworkInterface(); + if (activeNic != null) + { + _activeNicId = activeNic.Id; + _activeNicName = activeNic.Description; + var stats = activeNic.GetIPStatistics(); + _prevBytesSent = stats.BytesSent; + _prevBytesReceived = stats.BytesReceived; + _prevNetSampleTime = DateTime.UtcNow; + _networkInitialized = true; + Logger.Debug($"Network throughput tracking re-initialized on: {_activeNicName}"); + } + } + } + catch (Exception ex) + { + Logger.Debug($"Network throughput collection failed: {ex.Message}"); + } + + if (data.Count > 0) + { + EmitEvent(new EnrollmentEvent + { + SessionId = SessionId, + TenantId = TenantId, + Timestamp = DateTime.UtcNow, + EventType = "performance_snapshot", + Severity = EventSeverity.Debug, + Source = "PerformanceCollector", + Phase = EnrollmentPhase.Unknown, + Message = $"CPU: {(data.ContainsKey("cpu_percent") ? data["cpu_percent"] : "?")}%, " + + $"Memory: {(data.ContainsKey("memory_used_percent") ? data["memory_used_percent"] : "?")}%, " + + $"Disk Free: {(data.ContainsKey("disk_free_gb") ? data["disk_free_gb"] : "?")} GB" + + (data.ContainsKey("net_receive_rate_kbps") + ? $", Net: \u2193{data["net_receive_rate_kbps"]} / \u2191{data["net_send_rate_kbps"]} kbps" + : ""), + Data = data + }); } } @@ -310,12 +286,5 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors } return null; } - - public void Dispose() - { - Stop(); - _cpuCounter?.Dispose(); - _diskQueueCounter?.Dispose(); - } } } diff --git a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt index cb3e25bb..e110e8da 100644 --- a/src/Agent/AutopilotMonitor.Agent/buildcounter.txt +++ b/src/Agent/AutopilotMonitor.Agent/buildcounter.txt @@ -1 +1 @@ -609 +617 diff --git a/src/Backend/AutopilotMonitor.Functions/AutopilotMonitor.Functions.csproj b/src/Backend/AutopilotMonitor.Functions/AutopilotMonitor.Functions.csproj index 8becbc2b..f3a951f4 100644 --- a/src/Backend/AutopilotMonitor.Functions/AutopilotMonitor.Functions.csproj +++ b/src/Backend/AutopilotMonitor.Functions/AutopilotMonitor.Functions.csproj @@ -23,6 +23,7 @@ + diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Admin/AutopilotDeviceValidationConsentFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Admin/AutopilotDeviceValidationConsentFunction.cs index 17fa1924..110dfec2 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Admin/AutopilotDeviceValidationConsentFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Admin/AutopilotDeviceValidationConsentFunction.cs @@ -13,21 +13,15 @@ public class AutopilotDeviceValidationConsentFunction { private readonly ILogger _logger; private readonly IConfiguration _configuration; - private readonly TenantAdminsService _tenantAdminsService; - private readonly GlobalAdminService _globalAdminService; private readonly GraphTokenService _graphTokenService; public AutopilotDeviceValidationConsentFunction( ILogger logger, IConfiguration configuration, - TenantAdminsService tenantAdminsService, - GlobalAdminService globalAdminService, GraphTokenService graphTokenService) { _logger = logger; _configuration = configuration; - _tenantAdminsService = tenantAdminsService; - _globalAdminService = globalAdminService; _graphTokenService = graphTokenService; } @@ -98,24 +92,15 @@ public class AutopilotDeviceValidationConsentFunction private async Task EnsureAuthorizedTenantAdminAsync(HttpRequestData req, string tenantId) { // Authentication enforced by PolicyEnforcementMiddleware - var authenticatedTenantId = TenantHelper.GetTenantId(req); - var userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); - if (!string.Equals(authenticatedTenantId, tenantId, StringComparison.OrdinalIgnoreCase)) - { - var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); - await forbidden.WriteAsJsonAsync(new { error = "Access denied. You can only manage your own tenant." }); - return forbidden; - } - - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - var isTenantAdmin = await _tenantAdminsService.IsTenantAdminAsync(tenantId, userIdentifier); - - if (!isGlobalAdmin && !isTenantAdmin) + // Middleware (TenantAdminOrGA policy) already verified GA or TenantAdmin of own tenant. + // For non-GA: only allow access to own tenant. + if (!requestCtx.IsGlobalAdmin && !tenantId.Equals(requestCtx.TenantId, StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning( "User {User} attempted autopilot-device-validation consent operation without admin rights for tenant {TenantId}", - userIdentifier, + requestCtx.UserPrincipalName, tenantId); var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Admin/TenantAdminManagementFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Admin/TenantAdminManagementFunction.cs index f4e47920..3e420cad 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Admin/TenantAdminManagementFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Admin/TenantAdminManagementFunction.cs @@ -1,5 +1,4 @@ using System.Net; -using AutopilotMonitor.Functions.Extensions; using AutopilotMonitor.Functions.Helpers; using AutopilotMonitor.Functions.Services; using AutopilotMonitor.Shared.DataAccess; @@ -18,18 +17,15 @@ public class TenantAdminManagementFunction { private readonly ILogger _logger; private readonly TenantAdminsService _tenantAdminsService; - private readonly GlobalAdminService _globalAdminService; private readonly IMaintenanceRepository _maintenanceRepo; public TenantAdminManagementFunction( ILogger logger, TenantAdminsService tenantAdminsService, - GlobalAdminService globalAdminService, IMaintenanceRepository maintenanceRepo) { _logger = logger; _tenantAdminsService = tenantAdminsService; - _globalAdminService = globalAdminService; _maintenanceRepo = maintenanceRepo; } @@ -46,17 +42,12 @@ public class TenantAdminManagementFunction FunctionContext context) { // Authentication enforced by PolicyEnforcementMiddleware - var principal = context.GetUser()!; + var requestCtx = context.GetRequestContext(); + var upn = requestCtx.UserPrincipalName; - var userTenantId = principal.GetTenantId(); - var upn = principal.GetUserPrincipalName(); - - // Check authorization: either Global Admin OR Tenant Admin of the same tenant - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(upn); - var isTenantAdmin = tenantId.Equals(userTenantId, StringComparison.OrdinalIgnoreCase) && - await _tenantAdminsService.IsTenantAdminAsync(tenantId, upn); - - if (!isGlobalAdmin && !isTenantAdmin) + // Middleware (TenantAdminOrGA policy) already verified GA or TenantAdmin of own tenant. + // For non-GA: only allow access to own tenant. + if (!requestCtx.IsGlobalAdmin && !tenantId.Equals(requestCtx.TenantId, StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning($"User {upn} attempted to access admins for tenant {tenantId} without authorization"); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); @@ -86,17 +77,12 @@ public class TenantAdminManagementFunction FunctionContext context) { // Authentication enforced by PolicyEnforcementMiddleware - var principal = context.GetUser()!; + var requestCtx = context.GetRequestContext(); + var upn = requestCtx.UserPrincipalName; - var userTenantId = principal.GetTenantId(); - var upn = principal.GetUserPrincipalName(); - - // Check authorization: either Global Admin OR Tenant Admin of the same tenant - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(upn); - var isTenantAdmin = tenantId.Equals(userTenantId, StringComparison.OrdinalIgnoreCase) && - await _tenantAdminsService.IsTenantAdminAsync(tenantId, upn); - - if (!isGlobalAdmin && !isTenantAdmin) + // Middleware (TenantAdminOrGA policy) already verified GA or TenantAdmin of own tenant. + // For non-GA: only allow access to own tenant. + if (!requestCtx.IsGlobalAdmin && !tenantId.Equals(requestCtx.TenantId, StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning($"User {upn} attempted to add admin to tenant {tenantId} without authorization"); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); @@ -152,17 +138,12 @@ public class TenantAdminManagementFunction FunctionContext context) { // Authentication enforced by PolicyEnforcementMiddleware - var principal = context.GetUser()!; + var requestCtx = context.GetRequestContext(); + var upn = requestCtx.UserPrincipalName; - var userTenantId = principal.GetTenantId(); - var upn = principal.GetUserPrincipalName(); - - // Check authorization: either Global Admin OR Tenant Admin of the same tenant - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(upn); - var isTenantAdmin = tenantId.Equals(userTenantId, StringComparison.OrdinalIgnoreCase) && - await _tenantAdminsService.IsTenantAdminAsync(tenantId, upn); - - if (!isGlobalAdmin && !isTenantAdmin) + // Middleware (TenantAdminOrGA policy) already verified GA or TenantAdmin of own tenant. + // For non-GA: only allow access to own tenant. + if (!requestCtx.IsGlobalAdmin && !tenantId.Equals(requestCtx.TenantId, StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning($"User {upn} attempted to remove admin from tenant {tenantId} without authorization"); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); @@ -174,7 +155,7 @@ public class TenantAdminManagementFunction if (adminUpn.Equals(upn, StringComparison.OrdinalIgnoreCase)) { // Check if this is the last Admin-role member (only for non-Global-Admins) - if (!isGlobalAdmin) + if (!requestCtx.IsGlobalAdmin) { var members = await _tenantAdminsService.GetTenantAdminsAsync(tenantId); var adminCount = members.Count(m => m.IsEnabled && (m.Role == null || m.Role == AutopilotMonitor.Shared.Constants.TenantRoles.Admin)); @@ -219,17 +200,12 @@ public class TenantAdminManagementFunction FunctionContext context) { // Authentication enforced by PolicyEnforcementMiddleware - var principal = context.GetUser()!; + var requestCtx = context.GetRequestContext(); + var upn = requestCtx.UserPrincipalName; - var userTenantId = principal.GetTenantId(); - var upn = principal.GetUserPrincipalName(); - - // Check authorization: either Global Admin OR Tenant Admin of the same tenant - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(upn); - var isTenantAdmin = tenantId.Equals(userTenantId, StringComparison.OrdinalIgnoreCase) && - await _tenantAdminsService.IsTenantAdminAsync(tenantId, upn); - - if (!isGlobalAdmin && !isTenantAdmin) + // Middleware (TenantAdminOrGA policy) already verified GA or TenantAdmin of own tenant. + // For non-GA: only allow access to own tenant. + if (!requestCtx.IsGlobalAdmin && !tenantId.Equals(requestCtx.TenantId, StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning($"User {upn} attempted to disable admin for tenant {tenantId} without authorization"); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); @@ -270,17 +246,12 @@ public class TenantAdminManagementFunction FunctionContext context) { // Authentication enforced by PolicyEnforcementMiddleware - var principal = context.GetUser()!; + var requestCtx = context.GetRequestContext(); + var upn = requestCtx.UserPrincipalName; - var userTenantId = principal.GetTenantId(); - var upn = principal.GetUserPrincipalName(); - - // Check authorization: either Global Admin OR Tenant Admin of the same tenant - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(upn); - var isTenantAdmin = tenantId.Equals(userTenantId, StringComparison.OrdinalIgnoreCase) && - await _tenantAdminsService.IsTenantAdminAsync(tenantId, upn); - - if (!isGlobalAdmin && !isTenantAdmin) + // Middleware (TenantAdminOrGA policy) already verified GA or TenantAdmin of own tenant. + // For non-GA: only allow access to own tenant. + if (!requestCtx.IsGlobalAdmin && !tenantId.Equals(requestCtx.TenantId, StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning($"User {upn} attempted to enable admin for tenant {tenantId} without authorization"); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); @@ -320,17 +291,12 @@ public class TenantAdminManagementFunction FunctionContext context) { // Authentication enforced by PolicyEnforcementMiddleware - var principal = context.GetUser()!; + var requestCtx = context.GetRequestContext(); + var upn = requestCtx.UserPrincipalName; - var userTenantId = principal.GetTenantId(); - var upn = principal.GetUserPrincipalName(); - - // Check authorization: either Global Admin OR Tenant Admin of the same tenant - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(upn); - var isTenantAdmin = tenantId.Equals(userTenantId, StringComparison.OrdinalIgnoreCase) && - await _tenantAdminsService.IsTenantAdminAsync(tenantId, upn); - - if (!isGlobalAdmin && !isTenantAdmin) + // Middleware (TenantAdminOrGA policy) already verified GA or TenantAdmin of own tenant. + // For non-GA: only allow access to own tenant. + if (!requestCtx.IsGlobalAdmin && !tenantId.Equals(requestCtx.TenantId, StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning("User {Upn} attempted to update member permissions for tenant {TenantId} without authorization", upn, tenantId); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); @@ -349,7 +315,7 @@ public class TenantAdminManagementFunction // Prevent demoting yourself if you're the last Admin if (adminUpn.Equals(upn, StringComparison.OrdinalIgnoreCase) && body.Role != AutopilotMonitor.Shared.Constants.TenantRoles.Admin) { - if (!isGlobalAdmin) + if (!requestCtx.IsGlobalAdmin) { var members = await _tenantAdminsService.GetTenantAdminsAsync(tenantId); var adminCount = members.Count(m => m.IsEnabled && (m.Role == null || m.Role == AutopilotMonitor.Shared.Constants.TenantRoles.Admin)); diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Admin/TenantOffboardFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Admin/TenantOffboardFunction.cs index c26bf65e..3688a19b 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Admin/TenantOffboardFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Admin/TenantOffboardFunction.cs @@ -1,8 +1,6 @@ using System.Net; -using AutopilotMonitor.Functions.Extensions; using AutopilotMonitor.Functions.Helpers; using AutopilotMonitor.Functions.Security; -using AutopilotMonitor.Functions.Services; using AutopilotMonitor.Shared.DataAccess; using AutopilotMonitor.Shared; using Microsoft.AspNetCore.Authorization; @@ -20,19 +18,13 @@ namespace AutopilotMonitor.Functions.Functions.Admin; public class TenantOffboardFunction { private readonly ILogger _logger; - private readonly TenantAdminsService _tenantAdminsService; - private readonly GlobalAdminService _globalAdminService; private readonly IMaintenanceRepository _maintenanceRepo; public TenantOffboardFunction( ILogger logger, - TenantAdminsService tenantAdminsService, - GlobalAdminService globalAdminService, IMaintenanceRepository maintenanceRepo) { _logger = logger; - _tenantAdminsService = tenantAdminsService; - _globalAdminService = globalAdminService; _maintenanceRepo = maintenanceRepo; } @@ -50,17 +42,12 @@ public class TenantOffboardFunction FunctionContext context) { // Authentication enforced by PolicyEnforcementMiddleware - var principal = context.GetUser()!; + var requestCtx = context.GetRequestContext(); + var upn = requestCtx.UserPrincipalName; - var userTenantId = principal.GetTenantId(); - var upn = principal.GetUserPrincipalName(); - - // Only Tenant Admins of the same tenant OR Global Admins may offboard - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(upn); - var isTenantAdmin = tenantId.Equals(userTenantId, StringComparison.OrdinalIgnoreCase) && - await _tenantAdminsService.IsTenantAdminAsync(tenantId, upn); - - if (!isGlobalAdmin && !isTenantAdmin) + // Middleware (TenantAdminOrGA policy) already verified GA or TenantAdmin of own tenant. + // For non-GA: only allow access to own tenant. + if (!requestCtx.IsGlobalAdmin && !tenantId.Equals(requestCtx.TenantId, StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning($"User {upn} attempted to offboard tenant {tenantId} without authorization"); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/CreateBootstrapSessionFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/CreateBootstrapSessionFunction.cs index e2a96b21..31bc5943 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/CreateBootstrapSessionFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/CreateBootstrapSessionFunction.cs @@ -21,20 +21,17 @@ namespace AutopilotMonitor.Functions.Functions.Bootstrap { private readonly ILogger _logger; private readonly BootstrapSessionService _bootstrapService; - private readonly GlobalAdminService _globalAdminService; private readonly TenantConfigurationService _configService; private readonly IMaintenanceRepository _maintenanceRepo; public CreateBootstrapSessionFunction( ILogger logger, BootstrapSessionService bootstrapService, - GlobalAdminService globalAdminService, TenantConfigurationService configService, IMaintenanceRepository maintenanceRepo) { _logger = logger; _bootstrapService = bootstrapService; - _globalAdminService = globalAdminService; _configService = configService; _maintenanceRepo = maintenanceRepo; } @@ -46,8 +43,9 @@ namespace AutopilotMonitor.Functions.Functions.Bootstrap try { // Authentication + BootstrapManagerOrGA authorization enforced by PolicyEnforcementMiddleware - var authenticatedTenantId = TenantHelper.GetTenantId(req); - var userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); + var authenticatedTenantId = requestCtx.TenantId; + var userIdentifier = requestCtx.UserPrincipalName; // Read request body string body; @@ -66,15 +64,11 @@ namespace AutopilotMonitor.Functions.Functions.Bootstrap var tenantId = !string.IsNullOrEmpty(request.TenantId) ? request.TenantId : authenticatedTenantId; // Cross-tenant boundary check — only Global Admins may operate on other tenants - if (!string.Equals(authenticatedTenantId, tenantId, StringComparison.OrdinalIgnoreCase)) + if (!requestCtx.IsGlobalAdmin && !string.Equals(authenticatedTenantId, tenantId, StringComparison.OrdinalIgnoreCase)) { - var isGlobal = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - if (!isGlobal) - { - var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); - await forbidden.WriteAsJsonAsync(new { error = "Access denied: tenant mismatch" }); - return forbidden; - } + var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); + await forbidden.WriteAsJsonAsync(new { error = "Access denied: tenant mismatch" }); + return forbidden; } // Check if bootstrap token feature is enabled for this tenant diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/ListBootstrapSessionsFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/ListBootstrapSessionsFunction.cs index 942d3112..95c396e6 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/ListBootstrapSessionsFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/ListBootstrapSessionsFunction.cs @@ -19,18 +19,15 @@ namespace AutopilotMonitor.Functions.Functions.Bootstrap { private readonly ILogger _logger; private readonly BootstrapSessionService _bootstrapService; - private readonly GlobalAdminService _globalAdminService; private readonly TenantConfigurationService _configService; public ListBootstrapSessionsFunction( ILogger logger, BootstrapSessionService bootstrapService, - GlobalAdminService globalAdminService, TenantConfigurationService configService) { _logger = logger; _bootstrapService = bootstrapService; - _globalAdminService = globalAdminService; _configService = configService; } @@ -41,21 +38,18 @@ namespace AutopilotMonitor.Functions.Functions.Bootstrap try { // Authentication + BootstrapManagerOrGA authorization enforced by PolicyEnforcementMiddleware - var authenticatedTenantId = TenantHelper.GetTenantId(req); - var userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); + var authenticatedTenantId = requestCtx.TenantId; + var userIdentifier = requestCtx.UserPrincipalName; var tenantId = req.Query["tenantId"] ?? authenticatedTenantId; // Cross-tenant boundary check — only Global Admins may operate on other tenants - if (!string.Equals(authenticatedTenantId, tenantId, StringComparison.OrdinalIgnoreCase)) + if (!requestCtx.IsGlobalAdmin && !string.Equals(authenticatedTenantId, tenantId, StringComparison.OrdinalIgnoreCase)) { - var isGlobal = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - if (!isGlobal) - { - var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); - await forbidden.WriteAsJsonAsync(new { error = "Access denied: tenant mismatch" }); - return forbidden; - } + var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); + await forbidden.WriteAsJsonAsync(new { error = "Access denied: tenant mismatch" }); + return forbidden; } // Check if bootstrap token feature is enabled for this tenant diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/RevokeBootstrapSessionFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/RevokeBootstrapSessionFunction.cs index a47a8b52..a35634d5 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/RevokeBootstrapSessionFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Bootstrap/RevokeBootstrapSessionFunction.cs @@ -18,20 +18,17 @@ namespace AutopilotMonitor.Functions.Functions.Bootstrap { private readonly ILogger _logger; private readonly BootstrapSessionService _bootstrapService; - private readonly GlobalAdminService _globalAdminService; private readonly TenantConfigurationService _configService; private readonly IMaintenanceRepository _maintenanceRepo; public RevokeBootstrapSessionFunction( ILogger logger, BootstrapSessionService bootstrapService, - GlobalAdminService globalAdminService, TenantConfigurationService configService, IMaintenanceRepository maintenanceRepo) { _logger = logger; _bootstrapService = bootstrapService; - _globalAdminService = globalAdminService; _configService = configService; _maintenanceRepo = maintenanceRepo; } @@ -44,21 +41,18 @@ namespace AutopilotMonitor.Functions.Functions.Bootstrap try { // Authentication + BootstrapManagerOrGA authorization enforced by PolicyEnforcementMiddleware - var authenticatedTenantId = TenantHelper.GetTenantId(req); - var userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); + var authenticatedTenantId = requestCtx.TenantId; + var userIdentifier = requestCtx.UserPrincipalName; var tenantId = req.Query["tenantId"] ?? authenticatedTenantId; // Cross-tenant boundary check — only Global Admins may operate on other tenants - if (!string.Equals(authenticatedTenantId, tenantId, StringComparison.OrdinalIgnoreCase)) + if (!requestCtx.IsGlobalAdmin && !string.Equals(authenticatedTenantId, tenantId, StringComparison.OrdinalIgnoreCase)) { - var isGlobal = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - if (!isGlobal) - { - var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); - await forbidden.WriteAsJsonAsync(new { error = "Access denied: tenant mismatch" }); - return forbidden; - } + var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); + await forbidden.WriteAsJsonAsync(new { error = "Access denied: tenant mismatch" }); + return forbidden; } // Check if bootstrap token feature is enabled for this tenant diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetTenantConfigurationFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetTenantConfigurationFunction.cs index 46f0a4e4..08b1d0fe 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetTenantConfigurationFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Config/GetTenantConfigurationFunction.cs @@ -13,16 +13,13 @@ namespace AutopilotMonitor.Functions.Functions.Config { private readonly ILogger _logger; private readonly TenantConfigurationService _configService; - private readonly GlobalAdminService _globalAdminService; public GetTenantConfigurationFunction( ILogger logger, - TenantConfigurationService configService, - GlobalAdminService globalAdminService) + TenantConfigurationService configService) { _logger = logger; _configService = configService; - _globalAdminService = globalAdminService; } [Function("GetTenantConfiguration")] @@ -33,25 +30,21 @@ namespace AutopilotMonitor.Functions.Functions.Config try { // Authentication + MemberRead authorization enforced by PolicyEnforcementMiddleware - string authenticatedTenantId = TenantHelper.GetTenantId(req); - string userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); + var userIdentifier = requestCtx.UserPrincipalName; // Validate tenant access: cross-tenant only for Global Admins - if (!string.Equals(authenticatedTenantId, tenantId, StringComparison.OrdinalIgnoreCase)) + if (!requestCtx.IsGlobalAdmin && !string.Equals(requestCtx.TenantId, tenantId, StringComparison.OrdinalIgnoreCase)) { - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - if (!isGlobalAdmin) + _logger.LogWarning("User {User} from tenant {AuthTenant} attempted to access configuration for tenant {TargetTenant}", + userIdentifier, requestCtx.TenantId, tenantId); + var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); + await forbiddenResponse.WriteAsJsonAsync(new { - _logger.LogWarning("User {User} from tenant {AuthTenant} attempted to access configuration for tenant {TargetTenant}", - userIdentifier, authenticatedTenantId, tenantId); - var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); - await forbiddenResponse.WriteAsJsonAsync(new - { - success = false, - message = "Access denied. You can only access your own tenant's configuration." - }); - return forbiddenResponse; - } + success = false, + message = "Access denied. You can only access your own tenant's configuration." + }); + return forbiddenResponse; } _logger.LogInformation($"GetTenantConfiguration: {tenantId} by user {userIdentifier}"); diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Config/UpdateTenantConfigurationFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Config/UpdateTenantConfigurationFunction.cs index 41b4e934..be837086 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Config/UpdateTenantConfigurationFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Config/UpdateTenantConfigurationFunction.cs @@ -18,18 +18,15 @@ namespace AutopilotMonitor.Functions.Functions.Config { private readonly ILogger _logger; private readonly TenantConfigurationService _configService; - private readonly GlobalAdminService _globalAdminService; private readonly IMaintenanceRepository _maintenanceRepo; public UpdateTenantConfigurationFunction( ILogger logger, TenantConfigurationService configService, - GlobalAdminService globalAdminService, IMaintenanceRepository maintenanceRepo) { _logger = logger; _configService = configService; - _globalAdminService = globalAdminService; _maintenanceRepo = maintenanceRepo; } @@ -41,17 +38,14 @@ namespace AutopilotMonitor.Functions.Functions.Config try { // Authentication + TenantAdminOrGA authorization enforced by PolicyEnforcementMiddleware - string authenticatedTenantId = TenantHelper.GetTenantId(req); - string userIdentifier = TenantHelper.GetUserIdentifier(req); - - // GA check needed for: cross-tenant bypass + protected field filtering - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); + var requestCtx = req.GetRequestContext(); + var userIdentifier = requestCtx.UserPrincipalName; // Validate tenant access: cross-tenant only for Global Admins - if (!isGlobalAdmin && !string.Equals(authenticatedTenantId, tenantId, StringComparison.OrdinalIgnoreCase)) + if (!requestCtx.IsGlobalAdmin && !string.Equals(requestCtx.TenantId, tenantId, StringComparison.OrdinalIgnoreCase)) { _logger.LogWarning("User {User} from tenant {AuthTenant} attempted to update configuration for tenant {TargetTenant}", - userIdentifier, authenticatedTenantId, tenantId); + userIdentifier, requestCtx.TenantId, tenantId); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); await forbiddenResponse.WriteAsJsonAsync(new { @@ -90,7 +84,7 @@ namespace AutopilotMonitor.Functions.Functions.Config // Protect GA-only fields from non-Global-Admin callers var existingConfig = await _configService.GetConfigurationAsync(tenantId); - if (!isGlobalAdmin) + if (!requestCtx.IsGlobalAdmin) { if (config.AllowInsecureAgentRequests != existingConfig.AllowInsecureAgentRequests || config.BootstrapTokenEnabled != existingConfig.BootstrapTokenEnabled || diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Diagnostics/DiagnosticsDownloadFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Diagnostics/DiagnosticsDownloadFunction.cs index 3c436a5f..3749e88a 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Diagnostics/DiagnosticsDownloadFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Diagnostics/DiagnosticsDownloadFunction.cs @@ -16,16 +16,13 @@ namespace AutopilotMonitor.Functions.Functions.Diagnostics { private readonly ILogger _logger; private readonly TenantConfigurationService _configService; - private readonly GlobalAdminService _globalAdminService; public DiagnosticsDownloadFunction( ILogger logger, - TenantConfigurationService configService, - GlobalAdminService globalAdminService) + TenantConfigurationService configService) { _logger = logger; _configService = configService; - _globalAdminService = globalAdminService; } [Function("DiagnosticsDownloadUrl")] @@ -35,8 +32,7 @@ namespace AutopilotMonitor.Functions.Functions.Diagnostics try { // Authentication + MemberRead authorization enforced by PolicyEnforcementMiddleware - var userTenantId = TenantHelper.GetTenantId(req); - var userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); var query = HttpUtility.ParseQueryString(req.Url.Query); var tenantId = query["tenantId"]; @@ -50,15 +46,11 @@ namespace AutopilotMonitor.Functions.Functions.Diagnostics } // Validate tenant access - if (tenantId != userTenantId) + if (!requestCtx.IsGlobalAdmin && tenantId != requestCtx.TenantId) { - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - if (!isGlobalAdmin) - { - var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); - await forbiddenResponse.WriteAsJsonAsync(new { success = false, message = "Access denied." }); - return forbiddenResponse; - } + var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); + await forbiddenResponse.WriteAsJsonAsync(new { success = false, message = "Access denied." }); + return forbiddenResponse; } // Validate blob name (prevent path traversal, double-encoding, and null byte attacks) diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Infrastructure/SignalRAddToGroupFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Infrastructure/SignalRAddToGroupFunction.cs index 0ab0a2e4..29f932d4 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Infrastructure/SignalRAddToGroupFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Infrastructure/SignalRAddToGroupFunction.cs @@ -1,6 +1,5 @@ using System.Net; using AutopilotMonitor.Functions.Helpers; -using AutopilotMonitor.Functions.Services; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Azure.Functions.Worker.Extensions.SignalRService; @@ -12,14 +11,11 @@ namespace AutopilotMonitor.Functions.Functions.Infrastructure public class SignalRAddToGroupFunction { private readonly ILogger _logger; - private readonly GlobalAdminService _globalAdminService; public SignalRAddToGroupFunction( - ILogger logger, - GlobalAdminService globalAdminService) + ILogger logger) { _logger = logger; - _globalAdminService = globalAdminService; } [Function("AddToGroup")] @@ -49,9 +45,10 @@ namespace AutopilotMonitor.Functions.Functions.Infrastructure return new AddToGroupOutput { HttpResponse = errorResponse }; } - // Get user's tenant ID from JWT - var userTenantId = TenantHelper.GetTenantId(req); - var userEmail = TenantHelper.GetUserIdentifier(req); + // Get user's tenant ID from RequestContext + var requestCtx = req.GetRequestContext(); + var userTenantId = requestCtx.TenantId; + var userEmail = requestCtx.UserPrincipalName; // Validate tenant access // Group names are in format: "tenant-{tenantId}", "session-{tenantId}-{sessionId}", or "global-admins" @@ -60,8 +57,7 @@ namespace AutopilotMonitor.Functions.Functions.Infrastructure // Explicit validation for the global-admins group if (request.GroupName == "global-admins") { - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userEmail); - if (!isGlobalAdmin) + if (!requestCtx.IsGlobalAdmin) { _logger.LogWarning($"User {userEmail} (tenant {userTenantId}) attempted to join global-admins group without being a Global Admin"); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); @@ -85,9 +81,7 @@ namespace AutopilotMonitor.Functions.Functions.Infrastructure if (requestedTenantId != userTenantId) { // Check if user is Global Admin (they can join any tenant's group) - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userEmail); - - if (!isGlobalAdmin) + if (!requestCtx.IsGlobalAdmin) { _logger.LogWarning($"User {userEmail} (tenant {userTenantId}) attempted to join group for tenant {requestedTenantId}"); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Infrastructure/SignalRRemoveFromGroupFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Infrastructure/SignalRRemoveFromGroupFunction.cs index 4b261129..7378423a 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Infrastructure/SignalRRemoveFromGroupFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Infrastructure/SignalRRemoveFromGroupFunction.cs @@ -1,6 +1,5 @@ using System.Net; using AutopilotMonitor.Functions.Helpers; -using AutopilotMonitor.Functions.Services; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Azure.Functions.Worker.Extensions.SignalRService; @@ -12,14 +11,11 @@ namespace AutopilotMonitor.Functions.Functions.Infrastructure public class SignalRRemoveFromGroupFunction { private readonly ILogger _logger; - private readonly GlobalAdminService _globalAdminService; public SignalRRemoveFromGroupFunction( - ILogger logger, - GlobalAdminService globalAdminService) + ILogger logger) { _logger = logger; - _globalAdminService = globalAdminService; } [Function("RemoveFromGroup")] @@ -49,9 +45,10 @@ namespace AutopilotMonitor.Functions.Functions.Infrastructure return new RemoveFromGroupOutput { HttpResponse = errorResponse }; } - // Get user's tenant ID from JWT - var userTenantId = TenantHelper.GetTenantId(req); - var userEmail = TenantHelper.GetUserIdentifier(req); + // Get user's tenant ID from RequestContext + var requestCtx = req.GetRequestContext(); + var userTenantId = requestCtx.TenantId; + var userEmail = requestCtx.UserPrincipalName; // Validate tenant access (same logic as AddToGroup) // Group names are in format: "tenant-{tenantId}", "session-{tenantId}-{sessionId}", or "global-admins" @@ -60,8 +57,7 @@ namespace AutopilotMonitor.Functions.Functions.Infrastructure // Explicit validation for the global-admins group if (request.GroupName == "global-admins") { - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userEmail); - if (!isGlobalAdmin) + if (!requestCtx.IsGlobalAdmin) { _logger.LogWarning($"User {userEmail} (tenant {userTenantId}) attempted to leave global-admins group without being a Global Admin"); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); @@ -85,9 +81,7 @@ namespace AutopilotMonitor.Functions.Functions.Infrastructure if (requestedTenantId != userTenantId) { // Check if user is Global Admin (they can leave any tenant's group) - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userEmail); - - if (!isGlobalAdmin) + if (!requestCtx.IsGlobalAdmin) { _logger.LogWarning($"User {userEmail} (tenant {userTenantId}) attempted to leave group for tenant {requestedTenantId}"); var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Progress/ProgressPortalFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Progress/ProgressPortalFunction.cs index 2f1abab6..0dc91043 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Progress/ProgressPortalFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Progress/ProgressPortalFunction.cs @@ -1,7 +1,6 @@ using System.Net; using System.Web; using AutopilotMonitor.Functions.Helpers; -using AutopilotMonitor.Functions.Services; using AutopilotMonitor.Shared.DataAccess; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; @@ -18,16 +17,13 @@ public class ProgressPortalFunction { private readonly ILogger _logger; private readonly ISessionRepository _sessionRepo; - private readonly GlobalAdminService _globalAdminService; public ProgressPortalFunction( ILogger logger, - ISessionRepository sessionRepo, - GlobalAdminService globalAdminService) + ISessionRepository sessionRepo) { _logger = logger; _sessionRepo = sessionRepo; - _globalAdminService = globalAdminService; } /// @@ -43,7 +39,7 @@ public class ProgressPortalFunction try { // Authentication + AuthenticatedUser authorization enforced by PolicyEnforcementMiddleware - var tenantId = TenantHelper.GetTenantId(req); + var tenantId = req.GetRequestContext().TenantId; _logger.LogInformation("ProgressGetSessions: Fetching sessions for tenant {TenantId}", tenantId); @@ -96,8 +92,8 @@ public class ProgressPortalFunction try { // Authentication + AuthenticatedUser authorization enforced by PolicyEnforcementMiddleware - var userTenantId = TenantHelper.GetTenantId(req); - var userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); + var userIdentifier = requestCtx.UserPrincipalName; var query = HttpUtility.ParseQueryString(req.Url.Query); var requestedTenantId = query["tenantId"]; @@ -117,23 +113,22 @@ public class ProgressPortalFunction } // Cross-tenant access only for Global Admins - if (requestedTenantId != userTenantId) + if (!requestCtx.IsGlobalAdmin && requestedTenantId != requestCtx.TenantId) { - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - if (!isGlobalAdmin) + var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); + await forbiddenResponse.WriteAsJsonAsync(new { - var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); - await forbiddenResponse.WriteAsJsonAsync(new - { - success = false, - message = "Access denied. You can only view events for sessions in your own tenant.", - sessionId = sessionId, - count = 0, - events = Array.Empty() - }); - return forbiddenResponse; - } + success = false, + message = "Access denied. You can only view events for sessions in your own tenant.", + sessionId = sessionId, + count = 0, + events = Array.Empty() + }); + return forbiddenResponse; + } + if (requestCtx.IsGlobalAdmin && requestedTenantId != requestCtx.TenantId) + { _logger.LogInformation("{SessionPrefix} Global Admin {User} accessing cross-tenant progress events (tenant: {TenantId})", sessionPrefix, userIdentifier, requestedTenantId); } diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Reports/SubmitSessionReportFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Reports/SubmitSessionReportFunction.cs index 2846a200..21b496a6 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Reports/SubmitSessionReportFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Reports/SubmitSessionReportFunction.cs @@ -14,7 +14,6 @@ namespace AutopilotMonitor.Functions.Functions.Reports private readonly ILogger _logger; private readonly SessionReportService _sessionReportService; private readonly IMaintenanceRepository _maintenanceRepo; - private readonly GlobalAdminService _globalAdminService; private readonly TelegramNotificationService _telegramNotificationService; private readonly GlobalNotificationService _globalNotificationService; @@ -22,14 +21,12 @@ namespace AutopilotMonitor.Functions.Functions.Reports ILogger logger, SessionReportService sessionReportService, IMaintenanceRepository maintenanceRepo, - GlobalAdminService globalAdminService, TelegramNotificationService telegramNotificationService, GlobalNotificationService globalNotificationService) { _logger = logger; _sessionReportService = sessionReportService; _maintenanceRepo = maintenanceRepo; - _globalAdminService = globalAdminService; _telegramNotificationService = telegramNotificationService; _globalNotificationService = globalNotificationService; } @@ -44,11 +41,9 @@ namespace AutopilotMonitor.Functions.Functions.Reports try { // Authentication + TenantAdminOrGA authorization enforced by PolicyEnforcementMiddleware - string tenantId = TenantHelper.GetTenantId(req); - string userIdentifier = TenantHelper.GetUserIdentifier(req); - - // Still needed: GA check for audit log skip logic - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); + var requestCtx = req.GetRequestContext(); + var tenantId = requestCtx.TenantId; + var userIdentifier = requestCtx.UserPrincipalName; // Request body size limit (1 MB) if (req.Headers.TryGetValues("Content-Length", out var clValues) @@ -84,7 +79,7 @@ namespace AutopilotMonitor.Functions.Functions.Reports var metadata = await _sessionReportService.SubmitReportAsync(request, userIdentifier); // Log audit entry — skip for Global Admins - if (!isGlobalAdmin) + if (!requestCtx.IsGlobalAdmin) { await _maintenanceRepo.LogAuditEntryAsync( request.TenantId, diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Rules/GetRuleResultsFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Rules/GetRuleResultsFunction.cs index 5c897d42..7298ad1d 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Rules/GetRuleResultsFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Rules/GetRuleResultsFunction.cs @@ -21,22 +21,19 @@ namespace AutopilotMonitor.Functions.Functions.Rules private readonly IMaintenanceRepository _maintenanceRepo; private readonly ISessionRepository _sessionRepo; private readonly AnalyzeRuleService _analyzeRuleService; - private readonly GlobalAdminService _globalAdminService; public GetRuleResultsFunction( ILogger logger, IRuleRepository ruleRepo, IMaintenanceRepository maintenanceRepo, ISessionRepository sessionRepo, - AnalyzeRuleService analyzeRuleService, - GlobalAdminService globalAdminService) + AnalyzeRuleService analyzeRuleService) { _logger = logger; _ruleRepo = ruleRepo; _maintenanceRepo = maintenanceRepo; _sessionRepo = sessionRepo; _analyzeRuleService = analyzeRuleService; - _globalAdminService = globalAdminService; } [Function("GetRuleResults")] @@ -45,25 +42,24 @@ namespace AutopilotMonitor.Functions.Functions.Rules string sessionId) { // Authentication + MemberRead authorization enforced by PolicyEnforcementMiddleware - var userTenantId = TenantHelper.GetTenantId(req); - var userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); + var userIdentifier = requestCtx.UserPrincipalName; // Resolve effective tenant ID: use query param if provided, fall back to JWT tenant var query = HttpUtility.ParseQueryString(req.Url.Query); var requestedTenantId = query["tenantId"]; - var effectiveTenantId = string.IsNullOrEmpty(requestedTenantId) ? userTenantId : requestedTenantId; + var effectiveTenantId = string.IsNullOrEmpty(requestedTenantId) ? requestCtx.TenantId : requestedTenantId; // Cross-tenant access requires Global Admin - if (effectiveTenantId != userTenantId) + if (!requestCtx.IsGlobalAdmin && effectiveTenantId != requestCtx.TenantId) { - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - if (!isGlobalAdmin) - { - var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); - await forbidden.WriteAsJsonAsync(new { success = false, message = "Access denied. You can only view analysis results for your own tenant." }); - return forbidden; - } + var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); + await forbidden.WriteAsJsonAsync(new { success = false, message = "Access denied. You can only view analysis results for your own tenant." }); + return forbidden; + } + if (requestCtx.IsGlobalAdmin && effectiveTenantId != requestCtx.TenantId) + { _logger.LogInformation($"Global Admin {userIdentifier} accessing cross-tenant analysis results (tenant: {effectiveTenantId})"); } diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetAllSessionsFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetAllSessionsFunction.cs index 2bed50a2..a586e2c0 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetAllSessionsFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetAllSessionsFunction.cs @@ -55,8 +55,7 @@ namespace AutopilotMonitor.Functions.Functions.Sessions page = await _sessionRepo.GetAllSessionsAsync(maxResults: 100, cursor: cursor); } - var response = req.CreateResponse(HttpStatusCode.OK); - await response.WriteAsJsonAsync(new + return await req.OkAsync(new { success = true, count = page.Sessions.Count, @@ -64,8 +63,6 @@ namespace AutopilotMonitor.Functions.Functions.Sessions cursor = page.Cursor, sessions = page.Sessions }); - - return response; } catch (Exception ex) { diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionEventsFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionEventsFunction.cs index d6d2262d..e86f90a5 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionEventsFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionEventsFunction.cs @@ -1,7 +1,6 @@ using System.Net; using System.Web; using AutopilotMonitor.Functions.Helpers; -using AutopilotMonitor.Functions.Services; using AutopilotMonitor.Shared.DataAccess; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; @@ -13,16 +12,13 @@ namespace AutopilotMonitor.Functions.Functions.Sessions { private readonly ILogger _logger; private readonly ISessionRepository _sessionRepo; - private readonly GlobalAdminService _globalAdminService; public GetSessionEventsFunction( ILogger logger, - ISessionRepository sessionRepo, - GlobalAdminService globalAdminService) + ISessionRepository sessionRepo) { _logger = logger; _sessionRepo = sessionRepo; - _globalAdminService = globalAdminService; } [Function("GetSessionEvents")] @@ -45,8 +41,8 @@ namespace AutopilotMonitor.Functions.Functions.Sessions // Authentication + MemberRead authorization enforced by PolicyEnforcementMiddleware // Get user's tenant ID and identifier from JWT - var userTenantId = TenantHelper.GetTenantId(req); - var userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); + var userIdentifier = requestCtx.UserPrincipalName; // Get requested tenant ID from query parameter var query = HttpUtility.ParseQueryString(req.Url.Query); @@ -68,43 +64,35 @@ namespace AutopilotMonitor.Functions.Functions.Sessions } // Validate tenant access: user must either own the tenant or be Global Admin - if (requestedTenantId != userTenantId) + if (!requestCtx.IsGlobalAdmin && requestedTenantId != requestCtx.TenantId) { - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - - if (!isGlobalAdmin) + _logger.LogWarning($"{sessionPrefix} User {userIdentifier} (tenant {requestCtx.TenantId}) attempted to access session events for tenant {requestedTenantId}"); + var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); + await forbiddenResponse.WriteAsJsonAsync(new { - _logger.LogWarning($"{sessionPrefix} User {userIdentifier} (tenant {userTenantId}) attempted to access session events for tenant {requestedTenantId}"); - var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); - await forbiddenResponse.WriteAsJsonAsync(new - { - success = false, - message = "Access denied. You can only view events for sessions in your own tenant.", - sessionId = sessionId, - count = 0, - events = Array.Empty() - }); - return forbiddenResponse; - } - else - { - _logger.LogInformation($"{sessionPrefix} Global Admin {userIdentifier} accessing cross-tenant session events (tenant: {requestedTenantId})"); - } + success = false, + message = "Access denied. You can only view events for sessions in your own tenant.", + sessionId = sessionId, + count = 0, + events = Array.Empty() + }); + return forbiddenResponse; + } + else if (requestCtx.IsGlobalAdmin && requestedTenantId != requestCtx.TenantId) + { + _logger.LogInformation($"{sessionPrefix} Global Admin {userIdentifier} accessing cross-tenant session events (tenant: {requestedTenantId})"); } // Get events from storage using the requested tenant ID var events = await _sessionRepo.GetSessionEventsAsync(requestedTenantId, sessionId); - var response = req.CreateResponse(HttpStatusCode.OK); - await response.WriteAsJsonAsync(new + return await req.OkAsync(new { success = true, sessionId = sessionId, count = events.Count, events = events }); - - return response; } catch (Exception ex) { diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionFunction.cs index a3f823c8..b87721eb 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionFunction.cs @@ -1,7 +1,6 @@ using System.Net; using System.Web; using AutopilotMonitor.Functions.Helpers; -using AutopilotMonitor.Functions.Services; using AutopilotMonitor.Shared.DataAccess; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; @@ -13,16 +12,13 @@ namespace AutopilotMonitor.Functions.Functions.Sessions { private readonly ILogger _logger; private readonly ISessionRepository _sessionRepo; - private readonly GlobalAdminService _globalAdminService; public GetSessionFunction( ILogger logger, - ISessionRepository sessionRepo, - GlobalAdminService globalAdminService) + ISessionRepository sessionRepo) { _logger = logger; _sessionRepo = sessionRepo; - _globalAdminService = globalAdminService; } [Function("GetSession")] @@ -46,11 +42,11 @@ namespace AutopilotMonitor.Functions.Functions.Sessions try { // Authentication + MemberRead authorization enforced by PolicyEnforcementMiddleware - var userTenantId = TenantHelper.GetTenantId(req); - var userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); + var userIdentifier = requestCtx.UserPrincipalName; var query = HttpUtility.ParseQueryString(req.Url.Query); var requestedTenantId = query["tenantId"]; - var effectiveTenantId = string.IsNullOrWhiteSpace(requestedTenantId) ? userTenantId : requestedTenantId; + var effectiveTenantId = string.IsNullOrWhiteSpace(requestedTenantId) ? requestCtx.TenantId : requestedTenantId; if (string.IsNullOrWhiteSpace(effectiveTenantId)) { @@ -63,20 +59,16 @@ namespace AutopilotMonitor.Functions.Functions.Sessions return badRequest; } - if (!string.Equals(effectiveTenantId, userTenantId, StringComparison.OrdinalIgnoreCase)) + if (!requestCtx.IsGlobalAdmin && !string.Equals(effectiveTenantId, requestCtx.TenantId, StringComparison.OrdinalIgnoreCase)) { - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - if (!isGlobalAdmin) + _logger.LogWarning($"{sessionPrefix} User {userIdentifier} (tenant {requestCtx.TenantId}) attempted to access session in tenant {effectiveTenantId}"); + var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); + await forbiddenResponse.WriteAsJsonAsync(new { - _logger.LogWarning($"{sessionPrefix} User {userIdentifier} (tenant {userTenantId}) attempted to access session in tenant {effectiveTenantId}"); - var forbiddenResponse = req.CreateResponse(HttpStatusCode.Forbidden); - await forbiddenResponse.WriteAsJsonAsync(new - { - success = false, - message = "Access denied. You can only view sessions for your own tenant." - }); - return forbiddenResponse; - } + success = false, + message = "Access denied. You can only view sessions for your own tenant." + }); + return forbiddenResponse; } var session = await _sessionRepo.GetSessionAsync(effectiveTenantId, sessionId); @@ -92,13 +84,11 @@ namespace AutopilotMonitor.Functions.Functions.Sessions return notFound; } - var response = req.CreateResponse(HttpStatusCode.OK); - await response.WriteAsJsonAsync(new + return await req.OkAsync(new { success = true, session }); - return response; } catch (Exception ex) { diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionsFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionsFunction.cs index 979ca08d..354d5c5d 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionsFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/GetSessionsFunction.cs @@ -35,8 +35,7 @@ namespace AutopilotMonitor.Functions.Functions.Sessions var page = await _sessionRepo.GetSessionsAsync(tenantId, maxResults: 100, cursor: cursor); - var response = req.CreateResponse(HttpStatusCode.OK); - await response.WriteAsJsonAsync(new + return await req.OkAsync(new { success = true, count = page.Sessions.Count, @@ -44,8 +43,6 @@ namespace AutopilotMonitor.Functions.Functions.Sessions cursor = page.Cursor, sessions = page.Sessions }); - - return response; } catch (Exception ex) { diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsByCveFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsByCveFunction.cs index bb022558..4c8d0808 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsByCveFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsByCveFunction.cs @@ -58,14 +58,12 @@ public class SearchSessionsByCveFunction var sessions = await _sessionRepo.SearchSessionsByCveAsync(tenantId, cveId, minCvssScore, overallRisk, limit); - var response = req.CreateResponse(HttpStatusCode.OK); - await response.WriteAsJsonAsync(new + return await req.OkAsync(new { success = true, count = sessions.Count, sessions }); - return response; } catch (Exception ex) { diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsByEventFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsByEventFunction.cs index a18acb12..02833160 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsByEventFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsByEventFunction.cs @@ -56,14 +56,12 @@ public class SearchSessionsByEventFunction var sessions = await _sessionRepo.SearchSessionsByEventAsync(tenantId, eventType, null, null, null, limit); - var response = req.CreateResponse(HttpStatusCode.OK); - await response.WriteAsJsonAsync(new + return await req.OkAsync(new { success = true, count = sessions.Count, sessions }); - return response; } catch (Exception ex) { diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsFunction.cs index 88153032..e8d22ef0 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Sessions/SearchSessionsFunction.cs @@ -84,14 +84,12 @@ public class SearchSessionsFunction var sessions = await _sessionRepo.SearchSessionsAsync(tenantId, filter); - var response = req.CreateResponse(HttpStatusCode.OK); - await response.WriteAsJsonAsync(new + return await req.OkAsync(new { success = true, count = sessions.Count, sessions }); - return response; } catch (Exception ex) { diff --git a/src/Backend/AutopilotMonitor.Functions/Functions/Vulnerability/GetVulnerabilityReportFunction.cs b/src/Backend/AutopilotMonitor.Functions/Functions/Vulnerability/GetVulnerabilityReportFunction.cs index 57726098..a07245c0 100644 --- a/src/Backend/AutopilotMonitor.Functions/Functions/Vulnerability/GetVulnerabilityReportFunction.cs +++ b/src/Backend/AutopilotMonitor.Functions/Functions/Vulnerability/GetVulnerabilityReportFunction.cs @@ -1,7 +1,6 @@ using System.Net; using System.Web; using AutopilotMonitor.Functions.Helpers; -using AutopilotMonitor.Functions.Services; using AutopilotMonitor.Functions.Services.Vulnerability; using AutopilotMonitor.Shared; using AutopilotMonitor.Shared.DataAccess; @@ -23,20 +22,17 @@ namespace AutopilotMonitor.Functions.Functions.Vulnerability private readonly ILogger _logger; private readonly IVulnerabilityRepository _vulnRepo; private readonly ISessionRepository _sessionRepo; - private readonly GlobalAdminService _globalAdminService; private readonly VulnerabilityCorrelationService _correlationService; public GetVulnerabilityReportFunction( ILogger logger, IVulnerabilityRepository vulnRepo, ISessionRepository sessionRepo, - GlobalAdminService globalAdminService, VulnerabilityCorrelationService correlationService) { _logger = logger; _vulnRepo = vulnRepo; _sessionRepo = sessionRepo; - _globalAdminService = globalAdminService; _correlationService = correlationService; } @@ -46,25 +42,24 @@ namespace AutopilotMonitor.Functions.Functions.Vulnerability string sessionId) { // Authentication + MemberRead authorization enforced by PolicyEnforcementMiddleware - var userTenantId = TenantHelper.GetTenantId(req); - var userIdentifier = TenantHelper.GetUserIdentifier(req); + var requestCtx = req.GetRequestContext(); + var userIdentifier = requestCtx.UserPrincipalName; // Resolve effective tenant ID: use query param if provided, fall back to JWT tenant var query = HttpUtility.ParseQueryString(req.Url.Query); var requestedTenantId = query["tenantId"]; - var effectiveTenantId = string.IsNullOrEmpty(requestedTenantId) ? userTenantId : requestedTenantId; + var effectiveTenantId = string.IsNullOrEmpty(requestedTenantId) ? requestCtx.TenantId : requestedTenantId; // Cross-tenant access requires Global Admin - if (effectiveTenantId != userTenantId) + if (!requestCtx.IsGlobalAdmin && effectiveTenantId != requestCtx.TenantId) { - var isGlobalAdmin = await _globalAdminService.IsGlobalAdminAsync(userIdentifier); - if (!isGlobalAdmin) - { - var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); - await forbidden.WriteAsJsonAsync(new { success = false, message = "Access denied. You can only view vulnerability reports for your own tenant." }); - return forbidden; - } + var forbidden = req.CreateResponse(HttpStatusCode.Forbidden); + await forbidden.WriteAsJsonAsync(new { success = false, message = "Access denied. You can only view vulnerability reports for your own tenant." }); + return forbidden; + } + if (requestCtx.IsGlobalAdmin && effectiveTenantId != requestCtx.TenantId) + { _logger.LogInformation("Global Admin {User} accessing cross-tenant vulnerability report (tenant: {TenantId})", userIdentifier, effectiveTenantId); } diff --git a/src/Backend/AutopilotMonitor.Functions/Helpers/RequestContext.cs b/src/Backend/AutopilotMonitor.Functions/Helpers/RequestContext.cs new file mode 100644 index 00000000..2e49ff57 --- /dev/null +++ b/src/Backend/AutopilotMonitor.Functions/Helpers/RequestContext.cs @@ -0,0 +1,61 @@ +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; + +namespace AutopilotMonitor.Functions.Helpers; + +/// +/// Resolved request context populated by PolicyEnforcementMiddleware after authentication and policy evaluation. +/// Eliminates redundant IsGlobalAdminAsync / IsTenantAdminAsync service calls in function handlers. +/// Retrieved via req.GetRequestContext() or context.GetRequestContext(). +/// +public sealed record RequestContext +{ + internal const string ItemsKey = "RequestContext"; + + /// The user's Azure AD tenant ID (from JWT tid claim). + public string TenantId { get; init; } = string.Empty; + + /// The user's UPN (from JWT upn/preferred_username claim). + public string UserPrincipalName { get; init; } = string.Empty; + + /// True if the user is a Global Admin of the platform. + public bool IsGlobalAdmin { get; init; } + + /// True if the user is a Tenant Admin of their own tenant. + public bool IsTenantAdmin { get; init; } + + /// The resolved role string (e.g. "GlobalAdmin", "Admin", "Operator", "Viewer"). + public string UserRole { get; init; } = string.Empty; +} + +/// +/// Extension methods for accessing the resolved RequestContext. +/// +public static class RequestContextExtensions +{ + /// + /// Gets the resolved RequestContext from FunctionContext.Items. + /// Populated by PolicyEnforcementMiddleware for authenticated requests. + /// Returns an empty context (all defaults) for device/anonymous routes. + /// + public static RequestContext GetRequestContext(this FunctionContext context) + { + if (context.Items.TryGetValue(RequestContext.ItemsKey, out var ctx) && ctx is RequestContext requestCtx) + return requestCtx; + return new RequestContext(); + } + + /// + /// Gets the resolved RequestContext via the HTTP request's FunctionContext. + /// + public static RequestContext GetRequestContext(this HttpRequestData req) + => req.FunctionContext.GetRequestContext(); + + /// Gets the correlation ID for this request (set by CorrelationIdMiddleware). + public static string GetCorrelationId(this FunctionContext context) + { + if (context.Items.TryGetValue("CorrelationId", out var id) && id is string correlationId) + return correlationId; + return string.Empty; + } +} diff --git a/src/Backend/AutopilotMonitor.Functions/Helpers/ResiliencePolicies.cs b/src/Backend/AutopilotMonitor.Functions/Helpers/ResiliencePolicies.cs new file mode 100644 index 00000000..265fcc18 --- /dev/null +++ b/src/Backend/AutopilotMonitor.Functions/Helpers/ResiliencePolicies.cs @@ -0,0 +1,108 @@ +using System.Net; +using Microsoft.Extensions.Logging; +using Polly; + +namespace AutopilotMonitor.Functions.Helpers; + +/// +/// Singleton container for Polly resilience policies used by external HTTP clients. +/// Must be registered as a DI singleton so circuit breaker state is shared across all requests. +/// +public sealed class ResiliencePolicies +{ + private static readonly HttpStatusCode[] TransientCodes = + [ + HttpStatusCode.RequestTimeout, + HttpStatusCode.TooManyRequests, + HttpStatusCode.InternalServerError, + HttpStatusCode.BadGateway, + HttpStatusCode.ServiceUnavailable, + HttpStatusCode.GatewayTimeout + ]; + + /// + /// Policy for external data APIs (GitHub, NVD, CISA, MSRC): + /// Retry 3× with exponential backoff + jitter, wrapped in an advanced circuit breaker + /// (≥50% failures in 30s → 60s open). + /// + public IAsyncPolicy ExternalDataApi { get; } + + /// + /// Policy for notification clients (webhook, Telegram): + /// 2 retries with 2s fixed delay. No circuit breaker — a single failing endpoint + /// should not block all notifications across tenants. + /// + public IAsyncPolicy Notification { get; } + + public ResiliencePolicies(ILoggerFactory loggerFactory) + { + var logger = loggerFactory.CreateLogger(nameof(ResiliencePolicies)); + ExternalDataApi = BuildExternalDataApi(logger); + Notification = BuildNotification(logger); + } + + private static IAsyncPolicy BuildExternalDataApi(ILogger logger) + { + var retry = Policy + .HandleResult(r => TransientCodes.Contains(r.StatusCode)) + .Or() + .Or() + .WaitAndRetryAsync( + retryCount: 3, + sleepDurationProvider: attempt => + TimeSpan.FromSeconds(Math.Pow(2, attempt - 1)) + + TimeSpan.FromMilliseconds(Random.Shared.Next(0, 500)), + onRetry: (outcome, delay, attempt, _) => + { + if (outcome.Exception is not null) + logger.LogWarning(outcome.Exception, + "External API request failed (attempt {Attempt}/3), retrying in {DelayMs}ms", + attempt, (int)delay.TotalMilliseconds); + else + logger.LogWarning( + "External API returned {StatusCode} (attempt {Attempt}/3), retrying in {DelayMs}ms", + outcome.Result?.StatusCode, attempt, (int)delay.TotalMilliseconds); + }); + + var circuitBreaker = Policy + .HandleResult(r => (int)r.StatusCode >= 500) + .Or() + .AdvancedCircuitBreakerAsync( + failureThreshold: 0.5, + samplingDuration: TimeSpan.FromSeconds(30), + minimumThroughput: 5, + durationOfBreak: TimeSpan.FromSeconds(60), + onBreak: (outcome, duration) => + logger.LogWarning( + "Circuit breaker opened for {DurationSec}s — {Reason}", + (int)duration.TotalSeconds, + outcome.Exception?.Message ?? outcome.Result?.StatusCode.ToString()), + onReset: () => logger.LogInformation("Circuit breaker reset — external API is healthy"), + onHalfOpen: () => logger.LogInformation("Circuit breaker half-open — probing external API")); + + // Retry (outer) wraps circuit breaker (inner): + // When the CB is open it throws BrokenCircuitException, which the retry policy + // does not handle, so retries stop immediately without exhausting the retry budget. + return Policy.WrapAsync(retry, circuitBreaker); + } + + private static IAsyncPolicy BuildNotification(ILogger logger) + => Policy + .HandleResult(r => TransientCodes.Contains(r.StatusCode)) + .Or() + .Or() + .WaitAndRetryAsync( + retryCount: 2, + sleepDurationProvider: _ => TimeSpan.FromSeconds(2), + onRetry: (outcome, _, attempt, _) => + { + if (outcome.Exception is not null) + logger.LogWarning(outcome.Exception, + "Notification request failed (attempt {Attempt}/2), retrying", + attempt); + else + logger.LogWarning( + "Notification returned {StatusCode} (attempt {Attempt}/2), retrying", + outcome.Result?.StatusCode, attempt); + }); +} diff --git a/src/Backend/AutopilotMonitor.Functions/Helpers/ResponseHelper.cs b/src/Backend/AutopilotMonitor.Functions/Helpers/ResponseHelper.cs new file mode 100644 index 00000000..4dd96fae --- /dev/null +++ b/src/Backend/AutopilotMonitor.Functions/Helpers/ResponseHelper.cs @@ -0,0 +1,75 @@ +using System.Net; +using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.Extensions.Logging; + +namespace AutopilotMonitor.Functions.Helpers; + +/// +/// Extension methods on HttpRequestData for creating consistent HTTP responses. +/// Eliminates repeated CreateResponse + WriteAsJsonAsync boilerplate across function handlers. +/// +public static class ResponseHelper +{ + /// 200 OK with a JSON body. + public static async Task OkAsync(this HttpRequestData req, object data) + { + var response = req.CreateResponse(HttpStatusCode.OK); + await response.WriteAsJsonAsync(data); + return response; + } + + /// 201 Created with a JSON body. + public static async Task CreatedAsync(this HttpRequestData req, object data) + { + var response = req.CreateResponse(HttpStatusCode.Created); + await response.WriteAsJsonAsync(data); + return response; + } + + /// 400 Bad Request with { "error": message }. + public static async Task BadRequestAsync(this HttpRequestData req, string message) + { + var response = req.CreateResponse(HttpStatusCode.BadRequest); + await response.WriteAsJsonAsync(new { error = message }); + return response; + } + + /// 401 Unauthorized with { "error": message }. + public static async Task UnauthorizedAsync(this HttpRequestData req, string message) + { + var response = req.CreateResponse(HttpStatusCode.Unauthorized); + await response.WriteAsJsonAsync(new { error = message }); + return response; + } + + /// 403 Forbidden with { "error": message }. + public static async Task ForbiddenAsync(this HttpRequestData req, string message) + { + var response = req.CreateResponse(HttpStatusCode.Forbidden); + await response.WriteAsJsonAsync(new { error = message }); + return response; + } + + /// 404 Not Found with { "error": message }. + public static async Task NotFoundAsync(this HttpRequestData req, string message) + { + var response = req.CreateResponse(HttpStatusCode.NotFound); + await response.WriteAsJsonAsync(new { error = message }); + return response; + } + + /// + /// 500 Internal Server Error. Logs the exception and returns { "error": "Internal server error" }. + /// + public static async Task InternalServerErrorAsync( + this HttpRequestData req, + ILogger logger, + Exception ex, + string logMessage = "Unhandled error") + { + logger.LogError(ex, logMessage); + var response = req.CreateResponse(HttpStatusCode.InternalServerError); + await response.WriteAsJsonAsync(new { error = "Internal server error" }); + return response; + } +} diff --git a/src/Backend/AutopilotMonitor.Functions/Middleware/CorrelationIdMiddleware.cs b/src/Backend/AutopilotMonitor.Functions/Middleware/CorrelationIdMiddleware.cs new file mode 100644 index 00000000..907e14e0 --- /dev/null +++ b/src/Backend/AutopilotMonitor.Functions/Middleware/CorrelationIdMiddleware.cs @@ -0,0 +1,58 @@ +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Middleware; +using Microsoft.Extensions.Logging; + +namespace AutopilotMonitor.Functions.Middleware; + +/// +/// Middleware that ensures every request carries a Correlation ID. +/// Reads X-Correlation-ID from the incoming request; generates a new compact GUID if absent. +/// The ID is stored in FunctionContext.Items["CorrelationId"] (retrieve via +/// context.GetCorrelationId()), echoed back in the X-Correlation-ID response header, +/// and injected into the logging scope so all log entries for the request carry it automatically. +/// +public class CorrelationIdMiddleware : IFunctionsWorkerMiddleware +{ + private const string HeaderName = "X-Correlation-ID"; + private const string ItemsKey = "CorrelationId"; + private readonly ILogger _logger; + + public CorrelationIdMiddleware(ILogger logger) + { + _logger = logger; + } + + public async Task Invoke(FunctionContext context, FunctionExecutionDelegate next) + { + var httpContext = context.GetHttpContext(); + + string correlationId; + if (httpContext != null + && httpContext.Request.Headers.TryGetValue(HeaderName, out var existingId) + && !string.IsNullOrEmpty(existingId)) + { + correlationId = existingId.ToString(); + } + else + { + correlationId = Guid.NewGuid().ToString("N"); + } + + context.Items[ItemsKey] = correlationId; + + if (httpContext != null) + { + httpContext.Response.OnStarting(() => + { + if (!httpContext.Response.Headers.ContainsKey(HeaderName)) + httpContext.Response.Headers[HeaderName] = correlationId; + return Task.CompletedTask; + }); + } + + using (_logger.BeginScope(new Dictionary { ["CorrelationId"] = correlationId })) + { + await next(context); + } + } +} diff --git a/src/Backend/AutopilotMonitor.Functions/Middleware/PolicyEnforcementMiddleware.cs b/src/Backend/AutopilotMonitor.Functions/Middleware/PolicyEnforcementMiddleware.cs index c0b69650..5690a0a9 100644 --- a/src/Backend/AutopilotMonitor.Functions/Middleware/PolicyEnforcementMiddleware.cs +++ b/src/Backend/AutopilotMonitor.Functions/Middleware/PolicyEnforcementMiddleware.cs @@ -1,6 +1,7 @@ using System.Net; using System.Security.Claims; using AutopilotMonitor.Functions.Extensions; +using AutopilotMonitor.Functions.Helpers; using AutopilotMonitor.Functions.Security; using AutopilotMonitor.Functions.Services; using AutopilotMonitor.Shared; @@ -72,6 +73,17 @@ public class PolicyEnforcementMiddleware : IFunctionsWorkerMiddleware if (decision.IsAllowed) { + // Store resolved context so functions can read IsGlobalAdmin/IsTenantAdmin without re-querying services + var principal = context.GetUser(); + context.Items[RequestContext.ItemsKey] = new RequestContext + { + TenantId = principal?.GetTenantId() ?? string.Empty, + UserPrincipalName = decision.UserIdentifier, + IsGlobalAdmin = decision.UserRole == "GlobalAdmin", + IsTenantAdmin = decision.UserRole == Constants.TenantRoles.Admin, + UserRole = decision.UserRole + }; + _logger.LogDebug("[PolicyEnforcement] ALLOW {Method} {Path} policy={Policy} user={User} role={Role}", httpMethod, requestPath, catalogEntry.Policy, decision.UserIdentifier, decision.UserRole); await next(context); diff --git a/src/Backend/AutopilotMonitor.Functions/Program.cs b/src/Backend/AutopilotMonitor.Functions/Program.cs index 3c73116e..e2893b61 100644 --- a/src/Backend/AutopilotMonitor.Functions/Program.cs +++ b/src/Backend/AutopilotMonitor.Functions/Program.cs @@ -4,6 +4,7 @@ using AutopilotMonitor.Functions.DataAccess; using AutopilotMonitor.Functions.Functions.Config; using AutopilotMonitor.Functions.Functions.Ingest; using AutopilotMonitor.Functions.Functions.Sessions; +using AutopilotMonitor.Functions.Helpers; using AutopilotMonitor.Functions.Middleware; using AutopilotMonitor.Functions.Services; using Microsoft.AspNetCore.Authentication.JwtBearer; @@ -20,7 +21,8 @@ var builder = FunctionsApplication.CreateBuilder(args); builder.ConfigureFunctionsWebApplication(); // Register middleware pipeline (Azure Functions .NET 8 isolated worker pattern) -// Order matters: API key auth → JWT authentication (401) → policy enforcement (403) +// Order matters: correlation ID (all requests) → API key auth → JWT authentication (401) → policy enforcement (403) +builder.UseMiddleware(); builder.UseMiddleware(); builder.UseMiddleware(); builder.UseMiddleware(); @@ -99,6 +101,7 @@ builder.Services.AddHttpContextAccessor(); // Register our services builder.Services.AddMemoryCache(); builder.Services.AddHttpClient(); +builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddHostedService(); // Initialize all tables at startup @@ -118,7 +121,8 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); -builder.Services.AddHttpClient(); +builder.Services.AddHttpClient() + .AddPolicyHandler((sp, _) => sp.GetRequiredService().ExternalDataApi); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); @@ -129,9 +133,12 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); // Vulnerability correlation services -builder.Services.AddHttpClient(); -builder.Services.AddHttpClient(); -builder.Services.AddHttpClient(); +builder.Services.AddHttpClient() + .AddPolicyHandler((sp, _) => sp.GetRequiredService().ExternalDataApi); +builder.Services.AddHttpClient() + .AddPolicyHandler((sp, _) => sp.GetRequiredService().ExternalDataApi); +builder.Services.AddHttpClient() + .AddPolicyHandler((sp, _) => sp.GetRequiredService().ExternalDataApi); builder.Services.AddSingleton(); // Register agent Function classes so bootstrap wrappers can inject them for code reuse @@ -142,8 +149,10 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); -builder.Services.AddHttpClient(); -builder.Services.AddHttpClient(); +builder.Services.AddHttpClient() + .AddPolicyHandler((sp, _) => sp.GetRequiredService().Notification); +builder.Services.AddHttpClient() + .AddPolicyHandler((sp, _) => sp.GetRequiredService().Notification); builder.Services.AddSingleton(); builder.Services.AddSingleton(); diff --git a/src/Backend/AutopilotMonitor.Functions/Services/GitHubRuleRepository.cs b/src/Backend/AutopilotMonitor.Functions/Services/GitHubRuleRepository.cs index 6c8cb76e..411decf2 100644 --- a/src/Backend/AutopilotMonitor.Functions/Services/GitHubRuleRepository.cs +++ b/src/Backend/AutopilotMonitor.Functions/Services/GitHubRuleRepository.cs @@ -12,7 +12,7 @@ namespace AutopilotMonitor.Functions.Services /// /// Fetches rule definitions from GitHub (raw.githubusercontent.com). /// Uses the CI-generated combined files from rules/dist/. - /// Includes retry logic with exponential backoff for transient failures. + /// Retry and circuit breaker resilience is handled by the Polly policy on the injected HttpClient. /// public class GitHubRuleRepository { @@ -20,13 +20,6 @@ namespace AutopilotMonitor.Functions.Services private readonly ILogger _logger; private readonly string _baseUrl; - private static readonly TimeSpan[] RetryDelays = new[] - { - TimeSpan.FromSeconds(2), - TimeSpan.FromSeconds(5), - TimeSpan.FromSeconds(10) - }; - public GitHubRuleRepository(HttpClient httpClient, IConfiguration config, ILogger logger) { _httpClient = httpClient; @@ -39,7 +32,7 @@ namespace AutopilotMonitor.Functions.Services { var url = $"{_baseUrl}/dist/gather-rules.json"; _logger.LogInformation("Fetching gather rules from {Url}", url); - var json = await FetchWithRetryAsync(url); + var json = await FetchAsync(url); var wrapper = JsonConvert.DeserializeObject>(json); var rules = wrapper?.Rules ?? new List(); _logger.LogInformation("Fetched {Count} gather rules from GitHub", rules.Count); @@ -50,7 +43,7 @@ namespace AutopilotMonitor.Functions.Services { var url = $"{_baseUrl}/dist/analyze-rules.json"; _logger.LogInformation("Fetching analyze rules from {Url}", url); - var json = await FetchWithRetryAsync(url); + var json = await FetchAsync(url); var wrapper = JsonConvert.DeserializeObject>(json); var rules = wrapper?.Rules ?? new List(); _logger.LogInformation("Fetched {Count} analyze rules from GitHub", rules.Count); @@ -61,7 +54,7 @@ namespace AutopilotMonitor.Functions.Services { var url = $"{_baseUrl}/dist/ime-log-patterns.json"; _logger.LogInformation("Fetching IME log patterns from {Url}", url); - var json = await FetchWithRetryAsync(url); + var json = await FetchAsync(url); var wrapper = JsonConvert.DeserializeObject>(json); var patterns = wrapper?.Rules ?? new List(); _logger.LogInformation("Fetched {Count} IME log patterns from GitHub", patterns.Count); @@ -72,7 +65,7 @@ namespace AutopilotMonitor.Functions.Services { var url = $"{_baseUrl}/dist/cpe-community-mappings.json"; _logger.LogInformation("Fetching community CPE mappings from {Url}", url); - var json = await FetchWithRetryAsync(url); + var json = await FetchAsync(url); _logger.LogInformation("Fetched community CPE mappings JSON from GitHub ({Length} bytes)", json.Length); return json; } @@ -81,69 +74,16 @@ namespace AutopilotMonitor.Functions.Services { var url = $"{_baseUrl}/dist/cpe-mapping-seed.json"; _logger.LogInformation("Fetching CPE seed mappings from {Url}", url); - var json = await FetchWithRetryAsync(url); + var json = await FetchAsync(url); _logger.LogInformation("Fetched CPE seed mappings JSON from GitHub ({Length} bytes)", json.Length); return json; } - /// - /// Fetches a URL with retry logic and exponential backoff. - /// Retries on transient HTTP errors (408, 429, 5xx) and network exceptions. - /// - private async Task FetchWithRetryAsync(string url) + private async Task FetchAsync(string url) { - for (int attempt = 0; attempt <= RetryDelays.Length; attempt++) - { - try - { - var response = await _httpClient.GetAsync(url); - - if (response.IsSuccessStatusCode) - { - return await response.Content.ReadAsStringAsync(); - } - - var statusCode = (int)response.StatusCode; - var isTransient = statusCode == 408 || statusCode == 429 - || statusCode >= 500 && statusCode <= 599; - - if (!isTransient || attempt >= RetryDelays.Length) - { - // Non-transient error or retries exhausted — throw to caller - var body = await response.Content.ReadAsStringAsync(); - _logger.LogWarning( - "GitHub fetch failed for {Url} after {Attempts} attempt(s). Status: {StatusCode}. Body: {Body}", - url, attempt + 1, statusCode, body); - response.EnsureSuccessStatusCode(); // Throws HttpRequestException - } - - var delay = RetryDelays[attempt]; - - // Respect Retry-After header (GitHub rate limiting) - if (response.Headers.RetryAfter?.Delta is TimeSpan retryAfterDelta && retryAfterDelta > delay) - { - delay = retryAfterDelta; - } - - _logger.LogWarning( - "GitHub fetch for {Url} returned {StatusCode} (attempt {Attempt}/{MaxAttempts}). Retrying in {Delay}s", - url, statusCode, attempt + 1, RetryDelays.Length + 1, delay.TotalSeconds); - - await Task.Delay(delay); - } - catch (Exception ex) when (attempt < RetryDelays.Length && (ex is HttpRequestException or TaskCanceledException)) - { - var delay = RetryDelays[attempt]; - _logger.LogWarning(ex, - "GitHub fetch for {Url} failed with network error (attempt {Attempt}/{MaxAttempts}). Retrying in {Delay}s", - url, attempt + 1, RetryDelays.Length + 1, delay.TotalSeconds); - - await Task.Delay(delay); - } - } - - // Should not reach here, but just in case - throw new HttpRequestException($"Failed to fetch {url} after {RetryDelays.Length + 1} attempts"); + var response = await _httpClient.GetAsync(url); + response.EnsureSuccessStatusCode(); + return await response.Content.ReadAsStringAsync(); } } } diff --git a/src/Backend/AutopilotMonitor.Functions/Services/Notifications/WebhookNotificationService.cs b/src/Backend/AutopilotMonitor.Functions/Services/Notifications/WebhookNotificationService.cs index e209c8d5..01935b1a 100644 --- a/src/Backend/AutopilotMonitor.Functions/Services/Notifications/WebhookNotificationService.cs +++ b/src/Backend/AutopilotMonitor.Functions/Services/Notifications/WebhookNotificationService.cs @@ -48,10 +48,15 @@ namespace AutopilotMonitor.Functions.Services.Notifications var json = renderer.RenderToJson(alert); var content = new StringContent(json, Encoding.UTF8, "application/json"); - var sent = await PostWithRetryAsync(webhookUrl, content, alert.Summary ?? "notification"); + var response = await _http.PostAsync(webhookUrl, content); - if (sent) + if (response.IsSuccessStatusCode) _logger.LogInformation("Webhook notification sent: {Summary} (provider={ProviderType})", alert.Summary, providerType); + else + { + var body = await response.Content.ReadAsStringAsync(); + _logger.LogWarning("Webhook returned {StatusCode} for {Summary}: {Body}", (int)response.StatusCode, alert.Summary, body); + } } catch (Exception ex) { @@ -99,46 +104,6 @@ namespace AutopilotMonitor.Functions.Services.Notifications } } - /// - /// Posts content to a webhook URL with a single retry on transient failures (429, 5xx, network errors). - /// - private async Task PostWithRetryAsync(string webhookUrl, StringContent content, string context) - { - const int maxAttempts = 2; - for (int attempt = 1; attempt <= maxAttempts; attempt++) - { - try - { - var response = await _http.PostAsync(webhookUrl, content); - - if (response.IsSuccessStatusCode) - return true; - - var statusCode = (int)response.StatusCode; - var isTransient = statusCode == 429 || statusCode >= 500 && statusCode <= 599; - - if (!isTransient || attempt >= maxAttempts) - { - var body = await response.Content.ReadAsStringAsync(); - _logger.LogWarning("Webhook returned {StatusCode} for {Context}: {Body}", statusCode, context, body); - return false; - } - - _logger.LogWarning( - "Webhook returned {StatusCode} for {Context} (attempt {Attempt}/{MaxAttempts}). Retrying in 2s", - statusCode, context, attempt, maxAttempts); - await Task.Delay(TimeSpan.FromSeconds(2)); - } - catch (Exception ex) when (attempt < maxAttempts && (ex is HttpRequestException or TaskCanceledException)) - { - _logger.LogWarning(ex, - "Webhook network error for {Context} (attempt {Attempt}/{MaxAttempts}). Retrying in 2s", - context, attempt, maxAttempts); - await Task.Delay(TimeSpan.FromSeconds(2)); - } - } - return false; - } } public class WebhookTestResult diff --git a/src/Backend/AutopilotMonitor.Functions/Services/TelegramNotificationService.cs b/src/Backend/AutopilotMonitor.Functions/Services/TelegramNotificationService.cs index 80e1b572..07e10bc2 100644 --- a/src/Backend/AutopilotMonitor.Functions/Services/TelegramNotificationService.cs +++ b/src/Backend/AutopilotMonitor.Functions/Services/TelegramNotificationService.cs @@ -52,14 +52,12 @@ namespace AutopilotMonitor.Functions.Services var json = JsonConvert.SerializeObject(payload); var content = new StringContent(json, Encoding.UTF8, "application/json"); - var sent = await PostWithRetryAsync(webhookUrl, content, $"signup:{tenantId}"); + var response = await _http.PostAsync(webhookUrl, content); - if (sent) - { + if (response.IsSuccessStatusCode) _logger.LogInformation( "Telegram Private Preview signup notification sent for tenant {TenantId}, UPN {Upn}", tenantId, upn); - } } catch (Exception ex) { @@ -93,13 +91,11 @@ namespace AutopilotMonitor.Functions.Services var json = JsonConvert.SerializeObject(payload); var content = new StringContent(json, Encoding.UTF8, "application/json"); - var sent = await PostWithRetryAsync(webhookUrl, content, $"report:{reportId}"); + var response = await _http.PostAsync(webhookUrl, content); - if (sent) - { + if (response.IsSuccessStatusCode) _logger.LogInformation( "Telegram session report notification sent for report {ReportId}", reportId); - } } catch (Exception ex) { @@ -173,12 +169,10 @@ namespace AutopilotMonitor.Functions.Services var json = JsonConvert.SerializeObject(payload); var content = new StringContent(json, Encoding.UTF8, "application/json"); - var sent = await PostWithRetryAsync(webhookUrl, content, $"feedback:{upn}"); + var response = await _http.PostAsync(webhookUrl, content); - if (sent) - { + if (response.IsSuccessStatusCode) _logger.LogInformation("Telegram feedback notification sent for user {Upn}", upn); - } } catch (Exception ex) { diff --git a/src/Web/autopilot-monitor-web/app/admin/AdminConfigContext.tsx b/src/Web/autopilot-monitor-web/app/admin/AdminConfigContext.tsx index 41f34157..105ec1b7 100644 --- a/src/Web/autopilot-monitor-web/app/admin/AdminConfigContext.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/AdminConfigContext.tsx @@ -2,7 +2,7 @@ import { createContext, useCallback, useContext, useEffect, useState } from "react"; import { useAuth } from "../../contexts/AuthContext"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; // Re-export for section components @@ -119,7 +119,7 @@ export function AdminConfigProvider({ children }: { children: React.ReactNode }) setLoadingConfig(true); setError(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/global/config`, getAccessToken); + const response = await authenticatedFetch(api.globalConfig.get(), getAccessToken); if (!response.ok) { throw new Error(`Failed to load admin configuration: ${response.statusText}`); @@ -159,8 +159,8 @@ export function AdminConfigProvider({ children }: { children: React.ReactNode }) setLoadingTenants(true); const [tenantsRes, previewRes] = await Promise.all([ - authenticatedFetch(`${API_BASE_URL}/api/config/all`, getAccessToken), - authenticatedFetch(`${API_BASE_URL}/api/preview/whitelist`, getAccessToken) + authenticatedFetch(api.config.all(), getAccessToken), + authenticatedFetch(api.preview.whitelist(), getAccessToken) ]); if (!tenantsRes.ok) { @@ -211,7 +211,7 @@ export function AdminConfigProvider({ children }: { children: React.ReactNode }) maintenanceBlockDurationHours, }; - const response = await authenticatedFetch(`${API_BASE_URL}/api/global/config`, getAccessToken, { + const response = await authenticatedFetch(api.globalConfig.get(), getAccessToken, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(updatedConfig), @@ -267,7 +267,7 @@ export function AdminConfigProvider({ children }: { children: React.ReactNode }) diagnosticsGlobalLogPathsJson: JSON.stringify(paths), }; - const response = await authenticatedFetch(`${API_BASE_URL}/api/global/config`, getAccessToken, { + const response = await authenticatedFetch(api.globalConfig.get(), getAccessToken, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(updatedConfig), diff --git a/src/Web/autopilot-monitor-web/app/admin/components/ConfigReseedSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/ConfigReseedSection.tsx index 831923af..f662fcba 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/ConfigReseedSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/ConfigReseedSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; interface ConfigReseedSectionProps { @@ -26,7 +26,7 @@ export function ConfigReseedSection({ setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/rules/reseed-from-github?type=analyze`, getAccessToken, { + const response = await authenticatedFetch(api.rules.reseedFromGitHub("analyze"), getAccessToken, { method: "POST", }); @@ -56,7 +56,7 @@ export function ConfigReseedSection({ setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/rules/reseed-from-github?type=gather`, getAccessToken, { + const response = await authenticatedFetch(api.rules.reseedFromGitHub("gather"), getAccessToken, { method: "POST", }); @@ -86,7 +86,7 @@ export function ConfigReseedSection({ setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/rules/reseed-from-github?type=ime`, getAccessToken, { + const response = await authenticatedFetch(api.rules.reseedFromGitHub("ime"), getAccessToken, { method: "POST", }); @@ -116,7 +116,7 @@ export function ConfigReseedSection({ setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/rules/reseed-from-github?type=all`, getAccessToken, { + const response = await authenticatedFetch(api.rules.reseedFromGitHub("all"), getAccessToken, { method: "POST", }); diff --git a/src/Web/autopilot-monitor-web/app/admin/components/DeviceBlockSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/DeviceBlockSection.tsx index 4a840e13..c1961d8f 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/DeviceBlockSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/DeviceBlockSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { trackEvent } from "@/lib/appInsights"; import { TenantConfiguration } from "./TenantManagementSection"; @@ -62,7 +62,7 @@ export function DeviceBlockSection({ if (!tenantId) return; try { setLoadingBlockedDevices(true); - const response = await authenticatedFetch(`${API_BASE_URL}/api/devices/blocked?tenantId=${encodeURIComponent(tenantId)}`, getAccessToken); + const response = await authenticatedFetch(api.devices.blocked(tenantId), getAccessToken); if (!response.ok) throw new Error(`Failed to load blocked devices: ${response.statusText}`); const data = await response.json(); setBlockedDevices(data.blocked ?? []); @@ -79,7 +79,7 @@ export function DeviceBlockSection({ const fetchAllBlockedDevices = async () => { try { setLoadingAllBlocked(true); - const response = await authenticatedFetch(`${API_BASE_URL}/api/global/devices/blocked`, getAccessToken); + const response = await authenticatedFetch(api.devices.allBlocked(), getAccessToken); if (!response.ok) throw new Error(`Failed to load blocked devices: ${response.statusText}`); const data = await response.json(); setBlockedDevices(data.blocked ?? []); @@ -104,7 +104,7 @@ export function DeviceBlockSection({ try { setBlockingDevice(true); setError(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/devices/block`, getAccessToken, { + const response = await authenticatedFetch(api.devices.block(), getAccessToken, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ @@ -143,7 +143,7 @@ export function DeviceBlockSection({ setUnblockingDevice(serialNumber); setError(null); const response = await authenticatedFetch( - `${API_BASE_URL}/api/devices/block/${encodeURIComponent(serialNumber)}?tenantId=${encodeURIComponent(tenantId)}`, + api.devices.unblock(serialNumber, tenantId), getAccessToken, { method: "DELETE" } ); @@ -172,7 +172,7 @@ export function DeviceBlockSection({ setKillingDevice(device.serialNumber); setError(null); const remainingHours = Math.max(1, Math.ceil((new Date(device.unblockAt).getTime() - Date.now()) / 3600000)); - const response = await authenticatedFetch(`${API_BASE_URL}/api/devices/block`, getAccessToken, { + const response = await authenticatedFetch(api.devices.block(), getAccessToken, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ diff --git a/src/Web/autopilot-monitor-web/app/admin/components/FeedbackSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/FeedbackSection.tsx index af27cb00..9b1c57b7 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/FeedbackSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/FeedbackSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useCallback, useEffect, useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; interface FeedbackEntry { @@ -31,7 +31,7 @@ export function FeedbackSection({ getAccessToken, setError }: FeedbackSectionPro setLoading(true); setError(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/feedback/all`, getAccessToken); + const response = await authenticatedFetch(api.feedback.all(), getAccessToken); if (!response.ok) { throw new Error(`Failed to load feedback: ${response.statusText}`); diff --git a/src/Web/autopilot-monitor-web/app/admin/components/MaintenanceSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/MaintenanceSection.tsx index 3975f48b..7229ed11 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/MaintenanceSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/MaintenanceSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; interface MaintenanceSectionProps { @@ -28,8 +28,7 @@ export function MaintenanceSection({ setError(null); setSuccessMessage(null); - const queryParams = maintenanceDate ? `?date=${maintenanceDate}` : ''; - const response = await authenticatedFetch(`${API_BASE_URL}/api/maintenance/trigger${queryParams}`, getAccessToken, { + const response = await authenticatedFetch(api.maintenance.trigger(maintenanceDate || undefined), getAccessToken, { method: "POST", }); @@ -60,7 +59,7 @@ export function MaintenanceSection({ setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/rules/reseed-from-github?type=analyze`, getAccessToken, { + const response = await authenticatedFetch(api.rules.reseedFromGitHub("analyze"), getAccessToken, { method: "POST", }); @@ -90,7 +89,7 @@ export function MaintenanceSection({ setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/rules/reseed-from-github?type=gather`, getAccessToken, { + const response = await authenticatedFetch(api.rules.reseedFromGitHub("gather"), getAccessToken, { method: "POST", }); @@ -120,7 +119,7 @@ export function MaintenanceSection({ setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/rules/reseed-from-github?type=ime`, getAccessToken, { + const response = await authenticatedFetch(api.rules.reseedFromGitHub("ime"), getAccessToken, { method: "POST", }); @@ -150,7 +149,7 @@ export function MaintenanceSection({ setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/rules/reseed-from-github?type=all`, getAccessToken, { + const response = await authenticatedFetch(api.rules.reseedFromGitHub("all"), getAccessToken, { method: "POST", }); diff --git a/src/Web/autopilot-monitor-web/app/admin/components/MaintenanceTriggerSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/MaintenanceTriggerSection.tsx index 93aa88ce..3ed1b7be 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/MaintenanceTriggerSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/MaintenanceTriggerSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; interface MaintenanceTriggerSectionProps { @@ -24,8 +24,7 @@ export function MaintenanceTriggerSection({ setError(null); setSuccessMessage(null); - const queryParams = maintenanceDate ? `?date=${maintenanceDate}` : ''; - const response = await authenticatedFetch(`${API_BASE_URL}/api/maintenance/trigger${queryParams}`, getAccessToken, { + const response = await authenticatedFetch(api.maintenance.trigger(maintenanceDate || undefined), getAccessToken, { method: "POST", }); diff --git a/src/Web/autopilot-monitor-web/app/admin/components/SessionExportSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/SessionExportSection.tsx index 0ca28ff6..551db1f9 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/SessionExportSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/SessionExportSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { TenantConfiguration } from "./TenantManagementSection"; import { TenantSearchSelect } from "./TenantSearchSelect"; @@ -47,7 +47,7 @@ export function SessionExportSection({ setExportError(null); setExportedEvents(null); const res = await authenticatedFetch( - `${API_BASE_URL}/api/sessions/${sid}/events?tenantId=${encodeURIComponent(tid)}`, + api.sessions.events(sid, tid), getAccessToken ); if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`); diff --git a/src/Web/autopilot-monitor-web/app/admin/components/SessionReportsSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/SessionReportsSection.tsx index b3b410fe..85ae3eba 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/SessionReportsSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/SessionReportsSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useState, useEffect } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { trackEvent } from "@/lib/appInsights"; @@ -81,7 +81,7 @@ export function SessionReportsSection({ setDownloadingBlob(blobName); const res = await authenticatedFetch( - `${API_BASE_URL}/api/global/session-reports/download-url?blobName=${encodeURIComponent(blobName)}`, + api.reports.downloadUrl(blobName), getAccessToken ); if (!res.ok) throw new Error(`Failed to get download URL: ${res.statusText}`); @@ -110,7 +110,7 @@ export function SessionReportsSection({ setNoteSaveResult(null); const res = await authenticatedFetch( - `${API_BASE_URL}/api/global/session-reports/${selectedReport.reportId}/note`, + api.reports.note(selectedReport.reportId), getAccessToken, { method: "PATCH", @@ -139,7 +139,7 @@ export function SessionReportsSection({ try { setLoading(true); - const res = await authenticatedFetch(`${API_BASE_URL}/api/global/session-reports`, getAccessToken); + const res = await authenticatedFetch(api.reports.list(), getAccessToken); if (res.status === 404) { // Table/container doesn't exist yet — no reports submitted so far diff --git a/src/Web/autopilot-monitor-web/app/admin/components/SoftwareMappingSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/SoftwareMappingSection.tsx index 83b52a8a..9094e8cb 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/SoftwareMappingSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/SoftwareMappingSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useCallback, useEffect, useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { trackEvent } from "@/lib/appInsights"; @@ -82,7 +82,7 @@ export function SoftwareMappingSection({ setError(null); const response = await authenticatedFetch( - `${API_BASE_URL}/api/vulnerability/unmatched-software`, + api.vulnerability.unmatchedSoftware(), getAccessToken ); @@ -117,7 +117,7 @@ export function SoftwareMappingSection({ setError(null); const response = await authenticatedFetch( - `${API_BASE_URL}/api/vulnerability/cpe-mappings`, + api.vulnerability.cpeMappings(), getAccessToken ); @@ -207,7 +207,7 @@ export function SoftwareMappingSection({ setError(null); const response = await authenticatedFetch( - `${API_BASE_URL}/api/vulnerability/cpe-mapping`, + api.vulnerability.cpeMapping(), getAccessToken, { method: "POST", @@ -316,7 +316,7 @@ export function SoftwareMappingSection({ .filter(Boolean); const response = await authenticatedFetch( - `${API_BASE_URL}/api/vulnerability/cpe-mapping`, + api.vulnerability.cpeMapping(), getAccessToken, { method: "POST", @@ -363,7 +363,7 @@ export function SoftwareMappingSection({ setError(null); const response = await authenticatedFetch( - `${API_BASE_URL}/api/vulnerability/cpe-mapping`, + api.vulnerability.cpeMapping(), getAccessToken, { method: "DELETE", diff --git a/src/Web/autopilot-monitor-web/app/admin/components/TenantAdminSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/TenantAdminSection.tsx index c27c0a8a..d550be81 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/TenantAdminSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/TenantAdminSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useEffect, useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; interface TenantAdmin { @@ -43,7 +43,7 @@ export function TenantAdminSection({ setLoadingAdmins(true); setCurrentAdminPage(0); // Reset to first page when loading new tenant - const response = await authenticatedFetch(`${API_BASE_URL}/api/tenants/${tid}/admins`, getAccessToken); + const response = await authenticatedFetch(api.tenants.admins(tid), getAccessToken); if (!response.ok) { throw new Error(`Failed to load admins: ${response.statusText}`); @@ -75,7 +75,7 @@ export function TenantAdminSection({ setAddingAdmin(true); setError(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/tenants/${tenantId}/admins`, getAccessToken, { + const response = await authenticatedFetch(api.tenants.admins(tenantId), getAccessToken, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ upn: newAdminEmail.trim() }), @@ -115,7 +115,7 @@ export function TenantAdminSection({ setRemovingAdmin(adminUpn); setError(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/tenants/${tenantId}/admins/${encodeURIComponent(adminUpn)}`, getAccessToken, { + const response = await authenticatedFetch(api.tenants.admin(tenantId, adminUpn), getAccessToken, { method: "DELETE", }); @@ -149,7 +149,7 @@ export function TenantAdminSection({ setError(null); const action = isEnabled ? 'disable' : 'enable'; - const response = await authenticatedFetch(`${API_BASE_URL}/api/tenants/${tenantId}/admins/${encodeURIComponent(adminUpn)}/${action}`, getAccessToken, { + const response = await authenticatedFetch(api.tenants.adminAction(tenantId, adminUpn, action), getAccessToken, { method: "PATCH", }); diff --git a/src/Web/autopilot-monitor-web/app/admin/components/TenantManagementSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/TenantManagementSection.tsx index 10024a7d..01fdd3de 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/TenantManagementSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/TenantManagementSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useCallback, useEffect, useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { TenantAdminSection } from "./TenantAdminSection"; @@ -93,7 +93,7 @@ export function TenantManagementSection({ setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/config/${tenant.tenantId}`, getAccessToken, { + const response = await authenticatedFetch(api.config.tenant(tenant.tenantId), getAccessToken, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(tenant), @@ -131,7 +131,7 @@ export function TenantManagementSection({ setSuccessMessage(null); const response = await authenticatedFetch( - `${API_BASE_URL}/api/preview/send-welcome-email/${tenantId}`, + api.preview.sendWelcomeEmail(tenantId), getAccessToken, { method: "POST", @@ -166,7 +166,7 @@ export function TenantManagementSection({ const isCurrentlyApproved = previewApproved.has(tenantId); - const response = await authenticatedFetch(`${API_BASE_URL}/api/preview/whitelist/${tenantId}`, getAccessToken, { + const response = await authenticatedFetch(api.preview.whitelistTenant(tenantId), getAccessToken, { method: isCurrentlyApproved ? "DELETE" : "POST", }); @@ -373,7 +373,7 @@ export function TenantManagementSection({ setNotificationEmail(""); try { const resp = await authenticatedFetch( - `${API_BASE_URL}/api/preview/notification-email/${tenant.tenantId}`, + api.preview.notificationEmailTenant(tenant.tenantId), getAccessToken ); if (resp.ok) { diff --git a/src/Web/autopilot-monitor-web/app/admin/components/VersionBlockSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/VersionBlockSection.tsx index acbb73df..e85da1ae 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/VersionBlockSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/VersionBlockSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; interface BlockedVersion { @@ -34,7 +34,7 @@ export function VersionBlockSection({ const fetchBlockedVersions = async () => { try { setLoadingVersions(true); - const response = await authenticatedFetch(`${API_BASE_URL}/api/versions/blocked`, getAccessToken); + const response = await authenticatedFetch(api.versions.blocked(), getAccessToken); if (!response.ok) throw new Error(`Failed to load version blocks: ${response.statusText}`); const data = await response.json(); setBlockedVersions(data.rules ?? []); @@ -58,7 +58,7 @@ export function VersionBlockSection({ try { setAddingRule(true); setError(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/versions/block`, getAccessToken, { + const response = await authenticatedFetch(api.versions.block(), getAccessToken, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ @@ -94,7 +94,7 @@ export function VersionBlockSection({ setRemovingPattern(pattern); setError(null); const response = await authenticatedFetch( - `${API_BASE_URL}/api/versions/block/${encodeURIComponent(pattern)}`, + api.versions.unblock(pattern), getAccessToken, { method: "DELETE" } ); diff --git a/src/Web/autopilot-monitor-web/app/admin/components/VulnerabilityDataSection.tsx b/src/Web/autopilot-monitor-web/app/admin/components/VulnerabilityDataSection.tsx index 6ea09e64..8629976a 100644 --- a/src/Web/autopilot-monitor-web/app/admin/components/VulnerabilityDataSection.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/components/VulnerabilityDataSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useCallback, useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import SaveResetBar from "../../settings/components/SaveResetBar"; @@ -85,7 +85,7 @@ export function VulnerabilityDataSection({ vulnerabilityCorrelationEnabled, }; - const response = await authenticatedFetch(`${API_BASE_URL}/api/global/config`, getAccessToken, { + const response = await authenticatedFetch(api.globalConfig.get(), getAccessToken, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(updatedConfig), @@ -124,7 +124,7 @@ export function VulnerabilityDataSection({ try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/vulnerability/sync`, + api.vulnerability.sync(), getAccessToken, { method: "POST" } ); @@ -143,7 +143,7 @@ export function VulnerabilityDataSection({ // Refresh admin config to get updated timestamp try { - const configResponse = await authenticatedFetch(`${API_BASE_URL}/api/global/config`, getAccessToken); + const configResponse = await authenticatedFetch(api.globalConfig.get(), getAccessToken); if (configResponse.ok) { const updatedConfig = await configResponse.json(); onAdminConfigUpdated(updatedConfig); @@ -173,7 +173,7 @@ export function VulnerabilityDataSection({ try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/vulnerability/sync?reseed=${type}`, + api.vulnerability.syncReseed(type), getAccessToken, { method: "POST" } ); @@ -197,7 +197,7 @@ export function VulnerabilityDataSection({ // Refresh admin config to get updated timestamp try { - const configResponse = await authenticatedFetch(`${API_BASE_URL}/api/global/config`, getAccessToken); + const configResponse = await authenticatedFetch(api.globalConfig.get(), getAccessToken); if (configResponse.ok) { const updatedConfig = await configResponse.json(); onAdminConfigUpdated(updatedConfig); diff --git a/src/Web/autopilot-monitor-web/app/admin/metrics/sections/SectionAgentMetrics.tsx b/src/Web/autopilot-monitor-web/app/admin/metrics/sections/SectionAgentMetrics.tsx index 3dd7410d..b4a0033e 100644 --- a/src/Web/autopilot-monitor-web/app/admin/metrics/sections/SectionAgentMetrics.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/metrics/sections/SectionAgentMetrics.tsx @@ -2,7 +2,7 @@ import { useEffect, useState, useMemo, useCallback } from 'react'; import { useRouter } from 'next/navigation'; -import { API_BASE_URL } from '@/lib/config'; +import { api } from '@/lib/api'; import { useAuth } from '../../../../contexts/AuthContext'; import { useNotifications } from '../../../../contexts/NotificationContext'; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; @@ -111,7 +111,7 @@ export function SectionAgentMetrics() { setError(null); try { - const res = await authenticatedFetch(`${API_BASE_URL}/api/global/metrics/platform`, getAccessToken); + const res = await authenticatedFetch(api.metrics.platform(), getAccessToken); if (!res.ok) { if (res.status === 403) { diff --git a/src/Web/autopilot-monitor-web/app/admin/metrics/sections/SectionPlatformUsage.tsx b/src/Web/autopilot-monitor-web/app/admin/metrics/sections/SectionPlatformUsage.tsx index 9304910b..67c7bd8b 100644 --- a/src/Web/autopilot-monitor-web/app/admin/metrics/sections/SectionPlatformUsage.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/metrics/sections/SectionPlatformUsage.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; -import { API_BASE_URL } from '@/lib/config'; +import { api } from '@/lib/api'; import { useAuth } from '../../../../contexts/AuthContext'; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; @@ -99,7 +99,7 @@ export function SectionPlatformUsage() { setError(null); // Platform-wide metrics - cross-tenant (Global Admin only) - const response = await authenticatedFetch(`${API_BASE_URL}/api/global/metrics/usage`, getAccessToken); + const response = await authenticatedFetch(api.metrics.globalUsage(), getAccessToken); if (!response.ok) { throw new Error(`Failed to fetch platform usage metrics: ${response.statusText}`); diff --git a/src/Web/autopilot-monitor-web/app/admin/tenants/sections/SectionTenantConfigReport.tsx b/src/Web/autopilot-monitor-web/app/admin/tenants/sections/SectionTenantConfigReport.tsx index 818c4b0c..cd0d03e6 100644 --- a/src/Web/autopilot-monitor-web/app/admin/tenants/sections/SectionTenantConfigReport.tsx +++ b/src/Web/autopilot-monitor-web/app/admin/tenants/sections/SectionTenantConfigReport.tsx @@ -2,7 +2,7 @@ import { useEffect, useState, useCallback } from 'react'; import { useAuth } from '../../../../contexts/AuthContext'; -import { API_BASE_URL } from '@/lib/config'; +import { api } from '@/lib/api'; import { authenticatedFetch, TokenExpiredError } from '@/lib/authenticatedFetch'; // ── Types ──────────────────────────────────────────────────────────────────── @@ -330,7 +330,7 @@ export function SectionTenantConfigReport() { const fetchTenants = async () => { try { setLoadingTenants(true); - const response = await authenticatedFetch(`${API_BASE_URL}/api/config/all`, getAccessToken); + const response = await authenticatedFetch(api.config.all(), getAccessToken); if (response.ok) { const data = await response.json(); const mapped: TenantInfo[] = data.map((t: { tenantId: string; domainName: string }) => ({ @@ -361,7 +361,7 @@ export function SectionTenantConfigReport() { setLoading(true); setError(null); const response = await authenticatedFetch( - `${API_BASE_URL}/api/config/${selectedTenantId}`, + api.config.tenant(selectedTenantId), getAccessToken, ); if (!response.ok) { diff --git a/src/Web/autopilot-monitor-web/app/analyze-rules/page.tsx b/src/Web/autopilot-monitor-web/app/analyze-rules/page.tsx index 19ef5264..d7ebc43d 100644 --- a/src/Web/autopilot-monitor-web/app/analyze-rules/page.tsx +++ b/src/Web/autopilot-monitor-web/app/analyze-rules/page.tsx @@ -6,7 +6,7 @@ import { useRouter } from "next/navigation"; import { ProtectedRoute } from "../../components/ProtectedRoute"; import { useTenant } from "../../contexts/TenantContext"; import { useAuth } from "../../contexts/AuthContext"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch } from "@/lib/authenticatedFetch"; import { trackEvent } from "@/lib/appInsights"; import { downloadAsJson, stripInternalFields, bumpVersion } from "@/lib/rulePageHelpers"; @@ -15,6 +15,7 @@ import { RuleFilterBar } from "@/components/rules/RuleFilterBar"; import { EmptyState } from "@/components/rules/EmptyState"; import { FormJsonToggle, JsonModeToggleButtons } from "@/components/rules/FormJsonToggle"; import { useAuthenticatedFetch, useNotificationMessages } from "@/hooks"; +import { useAdminMode } from "@/hooks/useAdminMode"; import { AnalyzeRule, RuleForm, EMPTY_FORM, EMPTY_CONDITION, ruleToForm } from "./types"; import AnalyzeRuleFormFields from "./components/AnalyzeRuleFormFields"; @@ -71,12 +72,7 @@ export default function AnalyzeRulesPage() { const [deletingRuleId, setDeletingRuleId] = useState(null); // Global admin mode - const [globalAdminMode] = useState(() => { - if (typeof window !== 'undefined') { - return localStorage.getItem('globalAdminMode') === 'true'; - } - return false; - }); + const { globalAdminMode } = useAdminMode(); const [tenants, setTenants] = useState([]); const [selectedTenantId, setSelectedTenantId] = useState(''); @@ -84,7 +80,7 @@ export default function AnalyzeRulesPage() { if (!globalAdminMode || !user?.isGlobalAdmin) return; const fetchTenants = async () => { try { - const response = await authenticatedFetch(`${API_BASE_URL}/api/config/all`, getAccessToken); + const response = await authenticatedFetch(api.config.all(), getAccessToken); if (response.ok) { const data = await response.json(); const mapped: TenantInfo[] = data.map((t: { tenantId: string; domainName: string }) => ({ @@ -118,8 +114,8 @@ export default function AnalyzeRulesPage() { const fetchRules = useCallback(async () => { if (!effectiveTenantId) return; const url = isGlobalOverride - ? `${API_BASE_URL}/api/global/rules/analyze?tenantId=${effectiveTenantId}` - : `${API_BASE_URL}/api/rules/analyze`; + ? api.rules.globalAnalyze(effectiveTenantId) + : api.rules.analyze(); await fetchRulesExec( url, undefined, @@ -135,7 +131,7 @@ export default function AnalyzeRulesPage() { const handleToggleRule = async (rule: AnalyzeRule) => { setTogglingRuleId(rule.ruleId); const result = await mutate( - `${API_BASE_URL}/api/rules/analyze/${encodeURIComponent(rule.ruleId)}`, + api.rules.analyzeRule(rule.ruleId), { method: "PUT", headers: { "Content-Type": "application/json" }, @@ -159,7 +155,7 @@ export default function AnalyzeRulesPage() { setDeletingRuleId(rule.ruleId); const result = await mutate( - `${API_BASE_URL}/api/rules/analyze/${encodeURIComponent(rule.ruleId)}`, + api.rules.analyzeRule(rule.ruleId), { method: "DELETE" } ); if (result !== null) { @@ -197,7 +193,7 @@ export default function AnalyzeRulesPage() { }; const result = await mutate( - `${API_BASE_URL}/api/rules/analyze`, + api.rules.analyze(), { method: "POST", headers: { "Content-Type": "application/json" }, @@ -248,7 +244,7 @@ export default function AnalyzeRulesPage() { }; const result = await mutate( - `${API_BASE_URL}/api/rules/analyze/${encodeURIComponent(rule.ruleId)}`, + api.rules.analyzeRule(rule.ruleId), { method: "PUT", headers: { "Content-Type": "application/json" }, diff --git a/src/Web/autopilot-monitor-web/app/audit/page.tsx b/src/Web/autopilot-monitor-web/app/audit/page.tsx index b43c19c7..45d4eba4 100644 --- a/src/Web/autopilot-monitor-web/app/audit/page.tsx +++ b/src/Web/autopilot-monitor-web/app/audit/page.tsx @@ -6,8 +6,9 @@ import { useTenant } from '../../contexts/TenantContext'; import { useAuth } from '../../contexts/AuthContext'; import { useNotifications } from '../../contexts/NotificationContext'; import { ProtectedRoute } from '../../components/ProtectedRoute'; -import { API_BASE_URL } from '@/lib/config'; +import { api } from '@/lib/api'; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; +import { useAdminMode } from "@/hooks/useAdminMode"; interface AuditLogEntry { @@ -40,12 +41,7 @@ export default function AuditPage() { const [currentPage, setCurrentPage] = useState(1); const logsPerPage = 12; - const [globalAdminMode] = useState(() => { - if (typeof window !== 'undefined') { - return localStorage.getItem('globalAdminMode') === 'true'; - } - return false; - }); + const { globalAdminMode } = useAdminMode(); const fetchAuditLogs = async (showRefreshing = false) => { try { @@ -56,8 +52,8 @@ export default function AuditPage() { } const endpoint = globalAdminMode - ? `${API_BASE_URL}/api/global/audit/logs` - : `${API_BASE_URL}/api/audit/logs`; + ? api.audit.globalLogs() + : api.audit.logs(); const response = await authenticatedFetch(endpoint, getAccessToken); if (!response.ok) { diff --git a/src/Web/autopilot-monitor-web/app/dashboard/hooks/useBlockDevice.ts b/src/Web/autopilot-monitor-web/app/dashboard/hooks/useBlockDevice.ts new file mode 100644 index 00000000..2ced5927 --- /dev/null +++ b/src/Web/autopilot-monitor-web/app/dashboard/hooks/useBlockDevice.ts @@ -0,0 +1,94 @@ +"use client"; +import { useState, useEffect } from "react"; +import { api } from "@/lib/api"; +import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; +import { NotificationType } from "@/contexts/NotificationContext"; + +interface BlockTarget { + serialNumber: string; + tenantId: string; + deviceName?: string; +} + +export function useBlockDevice( + getAccessToken: (forceRefresh?: boolean) => Promise, + addNotification: (type: NotificationType, title: string, message: string, key?: string, href?: string) => void, + adminMode: boolean, + globalAdminMode: boolean +) { + const [showBlockConfirm, setShowBlockConfirm] = useState(false); + const [sessionToBlock, setSessionToBlock] = useState(null); + const [blockingDevice, setBlockingDevice] = useState(false); + const [blockedDevicesSet, setBlockedDevicesSet] = useState>(new Set()); + + // Reset blocked set when admin mode or global admin mode is turned off + useEffect(() => { + if (!adminMode || !globalAdminMode) { + setBlockedDevicesSet(new Set()); + } + }, [adminMode, globalAdminMode]); + + const blockDevice = (serialNumber: string, tenantId: string, deviceName?: string) => { + setSessionToBlock({ serialNumber, tenantId, deviceName }); + setShowBlockConfirm(true); + }; + + const confirmBlock = async () => { + if (!sessionToBlock) return; + + try { + setBlockingDevice(true); + + const response = await authenticatedFetch(api.devices.block(), getAccessToken, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + tenantId: sessionToBlock.tenantId, + serialNumber: sessionToBlock.serialNumber, + durationHours: 24, + reason: `Blocked from dashboard by Global Admin` + }) + }); + + if (response.ok) { + console.log(`Device ${sessionToBlock.serialNumber} blocked successfully`); + setShowBlockConfirm(false); + setSessionToBlock(null); + addNotification('success', 'Device Blocked', `Device ${sessionToBlock.deviceName || sessionToBlock.serialNumber} blocked for 24 hours.`); + setBlockedDevicesSet(prev => { + const next = new Set(prev); + next.add(`${sessionToBlock.tenantId}:${sessionToBlock.serialNumber}`); + return next; + }); + } else { + const data = await response.json(); + alert(`Fehler beim Blocken: ${data.message || 'Unbekannter Fehler'}`); + } + } catch (error) { + if (error instanceof TokenExpiredError) { + addNotification('error', 'Session Expired', error.message, 'session-expired-error'); + } else { + console.error('Failed to block device:', error); + alert('Fehler beim Blocken des Geräts'); + } + } finally { + setBlockingDevice(false); + } + }; + + const cancelBlock = () => { + setShowBlockConfirm(false); + setSessionToBlock(null); + }; + + return { + showBlockConfirm, + sessionToBlock, + blockingDevice, + blockedDevicesSet, + setBlockedDevicesSet, + blockDevice, + confirmBlock, + cancelBlock, + }; +} diff --git a/src/Web/autopilot-monitor-web/app/dashboard/hooks/useDeleteSession.ts b/src/Web/autopilot-monitor-web/app/dashboard/hooks/useDeleteSession.ts new file mode 100644 index 00000000..1e62546a --- /dev/null +++ b/src/Web/autopilot-monitor-web/app/dashboard/hooks/useDeleteSession.ts @@ -0,0 +1,62 @@ +"use client"; +import { useState } from "react"; +import { api } from "@/lib/api"; +import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; +import { trackEvent } from "@/lib/appInsights"; +import { NotificationType } from "@/contexts/NotificationContext"; + +interface DeleteTarget { + sessionId: string; + tenantId: string; + deviceName?: string; +} + +export function useDeleteSession( + getAccessToken: (forceRefresh?: boolean) => Promise, + addNotification: (type: NotificationType, title: string, message: string, key?: string, href?: string) => void, + adminMode: boolean, + onSessionDeleted: (sessionId: string) => void +) { + const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); + const [sessionToDelete, setSessionToDelete] = useState(null); + + const deleteSession = (sessionId: string, tenantId: string, deviceName?: string) => { + setSessionToDelete({ sessionId, tenantId, deviceName }); + setShowDeleteConfirm(true); + }; + + const confirmDelete = async () => { + if (!sessionToDelete) return; + + try { + const response = await authenticatedFetch(api.sessions.delete(sessionToDelete.sessionId, sessionToDelete.tenantId), getAccessToken, { + method: 'DELETE', + }); + + if (response.ok) { + trackEvent("session_deleted", { inAdminMode: adminMode }); + onSessionDeleted(sessionToDelete.sessionId); + console.log(`Session ${sessionToDelete.sessionId} deleted successfully`); + setShowDeleteConfirm(false); + setSessionToDelete(null); + } else { + const data = await response.json(); + alert(`Fehler beim Löschen: ${data.message || 'Unbekannter Fehler'}`); + } + } catch (error) { + if (error instanceof TokenExpiredError) { + addNotification('error', 'Session Expired', error.message, 'session-expired-error'); + } else { + console.error('Failed to delete session:', error); + alert('Fehler beim Löschen der Session'); + } + } + }; + + const cancelDelete = () => { + setShowDeleteConfirm(false); + setSessionToDelete(null); + }; + + return { showDeleteConfirm, sessionToDelete, deleteSession, confirmDelete, cancelDelete }; +} diff --git a/src/Web/autopilot-monitor-web/app/dashboard/page.tsx b/src/Web/autopilot-monitor-web/app/dashboard/page.tsx index bbebdedd..85b9bdf9 100644 --- a/src/Web/autopilot-monitor-web/app/dashboard/page.tsx +++ b/src/Web/autopilot-monitor-web/app/dashboard/page.tsx @@ -8,7 +8,7 @@ import { useSignalR } from "../../contexts/SignalRContext"; import { useTenant } from "../../contexts/TenantContext"; import { useAuth } from "../../contexts/AuthContext"; import { useNotifications } from "../../contexts/NotificationContext"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { trackEvent } from "@/lib/appInsights"; import { Session } from "./types"; @@ -16,6 +16,9 @@ import { StatsCard } from "./components/StatsCards"; import { WelcomeMessage } from "./components/WelcomeMessage"; import { SessionTable } from "./components/SessionTable"; import { DeleteConfirmModal, BlockConfirmModal } from "./components/ConfirmationModals"; +import { useAdminMode } from "@/hooks/useAdminMode"; +import { useDeleteSession } from "./hooks/useDeleteSession"; +import { useBlockDevice } from "./hooks/useBlockDevice"; interface TenantConfigurationSummary { validateAutopilotDevice: boolean; @@ -46,24 +49,22 @@ export default function Home() { } return 10; }); - const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); - const [sessionToDelete, setSessionToDelete] = useState<{ sessionId: string; tenantId: string; deviceName?: string } | null>(null); - const [showBlockConfirm, setShowBlockConfirm] = useState(false); - const [sessionToBlock, setSessionToBlock] = useState<{ serialNumber: string; tenantId: string; deviceName?: string } | null>(null); - const [blockingDevice, setBlockingDevice] = useState(false); - const [blockedDevicesSet, setBlockedDevicesSet] = useState>(new Set()); - const [adminMode, setAdminMode] = useState(() => { - if (typeof window !== 'undefined') { - return localStorage.getItem('adminMode') === 'true'; - } - return false; - }); - const [globalAdminMode, setGlobalAdminMode] = useState(() => { - if (typeof window !== 'undefined') { - return localStorage.getItem('globalAdminMode') === 'true'; - } - return false; - }); + const { adminMode, setAdminMode, globalAdminMode, setGlobalAdminMode } = useAdminMode(); + + const { + showDeleteConfirm, sessionToDelete, + deleteSession, confirmDelete, cancelDelete, + } = useDeleteSession( + getAccessToken, + addNotification, + adminMode, + (deletedId) => setSessions(prev => prev.filter(s => s.sessionId !== deletedId)) + ); + + const { + showBlockConfirm, sessionToBlock, blockingDevice, blockedDevicesSet, setBlockedDevicesSet, + blockDevice, confirmBlock, cancelBlock, + } = useBlockDevice(getAccessToken, addNotification, adminMode, globalAdminMode); // Use global contexts const { on, off, isConnected, joinGroup, leaveGroup } = useSignalR(); @@ -94,8 +95,8 @@ export default function Home() { // Use different endpoint based on global admin mode const effectiveTenantFilter = globalTenantIdOverride !== undefined ? globalTenantIdOverride : tenantIdFilter.trim(); let endpoint = globalAdminMode - ? `${API_BASE_URL}/api/global/sessions${effectiveTenantFilter ? `?tenantId=${encodeURIComponent(effectiveTenantFilter)}` : ''}` - : `${API_BASE_URL}/api/sessions?tenantId=${tenantId}`; + ? api.globalSessions.list(effectiveTenantFilter || undefined) + : api.sessions.list(tenantId); // Append cursor for "Load More" requests if (loadMoreCursor) { @@ -160,7 +161,7 @@ export default function Home() { const results = await Promise.allSettled( tenantIds.map(tid => - authenticatedFetch(`${API_BASE_URL}/api/devices/blocked?tenantId=${encodeURIComponent(tid)}`, getAccessToken) + authenticatedFetch(api.devices.blocked(tid), getAccessToken) .then(res => res.ok ? res.json() : { blocked: [] }) ) ); @@ -197,7 +198,7 @@ export default function Home() { if (user && !user.isTenantAdmin && !user.isGlobalAdmin && user.role !== 'Operator') return; try { - const response = await authenticatedFetch(`${API_BASE_URL}/api/config/${tenantId}`, getAccessToken); + const response = await authenticatedFetch(api.config.tenant(tenantId), getAccessToken); if (!response.ok) { setSerialValidationEnabled(null); @@ -358,22 +359,6 @@ export default function Home() { return () => clearTimeout(timer); }, [searchQuery]); - // Save admin mode to localStorage when it changes - useEffect(() => { - localStorage.setItem('adminMode', adminMode.toString()); - }, [adminMode]); - - // Save global admin mode to localStorage when it changes - useEffect(() => { - localStorage.setItem('globalAdminMode', globalAdminMode.toString()); - }, [globalAdminMode]); - - // Clear blocked devices set when admin mode or global admin mode is turned off - useEffect(() => { - if (!adminMode || !globalAdminMode) { - setBlockedDevicesSet(new Set()); - } - }, [adminMode, globalAdminMode]); // Disable global admin mode if user is not a global admin useEffect(() => { @@ -383,37 +368,6 @@ export default function Home() { } }, [user, globalAdminMode]); - // Listen for localStorage changes from other components (e.g., Navbar) - useEffect(() => { - const handleStorageChange = (e: StorageEvent) => { - if (e.key === 'adminMode' && e.newValue !== null) { - setAdminMode(e.newValue === 'true'); - } - if (e.key === 'globalAdminMode' && e.newValue !== null) { - setGlobalAdminMode(e.newValue === 'true'); - } - }; - - const handleCustomStorageChange = () => { - const newAdminMode = localStorage.getItem('adminMode') === 'true'; - const newGlobalMode = localStorage.getItem('globalAdminMode') === 'true'; - - if (newAdminMode !== adminMode) { - setAdminMode(newAdminMode); - } - if (newGlobalMode !== globalAdminMode) { - setGlobalAdminMode(newGlobalMode); - } - }; - - window.addEventListener('storage', handleStorageChange); - window.addEventListener('localStorageChange', handleCustomStorageChange); - - return () => { - window.removeEventListener('storage', handleStorageChange); - window.removeEventListener('localStorageChange', handleCustomStorageChange); - }; - }, [adminMode, globalAdminMode]); // Refetch sessions when global admin mode changes useEffect(() => { @@ -464,97 +418,6 @@ export default function Home() { fetchSessions(undefined, ""); }; - const deleteSession = (sessionId: string, sessionTenantId: string, deviceName?: string) => { - setSessionToDelete({ sessionId, tenantId: sessionTenantId, deviceName }); - setShowDeleteConfirm(true); - }; - - const confirmDelete = async () => { - if (!sessionToDelete) return; - - try { - const response = await authenticatedFetch(`${API_BASE_URL}/api/sessions/${sessionToDelete.sessionId}?tenantId=${sessionToDelete.tenantId}`, getAccessToken, { - method: 'DELETE', - }); - - if (response.ok) { - trackEvent("session_deleted", { inAdminMode: adminMode }); - setSessions(prevSessions => prevSessions.filter(s => s.sessionId !== sessionToDelete.sessionId)); - console.log(`Session ${sessionToDelete.sessionId} deleted successfully`); - setShowDeleteConfirm(false); - setSessionToDelete(null); - } else { - const data = await response.json(); - alert(`Fehler beim Löschen: ${data.message || 'Unbekannter Fehler'}`); - } - } catch (error) { - if (error instanceof TokenExpiredError) { - addNotification('error', 'Session Expired', error.message, 'session-expired-error'); - } else { - console.error('Failed to delete session:', error); - alert('Fehler beim Löschen der Session'); - } - } - }; - - const cancelDelete = () => { - setShowDeleteConfirm(false); - setSessionToDelete(null); - }; - - const blockDevice = (serialNumber: string, sessionTenantId: string, deviceName?: string) => { - setSessionToBlock({ serialNumber, tenantId: sessionTenantId, deviceName }); - setShowBlockConfirm(true); - }; - - const confirmBlock = async () => { - if (!sessionToBlock) return; - - try { - setBlockingDevice(true); - - const response = await authenticatedFetch(`${API_BASE_URL}/api/devices/block`, getAccessToken, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - tenantId: sessionToBlock.tenantId, - serialNumber: sessionToBlock.serialNumber, - durationHours: 24, - reason: `Blocked from dashboard by Global Admin` - }) - }); - - if (response.ok) { - console.log(`Device ${sessionToBlock.serialNumber} blocked successfully`); - setShowBlockConfirm(false); - setSessionToBlock(null); - addNotification('success', 'Device Blocked', `Device ${sessionToBlock.deviceName || sessionToBlock.serialNumber} blocked for 24 hours.`); - setBlockedDevicesSet(prev => { - const next = new Set(prev); - next.add(`${sessionToBlock.tenantId}:${sessionToBlock.serialNumber}`); - return next; - }); - } else { - const data = await response.json(); - alert(`Fehler beim Blocken: ${data.message || 'Unbekannter Fehler'}`); - } - } catch (error) { - if (error instanceof TokenExpiredError) { - addNotification('error', 'Session Expired', error.message, 'session-expired-error'); - } else { - console.error('Failed to block device:', error); - alert('Fehler beim Blocken des Geräts'); - } - } finally { - setBlockingDevice(false); - } - }; - - const cancelBlock = () => { - setShowBlockConfirm(false); - setSessionToBlock(null); - }; - // Client-side tenant filter: ensures sessions from other tenants are never displayed, // regardless of how they entered the sessions state (SignalR, race conditions, etc.) const effectiveSessions = globalAdminMode @@ -632,14 +495,21 @@ export default function Home() { const sortedSessions = [...filteredSessions].sort((a, b) => { if (!sortColumn) return 0; - let aValue: any = a[sortColumn]; - let bValue: any = b[sortColumn]; + const rawA: Session[typeof sortColumn] = a[sortColumn]; + const rawB: Session[typeof sortColumn] = b[sortColumn]; + + let aValue: number | string | boolean | null | undefined; + let bValue: number | string | boolean | null | undefined; if (sortColumn === "startedAt") { - aValue = new Date(aValue).getTime(); - bValue = new Date(bValue).getTime(); + aValue = new Date(rawA as string).getTime(); + bValue = new Date(rawB as string).getTime(); + } else { + aValue = rawA; + bValue = rawB; } + if (aValue == null || bValue == null) return 0; if (aValue < bValue) return sortDirection === "asc" ? -1 : 1; if (aValue > bValue) return sortDirection === "asc" ? 1 : -1; return 0; diff --git a/src/Web/autopilot-monitor-web/app/diagnosis/[sessionId]/page.tsx b/src/Web/autopilot-monitor-web/app/diagnosis/[sessionId]/page.tsx index 1923744d..979e6ec8 100644 --- a/src/Web/autopilot-monitor-web/app/diagnosis/[sessionId]/page.tsx +++ b/src/Web/autopilot-monitor-web/app/diagnosis/[sessionId]/page.tsx @@ -7,11 +7,12 @@ import { useTenant } from "../../../contexts/TenantContext"; import { useAuth } from "../../../contexts/AuthContext"; import { useNotifications } from "../../../contexts/NotificationContext"; import { ProtectedRoute } from "../../../components/ProtectedRoute"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { formatInlineMarkdown } from "@/lib/formatInlineMarkdown"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { ConfidenceBadge, SeverityBadge } from "./components/DiagnosisBadges"; import { Session, EnrollmentEvent, RuleResult } from "@/types"; +import { useAdminMode } from "@/hooks/useAdminMode"; export default function DiagnosisPage() { const params = useParams(); @@ -37,12 +38,7 @@ export default function DiagnosisPage() { const { getAccessToken } = useAuth(); const { addNotification } = useNotifications(); - const [globalAdminMode] = useState(() => { - if (typeof window !== "undefined") { - return localStorage.getItem("globalAdminMode") === "true"; - } - return false; - }); + const { globalAdminMode } = useAdminMode(); useEffect(() => { if (!sessionId) return; @@ -117,8 +113,8 @@ export default function DiagnosisPage() { const fetchSessionDetails = async () => { try { const endpoint = globalAdminMode - ? `${API_BASE_URL}/api/global/sessions` - : `${API_BASE_URL}/api/sessions?tenantId=${tenantId}`; + ? api.globalSessions.list() + : api.sessions.list(tenantId); const response = await authenticatedFetch(endpoint, getAccessToken); if (response.ok) { const data = await response.json(); @@ -146,7 +142,7 @@ export default function DiagnosisPage() { const effectiveTenantId = sessionTenantId || tenantId; try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/sessions/${sessionId}/events?tenantId=${effectiveTenantId}`, + api.sessions.events(sessionId, effectiveTenantId), getAccessToken ); if (response.ok) { @@ -169,7 +165,7 @@ export default function DiagnosisPage() { const effectiveTenantId = sessionTenantId || tenantId; try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/sessions/${sessionId}/analysis?tenantId=${effectiveTenantId}`, + api.sessions.analysis(sessionId, effectiveTenantId), getAccessToken ); if (response.ok) { diff --git a/src/Web/autopilot-monitor-web/app/fleet-health/page.tsx b/src/Web/autopilot-monitor-web/app/fleet-health/page.tsx index e4dba42b..581b7cf1 100644 --- a/src/Web/autopilot-monitor-web/app/fleet-health/page.tsx +++ b/src/Web/autopilot-monitor-web/app/fleet-health/page.tsx @@ -7,10 +7,11 @@ import { useSignalR } from "../../contexts/SignalRContext"; import { useTenant } from "../../contexts/TenantContext"; import { useAuth } from "../../contexts/AuthContext"; import { useNotifications } from "../../contexts/NotificationContext"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import FleetStatCard from "./components/FleetStatCard"; import { Session } from "@/types"; +import { useAdminMode } from "@/hooks/useAdminMode"; interface AppMetric { appName: string; @@ -49,12 +50,7 @@ export default function FleetHealthPage() { const { getAccessToken } = useAuth(); const { addNotification } = useNotifications(); - const [globalAdminMode] = useState(() => { - if (typeof window !== "undefined") { - return localStorage.getItem("globalAdminMode") === "true"; - } - return false; - }); + const { globalAdminMode } = useAdminMode(); useEffect(() => { if (!globalAdminMode && !tenantId) return; // wait for real tenant ID @@ -128,8 +124,8 @@ export default function FleetHealthPage() { const fetchSessions = async () => { try { const endpoint = globalAdminMode - ? `${API_BASE_URL}/api/global/sessions` - : `${API_BASE_URL}/api/sessions?tenantId=${tenantId}`; + ? api.globalSessions.list() + : api.sessions.list(tenantId); const response = await authenticatedFetch(endpoint, getAccessToken); if (response.ok) { const data = await response.json(); @@ -153,8 +149,8 @@ export default function FleetHealthPage() { try { const days = range === "7d" ? 7 : range === "30d" ? 30 : 90; const endpoint = globalAdminMode - ? `${API_BASE_URL}/api/global/metrics/app?days=${days}` - : `${API_BASE_URL}/api/metrics/app?tenantId=${tenantId}&days=${days}`; + ? api.metrics.globalApp(days) + : api.metrics.app(tenantId, days); const response = await authenticatedFetch(endpoint, getAccessToken); if (response.ok) { const data = await response.json(); diff --git a/src/Web/autopilot-monitor-web/app/gather-rules/page.tsx b/src/Web/autopilot-monitor-web/app/gather-rules/page.tsx index ae864fc2..4d7e006c 100644 --- a/src/Web/autopilot-monitor-web/app/gather-rules/page.tsx +++ b/src/Web/autopilot-monitor-web/app/gather-rules/page.tsx @@ -6,7 +6,7 @@ import { useRouter } from "next/navigation"; import { ProtectedRoute } from "../../components/ProtectedRoute"; import { useTenant } from "../../contexts/TenantContext"; import { useAuth } from "../../contexts/AuthContext"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch } from "@/lib/authenticatedFetch"; import { trackEvent } from "@/lib/appInsights"; import { downloadAsJson, stripInternalFields, bumpVersion } from "@/lib/rulePageHelpers"; @@ -15,6 +15,7 @@ import { RuleFilterBar } from "@/components/rules/RuleFilterBar"; import { EmptyState } from "@/components/rules/EmptyState"; import { FormJsonToggle, JsonModeToggleButtons } from "@/components/rules/FormJsonToggle"; import { useAuthenticatedFetch, useNotificationMessages } from "@/hooks"; +import { useAdminMode } from "@/hooks/useAdminMode"; import { GatherRule, NewRuleForm, EMPTY_FORM, CATEGORY_COLORS } from "./types"; import { GatherRuleFormFields } from "./components/GatherRuleFormFields"; import { GatherRuleCard } from "./components/GatherRuleCard"; @@ -72,12 +73,7 @@ export default function GatherRulesPage() { const [unrestrictedMode, setUnrestrictedMode] = useState(false); // Global admin mode - const [globalAdminMode] = useState(() => { - if (typeof window !== 'undefined') { - return localStorage.getItem('globalAdminMode') === 'true'; - } - return false; - }); + const { globalAdminMode } = useAdminMode(); const [tenants, setTenants] = useState([]); const [selectedTenantId, setSelectedTenantId] = useState(''); @@ -85,7 +81,7 @@ export default function GatherRulesPage() { if (!globalAdminMode || !user?.isGlobalAdmin) return; const fetchTenants = async () => { try { - const response = await authenticatedFetch(`${API_BASE_URL}/api/config/all`, getAccessToken); + const response = await authenticatedFetch(api.config.all(), getAccessToken); if (response.ok) { const data = await response.json(); const mapped: TenantInfo[] = data.map((t: { tenantId: string; domainName: string }) => ({ @@ -119,8 +115,8 @@ export default function GatherRulesPage() { const fetchRules = useCallback(async () => { if (!effectiveTenantId) return; const url = isGlobalOverride - ? `${API_BASE_URL}/api/global/rules/gather?tenantId=${effectiveTenantId}` - : `${API_BASE_URL}/api/rules/gather?tenantId=${effectiveTenantId}`; + ? api.rules.globalGather(effectiveTenantId) + : api.rules.gather(effectiveTenantId); await fetchRulesExec( url, undefined, @@ -140,8 +136,8 @@ export default function GatherRulesPage() { const fetchConfig = async () => { try { const url = isGlobalOverride - ? `${API_BASE_URL}/api/global/config/${effectiveTenantId}` - : `${API_BASE_URL}/api/config/${effectiveTenantId}`; + ? api.globalConfig.tenant(effectiveTenantId) + : api.config.tenant(effectiveTenantId); const response = await authenticatedFetch(url, getAccessToken); if (response.ok) { const data = await response.json(); @@ -157,7 +153,7 @@ export default function GatherRulesPage() { const handleToggleRule = async (rule: GatherRule) => { setTogglingRule(rule.ruleId); const result = await mutate( - `${API_BASE_URL}/api/rules/gather/${rule.ruleId}?tenantId=${effectiveTenantId}`, + api.rules.gatherRule(rule.ruleId, effectiveTenantId), { method: "PUT", headers: { "Content-Type": "application/json" }, @@ -180,7 +176,7 @@ export default function GatherRulesPage() { setDeletingRule(rule.ruleId); const result = await mutate( - `${API_BASE_URL}/api/rules/gather/${rule.ruleId}?tenantId=${effectiveTenantId}`, + api.rules.gatherRule(rule.ruleId, effectiveTenantId), { method: "DELETE" } ); if (result !== null) { @@ -250,7 +246,7 @@ export default function GatherRulesPage() { }; const result = await mutate( - `${API_BASE_URL}/api/rules/gather?tenantId=${effectiveTenantId}`, + api.rules.gather(effectiveTenantId), { method: "POST", headers: { "Content-Type": "application/json" }, @@ -334,7 +330,7 @@ export default function GatherRulesPage() { }; const result = await mutate( - `${API_BASE_URL}/api/rules/gather/${rule.ruleId}?tenantId=${effectiveTenantId}`, + api.rules.gatherRule(rule.ruleId, effectiveTenantId), { method: "PUT", headers: { "Content-Type": "application/json" }, diff --git a/src/Web/autopilot-monitor-web/app/geographic-performance/page.tsx b/src/Web/autopilot-monitor-web/app/geographic-performance/page.tsx index 87b93818..1901e0f1 100644 --- a/src/Web/autopilot-monitor-web/app/geographic-performance/page.tsx +++ b/src/Web/autopilot-monitor-web/app/geographic-performance/page.tsx @@ -6,8 +6,9 @@ import dynamic from "next/dynamic"; import { ProtectedRoute } from "../../components/ProtectedRoute"; import { useTenant } from "../../contexts/TenantContext"; import { useAuth } from "../../contexts/AuthContext"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; +import { useAdminMode } from "@/hooks/useAdminMode"; // Dynamically import the map component (Leaflet requires window/document) const GeoMap = dynamic(() => import("./GeoMap"), { ssr: false }); @@ -106,19 +107,14 @@ export default function GeographicPerformancePage() { const { tenantId } = useTenant(); const { getAccessToken } = useAuth(); - const [globalAdminMode] = useState(() => { - if (typeof window !== "undefined") { - return localStorage.getItem("globalAdminMode") === "true"; - } - return false; - }); + const { globalAdminMode } = useAdminMode(); const fetchGeoMetrics = useCallback(async (range: TimeRange = timeRange, group: GroupBy = groupBy) => { try { const days = range === "7d" ? 7 : range === "30d" ? 30 : 90; const endpoint = globalAdminMode - ? `${API_BASE_URL}/api/global/metrics/geographic?days=${days}&groupBy=${group}` - : `${API_BASE_URL}/api/metrics/geographic?tenantId=${tenantId}&days=${days}&groupBy=${group}`; + ? api.metrics.globalGeographic(days, group) + : api.metrics.geographic(tenantId, days, group); const response = await authenticatedFetch(endpoint, getAccessToken); if (response.ok) { const data = await response.json(); diff --git a/src/Web/autopilot-monitor-web/app/geographic-performance/sessions/page.tsx b/src/Web/autopilot-monitor-web/app/geographic-performance/sessions/page.tsx index c80bab8a..e2b477d9 100644 --- a/src/Web/autopilot-monitor-web/app/geographic-performance/sessions/page.tsx +++ b/src/Web/autopilot-monitor-web/app/geographic-performance/sessions/page.tsx @@ -5,8 +5,9 @@ import { useRouter, useSearchParams } from "next/navigation"; import { ProtectedRoute } from "../../../components/ProtectedRoute"; import { useTenant } from "../../../contexts/TenantContext"; import { useAuth } from "../../../contexts/AuthContext"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; +import { useAdminMode } from "@/hooks/useAdminMode"; interface SessionSummary { sessionId: string; @@ -93,19 +94,14 @@ function LocationSessionsContent() { const { tenantId } = useTenant(); const { getAccessToken } = useAuth(); - const [globalAdminMode] = useState(() => { - if (typeof window !== "undefined") { - return localStorage.getItem("globalAdminMode") === "true"; - } - return false; - }); + const { globalAdminMode } = useAdminMode(); const fetchSessions = useCallback(async () => { if (!locationKey) return; try { const endpoint = globalAdminMode - ? `${API_BASE_URL}/api/global/metrics/geographic/sessions?days=${days}&groupBy=${groupBy}&locationKey=${encodeURIComponent(locationKey)}` - : `${API_BASE_URL}/api/metrics/geographic/sessions?tenantId=${tenantId}&days=${days}&groupBy=${groupBy}&locationKey=${encodeURIComponent(locationKey)}`; + ? api.metrics.globalGeographicSessions(Number(days), groupBy, locationKey) + : api.metrics.geographicSessions(tenantId, Number(days), groupBy, locationKey); const response = await authenticatedFetch(endpoint, getAccessToken); if (response.ok) { const result = await response.json(); diff --git a/src/Web/autopilot-monitor-web/app/health-check/page.tsx b/src/Web/autopilot-monitor-web/app/health-check/page.tsx index 5b0b8aec..39a2a9fb 100644 --- a/src/Web/autopilot-monitor-web/app/health-check/page.tsx +++ b/src/Web/autopilot-monitor-web/app/health-check/page.tsx @@ -6,7 +6,7 @@ import { useSignalR } from '@/contexts/SignalRContext'; import { useTenant } from '@/contexts/TenantContext'; import { useState, useEffect, useCallback } from 'react'; import * as signalR from '@microsoft/signalr'; -import { API_BASE_URL } from '@/lib/config'; +import { api } from '@/lib/api'; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; interface HealthCheck { @@ -37,7 +37,7 @@ export default function HealthCheckPage() { const performHealthCheck = useCallback(async () => { setLoading(true); try { - const response = await authenticatedFetch(`${API_BASE_URL}/api/health/detailed`, getAccessToken); + const response = await authenticatedFetch(api.health.detailed(), getAccessToken); if (!response.ok) { if (response.status === 403) { diff --git a/src/Web/autopilot-monitor-web/app/ime-log-patterns/page.tsx b/src/Web/autopilot-monitor-web/app/ime-log-patterns/page.tsx index 2e5fc741..bb1ef596 100644 --- a/src/Web/autopilot-monitor-web/app/ime-log-patterns/page.tsx +++ b/src/Web/autopilot-monitor-web/app/ime-log-patterns/page.tsx @@ -5,8 +5,9 @@ import { useRouter } from "next/navigation"; import { ProtectedRoute } from "../../components/ProtectedRoute"; import { useTenant } from "../../contexts/TenantContext"; import { useAuth } from "../../contexts/AuthContext"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { useAuthenticatedFetch, useNotificationMessages } from "@/hooks"; +import { useAdminMode } from "@/hooks/useAdminMode"; import { downloadAsJson, stripInternalFields } from "@/lib/rulePageHelpers"; import { StatCard } from "@/components/rules/StatCard"; import { RuleFilterBar } from "@/components/rules/RuleFilterBar"; @@ -22,7 +23,7 @@ export default function ImeLogPatternsPage() { const { tenantId } = useTenant(); const { user } = useAuth(); const isGlobalAdmin = user?.isGlobalAdmin ?? false; - const [globalAdminMode, setGlobalAdminMode] = useState(false); + const { globalAdminMode } = useAdminMode(); const { successMessage, error, showSuccess, showError } = useNotificationMessages(); @@ -59,20 +60,12 @@ export default function ImeLogPatternsPage() { const [newParamKey, setNewParamKey] = useState(""); const [newParamValue, setNewParamValue] = useState(""); - // Check global admin mode from localStorage - useEffect(() => { - const mode = localStorage.getItem("globalAdminMode") === "true"; - setGlobalAdminMode(mode); - const handleStorage = () => setGlobalAdminMode(localStorage.getItem("globalAdminMode") === "true"); - window.addEventListener("storage", handleStorage); - return () => window.removeEventListener("storage", handleStorage); - }, []); // Fetch patterns const fetchPatterns = useCallback(async () => { if (!tenantId) return; await fetchPatternsExec( - `${API_BASE_URL}/api/rules/ime-log-patterns`, + api.rules.imeLogPatterns(), undefined, { transform: (d) => { const r = d as { success?: boolean; patterns?: ImeLogPattern[] }; return r.success && Array.isArray(r.patterns) ? r.patterns : []; } } ); @@ -88,7 +81,7 @@ export default function ImeLogPatternsPage() { setTogglingPattern(pattern.patternId); const result = await mutate( - `${API_BASE_URL}/api/rules/ime-log-patterns/${encodeURIComponent(pattern.patternId)}?global=true`, + api.rules.imeLogPattern(pattern.patternId), { method: "PUT", headers: { "Content-Type": "application/json" }, @@ -139,7 +132,7 @@ export default function ImeLogPatternsPage() { }; const result = await mutate( - `${API_BASE_URL}/api/rules/ime-log-patterns/${encodeURIComponent(patternId)}?global=true`, + api.rules.imeLogPattern(patternId), { method: "PUT", headers: { "Content-Type": "application/json" }, diff --git a/src/Web/autopilot-monitor-web/app/preview/page.tsx b/src/Web/autopilot-monitor-web/app/preview/page.tsx index 5a877851..552e5722 100644 --- a/src/Web/autopilot-monitor-web/app/preview/page.tsx +++ b/src/Web/autopilot-monitor-web/app/preview/page.tsx @@ -3,7 +3,7 @@ import { useAuth } from "../../contexts/AuthContext"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; export default function PreviewPage() { const { isAuthenticated, isLoading, user, isPreviewBlocked, previewMessage, logout, getAccessToken } = useAuth(); @@ -44,7 +44,7 @@ export default function PreviewPage() { throw new Error("Not authenticated"); } - const response = await fetch(`${API_BASE_URL}/api/preview/notification-email`, { + const response = await fetch(api.preview.notificationEmail(), { method: "PUT", headers: { "Authorization": `Bearer ${token}`, diff --git a/src/Web/autopilot-monitor-web/app/progress/page.tsx b/src/Web/autopilot-monitor-web/app/progress/page.tsx index b386690a..e0df1589 100644 --- a/src/Web/autopilot-monitor-web/app/progress/page.tsx +++ b/src/Web/autopilot-monitor-web/app/progress/page.tsx @@ -1,7 +1,7 @@ "use client"; import { useState, useEffect, useRef, useMemo } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { trackEvent } from "@/lib/appInsights"; import { useTenant } from "../../contexts/TenantContext"; @@ -162,7 +162,7 @@ export default function ProgressPortalPage() { const fetchEvents = async () => { try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/progress/sessions/${session.sessionId}/events?tenantId=${tenantId}`, + api.progress.sessionEvents(session.sessionId, tenantId), getAccessToken ); if (response.ok) { @@ -205,7 +205,7 @@ export default function ProgressPortalPage() { try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/progress/sessions?tenantId=${tenantId}`, + api.progress.sessions(tenantId), getAccessToken ); diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/DeviceDetailsCard.tsx b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/DeviceDetailsCard.tsx index 314a5dad..9e242c9e 100644 --- a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/DeviceDetailsCard.tsx +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/DeviceDetailsCard.tsx @@ -201,16 +201,17 @@ export default function DeviceDetailsCard({ events }: { events: EnrollmentEvent[ {(networkAdapters || dnsConfig || proxyConfig || networkInterfaceInfo || wifiSignalInfo) && ( {networkAdapters && networkAdapters.adapters && ( - (networkAdapters.adapters as any[]).map((adapter: any, i: number) => { - const { ipv4, ipv6 } = adapter.ipAddresses ? splitIpAddresses(adapter.ipAddresses) : { ipv4: [], ipv6: [] }; + (networkAdapters.adapters as unknown[]).map((adapter, i: number) => { + const a = adapter as Record; + const { ipv4, ipv6 } = a.ipAddresses ? splitIpAddresses(a.ipAddresses as string) : { ipv4: [], ipv6: [] }; const hasIpv6 = ipv6.length > 0; const isIpv6Shown = showIpv6[i] ?? false; return (
-
{adapter.description || adapter.name || `Adapter ${i + 1}`}
- {adapter.dhcpEnabled !== undefined && } - {adapter.macAddress && } +
{(a.description || a.name || `Adapter ${i + 1}`) as string}
+ {a.dhcpEnabled !== undefined && } + {a.macAddress && } {ipv4.length > 0 && } {hasIpv6 && (
@@ -233,10 +234,11 @@ export default function DeviceDetailsCard({ events }: { events: EnrollmentEvent[
)} {dnsConfig?.dnsEntries && Array.isArray(dnsConfig.dnsEntries) && ( - (dnsConfig.dnsEntries as any[]) - .filter((entry: any) => entry.adapter === adapter.description || entry.adapter === adapter.name) - .map((entry: any, dnsIdx: number) => ( - + (dnsConfig.dnsEntries as unknown[]) + .map(e => e as Record) + .filter(entry => entry.adapter === a.description || entry.adapter === a.name) + .map((entry, dnsIdx: number) => ( + )) )}
@@ -303,14 +305,17 @@ export default function DeviceDetailsCard({ events }: { events: EnrollmentEvent[ {bitLockerStatus.volumes && Array.isArray(bitLockerStatus.volumes) && bitLockerStatus.volumes.length > 0 && (
- {(bitLockerStatus.volumes as any[]).map((vol: any, i: number) => ( + {(bitLockerStatus.volumes as unknown[]).map((vol, i: number) => { + const v = vol as Record; + return (
- {vol.driveLetter} {vol.protectionStatus === "1" ? "Protected" : "Not Protected"} - {vol.encryptionMethod !== undefined && vol.encryptionMethod !== null && vol.encryptionMethod !== "" && ( - ` (Method: ${getBitLockerEncryptionMethodLabel(vol.encryptionMethod)})` + {v.driveLetter as string} {v.protectionStatus === "1" ? "Protected" : "Not Protected"} + {v.encryptionMethod !== undefined && v.encryptionMethod !== null && v.encryptionMethod !== "" && ( + ` (Method: ${getBitLockerEncryptionMethodLabel(v.encryptionMethod)})` )}
- ))} + ); + })}
)} @@ -414,9 +419,12 @@ export default function DeviceDetailsCard({ events }: { events: EnrollmentEvent[ )} - {hwSpec.disks && Array.isArray(hwSpec.disks) && (hwSpec.disks as any[]).map((disk: any, i: number) => ( - 1 ? `Disk ${i + 1}` : 'Disk'} value={`${disk.model || 'Unknown'}${disk.sizeGB ? ` (${disk.sizeGB} GB)` : ''}${disk.mediaType && disk.mediaType !== 'Unknown' ? ` — ${disk.mediaType}` : ''}`} /> - ))} + {hwSpec.disks && Array.isArray(hwSpec.disks) && (hwSpec.disks as unknown[]).map((disk, i: number) => { + const d = disk as Record; + return ( + 1 ? `Disk ${i + 1}` : 'Disk'} value={`${d.model || 'Unknown'}${d.sizeGB ? ` (${d.sizeGB} GB)` : ''}${d.mediaType && d.mediaType !== 'Unknown' ? ` — ${d.mediaType}` : ''}`} /> + ); + })} {hwSpec.systemDriveFreeGB !== undefined && hwSpec.systemDriveTotalGB !== undefined && ( )} @@ -440,9 +448,12 @@ export default function DeviceDetailsCard({ events }: { events: EnrollmentEvent[ )} {hwSpec.batteryPresent === false && } - {hwSpec.gpus && Array.isArray(hwSpec.gpus) && (hwSpec.gpus as any[]).map((gpu: any, i: number) => ( - 1 ? `GPU ${i + 1}` : 'GPU'} value={`${gpu.name || 'Unknown'}${gpu.adapterRAMGB ? ` (${gpu.adapterRAMGB} GB)` : ''}`} /> - ))} + {hwSpec.gpus && Array.isArray(hwSpec.gpus) && (hwSpec.gpus as unknown[]).map((gpu, i: number) => { + const g = gpu as Record; + return ( + 1 ? `GPU ${i + 1}` : 'GPU'} value={`${g.name || 'Unknown'}${g.adapterRAMGB ? ` (${g.adapterRAMGB} GB)` : ''}`} /> + ); + })}
)} diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/ReportSessionModal.tsx b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/ReportSessionModal.tsx index fc2b3558..87354865 100644 --- a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/ReportSessionModal.tsx +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/ReportSessionModal.tsx @@ -104,9 +104,9 @@ export default function ReportSessionModal({ setScreenshotFiles([]); setAgentLogFiles([]); setAgentLogError(null); - } catch (err: any) { + } catch (err: unknown) { setSubmitResult('error'); - setSubmitErrorMessage(err?.message || 'Failed to submit report.'); + setSubmitErrorMessage(err instanceof Error ? err.message : 'Failed to submit report.'); } }; diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/VulnerabilityReportSection.tsx b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/VulnerabilityReportSection.tsx index 08b035a1..a78f51bb 100644 --- a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/VulnerabilityReportSection.tsx +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/components/VulnerabilityReportSection.tsx @@ -1,10 +1,11 @@ "use client"; import { useState, useMemo } from "react"; +import type { EnrollmentEvent } from "@/types"; interface VulnerabilityReportSectionProps { - events: any[]; - vulnerabilityReport: any; + events: EnrollmentEvent[]; + vulnerabilityReport: unknown; expanded: boolean; setExpanded: (v: boolean) => void; onRescan?: () => Promise | void; @@ -128,18 +129,18 @@ export default function VulnerabilityReportSection({ let kevCount = 0; for (const evt of vulnReportData) { - const d = evt.data || {}; + const d = (evt.data || {}) as Record; if (d.findings && Array.isArray(d.findings)) { for (const f of d.findings) { const key = `${f.softwareName || f.software || "Unknown"}|||${f.version || ""}`; - const cves: CveDetail[] = (f.cves || f.vulnerabilities || []).map((c: any) => ({ - cveId: c.cveId || c.id || c.cve_id || "Unknown", - cvss: c.cvss ?? c.cvssScore ?? c.cvss_score ?? 0, - severity: normalizeSeverity(c.severity), - description: c.description || c.summary || "", - kev: c.kev ?? c.isKev ?? c.is_kev ?? false, - publishedDate: c.publishedDate || c.published_date || "", - references: c.references || [], + const cves: CveDetail[] = (f.cves || f.vulnerabilities || []).map((c: Record) => ({ + cveId: (c.cveId || c.id || c.cve_id || "Unknown") as string, + cvss: (c.cvss ?? c.cvssScore ?? c.cvss_score ?? 0) as number, + severity: normalizeSeverity(c.severity as string | undefined), + description: (c.description || c.summary || "") as string, + kev: (c.kev ?? c.isKev ?? c.is_kev ?? false) as boolean, + publishedDate: (c.publishedDate || c.published_date || "") as string, + references: (c.references || []) as string[], })); const maxCvss = cves.reduce((max: number, c: CveDetail) => Math.max(max, c.cvss ?? 0), 0); @@ -179,8 +180,8 @@ export default function VulnerabilityReportSection({ } else if (d.unmatched_software && Array.isArray(d.unmatched_software)) { unmatched = [...unmatched, ...d.unmatched_software]; } - total = d.totalSoftware ?? d.total_software ?? d.totalCount ?? total; - freshness = d.dataFreshness || d.data_freshness || d.analyzedAt || d.analyzed_at || freshness; + total = (d.totalSoftware ?? d.total_software ?? d.totalCount ?? total) as number; + freshness = (d.dataFreshness || d.data_freshness || d.analyzedAt || d.analyzed_at || freshness) as string; } // Deduplicate unmatched @@ -216,14 +217,17 @@ export default function VulnerabilityReportSection({ const triggeredAt = d.triggered_at || d.triggeredAt || evt.timestamp || "default"; const chunkIndex = d.chunk_index ?? d.chunkIndex ?? 0; const chunkCount = d.chunk_count ?? d.chunkCount ?? 1; - const items: InventoryItem[] = (d.inventory || d.software || d.items || []).map((item: any) => ({ - name: item.displayName || item.name || item.normalizedName || item.softwareName || "Unknown", - version: item.displayVersion || item.version || item.normalizedVersion || "", - publisher: item.publisher || item.normalizedPublisher || item.vendor || "", - installDate: item.installDate || item.install_date || "", - source: item.registrySource || item.source || "", - confidence: item.normalizationConfidence || item.confidence || "", - })); + const items: InventoryItem[] = ((d.inventory || d.software || d.items || []) as unknown[]).map((item: unknown) => { + const i = item as Record; + return { + name: (i.displayName || i.name || i.normalizedName || i.softwareName || "Unknown") as string, + version: (i.displayVersion || i.version || i.normalizedVersion || "") as string, + publisher: (i.publisher || i.normalizedPublisher || i.vendor || "") as string, + installDate: (i.installDate || i.install_date || "") as string, + source: (i.registrySource || i.source || "") as string, + confidence: (i.normalizationConfidence || i.confidence || "") as string, + }; + }); if (!chunkGroups.has(triggeredAt)) { chunkGroups.set(triggeredAt, { items: [], chunkCount, seenChunks: new Set() }); @@ -252,17 +256,18 @@ export default function VulnerabilityReportSection({ const items: InventoryItem[] = []; // Look in vulnerability report and inventory events for new_installs_during_enrollment for (const evt of [...vulnReportData, ...inventoryEvents]) { - const d = evt.data || {}; + const d = (evt.data || {}) as Record; const newInstalls = d.new_installs_during_enrollment || d.newInstallsDuringEnrollment || []; if (Array.isArray(newInstalls)) { - for (const item of newInstalls) { + for (const rawItem of newInstalls) { + const item = rawItem as Record; items.push({ - name: item.displayName || item.name || item.normalizedName || item.softwareName || "Unknown", - version: item.displayVersion || item.version || item.normalizedVersion || "", - publisher: item.publisher || item.normalizedPublisher || item.vendor || "", - installDate: item.installDate || item.install_date || "", - source: item.registrySource || item.source || "", - confidence: item.normalizationConfidence || item.confidence || "", + name: (item.displayName || item.name || item.normalizedName || item.softwareName || "Unknown") as string, + version: (item.displayVersion || item.version || item.normalizedVersion || "") as string, + publisher: (item.publisher || item.normalizedPublisher || item.vendor || "") as string, + installDate: (item.installDate || item.install_date || "") as string, + source: (item.registrySource || item.source || "") as string, + confidence: (item.normalizationConfidence || item.confidence || "") as string, }); } } diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/hooks/useAutoScroll.ts b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/hooks/useAutoScroll.ts new file mode 100644 index 00000000..31830478 --- /dev/null +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/hooks/useAutoScroll.ts @@ -0,0 +1,57 @@ +"use client"; +import { useState, useRef, useEffect } from "react"; +import { EnrollmentEvent } from "@/types"; + +export function useAutoScroll(events: EnrollmentEvent[]) { + const [autoScroll, setAutoScroll] = useState(false); + const isNearBottomRef = useRef(false); + const isProgrammaticScrollRef = useRef(false); + + // Auto-scroll: track whether user is near the bottom (only while feature is enabled). + // Uses a ref so scroll events don't cause re-renders. + useEffect(() => { + if (!autoScroll) return; + const handleScroll = () => { + const distanceFromBottom = document.body.scrollHeight - window.scrollY - window.innerHeight; + if (isProgrammaticScrollRef.current) { + // During a programmatic scroll animation, only allow flipping to true + // (we reached the bottom) — never flip to false (content grew mid-animation). + if (distanceFromBottom <= 150) isNearBottomRef.current = true; + } else { + isNearBottomRef.current = distanceFromBottom <= 150; + } + }; + window.addEventListener('scroll', handleScroll, { passive: true }); + return () => window.removeEventListener('scroll', handleScroll); + }, [autoScroll]); + + // Auto-scroll: when new events arrive, scroll to bottom only if user is already near the bottom. + useEffect(() => { + if (!autoScroll || events.length === 0 || !isNearBottomRef.current) return; + isProgrammaticScrollRef.current = true; + const timer = setTimeout(() => { + window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); + // Keep the guard up long enough for the smooth scroll animation to finish. + setTimeout(() => { isProgrammaticScrollRef.current = false; }, 600); + }, 150); + return () => { clearTimeout(timer); isProgrammaticScrollRef.current = false; }; + }, [events, autoScroll]); + + const handleAutoScrollToggle = () => { + setAutoScroll(prev => { + const next = !prev; + if (next) { + // Enabling: immediately scroll to bottom and mark as near-bottom + isNearBottomRef.current = true; + isProgrammaticScrollRef.current = true; + setTimeout(() => { + window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); + setTimeout(() => { isProgrammaticScrollRef.current = false; }, 600); + }, 50); + } + return next; + }); + }; + + return { autoScroll, handleAutoScrollToggle }; +} diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/hooks/useSessionAnalysis.ts b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/hooks/useSessionAnalysis.ts new file mode 100644 index 00000000..839592d5 --- /dev/null +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/hooks/useSessionAnalysis.ts @@ -0,0 +1,64 @@ +"use client"; +import { useState, useCallback } from "react"; +import { api } from "@/lib/api"; +import { authenticatedFetch } from "@/lib/authenticatedFetch"; +import { RuleResult } from "@/types"; + +const GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + +export function useSessionAnalysis( + sessionId: string, + sessionTenantId: string | null, + getAccessToken: (forceRefresh?: boolean) => Promise +) { + const [analysisResults, setAnalysisResults] = useState([]); + const [loadingAnalysis, setLoadingAnalysis] = useState(false); + const [vulnerabilityReport, setVulnerabilityReport] = useState(null); + + const fetchAnalysisResults = useCallback(async (reanalyze = false) => { + if (!sessionTenantId || !GUID_REGEX.test(sessionTenantId)) return; + try { + setLoadingAnalysis(true); + + const response = await authenticatedFetch( + api.sessions.analysis(sessionId, sessionTenantId, reanalyze || undefined), + getAccessToken + ); + if (response.ok) { + const data = await response.json(); + if (data.results) { + setAnalysisResults(data.results.sort((a: RuleResult, b: RuleResult) => b.confidenceScore - a.confidenceScore)); + } + } + } catch (error) { + console.error("Failed to fetch analysis results:", error); + } finally { + setLoadingAnalysis(false); + } + }, [sessionId, sessionTenantId, getAccessToken]); + + const fetchVulnerabilityReport = useCallback(async (rescan = false) => { + if (!sessionTenantId || !GUID_REGEX.test(sessionTenantId)) return; + try { + const response = await authenticatedFetch( + api.sessions.vulnerabilityReport(sessionId, sessionTenantId, rescan || undefined), + getAccessToken + ); + if (response.ok) { + const data = await response.json(); + setVulnerabilityReport(data.report ?? null); + } + } catch (error) { + console.error("Failed to fetch vulnerability report:", error); + } + }, [sessionId, sessionTenantId, getAccessToken]); + + return { + analysisResults, + loadingAnalysis, + vulnerabilityReport, + setVulnerabilityReport, + fetchAnalysisResults, + fetchVulnerabilityReport, + }; +} diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx index f974168f..c7e37a15 100644 --- a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/page.tsx @@ -1,6 +1,8 @@ "use client"; import { useEffect, useState, useRef, useMemo } from "react"; +import { useSessionAnalysis } from "./hooks/useSessionAnalysis"; +import { useAutoScroll } from "./hooks/useAutoScroll"; import { useParams, useRouter } from "next/navigation"; import { useSignalR } from "../../../contexts/SignalRContext"; import { useTenant } from "../../../contexts/TenantContext"; @@ -11,7 +13,7 @@ import PerformanceChart from '../../../components/PerformanceChart'; import DownloadProgress from '../../../components/DownloadProgress'; import InstallProgress from '../../../components/InstallProgress'; import ScriptExecutions from '../../../components/ScriptExecutions'; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { V1_PHASE_NAMES, V2_PHASE_NAMES, V1_PHASE_ORDER, V2_PHASE_ORDER } from "./utils/phaseConstants"; @@ -30,6 +32,7 @@ import DeviceDetailsCard from "./components/DeviceDetailsCard"; import { generateUiExport, generateCsvExport, generateSessionCsvExport, generateRuleResultsCsvExport, SessionExportEvent } from "@/lib/sessionExportUtils"; import { Session, EnrollmentEvent, RuleResult } from "@/types"; import { trackEvent } from "@/lib/appInsights"; +import { useAdminMode } from "@/hooks/useAdminMode"; const GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; @@ -49,27 +52,12 @@ export default function SessionDetailPage() { const [reportSubmitting, setReportSubmitting] = useState(false); const [showScriptOutput, setShowScriptOutput] = useState(true); const [enableSoftwareInventoryAnalyzer, setEnableSoftwareInventoryAnalyzer] = useState(false); - const [analysisResults, setAnalysisResults] = useState([]); - const [loadingAnalysis, setLoadingAnalysis] = useState(false); const [analysisExpanded, setAnalysisExpanded] = useState(true); - const [vulnerabilityReport, setVulnerabilityReport] = useState(null); const [vulnerabilityReportExpanded, setVulnerabilityReportExpanded] = useState(false); const [phaseTimelineExpanded, setPhaseTimelineExpanded] = useState(true); const [perfExpanded, setPerfExpanded] = useState(true); const [timelineExpanded, setTimelineExpanded] = useState(true); - const [autoScroll, setAutoScroll] = useState(false); - const [adminMode, setAdminMode] = useState(() => { - if (typeof window !== 'undefined') { - return localStorage.getItem('adminMode') === 'true'; - } - return false; - }); - const [globalAdminMode, setGlobalAdminMode] = useState(() => { - if (typeof window !== 'undefined') { - return localStorage.getItem('globalAdminMode') === 'true'; - } - return false; - }); + const { adminMode, setAdminMode, globalAdminMode, setGlobalAdminMode } = useAdminMode(); // Debounce real-time event refreshes to avoid burst reads in Table Storage. const eventRefreshTimeoutRef = useRef(null); @@ -88,19 +76,23 @@ export default function SessionDetailPage() { const fetchEventsInFlight = useRef(false); const fetchEventsQueued = useRef(false); - // Auto-scroll: tracks whether the user is near the bottom of the page - const isNearBottomRef = useRef(false); - // Auto-scroll: guards against race condition where content growth during - // a programmatic smooth-scroll temporarily moves the viewport away from - // the bottom, causing isNearBottomRef to flip false prematurely. - const isProgrammaticScrollRef = useRef(false); - // Use global contexts const { on, off, isConnected, joinGroup, leaveGroup } = useSignalR(); const { tenantId } = useTenant(); const { getAccessToken, user } = useAuth(); const { addNotification } = useNotifications(); + const { + analysisResults, + loadingAnalysis, + vulnerabilityReport, + setVulnerabilityReport, + fetchAnalysisResults, + fetchVulnerabilityReport, + } = useSessionAnalysis(sessionId, sessionTenantId, getAccessToken); + + const { autoScroll, handleAutoScrollToggle } = useAutoScroll(events); + useEffect(() => { sessionRef.current = session; }, [session]); @@ -117,52 +109,6 @@ export default function SessionDetailPage() { globalAdminModeRef.current = globalAdminMode; }, [globalAdminMode]); - // Auto-scroll: track whether user is near the bottom (only while feature is enabled). - // Uses a ref so scroll events don't cause re-renders. - useEffect(() => { - if (!autoScroll) return; - const handleScroll = () => { - const distanceFromBottom = document.body.scrollHeight - window.scrollY - window.innerHeight; - if (isProgrammaticScrollRef.current) { - // During a programmatic scroll animation, only allow flipping to true - // (we reached the bottom) — never flip to false (content grew mid-animation). - if (distanceFromBottom <= 150) isNearBottomRef.current = true; - } else { - isNearBottomRef.current = distanceFromBottom <= 150; - } - }; - window.addEventListener('scroll', handleScroll, { passive: true }); - return () => window.removeEventListener('scroll', handleScroll); - }, [autoScroll]); - - // Auto-scroll: when new events arrive, scroll to bottom only if user is already near the bottom. - useEffect(() => { - if (!autoScroll || events.length === 0 || !isNearBottomRef.current) return; - isProgrammaticScrollRef.current = true; - const timer = setTimeout(() => { - window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); - // Keep the guard up long enough for the smooth scroll animation to finish. - setTimeout(() => { isProgrammaticScrollRef.current = false; }, 600); - }, 150); - return () => { clearTimeout(timer); isProgrammaticScrollRef.current = false; }; - }, [events, autoScroll]); - - const handleAutoScrollToggle = () => { - setAutoScroll(prev => { - const next = !prev; - if (next) { - // Enabling: immediately scroll to bottom and mark as near-bottom - isNearBottomRef.current = true; - isProgrammaticScrollRef.current = true; - setTimeout(() => { - window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); - setTimeout(() => { isProgrammaticScrollRef.current = false; }, 600); - }, 50); - } - return next; - }); - }; - const resolveEffectiveTenantId = () => { const knownSessionTenant = sessionTenantIdRef.current || sessionRef.current?.tenantId || null; if (knownSessionTenant) return knownSessionTenant; @@ -214,7 +160,7 @@ export default function SessionDetailPage() { (async () => { try { const res = await authenticatedFetch( - `${API_BASE_URL}/api/config/${sessionTenantId}`, + api.config.tenant(sessionTenantId), getAccessToken ); if (res.ok) { @@ -347,10 +293,10 @@ export default function SessionDetailPage() { try { const knownTenantId = resolveEffectiveTenantId(); const endpoint = knownTenantId - ? `${API_BASE_URL}/api/sessions/${sessionId}?tenantId=${knownTenantId}` + ? api.sessions.get(sessionId, knownTenantId) : globalAdminMode - ? `${API_BASE_URL}/api/global/sessions` - : `${API_BASE_URL}/api/sessions/${sessionId}`; + ? api.globalSessions.list() + : api.sessions.get(sessionId); const response = await authenticatedFetch(endpoint, getAccessToken); if (response.ok) { @@ -392,7 +338,7 @@ export default function SessionDetailPage() { try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/sessions/${sessionId}/events?tenantId=${effectiveTenantId}`, + api.sessions.events(sessionId, effectiveTenantId), getAccessToken ); if (response.ok) { @@ -449,48 +395,6 @@ export default function SessionDetailPage() { } }; - const fetchAnalysisResults = async (reanalyze = false) => { - const effectiveTenantId = resolveEffectiveTenantId(); - if (!effectiveTenantId || !GUID_REGEX.test(effectiveTenantId)) return; - try { - setLoadingAnalysis(true); - - const reanalyzeParam = reanalyze ? '&reanalyze=true' : ''; - const response = await authenticatedFetch( - `${API_BASE_URL}/api/sessions/${sessionId}/analysis?tenantId=${effectiveTenantId}${reanalyzeParam}`, - getAccessToken - ); - if (response.ok) { - const data = await response.json(); - if (data.results) { - setAnalysisResults(data.results.sort((a: RuleResult, b: RuleResult) => b.confidenceScore - a.confidenceScore)); - } - } - } catch (error) { - console.error("Failed to fetch analysis results:", error); - } finally { - setLoadingAnalysis(false); - } - }; - - const fetchVulnerabilityReport = async (rescan = false) => { - const effectiveTenantId = resolveEffectiveTenantId(); - if (!effectiveTenantId || !GUID_REGEX.test(effectiveTenantId)) return; - try { - const rescanParam = rescan ? '&rescan=true' : ''; - const response = await authenticatedFetch( - `${API_BASE_URL}/api/sessions/${sessionId}/vulnerability-report?tenantId=${effectiveTenantId}${rescanParam}`, - getAccessToken - ); - if (response.ok) { - const data = await response.json(); - setVulnerabilityReport(data.report ?? null); - } - } catch (error) { - console.error("Failed to fetch vulnerability report:", error); - } - }; - const markAsFailed = () => { setShowMarkFailedConfirm(true); }; @@ -504,7 +408,7 @@ export default function SessionDetailPage() { try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/sessions/${sessionId}/mark-failed?tenantId=${effectiveTenantId}`, + api.sessions.markFailed(sessionId, effectiveTenantId), getAccessToken, { method: 'POST' } ); @@ -527,7 +431,7 @@ export default function SessionDetailPage() { try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/sessions/${sessionId}/mark-succeeded?tenantId=${effectiveTenantId}`, + api.sessions.markSucceeded(sessionId, effectiveTenantId), getAccessToken, { method: 'POST' } ); @@ -573,7 +477,7 @@ export default function SessionDetailPage() { const ruleResultsCsv = generateRuleResultsCsvExport(analysisResults); const response = await authenticatedFetch( - `${API_BASE_URL}/api/sessions/${sessionId}/report?tenantId=${effectiveTenantId}`, + api.sessions.report(sessionId, effectiveTenantId), getAccessToken, { method: 'POST', @@ -604,10 +508,11 @@ export default function SessionDetailPage() { addNotification('error', 'Report Failed', message, 'report-error'); throw new Error(message); } - } catch (err: any) { + } catch (err: unknown) { // Re-throw so the modal can show inline error feedback. // Only log unexpected errors (not the ones we threw ourselves above). - if (!err?.message?.includes('Failed to submit report') && !err?.message?.includes('Failed to get access token')) { + const errMessage = err instanceof Error ? err.message : ''; + if (!errMessage.includes('Failed to submit report') && !errMessage.includes('Failed to get access token')) { console.error('Error submitting report:', err); } throw err; @@ -930,7 +835,7 @@ export default function SessionDetailPage() { onClick={async () => { try { const res = await authenticatedFetch( - `${API_BASE_URL}/api/diagnostics/download-url?tenantId=${session.tenantId}&blobName=${encodeURIComponent(session.diagnosticsBlobName!)}`, + api.diagnostics.downloadUrl(session.tenantId, session.diagnosticsBlobName!), getAccessToken ); if (!res.ok) throw new Error('Failed to get download URL'); diff --git a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/utils/eventHelpers.ts b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/utils/eventHelpers.ts index 405acb55..e5a1a9b7 100644 --- a/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/utils/eventHelpers.ts +++ b/src/Web/autopilot-monitor-web/app/sessions/[sessionId]/utils/eventHelpers.ts @@ -62,7 +62,8 @@ export function groupEventsByPhase( return { eventsByPhase, orderedPhases }; } -export function normalizeJsonLikeValue(value: any): any { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function normalizeJsonLikeValue(value: unknown): any { if (typeof value === "string") { const trimmed = value.trim(); const looksLikeJson = diff --git a/src/Web/autopilot-monitor-web/app/settings/TenantConfigContext.tsx b/src/Web/autopilot-monitor-web/app/settings/TenantConfigContext.tsx index 21fc7e6d..1806df19 100644 --- a/src/Web/autopilot-monitor-web/app/settings/TenantConfigContext.tsx +++ b/src/Web/autopilot-monitor-web/app/settings/TenantConfigContext.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/navigation"; import { useTenant } from "../../contexts/TenantContext"; import { useAuth } from "../../contexts/AuthContext"; import { useNotifications } from "../../contexts/NotificationContext"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; import { trackEvent } from "@/lib/appInsights"; import { parseSasExpiry } from "./components/DiagnosticsSection"; @@ -278,7 +278,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } setLoading(true); setError(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/config/${tenantId}`, getAccessToken); + const response = await authenticatedFetch(api.config.tenant(tenantId), getAccessToken); if (!response.ok) { throw new Error(`Failed to load configuration: ${response.statusText}`); @@ -390,7 +390,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } if (!tenantId) return; try { setLoadingAdmins(true); - const response = await authenticatedFetch(`${API_BASE_URL}/api/tenants/${tenantId}/admins`, getAccessToken); + const response = await authenticatedFetch(api.tenants.admins(tenantId), getAccessToken); if (!response.ok) { throw new Error(`Failed to load admins: ${response.statusText}`); } @@ -422,7 +422,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } try { setBootstrapLoading(true); const response = await authenticatedFetch( - `${API_BASE_URL}/api/bootstrap/sessions?tenantId=${tenantId}`, + api.bootstrap.sessions(tenantId), getAccessToken, ); if (response.ok) { @@ -448,7 +448,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } if (!user?.isGlobalAdmin) return; const fetchGlobalDiagPaths = async () => { try { - const res = await authenticatedFetch(`${API_BASE_URL}/api/global/config`, getAccessToken); + const res = await authenticatedFetch(api.globalConfig.get(), getAccessToken); if (!res.ok) return; const data = await res.json(); if (data.diagnosticsGlobalLogPathsJson) { @@ -516,7 +516,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } unrestrictedMode, }; - const response = await authenticatedFetch(`${API_BASE_URL}/api/config/${tenantId}`, getAccessToken, { + const response = await authenticatedFetch(api.config.tenant(tenantId), getAccessToken, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(updatedConfig), @@ -571,7 +571,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } const redirectUri = `${window.location.origin}/settings/validation/autopilot`; const response = await authenticatedFetch( - `${API_BASE_URL}/api/config/${tenantId}/autopilot-device-validation/consent-url?redirectUri=${encodeURIComponent(redirectUri)}`, + api.config.autopilotConsentUrl(tenantId, redirectUri), getAccessToken, ); @@ -633,7 +633,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } setAutopilotConsentInProgress(true); const statusResponse = await authenticatedFetch( - `${API_BASE_URL}/api/config/${tenantId}/autopilot-device-validation/consent-status`, + api.config.autopilotConsentStatus(tenantId), getAccessToken, ); @@ -677,7 +677,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } setTestingWebhook(true); setTestWebhookResult(null); try { - const response = await authenticatedFetch(`${API_BASE_URL}/api/config/${tenantId}/test-notification`, getAccessToken, { + const response = await authenticatedFetch(api.config.testNotification(tenantId), getAccessToken, { method: "POST", }); const data = await response.json(); @@ -780,7 +780,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/tenants/${tenantId}/admins`, getAccessToken, { + const response = await authenticatedFetch(api.tenants.admins(tenantId), getAccessToken, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ upn: newAdminEmail.trim(), role: newMemberRole }), @@ -820,7 +820,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } setError(null); setSuccessMessage(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/tenants/${tenantId}/admins/${encodeURIComponent(adminUpn)}`, getAccessToken, { + const response = await authenticatedFetch(api.tenants.admin(tenantId, adminUpn), getAccessToken, { method: "DELETE", }); @@ -857,7 +857,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } setSuccessMessage(null); const response = await authenticatedFetch( - `${API_BASE_URL}/api/tenants/${tenantId}/admins/${encodeURIComponent(adminUpn)}/${action}`, + api.tenants.adminAction(tenantId, adminUpn, action), getAccessToken, { method: "PATCH" }, ); @@ -894,7 +894,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } setSuccessMessage(null); const response = await authenticatedFetch( - `${API_BASE_URL}/api/tenants/${tenantId}/admins/${encodeURIComponent(adminUpn)}/permissions`, + api.tenants.adminPermissions(tenantId, adminUpn), getAccessToken, { method: "PATCH", @@ -932,7 +932,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } const createBootstrapSession = useCallback(async (validityHours: number, label: string): Promise => { if (!tenantId) return null; try { - const response = await authenticatedFetch(`${API_BASE_URL}/api/bootstrap/sessions`, getAccessToken, { + const response = await authenticatedFetch(api.bootstrap.sessions(), getAccessToken, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ tenantId, validityHours, label }), @@ -961,7 +961,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } if (!tenantId) return; try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/bootstrap/sessions/${code}?tenantId=${tenantId}`, + api.bootstrap.session(code, tenantId), getAccessToken, { method: "DELETE" }, ); @@ -991,7 +991,7 @@ export function TenantConfigProvider({ children }: { children: React.ReactNode } setOffboarding(true); setOffboardError(null); - const response = await authenticatedFetch(`${API_BASE_URL}/api/tenants/${tenantId}/offboard`, getAccessToken, { + const response = await authenticatedFetch(api.tenants.offboard(tenantId), getAccessToken, { method: 'DELETE', }); diff --git a/src/Web/autopilot-monitor-web/app/settings/components/ApiKeysSection.tsx b/src/Web/autopilot-monitor-web/app/settings/components/ApiKeysSection.tsx index bbebf291..23c48436 100644 --- a/src/Web/autopilot-monitor-web/app/settings/components/ApiKeysSection.tsx +++ b/src/Web/autopilot-monitor-web/app/settings/components/ApiKeysSection.tsx @@ -1,7 +1,7 @@ "use client"; import { useState, useEffect, useCallback } from "react"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; interface ApiKey { @@ -43,7 +43,7 @@ export default function ApiKeysSection({ const loadKeys = useCallback(async () => { try { setLoading(true); - const endpoint = isGlobalAdmin ? `${API_BASE_URL}/api/global/api-keys` : `${API_BASE_URL}/api/api-keys`; + const endpoint = isGlobalAdmin ? api.apiKeys.globalList() : api.apiKeys.list(); const res = await authenticatedFetch(endpoint, getAccessToken); if (!res.ok) throw new Error(`Failed to load API keys: ${res.statusText}`); const data = await res.json(); @@ -66,7 +66,7 @@ export default function ApiKeysSection({ const body: Record = { label: newLabel.trim(), scope: newScope }; if (newExpiryDays && parseInt(newExpiryDays) > 0) body.expiresInDays = parseInt(newExpiryDays); if (newScope === "tenant" && newTenantId) body.tenantIdOverride = newTenantId; - const res = await authenticatedFetch(`${API_BASE_URL}/api/api-keys`, getAccessToken, { + const res = await authenticatedFetch(api.apiKeys.list(), getAccessToken, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), @@ -91,7 +91,7 @@ export default function ApiKeysSection({ try { setRevokingKey(keyId); setError(null); - const res = await authenticatedFetch(`${API_BASE_URL}/api/api-keys/${keyId}`, getAccessToken, { method: "DELETE" }); + const res = await authenticatedFetch(api.apiKeys.delete(keyId), getAccessToken, { method: "DELETE" }); if (!res.ok) throw new Error(`Failed to revoke: ${res.statusText}`); setSuccessMessage("API key revoked successfully"); await loadKeys(); diff --git a/src/Web/autopilot-monitor-web/app/usage-metrics/page.tsx b/src/Web/autopilot-monitor-web/app/usage-metrics/page.tsx index 8a081c95..0ca04b01 100644 --- a/src/Web/autopilot-monitor-web/app/usage-metrics/page.tsx +++ b/src/Web/autopilot-monitor-web/app/usage-metrics/page.tsx @@ -6,8 +6,9 @@ import { useTenant } from '../../contexts/TenantContext'; import { useAuth } from '../../contexts/AuthContext'; import { useNotifications } from '../../contexts/NotificationContext'; import { ProtectedRoute } from '../../components/ProtectedRoute'; -import { API_BASE_URL } from '@/lib/config'; +import { api } from "@/lib/api"; import { authenticatedFetch, TokenExpiredError } from "@/lib/authenticatedFetch"; +import { useAdminMode } from "@/hooks/useAdminMode"; interface TenantInfo { tenantId: string; @@ -87,12 +88,7 @@ export default function UsageMetricsPage() { const [refreshing, setRefreshing] = useState(false); // Global admin mode - const [globalAdminMode] = useState(() => { - if (typeof window !== 'undefined') { - return localStorage.getItem('globalAdminMode') === 'true'; - } - return false; - }); + const { globalAdminMode } = useAdminMode(); const [tenants, setTenants] = useState([]); const [selectedTenantId, setSelectedTenantId] = useState(''); @@ -101,7 +97,7 @@ export default function UsageMetricsPage() { if (!globalAdminMode || !user?.isGlobalAdmin) return; const fetchTenants = async () => { try { - const response = await authenticatedFetch(`${API_BASE_URL}/api/config/all`, getAccessToken); + const response = await authenticatedFetch(api.config.all(), getAccessToken); if (response.ok) { const data = await response.json(); const mapped: TenantInfo[] = data.map((t: { tenantId: string; domainName: string }) => ({ @@ -143,8 +139,8 @@ export default function UsageMetricsPage() { // Global admin viewing another tenant → use global endpoint const url = isGlobalOverride - ? `${API_BASE_URL}/api/global/metrics/usage?tenantId=${effectiveTenantId}` - : `${API_BASE_URL}/api/metrics/usage?tenantId=${effectiveTenantId}`; + ? api.metrics.globalUsage(effectiveTenantId) + : api.metrics.usage(effectiveTenantId); const response = await authenticatedFetch(url, getAccessToken); diff --git a/src/Web/autopilot-monitor-web/components/FeedbackBubble.tsx b/src/Web/autopilot-monitor-web/components/FeedbackBubble.tsx index 7b793ce4..c15363a5 100644 --- a/src/Web/autopilot-monitor-web/components/FeedbackBubble.tsx +++ b/src/Web/autopilot-monitor-web/components/FeedbackBubble.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect, useState } from "react"; import { useAuth } from "@/contexts/AuthContext"; -import { API_BASE_URL } from "@/lib/config"; +import { api } from "@/lib/api"; import { authenticatedFetch } from "@/lib/authenticatedFetch"; type Phase = "loading" | "bubble" | "form" | "thankyou" | "hidden"; @@ -24,7 +24,7 @@ export default function FeedbackBubble() { const checkEligibility = async () => { try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/feedback/status`, + api.feedback.status(), getAccessToken ); if (cancelled) return; @@ -54,7 +54,7 @@ export default function FeedbackBubble() { const handleDismiss = useCallback(async () => { setPhase("hidden"); try { - await authenticatedFetch(`${API_BASE_URL}/api/feedback`, getAccessToken, { + await authenticatedFetch(api.feedback.submit(), getAccessToken, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ dismissed: true }), @@ -69,7 +69,7 @@ export default function FeedbackBubble() { setSubmitting(true); try { - await authenticatedFetch(`${API_BASE_URL}/api/feedback`, getAccessToken, { + await authenticatedFetch(api.feedback.submit(), getAccessToken, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ rating, comment: comment.trim() || null, dismissed: false }), diff --git a/src/Web/autopilot-monitor-web/components/GlobalSidebar.tsx b/src/Web/autopilot-monitor-web/components/GlobalSidebar.tsx index e3b35cc8..faee33c2 100644 --- a/src/Web/autopilot-monitor-web/components/GlobalSidebar.tsx +++ b/src/Web/autopilot-monitor-web/components/GlobalSidebar.tsx @@ -9,6 +9,7 @@ import { CollapseState } from "../hooks/useSidebarState"; import { DefaultSectionIcon, BookOpenIcon, RocketLaunchIcon, InformationCircleIcon, DocumentTextIcon, ShieldCheckIcon } from "../lib/sidebarIcons"; import { DASHBOARD_ITEM, NAV_GROUPS, EXPANDABLE_NAV_GROUPS, REGULAR_USER_ITEMS, NavItem, NavGroup, ExpandableNavGroup, ExpandableNavItem } from "../lib/globalNavConfig"; import { PublicSiteNavbar } from "./PublicSiteNavbar"; +import { useAdminMode } from "../hooks/useAdminMode"; // Sidebar pixel widths export const SIDEBAR_PX: Record = { @@ -45,19 +46,8 @@ export function GlobalSidebar({ children }: { children: ReactNode }) { return () => mql.removeEventListener("change", handler); }, []); - // Global admin mode from localStorage (same pattern as Navbar) - const [globalAdminMode, setGlobalAdminMode] = useState(false); - useEffect(() => { - if (typeof window === "undefined") return; - const read = () => setGlobalAdminMode(localStorage.getItem("globalAdminMode") === "true"); - read(); - window.addEventListener("localStorageChange", read); - window.addEventListener("storage", read); - return () => { - window.removeEventListener("localStorageChange", read); - window.removeEventListener("storage", read); - }; - }, []); + // Global admin mode from hook + const { globalAdminMode } = useAdminMode(); // --- Scroll-spy for page sections --- const [activeSectionId, setActiveSectionId] = useState(""); diff --git a/src/Web/autopilot-monitor-web/components/Navbar.tsx b/src/Web/autopilot-monitor-web/components/Navbar.tsx index 187a78ff..1e291690 100644 --- a/src/Web/autopilot-monitor-web/components/Navbar.tsx +++ b/src/Web/autopilot-monitor-web/components/Navbar.tsx @@ -6,9 +6,9 @@ import { useGlobalNotifications } from '@/contexts/GlobalNotificationContext'; import { useTheme } from '@/contexts/ThemeContext'; import { useState, useRef, useEffect } from 'react'; import Link from 'next/link'; -import { API_BASE_URL } from '@/lib/config'; import { usePathname } from 'next/navigation'; import { trackEvent } from '@/lib/appInsights'; +import { useAdminMode } from '@/hooks/useAdminMode'; export default function Navbar() { const { isAuthenticated, user, logout } = useAuth(); @@ -21,18 +21,7 @@ export default function Navbar() { const [showUserMenu, setShowUserMenu] = useState(false); const [showSettings, setShowSettings] = useState(false); const [showHelp, setShowHelp] = useState(false); - const [adminMode, setAdminMode] = useState(() => { - if (typeof window !== 'undefined') { - return localStorage.getItem('adminMode') === 'true'; - } - return false; - }); - const [globalAdminMode, setGlobalAdminMode] = useState(() => { - if (typeof window !== 'undefined') { - return localStorage.getItem('globalAdminMode') === 'true'; - } - return false; - }); + const { adminMode, setAdminMode, globalAdminMode, setGlobalAdminMode } = useAdminMode(); const [previewMode, setPreviewMode] = useState(() => { if (typeof window !== 'undefined') { return localStorage.getItem('previewMode') === 'true'; @@ -45,21 +34,6 @@ export default function Navbar() { const settingsRef = useRef(null); const helpRef = useRef(null); - // Update localStorage when modes change and dispatch custom event - useEffect(() => { - if (typeof window !== 'undefined') { - localStorage.setItem('adminMode', adminMode.toString()); - window.dispatchEvent(new Event('localStorageChange')); - } - }, [adminMode]); - - useEffect(() => { - if (typeof window !== 'undefined') { - localStorage.setItem('globalAdminMode', globalAdminMode.toString()); - window.dispatchEvent(new Event('localStorageChange')); - } - }, [globalAdminMode]); - useEffect(() => { if (typeof window !== 'undefined') { localStorage.setItem('previewMode', previewMode.toString()); diff --git a/src/Web/autopilot-monitor-web/contexts/AuthContext.tsx b/src/Web/autopilot-monitor-web/contexts/AuthContext.tsx index 69511157..97bf42b2 100644 --- a/src/Web/autopilot-monitor-web/contexts/AuthContext.tsx +++ b/src/Web/autopilot-monitor-web/contexts/AuthContext.tsx @@ -4,7 +4,7 @@ import React, { createContext, useContext, useEffect, useState, useCallback, use import { PublicClientApplication, AccountInfo, InteractionStatus, InteractionRequiredAuthError, BrowserAuthError } from '@azure/msal-browser'; import { MsalProvider, useMsal, useIsAuthenticated } from '@azure/msal-react'; import { msalConfig, loginRequest, apiRequest } from '@/lib/msalConfig'; -import { API_BASE_URL } from '@/lib/config'; +import { api } from '@/lib/api'; // Initialize MSAL instance const msalInstance = new PublicClientApplication(msalConfig); @@ -124,7 +124,7 @@ function AuthProviderInternal({ children }: { children: React.ReactNode }) { const authMeTimeout = setTimeout(() => authMeController.abort(), 8000); let response: Response; try { - response = await fetch(`${API_BASE_URL}/api/auth/me`, { + response = await fetch(api.auth.me(), { headers: { 'Authorization': `Bearer ${tokenResponse.accessToken}`, }, @@ -269,10 +269,10 @@ function AuthProviderInternal({ children }: { children: React.ReactNode }) { try { await instance.loginRedirect(loginRequest); - } catch (error: any) { + } catch (error: unknown) { // Ignore interaction_in_progress errors - this can happen if user clicks button multiple times // or if another part of the app already triggered a redirect. - if (error?.errorCode === 'interaction_in_progress') { + if (error instanceof Error && 'errorCode' in error && error.errorCode === 'interaction_in_progress') { console.log('[Auth] Interaction already in progress, ignoring duplicate login attempt'); return; } diff --git a/src/Web/autopilot-monitor-web/contexts/GlobalNotificationContext.tsx b/src/Web/autopilot-monitor-web/contexts/GlobalNotificationContext.tsx index 16df2e08..1eb7cacc 100644 --- a/src/Web/autopilot-monitor-web/contexts/GlobalNotificationContext.tsx +++ b/src/Web/autopilot-monitor-web/contexts/GlobalNotificationContext.tsx @@ -2,7 +2,7 @@ import React, { createContext, useContext, useState, useCallback, useEffect, useRef } from 'react'; import { useAuth } from './AuthContext'; -import { API_BASE_URL } from '@/lib/config'; +import { api } from '@/lib/api'; import { authenticatedFetch } from '@/lib/authenticatedFetch'; export interface GlobalNotification { @@ -41,7 +41,7 @@ export function GlobalNotificationProvider({ children }: { children: React.React try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/global/notifications`, + api.notifications.list(), getAccessToken, ); if (response.ok) { @@ -89,7 +89,7 @@ export function GlobalNotificationProvider({ children }: { children: React.React try { await authenticatedFetch( - `${API_BASE_URL}/api/global/notifications/${id}/dismiss`, + api.notifications.dismiss(id), getAccessToken, { method: 'POST' }, ); @@ -103,7 +103,7 @@ export function GlobalNotificationProvider({ children }: { children: React.React try { await authenticatedFetch( - `${API_BASE_URL}/api/global/notifications/dismiss-all`, + api.notifications.dismissAll(), getAccessToken, { method: 'POST' }, ); diff --git a/src/Web/autopilot-monitor-web/contexts/SignalRContext.tsx b/src/Web/autopilot-monitor-web/contexts/SignalRContext.tsx index a16fa1c5..ae01f96b 100644 --- a/src/Web/autopilot-monitor-web/contexts/SignalRContext.tsx +++ b/src/Web/autopilot-monitor-web/contexts/SignalRContext.tsx @@ -2,7 +2,7 @@ import React, { createContext, useContext, useEffect, useRef, useState, useCallback } from 'react'; import * as signalR from '@microsoft/signalr'; -import { API_BASE_URL } from '@/lib/config'; +import { api } from '@/lib/api'; import { authenticatedFetch } from '@/lib/authenticatedFetch'; import { trackEvent } from '@/lib/appInsights'; import { useAuth } from './AuthContext'; @@ -47,7 +47,7 @@ export function SignalRProvider({ children }: { children: React.ReactNode }) { return; } - const hubUrl = `${API_BASE_URL}/api/realtime`; + const hubUrl = api.realtime.hub(); const newConnection = new signalR.HubConnectionBuilder() .withUrl(hubUrl, { accessTokenFactory: async () => { @@ -94,7 +94,7 @@ export function SignalRProvider({ children }: { children: React.ReactNode }) { for (const groupName of previousGroups) { try { const response = await authenticatedFetch( - `${API_BASE_URL}/api/realtime/groups/join`, + api.realtime.joinGroup(), getAccessToken, { method: 'POST', @@ -196,7 +196,7 @@ export function SignalRProvider({ children }: { children: React.ReactNode }) { } const response = await authenticatedFetch( - `${API_BASE_URL}/api/realtime/groups/join`, + api.realtime.joinGroup(), getAccessToken, { method: 'POST', @@ -239,7 +239,7 @@ export function SignalRProvider({ children }: { children: React.ReactNode }) { } const response = await authenticatedFetch( - `${API_BASE_URL}/api/realtime/groups/leave`, + api.realtime.leaveGroup(), getAccessToken, { method: 'POST', diff --git a/src/Web/autopilot-monitor-web/hooks/index.ts b/src/Web/autopilot-monitor-web/hooks/index.ts index 4b4d85f7..8fed52b2 100644 --- a/src/Web/autopilot-monitor-web/hooks/index.ts +++ b/src/Web/autopilot-monitor-web/hooks/index.ts @@ -1,3 +1,4 @@ +export { useAdminMode } from "./useAdminMode"; export { useAuthenticatedFetch } from "./useAuthenticatedFetch"; export type { UseAuthenticatedFetchOptions, diff --git a/src/Web/autopilot-monitor-web/hooks/useAdminMode.ts b/src/Web/autopilot-monitor-web/hooks/useAdminMode.ts new file mode 100644 index 00000000..9bee4584 --- /dev/null +++ b/src/Web/autopilot-monitor-web/hooks/useAdminMode.ts @@ -0,0 +1,81 @@ +"use client"; + +import { useState, useEffect } from "react"; + +interface UseAdminModeReturn { + adminMode: boolean; + setAdminMode: (value: boolean) => void; + globalAdminMode: boolean; + setGlobalAdminMode: (value: boolean) => void; +} + +/** + * Manages adminMode and globalAdminMode state with localStorage persistence. + * Changes are persisted to localStorage and broadcast via a 'localStorageChange' + * custom event so all components on the same page stay in sync. + * Cross-tab synchronization uses the native 'storage' event. + */ +export function useAdminMode(): UseAdminModeReturn { + const [adminMode, setAdminModeState] = useState(() => { + if (typeof window !== "undefined") { + return localStorage.getItem("adminMode") === "true"; + } + return false; + }); + + const [globalAdminMode, setGlobalAdminModeState] = useState(() => { + if (typeof window !== "undefined") { + return localStorage.getItem("globalAdminMode") === "true"; + } + return false; + }); + + // Persist to localStorage and notify same-tab listeners on change + useEffect(() => { + localStorage.setItem("adminMode", adminMode.toString()); + window.dispatchEvent(new Event("localStorageChange")); + }, [adminMode]); + + useEffect(() => { + localStorage.setItem("globalAdminMode", globalAdminMode.toString()); + window.dispatchEvent(new Event("localStorageChange")); + }, [globalAdminMode]); + + // Sync from external changes (cross-tab via 'storage', same-tab via 'localStorageChange') + useEffect(() => { + const handleStorageChange = (e: StorageEvent) => { + if (e.key === "adminMode" && e.newValue !== null) { + setAdminModeState(e.newValue === "true"); + } + if (e.key === "globalAdminMode" && e.newValue !== null) { + setGlobalAdminModeState(e.newValue === "true"); + } + }; + + const handleCustomStorageChange = () => { + const newAdminMode = localStorage.getItem("adminMode") === "true"; + const newGlobalMode = localStorage.getItem("globalAdminMode") === "true"; + setAdminModeState((prev) => (prev !== newAdminMode ? newAdminMode : prev)); + setGlobalAdminModeState((prev) => + prev !== newGlobalMode ? newGlobalMode : prev + ); + }; + + window.addEventListener("storage", handleStorageChange); + window.addEventListener("localStorageChange", handleCustomStorageChange); + return () => { + window.removeEventListener("storage", handleStorageChange); + window.removeEventListener( + "localStorageChange", + handleCustomStorageChange + ); + }; + }, []); + + return { + adminMode, + setAdminMode: setAdminModeState, + globalAdminMode, + setGlobalAdminMode: setGlobalAdminModeState, + }; +} diff --git a/src/Web/autopilot-monitor-web/lib/api.ts b/src/Web/autopilot-monitor-web/lib/api.ts new file mode 100644 index 00000000..63cc4e75 --- /dev/null +++ b/src/Web/autopilot-monitor-web/lib/api.ts @@ -0,0 +1,238 @@ +/** + * Typed API URL builder + * All backend endpoint URLs are defined here for type-safety and maintainability. + */ +import { API_BASE_URL } from "./config"; + +function qs(params: Record): string { + const p = new URLSearchParams(); + for (const [key, value] of Object.entries(params)) { + if (value !== undefined && value !== "") p.set(key, value); + } + const str = p.toString(); + return str ? `?${str}` : ""; +} + +export const api = { + // ── Auth ────────────────────────────────────────────────────────────────── + auth: { + me: () => `${API_BASE_URL}/api/auth/me`, + }, + + // ── Sessions ────────────────────────────────────────────────────────────── + sessions: { + list: (tenantId?: string) => + `${API_BASE_URL}/api/sessions${qs({ tenantId })}`, + get: (sessionId: string, tenantId?: string) => + `${API_BASE_URL}/api/sessions/${sessionId}${qs({ tenantId })}`, + events: (sessionId: string, tenantId?: string) => + `${API_BASE_URL}/api/sessions/${sessionId}/events${qs({ tenantId })}`, + delete: (sessionId: string, tenantId: string) => + `${API_BASE_URL}/api/sessions/${sessionId}${qs({ tenantId })}`, + analysis: (sessionId: string, tenantId?: string, reanalyze?: boolean) => + `${API_BASE_URL}/api/sessions/${sessionId}/analysis${qs({ tenantId, ...(reanalyze ? { reanalyze: "true" } : {}) })}`, + vulnerabilityReport: (sessionId: string, tenantId?: string, rescan?: boolean) => + `${API_BASE_URL}/api/sessions/${sessionId}/vulnerability-report${qs({ tenantId, ...(rescan ? { rescan: "true" } : {}) })}`, + markFailed: (sessionId: string, tenantId?: string) => + `${API_BASE_URL}/api/sessions/${sessionId}/mark-failed${qs({ tenantId })}`, + markSucceeded: (sessionId: string, tenantId?: string) => + `${API_BASE_URL}/api/sessions/${sessionId}/mark-succeeded${qs({ tenantId })}`, + report: (sessionId: string, tenantId?: string) => + `${API_BASE_URL}/api/sessions/${sessionId}/report${qs({ tenantId })}`, + }, + + // ── Global Sessions (global admin) ──────────────────────────────────────── + globalSessions: { + list: (tenantId?: string) => + `${API_BASE_URL}/api/global/sessions${qs({ tenantId })}`, + }, + + // ── Config ──────────────────────────────────────────────────────────────── + config: { + all: () => `${API_BASE_URL}/api/config/all`, + tenant: (tenantId: string) => `${API_BASE_URL}/api/config/${tenantId}`, + autopilotConsentUrl: (tenantId: string, redirectUri: string) => + `${API_BASE_URL}/api/config/${tenantId}/autopilot-device-validation/consent-url${qs({ redirectUri })}`, + autopilotConsentStatus: (tenantId: string) => + `${API_BASE_URL}/api/config/${tenantId}/autopilot-device-validation/consent-status`, + testNotification: (tenantId: string) => + `${API_BASE_URL}/api/config/${tenantId}/test-notification`, + }, + + // ── Global Config (global admin) ────────────────────────────────────────── + globalConfig: { + get: () => `${API_BASE_URL}/api/global/config`, + tenant: (tenantId: string) => `${API_BASE_URL}/api/global/config/${tenantId}`, + }, + + // ── Tenants ─────────────────────────────────────────────────────────────── + tenants: { + admins: (tenantId: string) => + `${API_BASE_URL}/api/tenants/${tenantId}/admins`, + admin: (tenantId: string, adminUpn: string) => + `${API_BASE_URL}/api/tenants/${tenantId}/admins/${encodeURIComponent(adminUpn)}`, + adminAction: (tenantId: string, adminUpn: string, action: string) => + `${API_BASE_URL}/api/tenants/${tenantId}/admins/${encodeURIComponent(adminUpn)}/${action}`, + adminPermissions: (tenantId: string, adminUpn: string) => + `${API_BASE_URL}/api/tenants/${tenantId}/admins/${encodeURIComponent(adminUpn)}/permissions`, + offboard: (tenantId: string) => + `${API_BASE_URL}/api/tenants/${tenantId}/offboard`, + }, + + // ── Devices ─────────────────────────────────────────────────────────────── + devices: { + blocked: (tenantId: string) => + `${API_BASE_URL}/api/devices/blocked${qs({ tenantId })}`, + block: () => `${API_BASE_URL}/api/devices/block`, + unblock: (serialNumber: string, tenantId: string) => + `${API_BASE_URL}/api/devices/block/${encodeURIComponent(serialNumber)}${qs({ tenantId })}`, + allBlocked: () => `${API_BASE_URL}/api/global/devices/blocked`, + }, + + // ── Versions ────────────────────────────────────────────────────────────── + versions: { + blocked: () => `${API_BASE_URL}/api/versions/blocked`, + block: () => `${API_BASE_URL}/api/versions/block`, + unblock: (pattern: string) => + `${API_BASE_URL}/api/versions/block/${encodeURIComponent(pattern)}`, + }, + + // ── Rules ───────────────────────────────────────────────────────────────── + rules: { + analyze: () => `${API_BASE_URL}/api/rules/analyze`, + analyzeRule: (ruleId: string) => + `${API_BASE_URL}/api/rules/analyze/${encodeURIComponent(ruleId)}`, + globalAnalyze: (tenantId?: string) => + `${API_BASE_URL}/api/global/rules/analyze${qs({ tenantId })}`, + gather: (tenantId?: string) => + `${API_BASE_URL}/api/rules/gather${qs({ tenantId })}`, + gatherRule: (ruleId: string, tenantId?: string) => + `${API_BASE_URL}/api/rules/gather/${ruleId}${qs({ tenantId })}`, + globalGather: (tenantId?: string) => + `${API_BASE_URL}/api/global/rules/gather${qs({ tenantId })}`, + reseedFromGitHub: (type: "analyze" | "gather" | "ime" | "all") => + `${API_BASE_URL}/api/rules/reseed-from-github${qs({ type })}`, + imeLogPatterns: () => `${API_BASE_URL}/api/rules/ime-log-patterns`, + imeLogPattern: (patternId: string) => + `${API_BASE_URL}/api/rules/ime-log-patterns/${encodeURIComponent(patternId)}${qs({ global: "true" })}`, + }, + + // ── Metrics ─────────────────────────────────────────────────────────────── + metrics: { + usage: (tenantId?: string) => + `${API_BASE_URL}/api/metrics/usage${qs({ tenantId })}`, + globalUsage: (tenantId?: string) => + `${API_BASE_URL}/api/global/metrics/usage${qs({ tenantId })}`, + app: (tenantId: string, days: number) => + `${API_BASE_URL}/api/metrics/app${qs({ tenantId, days: String(days) })}`, + globalApp: (days: number) => + `${API_BASE_URL}/api/global/metrics/app${qs({ days: String(days) })}`, + geographic: (tenantId: string, days: number, groupBy: string) => + `${API_BASE_URL}/api/metrics/geographic${qs({ tenantId, days: String(days), groupBy })}`, + globalGeographic: (days: number, groupBy: string) => + `${API_BASE_URL}/api/global/metrics/geographic${qs({ days: String(days), groupBy })}`, + geographicSessions: (tenantId: string, days: number, groupBy: string, locationKey: string) => + `${API_BASE_URL}/api/metrics/geographic/sessions${qs({ tenantId, days: String(days), groupBy, locationKey })}`, + globalGeographicSessions: (days: number, groupBy: string, locationKey: string) => + `${API_BASE_URL}/api/global/metrics/geographic/sessions${qs({ days: String(days), groupBy, locationKey })}`, + platform: () => `${API_BASE_URL}/api/global/metrics/platform`, + }, + + // ── Diagnostics ─────────────────────────────────────────────────────────── + diagnostics: { + downloadUrl: (tenantId: string, blobName: string) => + `${API_BASE_URL}/api/diagnostics/download-url${qs({ tenantId, blobName })}`, + }, + + // ── Progress ────────────────────────────────────────────────────────────── + progress: { + sessions: (tenantId: string) => + `${API_BASE_URL}/api/progress/sessions${qs({ tenantId })}`, + sessionEvents: (sessionId: string, tenantId: string) => + `${API_BASE_URL}/api/progress/sessions/${sessionId}/events${qs({ tenantId })}`, + }, + + // ── Bootstrap ───────────────────────────────────────────────────────────── + bootstrap: { + sessions: (tenantId?: string) => + `${API_BASE_URL}/api/bootstrap/sessions${qs({ tenantId })}`, + session: (code: string, tenantId: string) => + `${API_BASE_URL}/api/bootstrap/sessions/${code}${qs({ tenantId })}`, + }, + + // ── Reports ─────────────────────────────────────────────────────────────── + reports: { + list: () => `${API_BASE_URL}/api/global/session-reports`, + downloadUrl: (blobName: string) => + `${API_BASE_URL}/api/global/session-reports/download-url${qs({ blobName })}`, + note: (reportId: string) => + `${API_BASE_URL}/api/global/session-reports/${reportId}/note`, + }, + + // ── Notifications ───────────────────────────────────────────────────────── + notifications: { + list: () => `${API_BASE_URL}/api/global/notifications`, + dismiss: (id: string) => `${API_BASE_URL}/api/global/notifications/${id}/dismiss`, + dismissAll: () => `${API_BASE_URL}/api/global/notifications/dismiss-all`, + }, + + // ── Audit ───────────────────────────────────────────────────────────────── + audit: { + logs: () => `${API_BASE_URL}/api/audit/logs`, + globalLogs: () => `${API_BASE_URL}/api/global/audit/logs`, + }, + + // ── API Keys ────────────────────────────────────────────────────────────── + apiKeys: { + list: () => `${API_BASE_URL}/api/api-keys`, + globalList: () => `${API_BASE_URL}/api/global/api-keys`, + delete: (keyId: string) => `${API_BASE_URL}/api/api-keys/${keyId}`, + }, + + // ── Feedback ────────────────────────────────────────────────────────────── + feedback: { + status: () => `${API_BASE_URL}/api/feedback/status`, + submit: () => `${API_BASE_URL}/api/feedback`, + all: () => `${API_BASE_URL}/api/feedback/all`, + }, + + // ── Preview ─────────────────────────────────────────────────────────────── + preview: { + whitelist: () => `${API_BASE_URL}/api/preview/whitelist`, + whitelistTenant: (tenantId: string) => + `${API_BASE_URL}/api/preview/whitelist/${tenantId}`, + sendWelcomeEmail: (tenantId: string) => + `${API_BASE_URL}/api/preview/send-welcome-email/${tenantId}`, + notificationEmail: () => `${API_BASE_URL}/api/preview/notification-email`, + notificationEmailTenant: (tenantId: string) => + `${API_BASE_URL}/api/preview/notification-email/${tenantId}`, + }, + + // ── Vulnerability ───────────────────────────────────────────────────────── + vulnerability: { + sync: () => `${API_BASE_URL}/api/vulnerability/sync`, + syncReseed: (type: string) => + `${API_BASE_URL}/api/vulnerability/sync${qs({ reseed: type })}`, + cpeMappings: () => `${API_BASE_URL}/api/vulnerability/cpe-mappings`, + cpeMapping: () => `${API_BASE_URL}/api/vulnerability/cpe-mapping`, + unmatchedSoftware: () => `${API_BASE_URL}/api/vulnerability/unmatched-software`, + }, + + // ── Maintenance ─────────────────────────────────────────────────────────── + maintenance: { + trigger: (date?: string) => + `${API_BASE_URL}/api/maintenance/trigger${qs({ date })}`, + }, + + // ── Health ──────────────────────────────────────────────────────────────── + health: { + detailed: () => `${API_BASE_URL}/api/health/detailed`, + }, + + // ── Realtime (SignalR) ──────────────────────────────────────────────────── + realtime: { + hub: () => `${API_BASE_URL}/api/realtime`, + joinGroup: () => `${API_BASE_URL}/api/realtime/groups/join`, + leaveGroup: () => `${API_BASE_URL}/api/realtime/groups/leave`, + }, +}; diff --git a/src/Web/autopilot-monitor-web/tsconfig.tsbuildinfo b/src/Web/autopilot-monitor-web/tsconfig.tsbuildinfo index 49003fdf..b5db3c7c 100644 --- a/src/Web/autopilot-monitor-web/tsconfig.tsbuildinfo +++ b/src/Web/autopilot-monitor-web/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.es2023.d.ts","./node_modules/typescript/lib/lib.es2024.d.ts","./node_modules/typescript/lib/lib.esnext.d.ts","./node_modules/typescript/lib/lib.dom.d.ts","./node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2016.intl.d.ts","./node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.es2022.regexp.d.ts","./node_modules/typescript/lib/lib.es2023.array.d.ts","./node_modules/typescript/lib/lib.es2023.collection.d.ts","./node_modules/typescript/lib/lib.es2023.intl.d.ts","./node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2024.collection.d.ts","./node_modules/typescript/lib/lib.es2024.object.d.ts","./node_modules/typescript/lib/lib.es2024.promise.d.ts","./node_modules/typescript/lib/lib.es2024.regexp.d.ts","./node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2024.string.d.ts","./node_modules/typescript/lib/lib.esnext.array.d.ts","./node_modules/typescript/lib/lib.esnext.collection.d.ts","./node_modules/typescript/lib/lib.esnext.intl.d.ts","./node_modules/typescript/lib/lib.esnext.disposable.d.ts","./node_modules/typescript/lib/lib.esnext.promise.d.ts","./node_modules/typescript/lib/lib.esnext.decorators.d.ts","./node_modules/typescript/lib/lib.esnext.iterator.d.ts","./node_modules/typescript/lib/lib.esnext.float16.d.ts","./node_modules/typescript/lib/lib.esnext.error.d.ts","./node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts","./node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/typescript/lib/lib.decorators.legacy.d.ts","./node_modules/@types/react/global.d.ts","./node_modules/csstype/index.d.ts","./node_modules/@types/prop-types/index.d.ts","./node_modules/@types/react/index.d.ts","./node_modules/next/dist/styled-jsx/types/css.d.ts","./node_modules/next/dist/styled-jsx/types/macro.d.ts","./node_modules/next/dist/styled-jsx/types/style.d.ts","./node_modules/next/dist/styled-jsx/types/global.d.ts","./node_modules/next/dist/styled-jsx/types/index.d.ts","./node_modules/next/dist/shared/lib/amp.d.ts","./node_modules/next/amp.d.ts","./node_modules/next/dist/server/get-page-files.d.ts","./node_modules/@types/node/compatibility/disposable.d.ts","./node_modules/@types/node/compatibility/indexable.d.ts","./node_modules/@types/node/compatibility/iterators.d.ts","./node_modules/@types/node/compatibility/index.d.ts","./node_modules/@types/node/globals.typedarray.d.ts","./node_modules/@types/node/buffer.buffer.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/web-globals/abortcontroller.d.ts","./node_modules/@types/node/web-globals/domexception.d.ts","./node_modules/@types/node/web-globals/events.d.ts","./node_modules/undici-types/header.d.ts","./node_modules/undici-types/readable.d.ts","./node_modules/undici-types/file.d.ts","./node_modules/undici-types/fetch.d.ts","./node_modules/undici-types/formdata.d.ts","./node_modules/undici-types/connector.d.ts","./node_modules/undici-types/client.d.ts","./node_modules/undici-types/errors.d.ts","./node_modules/undici-types/dispatcher.d.ts","./node_modules/undici-types/global-dispatcher.d.ts","./node_modules/undici-types/global-origin.d.ts","./node_modules/undici-types/pool-stats.d.ts","./node_modules/undici-types/pool.d.ts","./node_modules/undici-types/handlers.d.ts","./node_modules/undici-types/balanced-pool.d.ts","./node_modules/undici-types/agent.d.ts","./node_modules/undici-types/mock-interceptor.d.ts","./node_modules/undici-types/mock-agent.d.ts","./node_modules/undici-types/mock-client.d.ts","./node_modules/undici-types/mock-pool.d.ts","./node_modules/undici-types/mock-errors.d.ts","./node_modules/undici-types/proxy-agent.d.ts","./node_modules/undici-types/env-http-proxy-agent.d.ts","./node_modules/undici-types/retry-handler.d.ts","./node_modules/undici-types/retry-agent.d.ts","./node_modules/undici-types/api.d.ts","./node_modules/undici-types/interceptors.d.ts","./node_modules/undici-types/util.d.ts","./node_modules/undici-types/cookies.d.ts","./node_modules/undici-types/patch.d.ts","./node_modules/undici-types/websocket.d.ts","./node_modules/undici-types/eventsource.d.ts","./node_modules/undici-types/filereader.d.ts","./node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/undici-types/content-type.d.ts","./node_modules/undici-types/cache.d.ts","./node_modules/undici-types/index.d.ts","./node_modules/@types/node/web-globals/fetch.d.ts","./node_modules/@types/node/web-globals/navigator.d.ts","./node_modules/@types/node/web-globals/storage.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/inspector.generated.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/sea.d.ts","./node_modules/@types/node/sqlite.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/@types/react/canary.d.ts","./node_modules/@types/react/experimental.d.ts","./node_modules/@types/react-dom/index.d.ts","./node_modules/@types/react-dom/canary.d.ts","./node_modules/@types/react-dom/experimental.d.ts","./node_modules/next/dist/lib/fallback.d.ts","./node_modules/next/dist/compiled/webpack/webpack.d.ts","./node_modules/next/dist/server/config.d.ts","./node_modules/next/dist/lib/load-custom-routes.d.ts","./node_modules/next/dist/shared/lib/image-config.d.ts","./node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","./node_modules/next/dist/server/body-streams.d.ts","./node_modules/next/dist/server/lib/cache-control.d.ts","./node_modules/next/dist/lib/setup-exception-listeners.d.ts","./node_modules/next/dist/lib/worker.d.ts","./node_modules/next/dist/lib/constants.d.ts","./node_modules/next/dist/client/components/app-router-headers.d.ts","./node_modules/next/dist/build/rendering-mode.d.ts","./node_modules/next/dist/server/lib/router-utils/build-prefetch-segment-data-route.d.ts","./node_modules/next/dist/server/require-hook.d.ts","./node_modules/next/dist/server/lib/experimental/ppr.d.ts","./node_modules/next/dist/build/webpack/plugins/app-build-manifest-plugin.d.ts","./node_modules/next/dist/lib/page-types.d.ts","./node_modules/next/dist/build/segment-config/app/app-segment-config.d.ts","./node_modules/next/dist/build/segment-config/pages/pages-segment-config.d.ts","./node_modules/next/dist/build/analysis/get-page-static-info.d.ts","./node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","./node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","./node_modules/next/dist/server/node-polyfill-crypto.d.ts","./node_modules/next/dist/server/node-environment-baseline.d.ts","./node_modules/next/dist/server/node-environment-extensions/error-inspect.d.ts","./node_modules/next/dist/server/node-environment-extensions/random.d.ts","./node_modules/next/dist/server/node-environment-extensions/date.d.ts","./node_modules/next/dist/server/node-environment-extensions/web-crypto.d.ts","./node_modules/next/dist/server/node-environment-extensions/node-crypto.d.ts","./node_modules/next/dist/server/node-environment.d.ts","./node_modules/next/dist/build/page-extensions-type.d.ts","./node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","./node_modules/next/dist/server/instrumentation/types.d.ts","./node_modules/next/dist/lib/coalesced-function.d.ts","./node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","./node_modules/next/dist/server/lib/router-utils/types.d.ts","./node_modules/next/dist/shared/lib/modern-browserslist-target.d.ts","./node_modules/next/dist/shared/lib/constants.d.ts","./node_modules/next/dist/trace/types.d.ts","./node_modules/next/dist/trace/trace.d.ts","./node_modules/next/dist/trace/shared.d.ts","./node_modules/next/dist/trace/index.d.ts","./node_modules/next/dist/build/load-jsconfig.d.ts","./node_modules/@next/env/dist/index.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/use-cache-tracker-utils.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/telemetry-plugin.d.ts","./node_modules/next/dist/telemetry/storage.d.ts","./node_modules/next/dist/build/build-context.d.ts","./node_modules/next/dist/shared/lib/bloom-filter.d.ts","./node_modules/next/dist/build/webpack-config.d.ts","./node_modules/next/dist/server/route-kind.d.ts","./node_modules/next/dist/server/route-definitions/route-definition.d.ts","./node_modules/next/dist/build/swc/generated-native.d.ts","./node_modules/next/dist/build/swc/types.d.ts","./node_modules/next/dist/server/dev/parse-version-info.d.ts","./node_modules/next/dist/next-devtools/shared/types.d.ts","./node_modules/next/dist/server/dev/dev-indicator-server-state.d.ts","./node_modules/next/dist/server/lib/parse-stack.d.ts","./node_modules/next/dist/next-devtools/server/shared.d.ts","./node_modules/next/dist/next-devtools/shared/stack-frame.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/utils/get-error-by-type.d.ts","./node_modules/@types/react/jsx-runtime.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/container/runtime-error/render-error.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/shared.d.ts","./node_modules/next/dist/server/dev/hot-reloader-types.d.ts","./node_modules/next/dist/server/lib/cache-handlers/types.d.ts","./node_modules/next/dist/server/response-cache/types.d.ts","./node_modules/next/dist/server/resume-data-cache/cache-store.d.ts","./node_modules/next/dist/server/resume-data-cache/resume-data-cache.d.ts","./node_modules/next/dist/server/render-result.d.ts","./node_modules/next/dist/server/lib/i18n-provider.d.ts","./node_modules/next/dist/server/web/next-url.d.ts","./node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","./node_modules/next/dist/server/web/spec-extension/cookies.d.ts","./node_modules/next/dist/server/web/spec-extension/request.d.ts","./node_modules/next/dist/server/after/builtin-request-context.d.ts","./node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","./node_modules/next/dist/server/web/spec-extension/response.d.ts","./node_modules/next/dist/build/segment-config/middleware/middleware-config.d.ts","./node_modules/next/dist/server/web/types.d.ts","./node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","./node_modules/next/dist/server/base-http/node.d.ts","./node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","./node_modules/next/dist/server/route-definitions/locale-route-definition.d.ts","./node_modules/next/dist/server/route-definitions/pages-route-definition.d.ts","./node_modules/next/dist/shared/lib/mitt.d.ts","./node_modules/next/dist/client/with-router.d.ts","./node_modules/next/dist/client/router.d.ts","./node_modules/next/dist/client/route-loader.d.ts","./node_modules/next/dist/client/page-loader.d.ts","./node_modules/next/dist/shared/lib/router/router.d.ts","./node_modules/next/dist/shared/lib/router-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/image-config-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-definitions/app-page-route-definition.d.ts","./node_modules/next/dist/build/webpack/loaders/metadata/types.d.ts","./node_modules/next/dist/build/webpack/loaders/next-app-loader/index.d.ts","./node_modules/next/dist/server/lib/app-dir-module.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","./node_modules/next/dist/server/async-storage/draft-mode-provider.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","./node_modules/next/dist/server/app-render/cache-signal.d.ts","./node_modules/next/dist/server/app-render/dynamic-rendering.d.ts","./node_modules/next/dist/server/request/fallback-params.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage-instance.d.ts","./node_modules/next/dist/server/response-cache/index.d.ts","./node_modules/next/dist/server/lib/lazy-result.d.ts","./node_modules/next/dist/server/lib/implicit-tags.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage.external.d.ts","./node_modules/next/dist/shared/lib/deep-readonly.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-relative-url.d.ts","./node_modules/next/dist/server/app-render/app-render.d.ts","./node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/amp-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.compiled.d.ts","./node_modules/next/dist/client/components/error-boundary.d.ts","./node_modules/next/dist/client/components/layout-router.d.ts","./node_modules/next/dist/client/components/render-from-template-context.d.ts","./node_modules/next/dist/server/app-render/action-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/action-async-storage.external.d.ts","./node_modules/next/dist/client/components/client-page.d.ts","./node_modules/next/dist/client/components/client-segment.d.ts","./node_modules/next/dist/server/request/search-params.d.ts","./node_modules/next/dist/client/components/hooks-server-context.d.ts","./node_modules/next/dist/client/components/http-access-fallback/error-boundary.d.ts","./node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","./node_modules/next/dist/lib/metadata/types/extra-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","./node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","./node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","./node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","./node_modules/next/dist/lib/metadata/types/resolvers.d.ts","./node_modules/next/dist/lib/metadata/types/icons.d.ts","./node_modules/next/dist/lib/metadata/resolve-metadata.d.ts","./node_modules/next/dist/lib/metadata/metadata.d.ts","./node_modules/next/dist/lib/framework/boundary-components.d.ts","./node_modules/next/dist/server/app-render/rsc/preloads.d.ts","./node_modules/next/dist/server/app-render/rsc/postpone.d.ts","./node_modules/next/dist/server/app-render/rsc/taint.d.ts","./node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.d.ts","./node_modules/next/dist/server/app-render/collect-segment-data.d.ts","./node_modules/next/dist/next-devtools/userspace/app/segment-explorer-node.d.ts","./node_modules/next/dist/server/app-render/entry-base.d.ts","./node_modules/next/dist/build/templates/app-page.d.ts","./node_modules/@types/react/jsx-dev-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.d.ts","./node_modules/@types/react-dom/client.d.ts","./node_modules/@types/react-dom/server.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.d.ts","./node_modules/next/dist/server/web/adapter.d.ts","./node_modules/next/dist/server/use-cache/cache-life.d.ts","./node_modules/next/dist/server/app-render/types.d.ts","./node_modules/next/dist/client/components/router-reducer/router-reducer-types.d.ts","./node_modules/next/dist/client/flight-data-helpers.d.ts","./node_modules/next/dist/client/components/router-reducer/fetch-server-response.d.ts","./node_modules/next/dist/shared/lib/app-router-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/pages/module.compiled.d.ts","./node_modules/next/dist/build/templates/pages.d.ts","./node_modules/next/dist/server/route-modules/pages/module.d.ts","./node_modules/next/dist/next-devtools/userspace/pages/pages-dev-overlay-setup.d.ts","./node_modules/next/dist/server/render.d.ts","./node_modules/next/dist/server/route-definitions/pages-api-route-definition.d.ts","./node_modules/next/dist/server/route-matches/pages-api-route-match.d.ts","./node_modules/next/dist/server/route-matchers/route-matcher.d.ts","./node_modules/next/dist/server/route-matcher-providers/route-matcher-provider.d.ts","./node_modules/next/dist/server/route-matcher-managers/route-matcher-manager.d.ts","./node_modules/next/dist/server/normalizers/normalizer.d.ts","./node_modules/next/dist/server/normalizers/locale-route-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/pathname-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/suffix.d.ts","./node_modules/next/dist/server/normalizers/request/rsc.d.ts","./node_modules/next/dist/server/normalizers/request/prefetch-rsc.d.ts","./node_modules/next/dist/server/normalizers/request/next-data.d.ts","./node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.d.ts","./node_modules/next/dist/build/static-paths/types.d.ts","./node_modules/next/dist/server/base-server.d.ts","./node_modules/next/dist/server/lib/async-callback-set.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","./node_modules/sharp/lib/index.d.ts","./node_modules/next/dist/server/image-optimizer.d.ts","./node_modules/next/dist/server/next-server.d.ts","./node_modules/next/dist/server/lib/types.d.ts","./node_modules/next/dist/server/lib/lru-cache.d.ts","./node_modules/next/dist/server/lib/dev-bundler-service.d.ts","./node_modules/next/dist/server/dev/static-paths-worker.d.ts","./node_modules/next/dist/server/dev/next-dev-server.d.ts","./node_modules/next/dist/server/next.d.ts","./node_modules/next/dist/server/lib/render-server.d.ts","./node_modules/next/dist/server/lib/router-server.d.ts","./node_modules/next/dist/shared/lib/router/utils/path-match.d.ts","./node_modules/next/dist/server/lib/router-utils/filesystem.d.ts","./node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.d.ts","./node_modules/next/dist/server/lib/router-utils/router-server-context.d.ts","./node_modules/next/dist/server/route-modules/route-module.d.ts","./node_modules/next/dist/server/load-components.d.ts","./node_modules/next/dist/server/route-definitions/app-route-route-definition.d.ts","./node_modules/next/dist/server/async-storage/work-store.d.ts","./node_modules/next/dist/server/web/http.d.ts","./node_modules/next/dist/server/route-modules/app-route/shared-modules.d.ts","./node_modules/next/dist/client/components/redirect-status-code.d.ts","./node_modules/next/dist/client/components/redirect-error.d.ts","./node_modules/next/dist/build/templates/app-route.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.compiled.d.ts","./node_modules/next/dist/build/segment-config/app/app-segments.d.ts","./node_modules/next/dist/build/utils.d.ts","./node_modules/next/dist/build/turborepo-access-trace/types.d.ts","./node_modules/next/dist/build/turborepo-access-trace/result.d.ts","./node_modules/next/dist/build/turborepo-access-trace/helpers.d.ts","./node_modules/next/dist/build/turborepo-access-trace/index.d.ts","./node_modules/next/dist/export/routes/types.d.ts","./node_modules/next/dist/export/types.d.ts","./node_modules/next/dist/export/worker.d.ts","./node_modules/next/dist/build/worker.d.ts","./node_modules/next/dist/build/index.d.ts","./node_modules/next/dist/server/lib/incremental-cache/index.d.ts","./node_modules/next/dist/server/after/after.d.ts","./node_modules/next/dist/server/after/after-context.d.ts","./node_modules/next/dist/server/app-render/work-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/work-async-storage.external.d.ts","./node_modules/next/dist/server/request/params.d.ts","./node_modules/next/dist/server/route-matches/route-match.d.ts","./node_modules/next/dist/server/request-meta.d.ts","./node_modules/next/dist/cli/next-test.d.ts","./node_modules/next/dist/server/config-shared.d.ts","./node_modules/next/dist/server/base-http/index.d.ts","./node_modules/next/dist/server/api-utils/index.d.ts","./node_modules/next/dist/types.d.ts","./node_modules/next/dist/shared/lib/html-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/utils.d.ts","./node_modules/next/dist/pages/_app.d.ts","./node_modules/next/app.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-cache.d.ts","./node_modules/next/dist/server/web/spec-extension/revalidate.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-no-store.d.ts","./node_modules/next/dist/server/use-cache/cache-tag.d.ts","./node_modules/next/cache.d.ts","./node_modules/next/dist/shared/lib/runtime-config.external.d.ts","./node_modules/next/config.d.ts","./node_modules/next/dist/pages/_document.d.ts","./node_modules/next/document.d.ts","./node_modules/next/dist/shared/lib/dynamic.d.ts","./node_modules/next/dynamic.d.ts","./node_modules/next/dist/pages/_error.d.ts","./node_modules/next/error.d.ts","./node_modules/next/dist/shared/lib/head.d.ts","./node_modules/next/head.d.ts","./node_modules/next/dist/server/request/cookies.d.ts","./node_modules/next/dist/server/request/headers.d.ts","./node_modules/next/dist/server/request/draft-mode.d.ts","./node_modules/next/headers.d.ts","./node_modules/next/dist/shared/lib/get-img-props.d.ts","./node_modules/next/dist/client/image-component.d.ts","./node_modules/next/dist/shared/lib/image-external.d.ts","./node_modules/next/image.d.ts","./node_modules/next/dist/client/link.d.ts","./node_modules/next/link.d.ts","./node_modules/next/dist/client/components/redirect.d.ts","./node_modules/next/dist/client/components/not-found.d.ts","./node_modules/next/dist/client/components/forbidden.d.ts","./node_modules/next/dist/client/components/unauthorized.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.server.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.d.ts","./node_modules/next/dist/client/components/navigation.react-server.d.ts","./node_modules/next/dist/client/components/unrecognized-action-error.d.ts","./node_modules/next/dist/client/components/navigation.d.ts","./node_modules/next/navigation.d.ts","./node_modules/next/router.d.ts","./node_modules/next/dist/client/script.d.ts","./node_modules/next/script.d.ts","./node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","./node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","./node_modules/next/dist/server/web/spec-extension/image-response.d.ts","./node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/types.d.ts","./node_modules/next/dist/server/after/index.d.ts","./node_modules/next/dist/server/request/root-params.d.ts","./node_modules/next/dist/server/request/connection.d.ts","./node_modules/next/server.d.ts","./node_modules/next/types/global.d.ts","./node_modules/next/types/compiled.d.ts","./node_modules/next/types.d.ts","./node_modules/next/index.d.ts","./node_modules/next/image-types/global.d.ts","./next-env.d.ts","./next.config.ts","./node_modules/source-map-js/source-map.d.ts","./node_modules/postcss/lib/previous-map.d.ts","./node_modules/postcss/lib/input.d.ts","./node_modules/postcss/lib/css-syntax-error.d.ts","./node_modules/postcss/lib/declaration.d.ts","./node_modules/postcss/lib/root.d.ts","./node_modules/postcss/lib/warning.d.ts","./node_modules/postcss/lib/lazy-result.d.ts","./node_modules/postcss/lib/no-work-result.d.ts","./node_modules/postcss/lib/processor.d.ts","./node_modules/postcss/lib/result.d.ts","./node_modules/postcss/lib/document.d.ts","./node_modules/postcss/lib/rule.d.ts","./node_modules/postcss/lib/node.d.ts","./node_modules/postcss/lib/comment.d.ts","./node_modules/postcss/lib/container.d.ts","./node_modules/postcss/lib/at-rule.d.ts","./node_modules/postcss/lib/list.d.ts","./node_modules/postcss/lib/postcss.d.ts","./node_modules/postcss/lib/postcss.d.mts","./node_modules/tailwindcss/types/generated/corepluginlist.d.ts","./node_modules/tailwindcss/types/generated/colors.d.ts","./node_modules/tailwindcss/types/config.d.ts","./node_modules/tailwindcss/types/index.d.ts","./tailwind.config.ts","./app/robots.ts","./app/docs/docsnavsections.ts","./lib/page-lastmod.generated.ts","./app/sitemap.ts","./app/admin/metrics/metricsnavsections.ts","./app/admin/reports/reportsnavsections.ts","./app/admin/security/securitynavsections.ts","./app/admin/settings/settingsnavsections.ts","./app/admin/tenants/tenantsnavsections.ts","./app/analyze-rules/types.ts","./types/session.ts","./types/enrollment.ts","./types/index.ts","./app/dashboard/types.ts","./app/gather-rules/types.ts","./app/go/[code]/route.ts","./app/ime-log-patterns/types.ts","./app/sessions/[sessionid]/utils/eventhelpers.ts","./app/sessions/[sessionid]/utils/phaseconstants.ts","./app/settings/types.ts","./app/settings/access/accessnavsections.ts","./app/settings/agent/agentnavsections.ts","./app/settings/integrations/integrationsnavsections.ts","./app/settings/management/managementnavsections.ts","./app/settings/validation/validationnavsections.ts","./node_modules/@azure/msal-common/dist/account/tokenclaims.d.ts","./node_modules/@azure/msal-common/dist/account/authtoken.d.ts","./node_modules/@azure/msal-common/dist/authority/authoritytype.d.ts","./node_modules/@azure/msal-common/dist/authority/openidconfigresponse.d.ts","./node_modules/@azure/msal-common/dist/url/iuri.d.ts","./node_modules/@azure/msal-common/dist/network/networkresponse.d.ts","./node_modules/@azure/msal-common/dist/network/inetworkmodule.d.ts","./node_modules/@azure/msal-common/dist/authority/protocolmode.d.ts","./node_modules/@azure/msal-common/dist/utils/constants.d.ts","./node_modules/@azure/msal-common/dist/logger/logger.d.ts","./node_modules/@azure/msal-common/dist/authority/oidcoptions.d.ts","./node_modules/@azure/msal-common/dist/authority/azureregion.d.ts","./node_modules/@azure/msal-common/dist/authority/azureregionconfiguration.d.ts","./node_modules/@azure/msal-common/dist/authority/clouddiscoverymetadata.d.ts","./node_modules/@azure/msal-common/dist/authority/cloudinstancediscoveryresponse.d.ts","./node_modules/@azure/msal-common/dist/authority/authorityoptions.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/credentialentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/idtokenentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/accesstokenentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/refreshtokenentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/appmetadataentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/cacherecord.d.ts","./node_modules/@azure/msal-common/dist/account/accountinfo.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/servertelemetryentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/throttlingentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/authoritymetadataentity.d.ts","./node_modules/@azure/msal-common/dist/request/storeincache.d.ts","./node_modules/@azure/msal-common/dist/telemetry/performance/performanceevent.d.ts","./node_modules/@azure/msal-common/dist/telemetry/performance/iperformancemeasurement.d.ts","./node_modules/@azure/msal-common/dist/telemetry/performance/iperformanceclient.d.ts","./node_modules/@azure/msal-common/dist/cache/cachemanager.d.ts","./node_modules/@azure/msal-common/dist/telemetry/server/servertelemetryrequest.d.ts","./node_modules/@azure/msal-common/dist/authority/regiondiscoverymetadata.d.ts","./node_modules/@azure/msal-common/dist/telemetry/server/servertelemetrymanager.d.ts","./node_modules/@azure/msal-common/dist/cache/interface/iserializabletokencache.d.ts","./node_modules/@azure/msal-common/dist/cache/persistence/tokencachecontext.d.ts","./node_modules/@azure/msal-common/dist/cache/interface/icacheplugin.d.ts","./node_modules/@azure/msal-common/dist/account/clientcredentials.d.ts","./node_modules/@azure/msal-common/dist/config/clientconfiguration.d.ts","./node_modules/@azure/msal-common/dist/utils/msaltypes.d.ts","./node_modules/@azure/msal-common/dist/crypto/joseheader.d.ts","./node_modules/@azure/msal-common/dist/crypto/signedhttprequest.d.ts","./node_modules/@azure/msal-common/dist/request/baseauthrequest.d.ts","./node_modules/@azure/msal-common/dist/crypto/icrypto.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/accountentity.d.ts","./node_modules/@azure/msal-common/dist/request/scopeset.d.ts","./node_modules/@azure/msal-common/dist/cache/utils/cachetypes.d.ts","./node_modules/@azure/msal-common/dist/cache/interface/icachemanager.d.ts","./node_modules/@azure/msal-common/dist/authority/authority.d.ts","./node_modules/@azure/msal-common/dist/authority/authorityfactory.d.ts","./node_modules/@azure/msal-common/dist/cache/utils/cachehelpers.d.ts","./node_modules/@azure/msal-common/dist/utils/timeutils.d.ts","./node_modules/@azure/msal-common/dist/response/serverauthorizationcoderesponse.d.ts","./node_modules/@azure/msal-common/dist/utils/urlutils.d.ts","./node_modules/@azure/msal-common/dist/constants/aadserverparamkeys.d.ts","./node_modules/@azure/msal-common/dist/response/serverauthorizationtokenresponse.d.ts","./node_modules/@azure/msal-common/dist/network/requestthumbprint.d.ts","./node_modules/@azure/msal-common/dist/account/ccscredential.d.ts","./node_modules/@azure/msal-common/dist/client/baseclient.d.ts","./node_modules/@azure/msal-common/dist/request/commonauthorizationurlrequest.d.ts","./node_modules/@azure/msal-common/dist/request/commonauthorizationcoderequest.d.ts","./node_modules/@azure/msal-common/dist/response/authenticationresult.d.ts","./node_modules/@azure/msal-common/dist/request/commonendsessionrequest.d.ts","./node_modules/@azure/msal-common/dist/response/authorizationcodepayload.d.ts","./node_modules/@azure/msal-common/dist/client/authorizationcodeclient.d.ts","./node_modules/@azure/msal-common/dist/request/commonrefreshtokenrequest.d.ts","./node_modules/@azure/msal-common/dist/request/commonsilentflowrequest.d.ts","./node_modules/@azure/msal-common/dist/client/refreshtokenclient.d.ts","./node_modules/@azure/msal-common/dist/client/silentflowclient.d.ts","./node_modules/@azure/msal-common/dist/account/clientinfo.d.ts","./node_modules/@azure/msal-common/dist/network/throttlingutils.d.ts","./node_modules/@azure/msal-common/dist/url/urlstring.d.ts","./node_modules/@azure/msal-common/dist/request/requestparameterbuilder.d.ts","./node_modules/@azure/msal-common/dist/utils/protocolutils.d.ts","./node_modules/@azure/msal-common/dist/response/responsehandler.d.ts","./node_modules/@azure/msal-common/dist/request/authenticationheaderparser.d.ts","./node_modules/@azure/msal-common/dist/error/autherrorcodes.d.ts","./node_modules/@azure/msal-common/dist/error/autherror.d.ts","./node_modules/@azure/msal-common/dist/error/interactionrequiredautherrorcodes.d.ts","./node_modules/@azure/msal-common/dist/error/interactionrequiredautherror.d.ts","./node_modules/@azure/msal-common/dist/error/servererror.d.ts","./node_modules/@azure/msal-common/dist/error/networkerror.d.ts","./node_modules/@azure/msal-common/dist/error/cacheerrorcodes.d.ts","./node_modules/@azure/msal-common/dist/error/cacheerror.d.ts","./node_modules/@azure/msal-common/dist/error/clientautherrorcodes.d.ts","./node_modules/@azure/msal-common/dist/error/clientautherror.d.ts","./node_modules/@azure/msal-common/dist/error/clientconfigurationerrorcodes.d.ts","./node_modules/@azure/msal-common/dist/error/clientconfigurationerror.d.ts","./node_modules/@azure/msal-common/dist/utils/stringutils.d.ts","./node_modules/@azure/msal-common/dist/utils/functionwrappers.d.ts","./node_modules/@azure/msal-common/dist/packagemetadata.d.ts","./node_modules/@azure/msal-common/dist/exports-common.d.ts","./node_modules/@azure/msal-common/dist/response/externaltokenresponse.d.ts","./node_modules/@azure/msal-common/dist/telemetry/performance/performanceclient.d.ts","./node_modules/@azure/msal-common/dist/telemetry/performance/stubperformanceclient.d.ts","./node_modules/@azure/msal-common/dist/crypto/poptokengenerator.d.ts","./node_modules/@azure/msal-common/dist/exports-browser-only.d.ts","./node_modules/@azure/msal-common/dist/index-browser.d.ts","./node_modules/@azure/msal-browser/dist/request/popupwindowattributes.d.ts","./node_modules/@azure/msal-browser/dist/request/popuprequest.d.ts","./node_modules/@azure/msal-browser/dist/request/redirectrequest.d.ts","./node_modules/@azure/msal-browser/dist/utils/browserconstants.d.ts","./node_modules/@azure/msal-browser/dist/navigation/navigationoptions.d.ts","./node_modules/@azure/msal-browser/dist/navigation/inavigationclient.d.ts","./node_modules/@azure/msal-browser/dist/config/configuration.d.ts","./node_modules/@azure/msal-browser/dist/utils/browserutils.d.ts","./node_modules/@azure/msal-browser/dist/request/silentrequest.d.ts","./node_modules/@azure/msal-browser/dist/cache/iwindowstorage.d.ts","./node_modules/@azure/msal-browser/dist/cache/memorystorage.d.ts","./node_modules/@azure/msal-browser/dist/broker/nativebroker/nativerequest.d.ts","./node_modules/@azure/msal-browser/dist/response/authenticationresult.d.ts","./node_modules/@azure/msal-browser/dist/request/ssosilentrequest.d.ts","./node_modules/@azure/msal-browser/dist/cache/cookiestorage.d.ts","./node_modules/@azure/msal-browser/dist/cache/browsercachemanager.d.ts","./node_modules/@azure/msal-browser/dist/cache/tokencache.d.ts","./node_modules/@azure/msal-browser/dist/cache/itokencache.d.ts","./node_modules/@azure/msal-browser/dist/request/authorizationcoderequest.d.ts","./node_modules/@azure/msal-browser/dist/request/endsessionrequest.d.ts","./node_modules/@azure/msal-browser/dist/request/endsessionpopuprequest.d.ts","./node_modules/@azure/msal-browser/dist/event/eventtype.d.ts","./node_modules/@azure/msal-browser/dist/event/eventmessage.d.ts","./node_modules/@azure/msal-browser/dist/request/clearcacherequest.d.ts","./node_modules/@azure/msal-browser/dist/request/initializeapplicationrequest.d.ts","./node_modules/@azure/msal-browser/dist/app/ipublicclientapplication.d.ts","./node_modules/@azure/msal-browser/dist/controllers/icontroller.d.ts","./node_modules/@azure/msal-browser/dist/app/publicclientapplication.d.ts","./node_modules/@azure/msal-browser/dist/app/publicclientnext.d.ts","./node_modules/@azure/msal-browser/dist/error/browserautherrorcodes.d.ts","./node_modules/@azure/msal-browser/dist/error/browserautherror.d.ts","./node_modules/@azure/msal-browser/dist/error/browserconfigurationautherrorcodes.d.ts","./node_modules/@azure/msal-browser/dist/error/browserconfigurationautherror.d.ts","./node_modules/@azure/msal-browser/dist/navigation/navigationclient.d.ts","./node_modules/@azure/msal-browser/dist/request/authorizationurlrequest.d.ts","./node_modules/@azure/msal-browser/dist/cache/browserstorage.d.ts","./node_modules/@azure/msal-browser/dist/cache/localstorage.d.ts","./node_modules/@azure/msal-browser/dist/cache/sessionstorage.d.ts","./node_modules/@azure/msal-browser/dist/event/eventhandler.d.ts","./node_modules/@azure/msal-browser/dist/crypto/signedhttprequest.d.ts","./node_modules/@azure/msal-browser/dist/telemetry/browserperformanceclient.d.ts","./node_modules/@azure/msal-browser/dist/telemetry/browserperformancemeasurement.d.ts","./node_modules/@azure/msal-browser/dist/packagemetadata.d.ts","./node_modules/@azure/msal-browser/dist/index.d.ts","./node_modules/@azure/msal-react/dist/msalcontext.d.ts","./node_modules/@azure/msal-react/dist/msalprovider.d.ts","./node_modules/@azure/msal-react/dist/types/accountidentifiers.d.ts","./node_modules/@azure/msal-react/dist/hooks/usemsalauthentication.d.ts","./node_modules/@azure/msal-react/dist/components/msalauthenticationtemplate.d.ts","./node_modules/@azure/msal-react/dist/components/authenticatedtemplate.d.ts","./node_modules/@azure/msal-react/dist/components/unauthenticatedtemplate.d.ts","./node_modules/@azure/msal-react/dist/utils/utilities.d.ts","./node_modules/@azure/msal-react/dist/components/withmsal.d.ts","./node_modules/@azure/msal-react/dist/hooks/usemsal.d.ts","./node_modules/@azure/msal-react/dist/hooks/useaccount.d.ts","./node_modules/@azure/msal-react/dist/hooks/useisauthenticated.d.ts","./node_modules/@azure/msal-react/dist/packagemetadata.d.ts","./node_modules/@azure/msal-react/dist/index.d.ts","./lib/msalconfig.ts","./lib/config.ts","./contexts/authcontext.tsx","./contexts/notificationcontext.tsx","./lib/authenticatedfetch.ts","./hooks/useauthenticatedfetch.ts","./hooks/usenotificationmessages.ts","./hooks/index.ts","./hooks/usesidebarstate.ts","./contexts/sidebarcontext.tsx","./hooks/usepagesections.ts","./node_modules/@nevware21/ts-utils/dist/types/ts-utils.d.ts","./node_modules/@microsoft/applicationinsights-shims/types/constants.d.ts","./node_modules/@microsoft/applicationinsights-shims/types/tslibshims.d.ts","./node_modules/@microsoft/applicationinsights-shims/types/tslibglobals.d.ts","./node_modules/@microsoft/applicationinsights-shims/types/applicationinsights-shims.d.ts","./node_modules/@nevware21/ts-async/dist/types/ts-async.d.ts","./node_modules/@microsoft/applicationinsights-core-js/types/applicationinsights-core-js.d.ts","./node_modules/@microsoft/applicationinsights-common/types/applicationinsights-common.d.ts","./node_modules/@microsoft/applicationinsights-analytics-js/types/applicationinsights-analytics-js.d.ts","./node_modules/@microsoft/applicationinsights-cfgsync-js/types/applicationinsights-cfgsync-js.d.ts","./node_modules/@microsoft/applicationinsights-dependencies-js/types/applicationinsights-dependencies-js.d.ts","./node_modules/@microsoft/applicationinsights-channel-js/types/applicationinsights-channel-js.d.ts","./node_modules/@microsoft/applicationinsights-properties-js/types/applicationinsights-properties-js.d.ts","./node_modules/@microsoft/applicationinsights-web/types/applicationinsights-web.d.ts","./lib/appinsights.ts","./lib/guardrails.generated.ts","./lib/guardvalidation.ts","./lib/rulepagehelpers.ts","./lib/sessionexportutils.ts","./node_modules/next/dist/compiled/@vercel/og/index.edge.d.ts","./node_modules/next/dist/compiled/@vercel/og/index.node.d.ts","./node_modules/next/dist/server/og/image-response.d.ts","./node_modules/next/og.d.ts","./app/apple-icon.tsx","./app/error.tsx","./app/global-error.tsx","./node_modules/next/dist/compiled/@next/font/dist/types.d.ts","./node_modules/next/dist/compiled/@next/font/dist/google/index.d.ts","./node_modules/next/font/google/index.d.ts","./node_modules/@microsoft/signalr/dist/esm/abortcontroller.d.ts","./node_modules/@microsoft/signalr/dist/esm/itransport.d.ts","./node_modules/@microsoft/signalr/dist/esm/errors.d.ts","./node_modules/@microsoft/signalr/dist/esm/ilogger.d.ts","./node_modules/@microsoft/signalr/dist/esm/ihubprotocol.d.ts","./node_modules/@microsoft/signalr/dist/esm/httpclient.d.ts","./node_modules/@microsoft/signalr/dist/esm/defaulthttpclient.d.ts","./node_modules/@microsoft/signalr/dist/esm/ihttpconnectionoptions.d.ts","./node_modules/@microsoft/signalr/dist/esm/istatefulreconnectoptions.d.ts","./node_modules/@microsoft/signalr/dist/esm/stream.d.ts","./node_modules/@microsoft/signalr/dist/esm/hubconnection.d.ts","./node_modules/@microsoft/signalr/dist/esm/iretrypolicy.d.ts","./node_modules/@microsoft/signalr/dist/esm/hubconnectionbuilder.d.ts","./node_modules/@microsoft/signalr/dist/esm/loggers.d.ts","./node_modules/@microsoft/signalr/dist/esm/jsonhubprotocol.d.ts","./node_modules/@microsoft/signalr/dist/esm/subject.d.ts","./node_modules/@microsoft/signalr/dist/esm/pkg-version.d.ts","./node_modules/@microsoft/signalr/dist/esm/utils.d.ts","./node_modules/@microsoft/signalr/dist/esm/index.d.ts","./contexts/signalrcontext.tsx","./contexts/tenantcontext.tsx","./contexts/globalnotificationcontext.tsx","./contexts/themecontext.tsx","./components/navbar.tsx","./components/scrolltotopbutton.tsx","./components/feedbackbubble.tsx","./lib/sidebaricons.tsx","./lib/globalnavconfig.tsx","./components/publicsitenavbar.tsx","./components/globalsidebar.tsx","./components/appinsightsinit.tsx","./app/layout.tsx","./app/opengraph-image.tsx","./components/landing/authgate.tsx","./components/landing/loginbutton.tsx","./components/landing/platformstats.tsx","./app/page.tsx","./app/twitter-image.tsx","./app/about/layout.tsx","./components/publicpageheader.tsx","./app/about/page.tsx","./components/validationindicator.tsx","./app/admin/components/diagnosticslogpathssection.tsx","./app/admin/components/tenantadminsection.tsx","./app/admin/components/tenantmanagementsection.tsx","./app/admin/adminconfigcontext.tsx","./app/admin/adminnotifications.tsx","./app/admin/adminpagesections.tsx","./components/protectedroute.tsx","./app/admin/layout.tsx","./app/admin/components/adminconfigsettingssection.tsx","./app/settings/components/apikeyssection.tsx","./app/admin/components/apikeyssection.tsx","./app/admin/components/configreseedsection.tsx","./app/admin/components/tenantsearchselect.tsx","./app/admin/components/deviceblocksection.tsx","./app/admin/components/feedbacksection.tsx","./app/admin/components/maintenancesection.tsx","./app/admin/components/maintenancetriggersection.tsx","./app/admin/components/sessionexportsection.tsx","./app/admin/components/sessionreportssection.tsx","./app/admin/components/softwaremappingsection.tsx","./app/admin/components/versionblocksection.tsx","./app/settings/components/saveresetbar.tsx","./app/admin/components/vulnerabilitydatasection.tsx","./app/admin/metrics/metricssidebar.tsx","./app/admin/metrics/layout.tsx","./app/admin/metrics/page.tsx","./app/admin/metrics/sections/sectionagentmetrics.tsx","./app/admin/metrics/sections/sectionplatformusage.tsx","./app/admin/metrics/[section]/page.tsx","./app/admin/ops/page.tsx","./app/admin/reports/reportssidebar.tsx","./app/admin/reports/layout.tsx","./app/admin/reports/page.tsx","./app/admin/reports/sections/sectionsessionreports.tsx","./app/admin/reports/sections/sectionuserfeedback.tsx","./app/admin/reports/sections/sectionsessionexport.tsx","./app/admin/reports/[section]/page.tsx","./app/admin/security/securitysidebar.tsx","./app/admin/security/layout.tsx","./app/admin/security/page.tsx","./app/admin/security/sections/sectiondeviceblock.tsx","./app/admin/security/sections/sectionversionblock.tsx","./app/admin/security/sections/sectionvulnerabilitydata.tsx","./app/admin/security/sections/sectionapikeys.tsx","./app/admin/security/[section]/page.tsx","./app/admin/settings/settingssidebar.tsx","./app/admin/settings/layout.tsx","./app/admin/settings/page.tsx","./app/admin/settings/sections/sectionglobalsettings.tsx","./app/admin/settings/sections/sectiondiagnosticslogpaths.tsx","./app/admin/settings/sections/sectionconfigreseed.tsx","./app/admin/settings/[section]/page.tsx","./app/admin/software/page.tsx","./app/admin/tenants/tenantssidebar.tsx","./app/admin/tenants/layout.tsx","./app/admin/tenants/page.tsx","./app/admin/tenants/sections/sectiontenantmanagement.tsx","./app/admin/tenants/sections/sectiontenantconfigreport.tsx","./app/admin/tenants/[section]/page.tsx","./components/rules/statcard.tsx","./components/rules/rulefilterbar.tsx","./components/rules/emptystate.tsx","./components/rules/formjsontoggle.tsx","./app/analyze-rules/components/analyzeruleformfields.tsx","./lib/formatinlinemarkdown.tsx","./app/analyze-rules/components/analyzerulecard.tsx","./app/analyze-rules/page.tsx","./app/audit/page.tsx","./app/changelog/layout.tsx","./app/changelog/page.tsx","./app/dashboard/components/statscards.tsx","./app/dashboard/components/welcomemessage.tsx","./app/dashboard/components/sessiontable.tsx","./app/dashboard/components/confirmationmodals.tsx","./app/dashboard/page.tsx","./app/dashboard/components/settingsmenu.tsx","./app/dashboard/components/usermenu.tsx","./app/diagnosis/[sessionid]/components/diagnosisbadges.tsx","./app/diagnosis/[sessionid]/page.tsx","./app/docs/docssidebar.tsx","./app/docs/layout.tsx","./app/docs/sections/sectionprivatepreview.tsx","./app/docs/sections/sectiongeneral.tsx","./app/docs/sections/sectionoverview.tsx","./app/docs/sections/sectionsetup.tsx","./app/docs/sections/sectionagent.tsx","./app/docs/sections/sectionagentsetup.tsx","./app/docs/sections/sectionsettings.tsx","./app/docs/sections/sectiongatherrules.tsx","./app/docs/sections/sectionanalyzerules.tsx","./app/docs/sections/sectionimelogpatterns.tsx","./app/docs/sections/sectionfaq.tsx","./app/docs/[section]/page.tsx","./app/fleet-health/components/fleetstatcard.tsx","./app/fleet-health/page.tsx","./app/gather-rules/components/gatherruleformfields.tsx","./app/gather-rules/components/gatherrulecard.tsx","./app/gather-rules/page.tsx","./node_modules/@types/geojson/index.d.ts","./node_modules/@types/leaflet/index.d.ts","./node_modules/react-leaflet/lib/hooks.d.ts","./node_modules/react-leaflet/lib/attributioncontrol.d.ts","./node_modules/@react-leaflet/core/lib/attribution.d.ts","./node_modules/@react-leaflet/core/lib/context.d.ts","./node_modules/@react-leaflet/core/lib/element.d.ts","./node_modules/@react-leaflet/core/lib/events.d.ts","./node_modules/@react-leaflet/core/lib/layer.d.ts","./node_modules/@react-leaflet/core/lib/path.d.ts","./node_modules/@react-leaflet/core/lib/circle.d.ts","./node_modules/@react-leaflet/core/lib/div-overlay.d.ts","./node_modules/@react-leaflet/core/lib/component.d.ts","./node_modules/@react-leaflet/core/lib/control.d.ts","./node_modules/@react-leaflet/core/lib/dom.d.ts","./node_modules/@react-leaflet/core/lib/generic.d.ts","./node_modules/@react-leaflet/core/lib/grid-layer.d.ts","./node_modules/@react-leaflet/core/lib/media-overlay.d.ts","./node_modules/@react-leaflet/core/lib/pane.d.ts","./node_modules/@react-leaflet/core/lib/index.d.ts","./node_modules/react-leaflet/lib/circle.d.ts","./node_modules/react-leaflet/lib/circlemarker.d.ts","./node_modules/react-leaflet/lib/layergroup.d.ts","./node_modules/react-leaflet/lib/featuregroup.d.ts","./node_modules/react-leaflet/lib/geojson.d.ts","./node_modules/react-leaflet/lib/imageoverlay.d.ts","./node_modules/react-leaflet/lib/layerscontrol.d.ts","./node_modules/react-leaflet/lib/mapcontainer.d.ts","./node_modules/react-leaflet/lib/marker.d.ts","./node_modules/react-leaflet/lib/pane.d.ts","./node_modules/react-leaflet/lib/polygon.d.ts","./node_modules/react-leaflet/lib/polyline.d.ts","./node_modules/react-leaflet/lib/popup.d.ts","./node_modules/react-leaflet/lib/rectangle.d.ts","./node_modules/react-leaflet/lib/scalecontrol.d.ts","./node_modules/react-leaflet/lib/svgoverlay.d.ts","./node_modules/react-leaflet/lib/tilelayer.d.ts","./node_modules/react-leaflet/lib/tooltip.d.ts","./node_modules/react-leaflet/lib/videooverlay.d.ts","./node_modules/react-leaflet/lib/wmstilelayer.d.ts","./node_modules/react-leaflet/lib/zoomcontrol.d.ts","./node_modules/react-leaflet/lib/index.d.ts","./app/geographic-performance/geomap.tsx","./app/geographic-performance/page.tsx","./app/geographic-performance/sessions/page.tsx","./app/health-check/page.tsx","./app/ime-log-patterns/components/imepatterncard.tsx","./app/ime-log-patterns/page.tsx","./app/preview/page.tsx","./app/privacy/layout.tsx","./app/privacy/page.tsx","./app/progress/page.tsx","./app/roadmap/layout.tsx","./app/roadmap/page.tsx","./components/performancechart.tsx","./components/downloadprogress.tsx","./components/installprogress.tsx","./components/scriptexecutions.tsx","./app/sessions/[sessionid]/components/sessioninfocard.tsx","./app/sessions/[sessionid]/components/phasetimeline.tsx","./app/sessions/[sessionid]/components/eventtimeline.tsx","./app/sessions/[sessionid]/components/analysisresultssection.tsx","./app/sessions/[sessionid]/components/vulnerabilityreportsection.tsx","./app/sessions/[sessionid]/components/adminoverridemodal.tsx","./node_modules/fflate/esm/browser.d.ts","./app/sessions/[sessionid]/components/reportsessionmodal.tsx","./app/sessions/[sessionid]/components/oobeconfigmodal.tsx","./app/sessions/[sessionid]/components/devicedetailscard.tsx","./app/sessions/[sessionid]/page.tsx","./app/sessions/[sessionid]/components/markfailedmodal.tsx","./app/settings/components/diagnosticssection.tsx","./app/settings/components/bootstrapsessionssection.tsx","./app/settings/tenantconfigcontext.tsx","./app/settings/settingspagesections.tsx","./app/settings/tenantnotifications.tsx","./app/settings/layout.tsx","./app/settings/page.tsx","./app/settings/access/accesssidebar.tsx","./app/settings/access/layout.tsx","./app/settings/access/page.tsx","./app/settings/components/adminmanagementsection.tsx","./app/settings/access/sections/sectionadminmanagement.tsx","./app/settings/access/sections/sectionbootstrapsessions.tsx","./app/settings/access/[section]/page.tsx","./app/settings/access/sections/sectionapikeys.tsx","./app/settings/agent/agentsidebar.tsx","./app/settings/agent/layout.tsx","./app/settings/agent/page.tsx","./app/settings/components/agentsettingssection.tsx","./app/settings/agent/sections/sectionagentsettings.tsx","./app/settings/components/agentanalyzerssection.tsx","./app/settings/agent/sections/sectionagentanalyzers.tsx","./app/settings/components/unrestrictedmodesection.tsx","./app/settings/agent/sections/sectionunrestrictedmode.tsx","./app/settings/agent/[section]/page.tsx","./app/settings/components/autopilotvalidationsection.tsx","./app/settings/components/datamanagementsection.tsx","./app/settings/components/hardwarewhitelistsection.tsx","./app/settings/components/notificationssection.tsx","./app/settings/components/offboardingsection.tsx","./app/settings/integrations/integrationssidebar.tsx","./app/settings/integrations/layout.tsx","./app/settings/integrations/page.tsx","./app/settings/integrations/sections/sectionnotifications.tsx","./app/settings/integrations/sections/sectiondiagnostics.tsx","./app/settings/integrations/[section]/page.tsx","./app/settings/management/managementsidebar.tsx","./app/settings/management/layout.tsx","./app/settings/management/page.tsx","./app/settings/management/sections/sectiondatamanagement.tsx","./app/settings/management/sections/sectionoffboarding.tsx","./app/settings/management/[section]/page.tsx","./app/settings/validation/validationsidebar.tsx","./app/settings/validation/layout.tsx","./app/settings/validation/page.tsx","./app/settings/validation/sections/sectionautopilotvalidation.tsx","./app/settings/validation/sections/sectionhardwarewhitelist.tsx","./app/settings/validation/[section]/page.tsx","./app/terms/layout.tsx","./app/terms/page.tsx","./app/usage-metrics/page.tsx","./node_modules/@types/estree/index.d.ts","./node_modules/@types/json-schema/index.d.ts","./node_modules/@types/json5/index.d.ts","./.next/types/routes.d.ts"],"fileIdsList":[[100,148,165,166,497],[100,148,165,166,470,786],[86,100,148,165,166,708,709,711,789,791],[100,148,165,166,792],[86,100,148,165,166,716,717,773],[100,148,165,166],[100,148,165,166,798],[86,100,148,165,166,708,711],[86,100,148,165,166,708,711,732,791,801],[86,100,148,165,166,734,788],[86,100,148,165,166,708,711,732,736,791,801],[86,100,148,165,166,708,711,732],[86,100,148,165,166,708,711,790],[86,100,148,165,166,791],[86,100,148,165,166,708,711,810],[86,100,148,165,166,480,709,792,795],[100,148,165,166,480,530,815,816],[100,148,165,166,812],[100,148,165,166,480],[86,100,148,165,166,480,708,709,710,711],[86,100,148,165,166,480,708,709,711],[100,148,165,166,792,793,805],[100,148,165,166,480,531,822,823,824],[100,148,165,166,819],[100,148,165,166,792,793,806],[100,148,165,166,792,793,807],[100,148,165,166,792,793,803],[100,148,165,166,480,532,829,830,831,832],[100,148,165,166,826],[100,148,165,166,792,793,799],[100,148,165,166,792,793,802],[100,148,165,166,792,793,809],[100,148,165,166,792,793,811],[100,148,165,166,480,533,837,838,839],[100,148,165,166,834],[100,148,165,166,792,793,800],[100,148,165,166,789,792,793],[100,148,165,166,792,793,797],[100,148,165,166,792,793,808],[100,148,165,166,480,534,845,846],[100,148,165,166,842],[86,100,148,165,166,708,709,711],[100,148,165,166,791,792],[86,100,148,165,166,535,735,851,852,853],[100,148,165,166,535],[86,100,148,165,166,470,480,535,708,709,711,714,732,735,767,795,848,849,850,851,852,854],[100,148,165,166,740],[86,100,148,165,166,480,708,709,710,711,767,795],[100,148,165,166,786],[86,100,148,165,166,480,539,732],[86,100,148,165,166],[100,148,165,166,470],[86,100,148,165,166,470,480,539,708,709,710,711,732,766,767,795,859,860,861,862],[100,148,165,166,538],[86,100,148,165,166,480,538,708,709,710,711,766,767,795,853,866],[100,148,165,166,480,497,527,870,871,872,873,874,875,876,877,878,879,880],[100,148,165,166,527,716,717,773],[100,148,165,166,497,868],[86,100,148,165,166,733],[86,100,148,165,166,480,538,708,709,710,711,766,767,795,882],[86,100,148,165,166,540,734,735,788,851,884],[86,100,148,165,166,540,734,788],[86,100,148,165,166,470,480,540,708,709,711,714,732,735,767,795,848,849,850,851,884,885],[86,100,148,165,166,928],[86,100,148,165,166,456,480,708,709,711,767,795,929],[86,100,148,165,166,480,708,709,711,767,795],[86,100,148,165,166,708,709,710,711,765,766,767],[86,100,148,165,166,542,735,851],[86,100,148,165,166,480,542,708,709,714,732,735,767,795,848,849,850,933],[100,148,165,166,497,709,710,716,746,766,767,768,769,770,771,772,776,777],[100,148,165,166,775,780,781,782],[86,100,148,165,166,480,708,709],[86,100,148,165,166,538,708,709,710,711,732,766,767,795],[86,100,148,165,166,538,853],[86,100,148,165,166,538,953],[86,100,148,165,166,538,543],[86,100,148,165,166,538,544],[86,100,148,165,166,538,951],[86,100,148,165,166,538],[86,100,148,165,166,480,538,543,544,708,709,710,711,716,717,732,736,766,767,773,795,941,942,943,944,945,946,947,948,949,950,952,954],[100,148,165,166,480,546,968,969],[100,148,165,166,964],[100,148,165,166,959,961,967],[100,148,165,166,798,959,961],[100,148,165,166,958,959,961],[100,148,165,166,480,547,976,978,980],[100,148,165,166,972],[100,148,165,166,959,961,977],[100,148,165,166,959,961,975],[100,148,165,166,959,961,979],[100,148,165,166,545],[100,148,165,166,810],[86,100,148,165,166,545,734,788,810],[86,100,148,165,166,810],[100,148,165,166,480,548,990,991],[100,148,165,166,987],[100,148,165,166,957,959,961],[100,148,165,166,959,961,985],[86,100,148,165,166,480,709,795,959],[100,148,165,166,480,549,996,997],[100,148,165,166,993],[100,148,165,166,959,961,983],[100,148,165,166,959,961,986],[86,100,148,165,166,480,709],[86,100,148,165,166,716,717,773,959],[86,100,148,165,166,480,545,708,709,710,711,732,767,957,958],[100,148,165,166,959],[100,148,165,166,480,550,1002,1003],[100,148,165,166,999],[100,148,165,166,959,961,982],[100,148,165,166,959,961,984],[100,148,165,166,497,527,528],[100,148,165,166,779],[86,100,148,165,166,709,732,767,769],[86,100,148,165,166,470,480,709,715,716,773,774,775],[100,148,165,166,709],[86,100,148,165,166,470,480,708,709,710,732,768,769],[100,148,165,166,470,709,769],[100,148,165,166,734],[86,100,148,165,166,692,706,707,708],[86,100,148,165,166,715],[86,100,148,165,166,708,709,711,732,765],[86,100,148,165,166,709],[100,148,165,166,712,713],[86,100,148,165,166,709,710,711],[86,100,148,165,166,716],[100,148,165,166,731],[100,148,165,166,773],[100,148,165,166,733],[100,148,165,166,692],[100,148,165,166,497,498,1011],[100,148,165,166,648,650,651,652,654,655,657,661,662,666,667,668,669,670,671,672,673],[100,148,165,166,648,650,651,652,654,655,657,661,662,666,667,668,669,670,671,672,673,674,675],[100,148,165,166,648,650,651,652,654,655,657,661,662,666,667,668,670,671,672,674,675],[100,148,165,166,648,652],[100,148,165,166,648,650,651,652,655,657,658,659,660,661,662,663],[100,148,165,166,658],[100,148,165,166,648,657,661,665],[100,148,165,166,648,655,657,661,664,666],[100,148,165,166,648,652,654],[100,148,165,166,648],[100,148,165,166,648,678],[100,148,165,166,648,680],[100,148,165,166,648,652,670,671],[100,148,165,166,648,650,651,652,657,661,662,668,670],[100,148,165,166,648,649,650,651,652,653,654,655,656,657,658,659,661,662,665,666,667,668,669,670,671,672,673,674,675,676,677,679,681,682,683,684,685,686,687,688,689,690,691],[100,148,165,166,653],[100,148,165,166,653,654],[100,148,165,166,652],[100,148,165,166,648,649],[100,148,165,166,648,655],[100,148,165,166,650,651],[100,148,165,166,551],[100,148,165,166,553,554,555,557,558,560,564,566,580,583,589,598],[100,148,165,166,557,560,566,580,598,599],[100,148,165,166,558,561,563,565],[100,148,165,166,562],[100,148,165,166,564],[100,148,165,166,559],[100,148,165,166,560,566,568,569,570,571,572,573,574,575,576,577,580,593,594,595,597,598],[100,148,165,166,559,567],[100,148,165,166,551,553,560,573,594,599],[100,148,165,166,568,569,570,571,595],[100,148,165,166,567],[100,148,165,166,568,569,570,571,572,573,574,575,576,577,595,597],[100,148,165,166,586],[100,148,165,166,585],[100,148,165,166,554,559,564,567,568,569,570,571,576],[100,148,165,166,559,568,569,570,571,573,574,575,576,595,596],[100,148,165,166,580,589,603,609,610,611,612,613,614],[100,148,165,166,556,557,560,580,581,584,589,593,594,599,606,607,608],[100,148,165,166,580,589,609,612,616,617],[100,148,165,166,559,580,589,609,612,617],[100,148,165,166,557,560,566,581,584,585,587,588,594,599],[100,148,165,166,592,593],[100,148,165,166,560,580,594],[100,148,165,166,591],[100,148,165,166,627],[100,148,165,166,633],[100,148,165,166,628,635],[100,148,165,166,628,637],[100,148,165,166,628,629],[100,148,165,166,628],[100,148,165,166,578,579,580,591,592,643,644,645,646],[100,148,165,166,551,552,553,555,556,557,558,559,560,561,562,563,566,567,568,569,570,571,572,573,574,575,576,577,581,582,584,589,590,593,594,595,596,597,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,628,630,631,632,634,636,638,639,640,641],[100,148,165,166,642,647],[100,148,165,166,589],[100,148,165,166,556],[100,148,165,166,559,592],[100,148,165,166,556,581,593,606,607],[100,148,165,166,559,577,589,590,592],[100,148,165,166,590,593,608],[100,148,165,166,559,573,590,593],[100,148,165,166,573,590],[100,148,165,166,573,590,593],[100,148,165,166,559,580,584,589,590,620],[100,148,165,166,573],[100,148,165,166,606],[100,148,165,166,551,560,572,580,581,585,587,593,594,595,599,603,606,612,614,624],[100,148,165,166,578,579],[100,148,165,166,560,578,579,580,589],[100,148,165,166,578,579,580],[100,148,165,166,559,574,581,582,583],[100,148,165,166,555],[100,148,165,166,560,580],[100,148,165,166,594],[100,148,165,166,603],[86,100,148,165,166,695],[86,100,148,165,166,692,693,695,696],[86,100,148,165,166,693,700],[100,148,165,166,692,695],[100,148,165,166,695],[100,148,165,166,693],[100,148,165,166,693,694,695,696,697,698,699,700,701,702,703,704,705],[86,100,148,165,166,692],[86,100,148,165,166,692,695],[100,148,165,166,724,725],[100,148,165,166,723,724,725],[100,148,165,166,724],[100,148,165,166,718,722,723],[100,148,165,166,718,719,720,721],[100,148,165,166,723,724,725,726,727,728,729,730],[100,148,165,166,750,752],[100,148,165,166,748],[100,148,165,166,747,751],[100,148,165,166,756],[100,148,165,166,748,750,751,754,755,757,758],[100,148,165,166,748,750,751,752],[100,148,165,166,748,750],[100,148,165,166,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,764],[100,148,165,166,748,750,751],[100,148,165,166,750],[100,148,165,166,750,752,754,756,762,763],[100,148,165,166,888],[86,100,148,165,166,888,896],[86,100,148,165,166,893,898],[86,100,148,165,166,888],[100,148,165,166,888,893],[100,148,165,166,888,892,893,895],[86,100,148,165,166,892],[86,100,148,165,166,888,892,893,895,896,898,899],[100,148,165,166,891,892,893,894,895,896,897,898,899,900,901,902,903,904,905],[100,148,165,166,888,892,893,894],[100,148,165,166,888,895],[100,148,165,166,888,892],[100,148,165,166,888,893,895],[100,148,165,166,887],[100,145,146,148,165,166],[100,147,148,165,166],[148,165,166],[100,148,153,165,166,183],[100,148,149,154,159,165,166,168,180,191],[100,148,149,150,159,165,166,168],[95,96,97,100,148,165,166],[100,148,151,165,166,192],[100,148,152,153,160,165,166,169],[100,148,153,165,166,180,188],[100,148,154,156,159,165,166,168],[100,147,148,155,165,166],[100,148,156,157,165,166],[100,148,158,159,165,166],[100,147,148,159,165,166],[100,148,159,160,161,165,166,180,191],[100,148,159,160,161,165,166,175,180,183],[100,141,148,156,159,162,165,166,168,180,191],[100,148,159,160,162,163,165,166,168,180,188,191],[100,148,162,164,165,166,180,188,191],[98,99,100,101,102,103,104,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197],[100,148,159,165,166],[100,148,165,166,167,191],[100,148,156,159,165,166,168,180],[100,148,165,166,169],[100,148,165,166,170],[100,147,148,165,166,171],[100,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197],[100,148,165,166,173],[100,148,165,166,174],[100,148,159,165,166,175,176],[100,148,165,166,175,177,192,194],[100,148,160,165,166],[100,148,159,165,166,180,181,183],[100,148,165,166,182,183],[100,148,165,166,180,181],[100,148,165,166,183],[100,148,165,166,184],[100,145,148,165,166,180,185,191],[100,148,159,165,166,186,187],[100,148,165,166,186,187],[100,148,153,165,166,168,180,188],[100,148,165,166,189],[100,148,165,166,168,190],[100,148,162,165,166,174,191],[100,148,153,165,166,192],[100,148,165,166,180,193],[100,148,165,166,167,194],[100,148,165,166,195],[100,141,148,165,166],[100,141,148,159,161,165,166,171,180,183,191,193,194,196],[100,148,165,166,180,197],[86,100,148,165,166,201,202,203,357],[86,100,148,165,166,201,202],[86,100,148,165,166,202,357],[86,90,100,148,165,166,200,441,489],[86,90,100,148,165,166,199,441,489],[83,84,85,100,148,165,166],[92,100,148,165,166],[100,148,165,166,444],[100,148,165,166,446,447,448,449],[100,148,165,166,451],[100,148,165,166,207,221,222,223,225,438],[100,148,165,166,207,246,248,250,251,254,438,440],[100,148,165,166,207,211,213,214,215,216,217,427,438,440],[100,148,165,166,438],[100,148,165,166,222,324,408,417,434],[100,148,165,166,207],[100,148,165,166,204,434],[100,148,165,166,258],[100,148,165,166,257,438,440],[100,148,162,165,166,306,324,353,495],[100,148,162,165,166,317,333,417,433],[100,148,162,165,166,369],[100,148,165,166,421],[100,148,165,166,420,421,422],[100,148,165,166,420],[94,100,148,162,165,166,204,207,211,214,218,219,220,222,226,234,235,362,387,418,438,441],[100,148,165,166,207,224,242,246,247,252,253,438,495],[100,148,165,166,224,495],[100,148,165,166,235,242,304,438,495],[100,148,165,166,495],[100,148,165,166,207,224,225,495],[100,148,165,166,249,495],[100,148,165,166,218,419,426],[100,148,165,166,174,266,434],[100,148,165,166,266,434],[86,100,148,165,166,266],[86,100,148,165,166,325],[100,148,165,166,321,367,434,477,478],[100,148,165,166,414,471,472,473,474,476],[100,148,165,166,413],[100,148,165,166,413,414],[100,148,165,166,215,363,364,365],[100,148,165,166,363,366,367],[100,148,165,166,475],[100,148,165,166,363,367],[86,100,148,165,166,208,465],[86,100,148,165,166,191],[86,100,148,165,166,224,294],[86,100,148,165,166,224],[100,148,165,166,292,296],[86,100,148,165,166,293,443],[100,148,165,166,744],[86,100,148,165,166,489],[86,100,148,165,166,180,198,489,737],[86,90,100,148,162,165,166,198,199,200,441,487,488],[100,148,162,165,166],[100,148,162,165,166,211,273,363,373,388,408,423,424,438,439,495],[100,148,165,166,234,425],[100,148,165,166,441],[100,148,165,166,206],[86,100,148,165,166,306,320,332,342,344,433],[100,148,165,166,174,306,320,341,342,343,433,494],[100,148,165,166,335,336,337,338,339,340],[100,148,165,166,337],[100,148,165,166,341],[100,148,165,166,264,265,266,268],[86,100,148,165,166,259,260,261,267],[100,148,165,166,264,267],[100,148,165,166,262],[100,148,165,166,263],[86,100,148,165,166,266,293,443],[86,100,148,165,166,266,442,443],[86,100,148,165,166,266,443],[100,148,165,166,388,430],[100,148,165,166,430],[100,148,162,165,166,439,443],[100,148,165,166,329],[100,147,148,165,166,328],[100,148,165,166,236,274,312,314,316,317,318,319,360,363,433,436,439],[100,148,165,166,236,350,363,367],[100,148,165,166,317,433],[86,100,148,165,166,317,326,327,329,330,331,332,333,334,345,346,347,348,349,351,352,433,434,495],[100,148,165,166,311],[100,148,162,165,166,174,236,237,273,288,318,360,361,362,367,388,408,429,438,439,440,441,495],[100,148,165,166,433],[100,147,148,165,166,222,315,318,362,429,431,432,439],[100,148,165,166,317],[100,147,148,165,166,273,278,307,308,309,310,311,312,313,314,316,433,434],[100,148,162,165,166,278,279,307,439,440],[100,148,165,166,222,362,363,388,429,433,439],[100,148,162,165,166,438,440],[100,148,162,165,166,180,436,439,440],[100,148,162,165,166,174,191,204,211,224,236,237,239,274,275,280,285,288,314,318,363,373,375,378,380,383,384,385,386,387,408,428,429,434,436,438,439,440],[100,148,162,165,166,180],[100,148,165,166,207,208,209,211,216,219,224,242,428,436,437,441,443,495],[100,148,162,165,166,180,191,254,256,258,259,260,261,268,495],[100,148,165,166,174,191,204,246,256,284,285,286,287,314,363,378,387,388,394,397,398,408,429,434,436],[100,148,165,166,218,219,234,362,387,429,438],[100,148,162,165,166,191,208,211,314,392,436,438],[100,148,165,166,305],[100,148,162,165,166,395,396,405],[100,148,165,166,436,438],[100,148,165,166,312,315],[100,148,165,166,314,318,428,443],[100,148,162,165,166,174,240,246,287,378,388,394,397,400,436],[100,148,162,165,166,218,234,246,401],[100,148,165,166,207,239,403,428,438],[100,148,162,165,166,191,438],[100,148,162,165,166,224,238,239,240,251,269,402,404,428,438],[94,100,148,165,166,236,318,407,441,443],[100,148,162,165,166,174,191,211,218,226,234,237,274,280,284,285,286,287,288,314,363,375,388,389,391,393,408,428,429,434,435,436,443],[100,148,162,165,166,180,218,394,399,405,436],[100,148,165,166,229,230,231,232,233],[100,148,165,166,275,379],[100,148,165,166,381],[100,148,165,166,379],[100,148,165,166,381,382],[100,148,165,166,738],[100,148,162,165,166,211,214,215,273,439],[100,148,162,165,166,174,206,208,236,274,288,318,371,372,408,436,440,441,443],[100,148,162,165,166,174,191,210,215,314,372,435,439],[100,148,165,166,307],[100,148,165,166,308],[100,148,165,166,309],[100,148,165,166,434],[100,148,165,166,255,271],[100,148,162,165,166,211,255,274],[100,148,165,166,270,271],[100,148,165,166,272],[100,148,165,166,255,256],[100,148,165,166,255,289],[100,148,165,166,255],[100,148,165,166,275,377,435],[100,148,165,166,376],[100,148,165,166,256,434,435],[100,148,165,166,374,435],[100,148,165,166,256,434],[100,148,165,166,360],[100,148,165,166,211,216,274,303,306,312,314,318,320,323,354,356,359,363,407,428,436,439],[100,148,165,166,297,300,301,302,321,322,367],[86,100,148,165,166,201,202,203,266,355],[86,100,148,165,166,201,202,203,266,355,358],[100,148,165,166,416],[100,148,165,166,222,279,317,318,329,333,363,407,409,410,411,412,414,415,418,428,433,438],[100,148,165,166,367],[100,148,165,166,371],[100,148,162,165,166,274,290,368,370,373,407,436,441,443],[100,148,165,166,297,298,299,300,301,302,321,322,367,442],[94,100,148,162,165,166,174,191,237,255,256,288,314,318,405,406,408,428,429,438,439,441],[100,148,165,166,279,281,284,429],[100,148,162,165,166,275,438],[100,148,165,166,278,317],[100,148,165,166,277],[100,148,165,166,279,280],[100,148,165,166,276,278,438],[100,148,162,165,166,210,279,281,282,283,438,439],[86,100,148,165,166,363,364,366],[100,148,165,166,241],[86,100,148,165,166,208],[86,100,148,165,166,434],[86,94,100,148,165,166,288,318,441,443],[100,148,165,166,208,465,466],[86,100,148,165,166,296],[86,100,148,165,166,174,191,206,253,291,293,295,443],[100,148,165,166,224,434,439],[100,148,165,166,390,434],[100,148,165,166,363],[86,100,148,160,162,165,166,174,206,242,248,296,441,442],[86,100,148,165,166,199,200,441,489],[86,87,88,89,90,100,148,165,166],[100,148,153,165,166],[100,148,165,166,243,244,245],[100,148,165,166,243],[86,90,100,148,162,164,165,166,174,198,199,200,201,203,204,206,237,341,400,438,440,443,489],[100,148,165,166,453],[100,148,165,166,455],[100,148,165,166,457],[100,148,165,166,745],[100,148,165,166,459],[100,148,165,166,461,462,463],[100,148,165,166,467],[91,93,100,148,165,166,445,450,452,454,456,458,460,464,468,470,480,481,483,493,494,495,496],[100,148,165,166,469],[100,148,165,166,479],[100,148,165,166,739],[100,148,165,166,293],[100,148,165,166,482],[100,147,148,165,166,279,281,282,284,332,434,484,485,486,489,490,491,492],[100,148,165,166,198],[100,148,165,166,516],[100,148,165,166,514,516],[100,148,165,166,505,513,514,515,517,519],[100,148,165,166,503],[100,148,165,166,506,511,516,519],[100,148,165,166,502,519],[100,148,165,166,506,507,510,511,512,519],[100,148,165,166,506,507,508,510,511,519],[100,148,165,166,503,504,505,506,507,511,512,513,515,516,517,519],[100,148,165,166,519],[100,148,165,166,501,503,504,505,506,507,508,510,511,512,513,514,515,516,517,518],[100,148,165,166,501,519],[100,148,165,166,506,508,509,511,512,519],[100,148,165,166,510,519],[100,148,165,166,511,512,516,519],[100,148,165,166,504,514],[86,100,148,165,166,888,906],[86,100,148,165,166,888,906,909],[86,100,148,165,166,887,888,906,909],[100,148,165,166,889,890,907,908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927],[86,100,148,165,166,887,888,906],[100,148,165,166,180,198],[100,148,165,166,521,522],[100,148,165,166,520,523],[100,113,117,148,165,166,191],[100,113,148,165,166,180,191],[100,108,148,165,166],[100,110,113,148,165,166,188,191],[100,148,165,166,168,188],[100,108,148,165,166,198],[100,110,113,148,165,166,168,191],[100,105,106,109,112,148,159,165,166,180,191],[100,113,120,148,165,166],[100,105,111,148,165,166],[100,113,134,135,148,165,166],[100,109,113,148,165,166,183,191,198],[100,134,148,165,166,198],[100,107,108,148,165,166,198],[100,113,148,165,166],[100,107,108,109,110,111,112,113,114,115,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,135,136,137,138,139,140,148,165,166],[100,113,128,148,165,166],[100,113,120,121,148,165,166],[100,111,113,121,122,148,165,166],[100,112,148,165,166],[100,105,108,113,148,165,166],[100,113,117,121,122,148,165,166],[100,117,148,165,166],[100,111,113,116,148,165,166,191],[100,105,110,113,120,148,165,166],[100,148,165,166,180],[100,108,113,134,148,165,166,196,198],[100,148,165,166,524],[100,148,165,166,536,537]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"2ab096661c711e4a81cc464fa1e6feb929a54f5340b46b0a07ac6bbf857471f0","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"73f78680d4c08509933daf80947902f6ff41b6230f94dd002ae372620adb0f60","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5239f5c01bcfa9cd32f37c496cf19c61d69d37e48be9de612b541aac915805b","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb5b19b86227ace1d29ea4cf81387279d04bb34051e944bc53df69f58914b788","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"87d9d29dbc745f182683f63187bf3d53fd8673e5fca38ad5eaab69798ed29fbc","impliedFormat":1},{"version":"035312d4945d13efa134ae482f6dc56a1a9346f7ac3be7ccbad5741058ce87f3","affectsGlobalScope":true,"impliedFormat":1},{"version":"acd8fd5090ac73902278889c38336ff3f48af6ba03aa665eb34a75e7ba1dccc4","impliedFormat":1},{"version":"d6258883868fb2680d2ca96bc8b1352cab69874581493e6d52680c5ffecdb6cc","impliedFormat":1},{"version":"1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","impliedFormat":1},{"version":"f258e3960f324a956fc76a3d3d9e964fff2244ff5859dcc6ce5951e5413ca826","impliedFormat":1},{"version":"643f7232d07bf75e15bd8f658f664d6183a0efaca5eb84b48201c7671a266979","impliedFormat":1},{"version":"0f6666b58e9276ac3a38fdc80993d19208442d6027ab885580d93aec76b4ef00","impliedFormat":1},{"version":"05fd364b8ef02fb1e174fbac8b825bdb1e5a36a016997c8e421f5fab0a6da0a0","impliedFormat":1},{"version":"631eff75b0e35d1b1b31081d55209abc43e16b49426546ab5a9b40bdd40b1f60","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"f949f7f6c7802a338039cfc2156d1fe285cdd1e092c64437ebe15ae8edc854e0","impliedFormat":1},{"version":"6b4e081d55ac24fc8a4631d5dd77fe249fa25900abd7d046abb87d90e3b45645","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"83e63d6ccf8ec004a3bb6d58b9bb0104f60e002754b1e968024b320730cc5311","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"d2bc7425ef40526650d6db7e072c1ff4a51101c3ac2cc4b666623b19496a6e27","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"f27524f4bef4b6519c604bdb23bf4465bddcccbf3f003abb901acbd0d7404d99","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"6b039f55681caaf111d5eb84d292b9bee9e0131d0db1ad0871eef0964f533c73","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c8d3e5a18ba35629954e48c4cc8f11dc88224650067a172685c736b27a34a4dc","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"0dba70b3fb0dcd713fda33c2df64fa6751fff6460e536971cee917260fb17882","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"9f663c2f91127ef7024e8ca4b3b4383ff2770e5f826696005de382282794b127","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"f9fd93190acb1ffe0bc0fb395df979452f8d625071e9ffc8636e4dfb86ab2508","impliedFormat":1},{"version":"5f41fd8732a89e940c58ce22206e3df85745feb8983e2b4c6257fb8cbb118493","impliedFormat":1},{"version":"17ed71200119e86ccef2d96b73b02ce8854b76ad6bd21b5021d4269bec527b5f","impliedFormat":1},{"version":"1cfa8647d7d71cb03847d616bd79320abfc01ddea082a49569fda71ac5ece66b","impliedFormat":1},{"version":"bb7a61dd55dc4b9422d13da3a6bb9cc5e89be888ef23bbcf6558aa9726b89a1c","impliedFormat":1},{"version":"413df52d4ea14472c2fa5bee62f7a40abd1eb49be0b9722ee01ee4e52e63beb2","impliedFormat":1},{"version":"db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","impliedFormat":1},{"version":"829b9e6028b29e6a8b1c01ddb713efe59da04d857089298fa79acbdb3cfcfdef","impliedFormat":1},{"version":"24f8562308dd8ba6013120557fa7b44950b619610b2c6cb8784c79f11e3c4f90","impliedFormat":1},{"version":"5d8717b437b9d6afeb4da84b9082db35cafce3dfd025bc7c9ad7abbe50fa2778","impliedFormat":1},{"version":"a86f82d646a739041d6702101afa82dcb935c416dd93cbca7fd754fd0282ce1f","impliedFormat":1},{"version":"ad0d1d75d129b1c80f911be438d6b61bfa8703930a8ff2be2f0e1f8a91841c64","impliedFormat":1},{"version":"ce75b1aebb33d510ff28af960a9221410a3eaf7f18fc5f21f9404075fba77256","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"496bbf339f3838c41f164238543e9fe5f1f10659cb30b68903851618464b98ba","impliedFormat":1},{"version":"5178eb4415a172c287c711dc60a619e110c3fd0b7de01ed0627e51a5336aa09c","impliedFormat":1},{"version":"ca6e5264278b53345bc1ce95f42fb0a8b733a09e3d6479c6ccfca55cdc45038c","impliedFormat":1},{"version":"9e2739b32f741859263fdba0244c194ca8e96da49b430377930b8f721d77c000","impliedFormat":1},{"version":"fb1d8e814a3eeb5101ca13515e0548e112bd1ff3fb358ece535b93e94adf5a3a","impliedFormat":1},{"version":"ffa495b17a5ef1d0399586b590bd281056cee6ce3583e34f39926f8dcc6ecdb5","impliedFormat":1},{"version":"98b18458acb46072947aabeeeab1e410f047e0cacc972943059ca5500b0a5e95","impliedFormat":1},{"version":"361e2b13c6765d7f85bb7600b48fde782b90c7c41105b7dab1f6e7871071ba20","impliedFormat":1},{"version":"c86fe861cf1b4c46a0fb7d74dffe596cf679a2e5e8b1456881313170f092e3fa","impliedFormat":1},{"version":"b6db56e4903e9c32e533b78ac85522de734b3d3a8541bf24d256058d464bf04b","impliedFormat":1},{"version":"24daa0366f837d22c94a5c0bad5bf1fd0f6b29e1fae92dc47c3072c3fdb2fbd5","impliedFormat":1},{"version":"570bb5a00836ffad3e4127f6adf581bfc4535737d8ff763a4d6f4cc877e60d98","impliedFormat":1},{"version":"889c00f3d32091841268f0b994beba4dceaa5df7573be12c2c829d7c5fbc232c","impliedFormat":1},{"version":"65f43099ded6073336e697512d9b80f2d4fec3182b7b2316abf712e84104db00","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"acf5a2ac47b59ca07afa9abbd2b31d001bf7448b041927befae2ea5b1951d9f9","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"d71291eff1e19d8762a908ba947e891af44749f3a2cbc5bd2ec4b72f72ea795f","impliedFormat":1},{"version":"c0480e03db4b816dff2682b347c95f2177699525c54e7e6f6aa8ded890b76be7","impliedFormat":1},{"version":"27ab780875bcbb65e09da7496f2ca36288b0c541abaa75c311450a077d54ec15","impliedFormat":1},{"version":"b620391fe8060cf9bedc176a4d01366e6574d7a71e0ac0ab344a4e76576fcbb8","impliedFormat":1},{"version":"380647d8f3b7f852cca6d154a376dbf8ac620a2f12b936594504a8a852e71d2f","impliedFormat":1},{"version":"208c9af9429dd3c76f5927b971263174aaa4bc7621ddec63f163640cbd3c473c","impliedFormat":1},{"version":"6459054aabb306821a043e02b89d54da508e3a6966601a41e71c166e4ea1474f","impliedFormat":1},{"version":"a23185bc5ef590c287c28a91baf280367b50ae4ea40327366ad01f6f4a8edbc5","impliedFormat":1},{"version":"bb37588926aba35c9283fe8d46ebf4e79ffe976343105f5c6d45f282793352b2","impliedFormat":1},{"version":"002eae065e6960458bda3cf695e578b0d1e2785523476f8a9170b103c709cd4f","impliedFormat":1},{"version":"c83bb0c9c5645a46c68356c2f73fdc9de339ce77f7f45a954f560c7e0b8d5ebb","impliedFormat":1},{"version":"05c97cddbaf99978f83d96de2d8af86aded9332592f08ce4a284d72d0952c391","impliedFormat":1},{"version":"72179f9dd22a86deaad4cc3490eb0fe69ee084d503b686985965654013f1391b","impliedFormat":1},{"version":"2e6114a7dd6feeef85b2c80120fdbfb59a5529c0dcc5bfa8447b6996c97a69f5","impliedFormat":1},{"version":"7b6ff760c8a240b40dab6e4419b989f06a5b782f4710d2967e67c695ef3e93c4","impliedFormat":1},{"version":"c8f004e6036aa1c764ad4ec543cf89a5c1893a9535c80ef3f2b653e370de45e6","impliedFormat":1},{"version":"dd80b1e600d00f5c6a6ba23f455b84a7db121219e68f89f10552c54ba46e4dc9","impliedFormat":1},{"version":"b064c36f35de7387d71c599bfcf28875849a1dbc733e82bd26cae3d1cd060521","impliedFormat":1},{"version":"6a148329edecbda07c21098639ef4254ef7869fb25a69f58e5d6a8b7b69d4236","impliedFormat":1},{"version":"8de9fe97fa9e00ec00666fa77ab6e91b35d25af8ca75dabcb01e14ad3299b150","impliedFormat":1},{"version":"f63ab283a1c8f5c79fabe7ca4ef85f9633339c4f0e822fce6a767f9d59282af2","impliedFormat":1},{"version":"dba114fb6a32b355a9cfc26ca2276834d72fe0e94cd2c3494005547025015369","impliedFormat":1},{"version":"a54c996c8870ef1728a2c1fa9b8eaec0bf4a8001cd2583c02dd5869289465b10","impliedFormat":1},{"version":"3e7efde639c6a6c3edb9847b3f61e308bf7a69685b92f665048c45132f51c218","impliedFormat":1},{"version":"df45ca1176e6ac211eae7ddf51336dc075c5314bc5c253651bae639defd5eec5","impliedFormat":1},{"version":"3754982006a3b32c502cff0867ca83584f7a43b1035989ca73603f400de13c96","impliedFormat":1},{"version":"a30ae9bb8a8fa7b90f24b8a0496702063ae4fe75deb27da731ed4a03b2eb6631","impliedFormat":1},{"version":"f974e4a06953682a2c15d5bd5114c0284d5abf8bc0fe4da25cb9159427b70072","impliedFormat":1},{"version":"50256e9c31318487f3752b7ac12ff365c8949953e04568009c8705db802776fb","impliedFormat":1},{"version":"7d73b24e7bf31dfb8a931ca6c4245f6bb0814dfae17e4b60c9e194a631fe5f7b","impliedFormat":1},{"version":"413586add0cfe7369b64979d4ec2ed56c3f771c0667fbde1bf1f10063ede0b08","impliedFormat":1},{"version":"06472528e998d152375ad3bd8ebcb69ff4694fd8d2effaf60a9d9f25a37a097a","impliedFormat":1},{"version":"50b5bc34ce6b12eccb76214b51aadfa56572aa6cc79c2b9455cdbb3d6c76af1d","impliedFormat":1},{"version":"b7e16ef7f646a50991119b205794ebfd3a4d8f8e0f314981ebbe991639023d0e","impliedFormat":1},{"version":"42c169fb8c2d42f4f668c624a9a11e719d5d07dacbebb63cbcf7ef365b0a75b3","impliedFormat":1},{"version":"a401617604fa1f6ce437b81689563dfdc377069e4c58465dbd8d16069aede0a5","impliedFormat":1},{"version":"e9dd71cf12123419c60dab867d44fbee5c358169f99529121eaef277f5c83531","impliedFormat":1},{"version":"5b6a189ba3a0befa1f5d9cb028eb9eec2af2089c32f04ff50e2411f63d70f25d","impliedFormat":1},{"version":"d6e73f8010935b7b4c7487b6fb13ea197cc610f0965b759bec03a561ccf8423a","impliedFormat":1},{"version":"174f3864e398f3f33f9a446a4f403d55a892aa55328cf6686135dfaf9e171657","impliedFormat":1},{"version":"824c76aec8d8c7e65769688cbee102238c0ef421ed6686f41b2a7d8e7e78a931","impliedFormat":1},{"version":"75b868be3463d5a8cfc0d9396f0a3d973b8c297401d00bfb008a42ab16643f13","impliedFormat":1},{"version":"15a234e5031b19c48a69ccc1607522d6e4b50f57d308ecb7fe863d44cd9f9eb3","impliedFormat":1},{"version":"d682336018141807fb602709e2d95a192828fcb8d5ba06dda3833a8ea98f69e3","impliedFormat":1},{"version":"6124e973eab8c52cabf3c07575204efc1784aca6b0a30c79eb85fe240a857efa","impliedFormat":1},{"version":"0d891735a21edc75df51f3eb995e18149e119d1ce22fd40db2b260c5960b914e","impliedFormat":1},{"version":"3b414b99a73171e1c4b7b7714e26b87d6c5cb03d200352da5342ab4088a54c85","impliedFormat":1},{"version":"4fbd3116e00ed3a6410499924b6403cc9367fdca303e34838129b328058ede40","impliedFormat":1},{"version":"b01bd582a6e41457bc56e6f0f9de4cb17f33f5f3843a7cf8210ac9c18472fb0f","impliedFormat":1},{"version":"0a437ae178f999b46b6153d79095b60c42c996bc0458c04955f1c996dc68b971","impliedFormat":1},{"version":"74b2a5e5197bd0f2e0077a1ea7c07455bbea67b87b0869d9786d55104006784f","impliedFormat":1},{"version":"4a7baeb6325920044f66c0f8e5e6f1f52e06e6d87588d837bdf44feb6f35c664","impliedFormat":1},{"version":"6dcf60530c25194a9ee0962230e874ff29d34c59605d8e069a49928759a17e0a","impliedFormat":1},{"version":"7274fbffbd7c9589d8d0ffba68157237afd5cecff1e99881ea3399127e60572f","impliedFormat":1},{"version":"1a42d2ec31a1fe62fdc51591768695ed4a2dc64c01be113e7ff22890bebb5e3f","impliedFormat":1},{"version":"1a82deef4c1d39f6882f28d275cad4c01f907b9b39be9cbc472fcf2cf051e05b","impliedFormat":1},{"version":"c5426dbfc1cf90532f66965a7aa8c1136a78d4d0f96d8180ecbfc11d7722f1a5","impliedFormat":1},{"version":"65a15fc47900787c0bd18b603afb98d33ede930bed1798fc984d5ebb78b26cf9","impliedFormat":1},{"version":"9d202701f6e0744adb6314d03d2eb8fc994798fc83d91b691b75b07626a69801","impliedFormat":1},{"version":"de9d2df7663e64e3a91bf495f315a7577e23ba088f2949d5ce9ec96f44fba37d","impliedFormat":1},{"version":"c7af78a2ea7cb1cd009cfb5bdb48cd0b03dad3b54f6da7aab615c2e9e9d570c5","impliedFormat":1},{"version":"1ee45496b5f8bdee6f7abc233355898e5bf9bd51255db65f5ff7ede617ca0027","impliedFormat":1},{"version":"0c7c947ff881c4274c0800deaa0086971e0bfe51f89a33bd3048eaa3792d4876","affectsGlobalScope":true,"impliedFormat":1},{"version":"db01d18853469bcb5601b9fc9826931cc84cc1a1944b33cad76fd6f1e3d8c544","affectsGlobalScope":true,"impliedFormat":1},{"version":"a8f8e6ab2fa07b45251f403548b78eaf2022f3c2254df3dc186cb2671fe4996d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa6c12a7c0f6b84d512f200690bfc74819e99efae69e4c95c4cd30f6884c526e","impliedFormat":1},{"version":"f1c32f9ce9c497da4dc215c3bc84b722ea02497d35f9134db3bb40a8d918b92b","impliedFormat":1},{"version":"b73c319af2cc3ef8f6421308a250f328836531ea3761823b4cabbd133047aefa","affectsGlobalScope":true,"impliedFormat":1},{"version":"e433b0337b8106909e7953015e8fa3f2d30797cea27141d1c5b135365bb975a6","impliedFormat":1},{"version":"15b36126e0089bfef173ab61329e8286ce74af5e809d8a72edcafd0cc049057f","impliedFormat":1},{"version":"ddff7fc6edbdc5163a09e22bf8df7bef75f75369ebd7ecea95ba55c4386e2441","impliedFormat":1},{"version":"106c6025f1d99fd468fd8bf6e5bda724e11e5905a4076c5d29790b6c3745e50c","impliedFormat":1},{"version":"a57b1802794433adec9ff3fed12aa79d671faed86c49b09e02e1ac41b4f1d33a","impliedFormat":1},{"version":"ad10d4f0517599cdeca7755b930f148804e3e0e5b5a3847adce0f1f71bbccd74","impliedFormat":1},{"version":"1042064ece5bb47d6aba91648fbe0635c17c600ebdf567588b4ca715602f0a9d","impliedFormat":1},{"version":"c49469a5349b3cc1965710b5b0f98ed6c028686aa8450bcb3796728873eb923e","impliedFormat":1},{"version":"4a889f2c763edb4d55cb624257272ac10d04a1cad2ed2948b10ed4a7fda2a428","impliedFormat":1},{"version":"7bb79aa2fead87d9d56294ef71e056487e848d7b550c9a367523ee5416c44cfa","impliedFormat":1},{"version":"72d63643a657c02d3e51cd99a08b47c9b020a565c55f246907050d3c8a5e77fb","impliedFormat":1},{"version":"1d415445ea58f8033ba199703e55ff7483c52ac6742075b803bd3e7bbe9f5d61","impliedFormat":1},{"version":"d6406c629bb3efc31aedb2de809bef471e475c86c7e67f3ef9b676b5d7e0d6b2","impliedFormat":1},{"version":"27ff4196654e6373c9af16b6165120e2dd2169f9ad6abb5c935af5abd8c7938c","impliedFormat":1},{"version":"71d8ba39a9e024d9e4bb922464d18542ed8d2c25ee78efa7890c27213cc6e5d3","impliedFormat":1},{"version":"8c030e515014c10a2b98f9f48408e3ba18023dfd3f56e3312c6c2f3ae1f55a16","impliedFormat":1},{"version":"dafc31e9e8751f437122eb8582b93d477e002839864410ff782504a12f2a550c","impliedFormat":1},{"version":"754498c5208ce3c5134f6eabd49b25cf5e1a042373515718953581636491f3c3","impliedFormat":1},{"version":"9c82171d836c47486074e4ca8e059735bf97b205e70b196535b5efd40cbe1bc5","impliedFormat":1},{"version":"f56bdc6884648806d34bc66d31cdb787c4718d04105ce2cd88535db214631f82","impliedFormat":1},{"version":"633d58a237f4bb25ec7d565e4ffa32cecdcee8660ac12189c4351c52557cee9e","impliedFormat":1},{"version":"2e4f37ffe8862b14d8e24ae8763daaa8340c0df0b859d9a9733def0eee7562d9","impliedFormat":1},{"version":"13283350547389802aa35d9f2188effaeac805499169a06ef5cd77ce2a0bd63f","impliedFormat":1},{"version":"ce791f6ea807560f08065d1af6014581eeb54a05abd73294777a281b6dfd73c2","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"49f95e989b4632c6c2a578cc0078ee19a5831832d79cc59abecf5160ea71abad","impliedFormat":1},{"version":"9666533332f26e8995e4d6fe472bdeec9f15d405693723e6497bf94120c566c8","impliedFormat":1},{"version":"ce0df82a9ae6f914ba08409d4d883983cc08e6d59eb2df02d8e4d68309e7848b","impliedFormat":1},{"version":"796273b2edc72e78a04e86d7c58ae94d370ab93a0ddf40b1aa85a37a1c29ecd7","impliedFormat":1},{"version":"5df15a69187d737d6d8d066e189ae4f97e41f4d53712a46b2710ff9f8563ec9f","impliedFormat":1},{"version":"e17cd049a1448de4944800399daa4a64c5db8657cc9be7ef46be66e2a2cd0e7c","impliedFormat":1},{"version":"43fa6ea8714e18adc312b30450b13562949ba2f205a1972a459180fa54471018","impliedFormat":1},{"version":"6e89c2c177347d90916bad67714d0fb473f7e37fb3ce912f4ed521fe2892cd0d","impliedFormat":1},{"version":"43ba4f2fa8c698f5c304d21a3ef596741e8e85a810b7c1f9b692653791d8d97a","impliedFormat":1},{"version":"4d4927cbee21750904af7acf940c5e3c491b4d5ebc676530211e389dd375607a","impliedFormat":1},{"version":"72105519d0390262cf0abe84cf41c926ade0ff475d35eb21307b2f94de985778","impliedFormat":1},{"version":"8a97e578a9bc40eb4f1b0ca78f476f2e9154ecbbfd5567ee72943bab37fc156a","impliedFormat":1},{"version":"c857e0aae3f5f444abd791ec81206020fbcc1223e187316677e026d1c1d6fe08","impliedFormat":1},{"version":"ccf6dd45b708fb74ba9ed0f2478d4eb9195c9dfef0ff83a6092fa3cf2ff53b4f","impliedFormat":1},{"version":"2d7db1d73456e8c5075387d4240c29a2a900847f9c1bff106a2e490da8fbd457","impliedFormat":1},{"version":"2b15c805f48e4e970f8ec0b1915f22d13ca6212375e8987663e2ef5f0205e832","impliedFormat":1},{"version":"f22d05663d873ee7a600faf78abb67f3f719d32266803440cf11d5db7ac0cab2","impliedFormat":1},{"version":"d93c544ad20197b3976b0716c6d5cd5994e71165985d31dcab6e1f77feb4b8f2","impliedFormat":1},{"version":"35069c2c417bd7443ae7c7cafd1de02f665bf015479fec998985ffbbf500628c","impliedFormat":1},{"version":"a8b1c79a833ee148251e88a2553d02ce1641d71d2921cce28e79678f3d8b96aa","impliedFormat":1},{"version":"126d4f950d2bba0bd45b3a86c76554d4126c16339e257e6d2fabf8b6bf1ce00c","impliedFormat":1},{"version":"7e0b7f91c5ab6e33f511efc640d36e6f933510b11be24f98836a20a2dc914c2d","impliedFormat":1},{"version":"045b752f44bf9bbdcaffd882424ab0e15cb8d11fa94e1448942e338c8ef19fba","impliedFormat":1},{"version":"2894c56cad581928bb37607810af011764a2f511f575d28c9f4af0f2ef02d1ab","impliedFormat":1},{"version":"0a72186f94215d020cb386f7dca81d7495ab6c17066eb07d0f44a5bf33c1b21a","impliedFormat":1},{"version":"2d3cc2211f352f46ea6b7cf2c751c141ffcdf514d6e7ae7ee20b7b6742da313f","impliedFormat":1},{"version":"c75445151ff8b77d9923191efed7203985b1a9e09eccf4b054e7be864e27923d","impliedFormat":1},{"version":"0aedb02516baf3e66b2c1db9fef50666d6ed257edac0f866ea32f1aa05aa474f","impliedFormat":1},{"version":"fa8a8fbf91ee2a4779496225f0312aac6635b0f21aa09cdafa4283fe32d519c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"0e8aef93d79b000deb6ec336b5645c87de167168e184e84521886f9ecc69a4b5","impliedFormat":1},{"version":"56ccb49443bfb72e5952f7012f0de1a8679f9f75fc93a5c1ac0bafb28725fc5f","impliedFormat":1},{"version":"d90b9f1520366d713a73bd30c5a9eb0040d0fb6076aff370796bc776fd705943","impliedFormat":1},{"version":"05321b823dd3781d0b6aac8700bfdc0c9181d56479fe52ba6a40c9196fd661a8","impliedFormat":1},{"version":"736a8712572e21ee73337055ce15edb08142fc0f59cd5410af4466d04beff0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef86adb77316505c6b471da1d9b8c9e428867c2566270e8894d4d773a1c4dc2","impliedFormat":1},{"version":"de7052bfee2981443498239a90c04ea5cc07065d5b9bb61b12cb6c84313ad4ef","impliedFormat":1},{"version":"a3e7d932dc9c09daa99141a8e4800fc6c58c625af0d4bbb017773dc36da75426","impliedFormat":1},{"version":"43e96a3d5d1411ab40ba2f61d6a3192e58177bcf3b133a80ad2a16591611726d","impliedFormat":1},{"version":"4a2edd238d9104eac35b60d727f1123de5062f452b70ed8e0366cb36387dfdfd","impliedFormat":1},{"version":"ca921bf56756cb6fe957f6af693a35251b134fb932dc13f3dfff0bb7106f80b4","impliedFormat":1},{"version":"fee92c97f1aa59eb7098a0cc34ff4df7e6b11bae71526aca84359a2575f313d8","impliedFormat":1},{"version":"0bd0297484aacea217d0b76e55452862da3c5d9e33b24430e0719d1161657225","impliedFormat":1},{"version":"2ab6d334bcbf2aff3acfc4fd8c73ecd82b981d3c3aa47b3f3b89281772286904","impliedFormat":1},{"version":"d07cbc787a997d83f7bde3877fec5fb5b12ce8c1b7047eb792996ed9726b4dde","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"4805f6161c2c8cefb8d3b8bd96a080c0fe8dbc9315f6ad2e53238f9a79e528a6","impliedFormat":1},{"version":"b83cb14474fa60c5f3ec660146b97d122f0735627f80d82dd03e8caa39b4388c","impliedFormat":1},{"version":"f374cb24e93e7798c4d9e83ff872fa52d2cdb36306392b840a6ddf46cb925cb6","impliedFormat":1},{"version":"49179c6a23701c642bd99abe30d996919748014848b738d8e85181fc159685ff","impliedFormat":1},{"version":"b73cbf0a72c8800cf8f96a9acfe94f3ad32ca71342a8908b8ae484d61113f647","impliedFormat":1},{"version":"bae6dd176832f6423966647382c0d7ba9e63f8c167522f09a982f086cd4e8b23","impliedFormat":1},{"version":"20865ac316b8893c1a0cc383ccfc1801443fbcc2a7255be166cf90d03fac88c9","impliedFormat":1},{"version":"c9958eb32126a3843deedda8c22fb97024aa5d6dd588b90af2d7f2bfac540f23","impliedFormat":1},{"version":"461d0ad8ae5f2ff981778af912ba71b37a8426a33301daa00f21c6ccb27f8156","impliedFormat":1},{"version":"e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","impliedFormat":1},{"version":"fcafff163ca5e66d3b87126e756e1b6dfa8c526aa9cd2a2b0a9da837d81bbd72","impliedFormat":1},{"version":"70246ad95ad8a22bdfe806cb5d383a26c0c6e58e7207ab9c431f1cb175aca657","impliedFormat":1},{"version":"f00f3aa5d64ff46e600648b55a79dcd1333458f7a10da2ed594d9f0a44b76d0b","impliedFormat":1},{"version":"772d8d5eb158b6c92412c03228bd9902ccb1457d7a705b8129814a5d1a6308fc","impliedFormat":1},{"version":"45490817629431853543adcb91c0673c25af52a456479588b6486daba34f68bb","impliedFormat":1},{"version":"802e797bcab5663b2c9f63f51bdf67eff7c41bc64c0fd65e6da3e7941359e2f7","impliedFormat":1},{"version":"8b4327413e5af38cd8cb97c59f48c3c866015d5d642f28518e3a891c469f240e","impliedFormat":1},{"version":"8514c62ce38e58457d967e9e73f128eedc1378115f712b9eef7127f7c88f82ae","impliedFormat":1},{"version":"f1289e05358c546a5b664fbb35a27738954ec2cc6eb4137350353099d154fc62","impliedFormat":1},{"version":"4b20fcf10a5413680e39f5666464859fc56b1003e7dfe2405ced82371ebd49b6","impliedFormat":1},{"version":"1d17ba45cfbe77a9c7e0df92f7d95f3eefd49ee23d1104d0548b215be56945ad","impliedFormat":1},{"version":"f7d628893c9fa52ba3ab01bcb5e79191636c4331ee5667ecc6373cbccff8ae12","impliedFormat":1},{"version":"1d879125d1ec570bf04bc1f362fdbe0cb538315c7ac4bcfcdf0c1e9670846aa6","impliedFormat":1},{"version":"e16344db9b8ee59d41abdb3a61e4470955b5712c0ee869fb47112e152aabe142","impliedFormat":1},{"version":"46273e8c29816125d0d0b56ce9a849cc77f60f9a5ba627447501d214466f0ff3","impliedFormat":1},{"version":"d663134457d8d669ae0df34eabd57028bddc04fc444c4bc04bc5215afc91e1f4","impliedFormat":1},{"version":"144bc326e90b894d1ec78a2af3ffb2eb3733f4d96761db0ca0b6239a8285f972","impliedFormat":1},{"version":"3af3584f79c57853028ef9421ec172539e1fe01853296dc05a9d615ade4ffaf6","impliedFormat":1},{"version":"f82579d87701d639ff4e3930a9b24f4ee13ca74221a9a3a792feb47f01881a9c","impliedFormat":1},{"version":"d7e5d5245a8ba34a274717d085174b2c9827722778129b0081fefd341cca8f55","impliedFormat":1},{"version":"d9d32f94056181c31f553b32ce41d0ef75004912e27450738d57efcd2409c324","impliedFormat":1},{"version":"752513f35f6cff294ffe02d6027c41373adf7bfa35e593dbfd53d95c203635ee","impliedFormat":1},{"version":"6c800b281b9e89e69165fd11536195488de3ff53004e55905e6c0059a2d8591e","impliedFormat":1},{"version":"7d4254b4c6c67a29d5e7f65e67d72540480ac2cfb041ca484847f5ae70480b62","impliedFormat":1},{"version":"1a7e2ea171726446850ec72f4d1525d547ff7e86724cc9e7eec509725752a758","impliedFormat":1},{"version":"8c901126d73f09ecdea4785e9a187d1ac4e793e07da308009db04a7283ec2f37","impliedFormat":1},{"version":"db97922b767bd2675fdfa71e08b49c38b7d2c847a1cc4a7274cb77be23b026f1","impliedFormat":1},{"version":"aab290b8e4b7c399f2c09b957666fc95335eb4522b2dd9ead1bf0cb64da6d6ee","impliedFormat":1},{"version":"94fe3281392e1015b22f39535878610b4fa6f1388dc8d78746be3bc4e4bb8950","impliedFormat":1},{"version":"2652448ac55a2010a1f71dd141f828b682298d39728f9871e1cdf8696ef443fd","impliedFormat":1},{"version":"06c25ddfc2242bd06c19f66c9eae4c46d937349a267810f89783680a1d7b5259","impliedFormat":1},{"version":"120599fd965257b1f4d0ff794bc696162832d9d8467224f4665f713a3119078b","impliedFormat":1},{"version":"5433f33b0a20300cca35d2f229a7fc20b0e8477c44be2affeb21cb464af60c76","impliedFormat":1},{"version":"db036c56f79186da50af66511d37d9fe77fa6793381927292d17f81f787bb195","impliedFormat":1},{"version":"bd4131091b773973ca5d2326c60b789ab1f5e02d8843b3587effe6e1ea7c9d86","impliedFormat":1},{"version":"c7f6485931085bf010fbaf46880a9b9ec1a285ad9dc8c695a9e936f5a48f34b4","impliedFormat":1},{"version":"14f6b927888a1112d662877a5966b05ac1bf7ed25d6c84386db4c23c95a5363b","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"0427df5c06fafc5fe126d14b9becd24160a288deff40e838bfbd92a35f8d0d00","impliedFormat":1},{"version":"90c54a02432d04e4246c87736e53a6a83084357acfeeba7a489c5422b22f5c7a","impliedFormat":1},{"version":"49c346823ba6d4b12278c12c977fb3a31c06b9ca719015978cb145eb86da1c61","impliedFormat":1},{"version":"bfac6e50eaa7e73bb66b7e052c38fdc8ccfc8dbde2777648642af33cf349f7f1","impliedFormat":1},{"version":"92f7c1a4da7fbfd67a2228d1687d5c2e1faa0ba865a94d3550a3941d7527a45d","impliedFormat":1},{"version":"f53b120213a9289d9a26f5af90c4c686dd71d91487a0aa5451a38366c70dc64b","impliedFormat":1},{"version":"83fe880c090afe485a5c02262c0b7cdd76a299a50c48d9bde02be8e908fb4ae6","impliedFormat":1},{"version":"0a372c2d12a259da78e21b25974d2878502f14d89c6d16b97bd9c5017ab1bc12","impliedFormat":1},{"version":"57d67b72e06059adc5e9454de26bbfe567d412b962a501d263c75c2db430f40e","impliedFormat":1},{"version":"6511e4503cf74c469c60aafd6589e4d14d5eb0a25f9bf043dcbecdf65f261972","impliedFormat":1},{"version":"ec1ca97598eda26b7a5e6c8053623acbd88e43be7c4d29c77ccd57abc4c43999","impliedFormat":1},{"version":"6e2261cd9836b2c25eecb13940d92c024ebed7f8efe23c4b084145cd3a13b8a6","impliedFormat":1},{"version":"a67b87d0281c97dfc1197ef28dfe397fc2c865ccd41f7e32b53f647184cc7307","impliedFormat":1},{"version":"771ffb773f1ddd562492a6b9aaca648192ac3f056f0e1d997678ff97dbb6bf9b","impliedFormat":1},{"version":"232f70c0cf2b432f3a6e56a8dc3417103eb162292a9fd376d51a3a9ea5fbbf6f","impliedFormat":1},{"version":"a47e6d954d22dd9ebb802e7e431b560ed7c581e79fb885e44dc92ed4f60d4c07","impliedFormat":1},{"version":"f019e57d2491c159d47a107fd90219a1734bdd2e25cd8d1db3c8fae5c6b414c4","impliedFormat":1},{"version":"8a0e762ceb20c7e72504feef83d709468a70af4abccb304f32d6b9bac1129b2c","impliedFormat":1},{"version":"d1c9bf292a54312888a77bb19dba5e2503ad803f5393beafd45d78d2f4fe9b48","impliedFormat":1},{"version":"9252d498a77517aab5d8d4b5eb9d71e4b225bbc7123df9713e08181de63180f6","impliedFormat":1},{"version":"cb8d8ef7b9ce8ed3e6f1c814fcbf3f90dab0cb8863079236784fc350746e27c4","impliedFormat":1},{"version":"35e6379c3f7cb27b111ad4c1aa69538fd8e788ab737b8ff7596a1b40e96f4f90","impliedFormat":1},{"version":"1fffe726740f9787f15b532e1dc870af3cd964dbe29e191e76121aa3dd8693f2","impliedFormat":1},{"version":"3be035da7bee86b4c3abf392e0edaa44fc6e45092995eefe36b39118c8a84068","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f828825d077c2fa0ea606649faeb122749273a353daab23924fe674e98ba44c","impliedFormat":1},{"version":"2896c2e673a5d3bd9b4246811f79486a073cbb03950c3d252fba10003c57411a","impliedFormat":1},{"version":"616775f16134fa9d01fc677ad3f76e68c051a056c22ab552c64cc281a9686790","impliedFormat":1},{"version":"65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","impliedFormat":1},{"version":"f9fe6af238339a0e5f7563acee3178f51db37f32a2e7c09f85273098cee7ec49","impliedFormat":1},{"version":"407a06ba04eede4074eec470ecba2784cbb3bf4e7de56833b097dd90a2aa0651","impliedFormat":1},{"version":"77e71242e71ebf8528c5802993697878f0533db8f2299b4d36aa015bae08a79c","impliedFormat":1},{"version":"98a787be42bd92f8c2a37d7df5f13e5992da0d967fab794adbb7ee18370f9849","impliedFormat":1},{"version":"5c96bad5f78466785cdad664c056e9e2802d5482ca5f862ed19ba34ffbb7b3a4","impliedFormat":1},{"version":"81d8603ac527e75cfec72bb9391228b58f161c2b33514a9d814c7f3ebd3ef466","impliedFormat":1},{"version":"5f3dc10ae646f375776b4e028d2bed039a93eebbba105694d8b910feebbe8b9c","impliedFormat":1},{"version":"bb0cd7862b72f5eba39909c9889d566e198fcaddf7207c16737d0c2246112678","impliedFormat":1},{"version":"4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","impliedFormat":1},{"version":"320f4091e33548b554d2214ce5fc31c96631b513dffa806e2e3a60766c8c49d9","impliedFormat":1},{"version":"a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","impliedFormat":1},{"version":"d90d5f524de38889d1e1dbc2aeef00060d779f8688c02766ddb9ca195e4a713d","impliedFormat":1},{"version":"a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","impliedFormat":1},{"version":"bad68fd0401eb90fe7da408565c8aee9c7a7021c2577aec92fa1382e8876071a","impliedFormat":1},{"version":"47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","impliedFormat":1},{"version":"fec01479923e169fb52bd4f668dbeef1d7a7ea6e6d491e15617b46f2cacfa37d","impliedFormat":1},{"version":"8a8fb3097ba52f0ae6530ec6ab34e43e316506eb1d9aa29420a4b1e92a81442d","impliedFormat":1},{"version":"44e09c831fefb6fe59b8e65ad8f68a7ecc0e708d152cfcbe7ba6d6080c31c61e","impliedFormat":1},{"version":"1c0a98de1323051010ce5b958ad47bc1c007f7921973123c999300e2b7b0ecc0","impliedFormat":1},{"version":"4655709c9cb3fd6db2b866cab7c418c40ed9533ce8ea4b66b5f17ec2feea46a9","impliedFormat":1},{"version":"87affad8e2243635d3a191fa72ef896842748d812e973b7510a55c6200b3c2a4","impliedFormat":1},{"version":"ad036a85efcd9e5b4f7dd5c1a7362c8478f9a3b6c3554654ca24a29aa850a9c5","impliedFormat":1},{"version":"fedebeae32c5cdd1a85b4e0504a01996e4a8adf3dfa72876920d3dd6e42978e7","impliedFormat":1},{"version":"3eecb25bb467a948c04874d70452b14ae7edb707660aac17dc053e42f2088b00","impliedFormat":1},{"version":"cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","impliedFormat":1},{"version":"330896c1a2b9693edd617be24fbf9e5895d6e18c7955d6c08f028f272b37314d","impliedFormat":1},{"version":"1d9c0a9a6df4e8f29dc84c25c5aa0bb1da5456ebede7a03e03df08bb8b27bae6","impliedFormat":1},{"version":"84380af21da938a567c65ef95aefb5354f676368ee1a1cbb4cae81604a4c7d17","impliedFormat":1},{"version":"1af3e1f2a5d1332e136f8b0b95c0e6c0a02aaabd5092b36b64f3042a03debf28","impliedFormat":1},{"version":"30d8da250766efa99490fc02801047c2c6d72dd0da1bba6581c7e80d1d8842a4","impliedFormat":1},{"version":"03566202f5553bd2d9de22dfab0c61aa163cabb64f0223c08431fb3fc8f70280","impliedFormat":1},{"version":"5f0292a40df210ab94b9fb44c8b775c51e96777e14e073900e392b295ca1061b","impliedFormat":1},{"version":"bc9ee0192f056b3d5527bcd78dc3f9e527a9ba2bdc0a2c296fbc9027147df4b2","impliedFormat":1},{"version":"8627ad129bcf56e82adff0ab5951627c993937aa99f5949c33240d690088b803","impliedFormat":1},{"version":"1de80059b8078ea5749941c9f863aa970b4735bdbb003be4925c853a8b6b4450","impliedFormat":1},{"version":"1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","impliedFormat":1},{"version":"5bf5c7a44e779790d1eb54c234b668b15e34affa95e78eada73e5757f61ed76a","impliedFormat":1},{"version":"5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","impliedFormat":1},{"version":"5c634644d45a1b6bc7b05e71e05e52ec04f3d73d9ac85d5927f647a5f965181a","impliedFormat":1},{"version":"4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","impliedFormat":1},{"version":"27be6622e2922a1b412eb057faa854831b95db9db5035c3f6d4b677b902ab3b7","impliedFormat":1},{"version":"a68d4b3182e8d776cdede7ac9630c209a7bfbb59191f99a52479151816ef9f9e","impliedFormat":99},{"version":"39644b343e4e3d748344af8182111e3bbc594930fff0170256567e13bbdbebb0","impliedFormat":99},{"version":"ed7fd5160b47b0de3b1571c5c5578e8e7e3314e33ae0b8ea85a895774ee64749","impliedFormat":99},{"version":"63a7595a5015e65262557f883463f934904959da563b4f788306f699411e9bac","impliedFormat":1},{"version":"ecbaf0da125974be39c0aac869e403f72f033a4e7fd0d8cd821a8349b4159628","impliedFormat":1},{"version":"4ba137d6553965703b6b55fd2000b4e07ba365f8caeb0359162ad7247f9707a6","impliedFormat":1},{"version":"ceec3c81b2d81f5e3b855d9367c1d4c664ab5046dff8fd56552df015b7ccbe8f","affectsGlobalScope":true,"impliedFormat":1},{"version":"8fac4a15690b27612d8474fb2fc7cc00388df52d169791b78d1a3645d60b4c8b","affectsGlobalScope":true,"impliedFormat":1},{"version":"064ac1c2ac4b2867c2ceaa74bbdce0cb6a4c16e7c31a6497097159c18f74aa7c","impliedFormat":1},{"version":"3dc14e1ab45e497e5d5e4295271d54ff689aeae00b4277979fdd10fa563540ae","impliedFormat":1},{"version":"1d63055b690a582006435ddd3aa9c03aac16a696fac77ce2ed808f3e5a06efab","impliedFormat":1},{"version":"b789bf89eb19c777ed1e956dbad0925ca795701552d22e68fd130a032008b9f9","impliedFormat":1},"f4e8976c19fc926644d72610bf1058bd6bf52add97e46a02bc0b912a751625c0",{"version":"50471843ca66d943fe693f98e52a2df0dcac339cd804edf41e96964a22506026","signature":"435a1e418e8338be3f39614b96b81a9aa2700bc8c27bc6b98f064ff9ce17c363"},{"version":"402e5c534fb2b85fa771170595db3ac0dd532112c8fa44fc23f233bc6967488b","impliedFormat":1},{"version":"8885cf05f3e2abf117590bbb951dcf6359e3e5ac462af1c901cfd24c6a6472e2","impliedFormat":1},{"version":"333caa2bfff7f06017f114de738050dd99a765c7eb16571c6d25a38c0d5365dc","impliedFormat":1},{"version":"e61df3640a38d535fd4bc9f4a53aef17c296b58dc4b6394fd576b808dd2fe5e6","impliedFormat":1},{"version":"459920181700cec8cbdf2a5faca127f3f17fd8dd9d9e577ed3f5f3af5d12a2e4","impliedFormat":1},{"version":"4719c209b9c00b579553859407a7e5dcfaa1c472994bd62aa5dd3cc0757eb077","impliedFormat":1},{"version":"7ec359bbc29b69d4063fe7dad0baaf35f1856f914db16b3f4f6e3e1bca4099fa","impliedFormat":1},{"version":"70790a7f0040993ca66ab8a07a059a0f8256e7bb57d968ae945f696cbff4ac7a","impliedFormat":1},{"version":"d1b9a81e99a0050ca7f2d98d7eedc6cda768f0eb9fa90b602e7107433e64c04c","impliedFormat":1},{"version":"a022503e75d6953d0e82c2c564508a5c7f8556fad5d7f971372d2d40479e4034","impliedFormat":1},{"version":"b215c4f0096f108020f666ffcc1f072c81e9f2f95464e894a5d5f34c5ea2a8b1","impliedFormat":1},{"version":"644491cde678bd462bb922c1d0cfab8f17d626b195ccb7f008612dc31f445d2d","impliedFormat":1},{"version":"dfe54dab1fa4961a6bcfba68c4ca955f8b5bbeb5f2ab3c915aa7adaa2eabc03a","impliedFormat":1},{"version":"1251d53755b03cde02466064260bb88fd83c30006a46395b7d9167340bc59b73","impliedFormat":1},{"version":"47865c5e695a382a916b1eedda1b6523145426e48a2eae4647e96b3b5e52024f","impliedFormat":1},{"version":"4cdf27e29feae6c7826cdd5c91751cc35559125e8304f9e7aed8faef97dcf572","impliedFormat":1},{"version":"331b8f71bfae1df25d564f5ea9ee65a0d847c4a94baa45925b6f38c55c7039bf","impliedFormat":1},{"version":"2a771d907aebf9391ac1f50e4ad37952943515eeea0dcc7e78aa08f508294668","impliedFormat":1},{"version":"0146fd6262c3fd3da51cb0254bb6b9a4e42931eb2f56329edd4c199cb9aaf804","impliedFormat":1},{"version":"183f480885db5caa5a8acb833c2be04f98056bdcc5fb29e969ff86e07efe57ab","impliedFormat":99},{"version":"b558c9a18ea4e6e4157124465c3ef1063e64640da139e67be5edb22f534f2f08","impliedFormat":1},{"version":"01374379f82be05d25c08d2f30779fa4a4c41895a18b93b33f14aeef51768692","impliedFormat":1},{"version":"b0dee183d4e65cf938242efaf3d833c6b645afb35039d058496965014f158141","impliedFormat":1},{"version":"c0bbbf84d3fbd85dd60d040c81e8964cc00e38124a52e9c5dcdedf45fea3f213","impliedFormat":1},{"version":"8c62ca2967cfb122b2e4353ce4e385239843de4887de67c268d550c65f09644f","signature":"f65ce75c9085571e6321abf2bf9833709f4897e381f89e9925521833dbb7ab16"},{"version":"d4a6acf500a7b4bb6917c2fc36441e12af430115b8cae917d3bc750ae649380c","signature":"5f5303388c23daf221df682ba0e6ed13924ad3a925fae5ec71f4cdfb6adf1b79"},{"version":"cfb529c313b7d9115d4c371211f9928e8f3dc835be4d0aa1cfcab26dae5d8f9b","signature":"59d9f23a869497c75dd46911840b2c92b17933e5dd2307f10c9bf4b3de577963"},{"version":"8e7486e254a16bd20d0247345249d227427338687f4714c4a29240ea932f8fa7","signature":"14777230ffb55ee7064d86fa58eefc198cb75724404895fcd824897035aac65c"},{"version":"147c0ca36568495119564a3b99b929ccca7685990352863f362fdbf69439b40a","signature":"ebc450cf4888573aef03e1d85e34f8587789f7436e4c80a3f1417a66429a9a29"},{"version":"6898eb3e45c37a67417733b23cf8519cda3cf305046531bd318cdef48e52ca5a","signature":"6153aea1b490266dc2df16b75e79b79e25a8f7492b4d73fb89727a5682d6a6ec"},{"version":"ec21dd4a45e54073cb36e9b947f01843db6a4a09cdb997da341e76802fab95ae","signature":"23822a168bf160052857e23ddd08b388199c72abfaf1e9f96d3d041f6fa7b1fc"},{"version":"62d4a2668b5c731742c7f3bebf3851ade404a707906d47d381aa3605219b58c3","signature":"d8f43844bb7e36c06a6c296202eb9b2698eb08d4dfc5a616d40e03fa003182c6"},{"version":"32fd5fa462a08fe65e8ba09351bb41d861d558a7af2f722564a070a1972ad6b9","signature":"41afd29567caf0c9639c58a2d342a9a9a9920091e080a328789181491bcc6451"},{"version":"598f3baa219909577e28e5e78d0170a49761f6e39a733be304b1321095dc340b","signature":"bd20c80b2e92e71acb328641090529220e226a378124c9c3d0616e53f888f7ff"},{"version":"4654f66c69f3da8a2848cfd68b75a23230a8d62b6eceebfcf214e0d623b6e7b4","signature":"a8c7595b174fd808b6caeadc7a886d13d99c17acf3e110f04a47398699fe9e81"},{"version":"75c1eb2f4c9bf91c50fb19f24c5c891ad314b125903d1c68b50edd6d8e0de86e","signature":"72af78ebc4c7ca71f3cd76f38659d0dc231f4b8df8bda968cead637bd1633242"},{"version":"cf929500b6b1714ebfdf9086ed4820ee3942b72a332c56bc5a59039b85331410","signature":"98c1c9e92d1e062f56f2da277c8c555bd635af7dd5ddff9e6c61ac31ab214670"},{"version":"7e981d1ec28163343d9819bbb5eca9c0e6b6238bf7ed0cb3e19014a2016091c4","signature":"c86473483edfb9d5d810a3e1714a6bc5359901cb3f3b9dee3f274c7e4f1eb627"},{"version":"7191bc1ec67488659398391a42cc918a0fa79c624c6ca4d4a0099c3892eee401","signature":"b8005de76cc5b5f3af31f292491ac127f9738a0c022a967db0089e11980b3914"},{"version":"07c8401bdd652da387c5bbfe80d786c3c59d101cdc6746408cfb8197f71bb7e4","signature":"759805e99c9e10dfbad43113e0a79ea634d265b2332e6d3f309026afdb66807b"},{"version":"a74cf061f6bd3b8209b82a1e118ca0d139ff08d0ff3c8a162ff3ac0e8cc698b1","signature":"c0a5e3199ce900caee714b0cc2ca870402dfff4b48f53553e18882ecb738047f"},{"version":"ffce762ea3b1bdd900efbb8f1cec0b8fb855691fa748d189f86ff0d60f3caa63","signature":"77c9adae7e0872bbd34729c05aa562718c0a3d603c9a436737327935f58ac85b"},{"version":"540a3e679e8dddc8493b31e16a081525a3f8e4f1aec86fe004e45324327365d8","signature":"8441a3818a22a2a444c7a6776cd7d6f83969a36a63796815a858c2629fc7370c"},{"version":"0b21cc62f28c164ef131d6e5afc304b392b0f0e65ad7a3d0cfdd0a632fd1309f","signature":"bbcf21fdb47d0a821efd28199218b48935e166e6a1cca9df5c2c66f71bf20881"},{"version":"d6fac77c5ef87eb0a08edf3b689da72e2c0aeee114b4de2ef71c6329ef547cf2","signature":"661d2ed6167fef10beac4ebaeadbecdd04e3d896d792ae9920b726efd170cf5c"},{"version":"4fdd8077bbf3e5adae262c207e3e13cadc86f4984ae3ed4124753f5a7b6fd9f5","signature":"5bff26d05c0f3f8aa96be3f88f5dc5b4ec061a61fac4a8c40751222d23a34b3b"},{"version":"0f6d1ec7aa3b1e3d613c8399e2c82d8ec0d193ae275c596df554c6289279a1f5","signature":"6f16862d9aaee2956b25c81ca10ccbfb93d4f586c31a28c265638881d1fdee50"},{"version":"758c24255cc5409471c8c8a85c0436ee2da68747533087397ab330a0ec62ed10","signature":"f5d17a198ea4541a200e784f47fab41c2555e2b2a56ccc23a901a87941fb2723"},{"version":"0fcaf14631739afd726ac11e6450b7c0aaa3f70f7e1ea4af4b874295122c19c2","signature":"e7de8e5f8db75638a60eb39eac3f8d15a8c3315c5f924a250afd23213ccd4bfb"},{"version":"22104eadb81738a9c3951741e14e8ee4cb0414faa5b1a02c379e89cc800ae190","signature":"e92d492c348b2e8b3bec329abf7db30924ed500dc7ce5e4ae0220b16bee228bf"},{"version":"848b257bdc73b54c167bed01b2db42fd44c1aab77350c9b1fc3a2ce3ff08f899","impliedFormat":99},{"version":"642b071c4d865ff593c1794e06fa1781a465338a37796a7d0e2501daa20172bb","impliedFormat":99},{"version":"ff87d4d02bfc715a3a038c825bb80d6a6cfd1750bec3a0fa6f0e407133b1cd2f","impliedFormat":99},{"version":"0da67df9ad0b921385c37c0eef3de0390b8ef7b0b36cf616fdf3590a67fed1e4","impliedFormat":99},{"version":"8b28fc7010a1cd9c54201b6015c7d6a04fc6a4981acc9eaa5d71d4523325c525","impliedFormat":99},{"version":"e72fd44d087aac63727f05fe82c0c4a984c6295f23fdb9a6290d4d9fda47cfc6","impliedFormat":99},{"version":"fa2cd67056be92f91c496c134c19c4e0a074103d79ffe5dd879c7ad0f3036b75","impliedFormat":99},{"version":"a5e9994461de1736556049ad37857577a0c1238cda95baed68d5997c45f353bb","impliedFormat":99},{"version":"479ae2d0df8346600082dab7eae56c7557bc0436ab0647c31063f3a02d7cc6c7","impliedFormat":99},{"version":"1faf72b15dbf252373a1f4b2867a199800a97cc7079dd3b01087a2f3c11f4a45","impliedFormat":99},{"version":"4af8ba68f5b509c7a7d353e7a91a4014d194779c537acd3afd330980e9cb972e","impliedFormat":99},{"version":"c4a78ea6e862ed9913ecf9b95c8b4a8f77384f2cf583eee7fc4b27c52f4fbaf7","impliedFormat":99},{"version":"ee9c59f4fa245924e3328a2a6620fe107b0c41860367a47a90d07a932e3a084a","impliedFormat":99},{"version":"e2a62c1f16bfc7e305e78143c1eeedb71ad1f272761aa07ff2ad70bb97248b13","impliedFormat":99},{"version":"1c1ba22485be7577e2a73cc103bf6e7a692ae0a025216619a4de42186eb1687f","impliedFormat":99},{"version":"ebbaa82abb5a1a7179dff85377f99c666dfa3a68f8a2ea405bbcf4f5e50149be","impliedFormat":99},{"version":"37673287f8bc80af36be1c23275ed9416bec11ee361b320a57a0b3a2797260ef","impliedFormat":99},{"version":"39e217bc229493f7b355cb2ce07f8600f6266500a6feaad43c254cc0a0f140e6","impliedFormat":99},{"version":"a33d889bdb82f43cdcd8158107c0e25d295d1838d82ee8649390ca0b88e87a07","impliedFormat":99},{"version":"f289d98b575f84044465ab3b7ac81e9a11b4d97cf2a9e92a822e948bc2f0ba7c","impliedFormat":99},{"version":"787a6b0d92df1148c7da1e75d705652030078c19e79985a72e622dc5b54487bc","impliedFormat":99},{"version":"ad09a94413ba6d37b86beaf348b252b378608dec764b67efc9e65d1dc4dff808","impliedFormat":99},{"version":"534611552e459b47ea008079ec9d520fa87c7b229c8a3a08993e8be650a8df71","impliedFormat":99},{"version":"d4ddcacf48fe1a273c71f4b04818eb912fd62bd7c0da092742a7e37a30cbc726","impliedFormat":99},{"version":"83098570d4ae37e31d8c788901c5d094313176a23f26870e78a5e98e5edd7777","impliedFormat":99},{"version":"9a43bf14da8556f0484d20c93074fd98845c06c85587f6b580fedda82685dc04","impliedFormat":99},{"version":"6a36631027099eca036047ab3bf0f262e23239c950ec1c65de700300d223ec44","impliedFormat":99},{"version":"fabd5be6cc2f406cbfcddb145a91a0e341a25e509e1c7521762441a46e58780d","impliedFormat":99},{"version":"80a9eb1f4fd46c863aec7d9c8490702ec6aee2b63ada21bcf231d558f5f0863f","impliedFormat":99},{"version":"72932bf7599a75bdd02788593ec6f060422f0c6e316f19629c568e2473d37db3","impliedFormat":99},{"version":"2d6244e9b7d19e7650ceaf09033ada34ebc2d0590a770707cba8da87bc125d59","impliedFormat":99},{"version":"6e0ce9899346df5cf80e1b45172eb655855837cdcad4539acbfc9305d8fc8976","impliedFormat":99},{"version":"ec56ed06f0a89fa2e3a20d7f7521d017e92decaebfa4d53afa0fd3a7b7a2be3b","impliedFormat":99},{"version":"236b90e223fa7a458b8561e87327d3737c8c83cac9ce4cdfbf04b3098da851fc","impliedFormat":99},{"version":"d64b03d8342c4f4d51706659a835c45197b9940b8938b0656bdc4df15d06f630","impliedFormat":99},{"version":"8ff0f34466d5136ab068a15358b99a958095d1c6e7e11c67d607111f81933fc4","impliedFormat":99},{"version":"98a72afb1b77b1c3f15beaed5662feb608060ccc604fa1747fba9d9deb070f80","impliedFormat":99},{"version":"cd5189682a722b13ec340b2bd112bd48b899bfeecd69d629bfc78166c15b64fe","impliedFormat":99},{"version":"a4017a3045a75c68509bc69bd314d91f7d4e1ec3f255416a86efe7dadfc0ee64","impliedFormat":99},{"version":"19599db9634ba72f2663db5b76de48dfe250280ffb4bb158109c97eb4e5b5e0c","impliedFormat":99},{"version":"f5a0ae8b389c104a6655117a8e4ee1b563c4d7cb33e045e4ce433cd6c458adb4","impliedFormat":99},{"version":"566247adad3c04b6c5b7e496700f3f23d05b07f31d983ab47fae1aa684b048c9","impliedFormat":99},{"version":"d10e1723404ce7559b75ab341c7e85b1ee2c97a871fe41630e47edcfb1bb1621","impliedFormat":99},{"version":"19b360e4fd7cd6683ab5455093e02c7c42dbbbd63ae5bd50f91f55a8709feb98","impliedFormat":99},{"version":"ee5ac98eb5ccf9bee886f916ae88856ac220858f4363362c094add66a0d44780","impliedFormat":99},{"version":"02efcdd69ab7a028c7fc316316748723763f7d40073f5b74f5136f9ded5c3073","impliedFormat":99},{"version":"35c834f84dabbdc3b595dd35c2208876af77af86ec3e0f4b622ff7f901843e80","impliedFormat":99},{"version":"dde618b9a6b780c35bffa2075f11ee29adabeaff3dbb73136ac530fd45035692","impliedFormat":99},{"version":"6902d565ebbc9b4f27b81f50a769ebbb673d299090146fc4d645c59b4433b36e","impliedFormat":99},{"version":"ac0e664aa993f918ba1006ca2bc107bbe326ec96341a61195f9b3054a9571a84","impliedFormat":99},{"version":"b184444a122ee085c61df92f39b23414dbe7adece24558bfd1a0dcb22687119a","impliedFormat":99},{"version":"b8ae8c7a851b19aa288e08fbd70e734f5aef3d1bca3a5844dd31658f1bd18f62","impliedFormat":99},{"version":"85377ed2b6029c8c1e851e1acf848d31fcfcc5a9264e726a00e046ccd68288ce","impliedFormat":99},{"version":"aa096547941633cc25eb4b24af41984906ca9e502d9c06c88e0b4bdc2a54b602","impliedFormat":99},{"version":"2b69aa435fea74564e7388f7530a8ce8dd5c9f9c6a67cf74aef6f99922f05885","impliedFormat":99},{"version":"6853837d5850cfd5322fa38f190d4afb7b1ad9d37b137a7fef26a1f489a48b61","impliedFormat":99},{"version":"60bc42d137352b88caf900df4bacbfee40c73c02b56b853e0a6d23a3edab7815","impliedFormat":99},{"version":"d90817a097f2792dc8ebaf9bc08298f1ab6cb18b4287c8cfc1cea297263df6d8","impliedFormat":99},{"version":"3cbfe6b48a9c4b5b6283f7fbce0c1f5ccf0796ac8b1a077893eeab13fc17ef73","impliedFormat":99},{"version":"01e1e0a0c437c0c64b0e55fd5b3123398c25b058fae214ffce0ff9a345d58777","impliedFormat":99},{"version":"23e97994d2f64dd504174c02b5ed713093f1f8c0ee4c3b587c7f12a641b8bcd2","impliedFormat":99},{"version":"fff0fc0ee248874a1f8d12dd439f1c26a8be008a18b7e36ee65c3e8cd634fe18","impliedFormat":99},{"version":"7e6a11a7c6f9070215e73bbf9620d274ef45979eadc8de39d50ffe6fb67f095f","impliedFormat":99},{"version":"c34715ff893e99af41dcf4f63b3eca2a45088ef0e4a025355204c440772278c8","impliedFormat":99},{"version":"cbc0e98cf745d22c786862ea94c3566321c06e04109f461d8f657a3c1151d057","impliedFormat":99},{"version":"35a5955d275c446b47dcbd8347f41e8ef6e230c563efd38f62ff715f7994b767","impliedFormat":99},{"version":"2bb58f627a12841ae367d97ee15993590a5cee4a826326e2a8be2bd750fca9dc","impliedFormat":99},{"version":"646d361245ec8052afcc7b90acb3c7f6098bf1340b88f32455e63f0369ddf1c5","impliedFormat":99},{"version":"2f6f7ba3522444f3d3e1f6d4a74ac37a096fc3dd292f902773d761a9eee57620","impliedFormat":99},{"version":"921a2668977ae600f6de2a4c19f53b237ed196ae5ae3297043b38781c11d9af4","impliedFormat":99},{"version":"37072b862cae4c819e335ac9eb855cc398719a50ebc60376de9ddae801610a3f","impliedFormat":99},{"version":"6473fc970e5fb3f18fece3e8681e9ad4454adf295be54463ebd74688b8b5051c","impliedFormat":99},{"version":"4e54895c51ee23f08f62fb429dbf4cfc1772ce34f6ec77855a3bb805dd16637e","impliedFormat":99},{"version":"800509db7d0b61907f28dea506dea01b57d2aa3cfffff03c78ccad04e8ceb976","impliedFormat":99},{"version":"887778667559bb4b7c64b006650210ca831f903c055ada3a069a8f08790c5718","impliedFormat":99},{"version":"bd96c9f72e9a439499bf19a4405d205fb8c2da019fdc9fea988c25005e76c200","impliedFormat":99},{"version":"9fe617a1d5e7c5c4290dd355f1bdbe1a80574d765a2c03bbf49181b664f11f0a","impliedFormat":99},{"version":"9afd17a7e1d2b474eb24bb37007d0f89ccbfb362ce904cd962a1eca5a2699efe","impliedFormat":99},{"version":"2841695cc12ded91f69e66e4ef44be524ad02c54bbe257bfe5802e3f6b851b5f","impliedFormat":99},{"version":"1132807f0a56b00d253a76bc21aeb23e79c8ba8478c52ec75ba9fcbd81738b6c","impliedFormat":99},{"version":"effbcf17a843123b20a54ce8389b29a26d12c056872f0dfc76a27460b22f716c","impliedFormat":99},{"version":"0e052acd94182df2373f96e362f064715c7a782452166e2344c91a126fb41d28","impliedFormat":99},{"version":"b7bce6b962d325bdd11ca9f3394b411f37354bffc995e798ddf66a7ee3b9de42","impliedFormat":99},{"version":"96d66cb0b5b2a0b1e2e6172e6bc163b5345f189c699852c61cb866812bc5f3a8","impliedFormat":99},{"version":"31e4839e4dc630cf7bc9f86c1afdf3dc2cdb4b8f6c3e11d12ba38ea18f4c421c","impliedFormat":99},{"version":"5b94968e8400015a4904bc1ba26ebcada2fd366c8fdeeb873904af54ccd4b423","impliedFormat":99},{"version":"1513e36e2863b615eaccce129355da5f5d8e169d4416d25e71e47dea8d2d35c5","impliedFormat":99},{"version":"7a128061e6e84e9375c9b46f84a0cfded49f537e8a41b42db0c72133666ab9e8","impliedFormat":99},{"version":"1140a35eddf2e3b9d706eeaf28ea74e969ecbe52e0d0f6a180d0753d2b8272b6","impliedFormat":99},{"version":"5e9cf2a12f0d82d2bb5989cbe663707bf1f3bdccf7cf0fdb84105712b9788e0d","impliedFormat":99},{"version":"ad1a1db6939b787bd9ae09f997f9b209cf0e689c72414090fb9cb7989163df77","impliedFormat":99},{"version":"95e857dd9e4984d5694b721cfe2d66430805db29660e212c2f681515ea08e8e3","impliedFormat":99},{"version":"2e8932517228de42f8b3db669c4d04d177367283d2da199b1a59cd94d009e65b","impliedFormat":99},{"version":"5fada2edbc2264cc0d7ab6080e8e4d4e3d5dfb9ef494b4eac9c8e49b90f30bdd","impliedFormat":99},{"version":"615d06216e7aaba7e4011cee475b9ef6d1d873886118f178bca21bc38ecc10a8","impliedFormat":99},{"version":"7ddf86abeff5aa521f606f9ea9ba2dfa19df8ee1c76ea838d9081afad9b28f68","impliedFormat":99},{"version":"ebd25c9c141e447ee6ba794c80c6878ebb39c42ad135a0c363d275af9fa6799f","impliedFormat":99},{"version":"4132803c2f4af9b16bd01853bc98cf15ec1ec9d11529665bc6ccff35bb742774","impliedFormat":99},{"version":"efb8e27827124bc3bf96b81288c0278c722d10f2372a1bbbb9de1943e784022b","impliedFormat":99},{"version":"1400f49fbe68fc416c2d47e19f6bc29a99a5480910bd560090a27fb6b68fbb45","impliedFormat":99},{"version":"98312a773a489dd6b924350b9ef0eeb1f9646b7e1b294501b582b67dd735cb3f","impliedFormat":99},{"version":"a9410e9f7d26ad51166dc6e55de1f0efe893750b665a4169cce9a1c46d793d18","impliedFormat":99},{"version":"4218cc9758b6c35b4e98131e96d6be902fddbc194936e0ba71a95767e11072b8","impliedFormat":99},{"version":"6f29d6927bf60c969a6a5ef57231d63b81e6820b6a30c22eef57821b5c429ac0","impliedFormat":99},{"version":"0df226906c522ff1903482f4fbb83c039fbd0dca93bd1b3e56baf10ab58bfa15","impliedFormat":99},{"version":"02f4852cbefa35edd7752e35e228adc060a2c98251be70a9446f64e196029bf0","impliedFormat":99},{"version":"4b70362f8a653d862fb4e5b65aec7943cb237e89c2409c76e6aabbe52952507a","impliedFormat":99},{"version":"8c83218e92cb960a020ce6ccf208c7fdd29fdba50f824ec9f7804b9a47c175d0","impliedFormat":99},{"version":"1da27ab546abd20e493012d7088a55cf1a00c92b61eb06aeb7a25581c6f9ff87","impliedFormat":99},{"version":"be74c0d9577d80d8dd6fc04a8830a2bc3ddbbad2570551305072dfd985534876","impliedFormat":99},{"version":"de3347bf58d986a47125ca7bcda6268d55c78d6006e165f59a03c20be861d95f","impliedFormat":99},{"version":"b1ef1a2530ef3a4308488bd172252a506f35fe16622d3117573865c2b6ad3485","impliedFormat":99},{"version":"840d2806690ca5764b0b3393d63fb4f4eed660f2fd1c60ed5a8aec3a851e775e","impliedFormat":99},{"version":"b222f67a18cb2bf55641e911467ca5f1cc4ce664824a3d4e2ffcc1eb91729be7","impliedFormat":99},{"version":"5a191a0753935e35e8560d6dff2a0bcbeccd0850d11a7429283e3061fa8bc8e9","impliedFormat":99},{"version":"e933510d79c03cb4b5ae2b910b72056332955385cd91774913ab04c9f7fdf00a","impliedFormat":99},{"version":"3a3dee0f5e3155384690cf45b07a217a6b3de5e1edb4e98ec8be5fbf3e500868","impliedFormat":99},{"version":"db2ed9c0a4fd561f950cea441d7833cd5763720e91856f7521d3d5f29fc4b7e7","impliedFormat":99},{"version":"c8a7aaf671a49f7f836c4bc4aa4fed23e5c8da16eccf72ef2b2a52197663e6cc","impliedFormat":99},{"version":"10856b8f8c6dc7fa2da62848f65f977524b073c6fd167578f21edda81832687d","impliedFormat":99},{"version":"067de9fe31618932f08e63ff479248118a39461669a06b6f6d438e7ef364cf29","impliedFormat":99},{"version":"f67169b04c2c933f4368c15bcea7f744f05a134dad020c6d418f7cca2f9926bb","impliedFormat":99},{"version":"078af8b67c2d6de37753072c1759f1215fb9846cd4344cf83a266b10fbbcd790","impliedFormat":99},{"version":"e27b61cd6a2953ce7955274ed4dafde236be2051b1a89d10b5640306b7d3b86f","impliedFormat":99},{"version":"91beef8d07b44eb328aa9d9c3db98bd79bde320adc5d1556d3fa7f463a90c3ce","impliedFormat":99},{"version":"7f7f86c7d1bc4a9f9e4d68fe0702f91667419056e6746494a66a7fd2882c8660","impliedFormat":99},{"version":"b87d0cb8854aa7f797bcc7f46ab0522fd091828dcce0463d4dc58b78e1f6ac10","impliedFormat":99},{"version":"934478c63db3268cc99351178a969840b2b93a2d21a4d165813cebe5eb6dc419","impliedFormat":99},{"version":"e1ac2ee125d07e130dafcc5727922a802f33bd894b3bdec61a58653cb25a105f","impliedFormat":99},{"version":"80d81e5352828e06dd7d79a0ad35f07087aa0c4f2aa80f8df7e67855ab544997","impliedFormat":99},{"version":"d78aa09669af770ed71d8a0d5b1e2ef23abb7a17dca11e1bc02adc9cf9816fd1","impliedFormat":99},{"version":"acc4b06dfbe56e355495b3571be65265b7bcba54ae6addebfc4c34823a3e8201","impliedFormat":99},{"version":"80d964c6d3fd00733c20f85ee9fa70c52e3459f1960adb17e5bf812cf9604ad6","impliedFormat":99},{"version":"1df19943bbd19525aa3e18c3f98f49ecdd788e07b5705d99c8579073771dcc06","impliedFormat":99},{"version":"8c2a083fb5fb302c0954709938e53e7810da0aa2daf489757af9dc6baa2f3b7a","impliedFormat":99},{"version":"fcc4a7940475065b3291a15623bc4e8db0c22f23dc29be00ec377892a805eba3","impliedFormat":99},{"version":"16f35e4256a94b314c98eb75040cb33ad9c430075bc29c53b43ede6405705700","impliedFormat":99},{"version":"a257b94f9f5403f63026dee4f4a95b9015742f8e23ff6eed7837f97f2ae501d9","impliedFormat":99},{"version":"254175b582a422c45bd9701e93d6ef9f6cf242c6247793a9a2e05770e1add917","impliedFormat":99},{"version":"c4dcab273dad7aaf0d3b4e0ca48e948aeb3cc269ac359301181fdfbb2efde033","impliedFormat":99},{"version":"d21671ff0f21081ecb19567351dadc8be7ad9443e26183d971ac658684479777","impliedFormat":99},{"version":"617be44c8811d411b4efc7dd13e57851bb1ab71f7e9d1a9eca04b7d0db0e1b35","impliedFormat":99},{"version":"948af5f3081a8e683756251a3834ed5a4ae6e4faf16b66abcc44b8a13e72d08f","impliedFormat":99},{"version":"af437043c5e9a8105f0e9633fea7ae79d1f7f89357897e2df99c6f3697c744fb","impliedFormat":99},{"version":"d0bede428ef73b5da47f0f1bdc440480a863a1baff3e6a6b28db98535efcaa6d","impliedFormat":99},{"version":"44015602830f6f90e043f14702f04e7f48ec4f2ce8a9925116fceaea73a43b8b","impliedFormat":99},{"version":"edadfd0ecbfc573c016b93064b18ec0ab64b17ebd252e5636c2ee55f0f6cd82e","impliedFormat":99},{"version":"45ccec80a9c659104e28cbf3dbff13ab92c57c4e1fad9b38671a0c9299afd4f6","impliedFormat":99},{"version":"1b59bf4043df6f2b48ac1685a0a6c3953ccdb49b1c7affd3364624f77ff58f0b","impliedFormat":99},{"version":"ca4a3925cfe8fc5bac902ea30a5fd441987ee1776ddf5a353715dd1c6579722a","impliedFormat":99},{"version":"658f055f615e8232a1f5b30753a0a1ce369a70c1dcf0685953f48d7d4d508ba0","impliedFormat":99},{"version":"341aee100ffa277e0737387b9b9db69280e6dfd056166e18656de5bced0e7f01","impliedFormat":99},{"version":"2cac36c32274e1e7faf7fb3bd1666e69763b07b9f5330eee6911352d3e6eee96","impliedFormat":99},{"version":"aef33b3c102b63e7e89208ec4982f8eac7168774b08b05e8c43e967729ea91e5","impliedFormat":99},{"version":"5788b512a6212523eb032c6898beb98d56dd14c84e186a786901c1b3cae527cf","impliedFormat":99},{"version":"e2f146177df266680126ba19e4336ffc6639094feb27b37d276577f8c3d2c186","impliedFormat":99},{"version":"e616fc8dc6c82cb4d47ffd510e180c7ea96a0ade6702f011d56d36707cbe27b7","signature":"ffb3e6a6be2aed1862c98e13255a030ed6205c7c04676bb752f526703468f17b"},{"version":"0eefc702c5de5c32835e290cbdcb5a76f6d98c956b87cdbf5da49c864d3ab88e","signature":"0a4895bce639e10d5ef215a48b4bbc4d73e444e9a3e214594ebae5e00a7140f8"},{"version":"61426e1db8f2891d0cb2b2a3eb5f85d33a30e0b213737a938544d5d065ea366c","signature":"692f5fa6f306b8aac3a4df2868958c4e1667da176c9695c7f961a30f27aec54c"},{"version":"88c305e239ed902480aca0f90537b2aab81b6a793eea9f05147c1f3269e3530b","signature":"81d4e18931396e11ea3a9238df2d578533292a7fbd3a21bea05fa1b5cf8b78f0"},{"version":"54f0fdce25f65dd46fea54a14ff0bfda9d1accb8cf13b208709ee7b527124abd","signature":"2277a245765dbac41e82b51724ea73eb058b58e261f7c67bad3a47924f48781b"},"f05d3e578bce30cf813093d2f435bc47cd78159af50856e246c3fc1e34217ddc",{"version":"37b49ad60620db9db26ff31a64f5a70a1cbe9c4598ff5c236433043f9bc63f04","signature":"6a96f44bcdb3e22101416e1bbdf5bcc70ec23d5215186089857e82b1d72283b4"},"01fe01d2ac935a652f21248717a8cb81a3bfe41d0b6a59a9baecddd3fab1a51f",{"version":"8f9ff94ef30f33846efdf40f521a79a9be87ac799dcbadde1d5c78a96e99151e","signature":"465474ec3bee370bcfb97e5467cb7f69af9f9815f65ece79d3252895357fe234"},{"version":"e10e48b0273e8e6f27618e9d9d3add55e9d93e00fe873516f61f3a639b7cd214","signature":"df93b3bbfc76a8c7d2583f152abeae935c9d36e878ff04c1c38b5a32e30c6ecf"},"b0f240b28e3760a1488d18190e11a8f888c689b42d220960e3d80b65c5554dd0",{"version":"da68b20c2da4fe8fff85e09b6b996c46d322fa3236e9faad0772caa9ac3cfcf1","impliedFormat":1},{"version":"6de0ef73d95431a5386ca68289fc73e7184b347290450e5b3c43413cd5efa87d","impliedFormat":1},{"version":"176f067f0d4f5a475e549aafae513dacf4fb65eacbe7e8c53aec4507da0d532a","impliedFormat":1},{"version":"e84d2c363ddc1caeaa5dc07e68f0e8f6daf6f4de7129648065658205a45e7419","impliedFormat":1},{"version":"2eec47fd2fa59588762d2d32cd21e0fbb48bab959355748fa69fd726c831b4f9","impliedFormat":1},{"version":"25cf93cd7101a3b4ccc331ed92446a4327d2b60e3c13172f60f179d3a5ef4b8c","impliedFormat":1},{"version":"2a2c6e0c174335928d9a9e69473193b1338ca3f69db315cbb6f1f29982048be5","impliedFormat":1},{"version":"47c68c8eba9c2d1e5185c0c8941238e393ca0d25beb87712749b776152a9142a","impliedFormat":1},{"version":"d72de9fb566361f7fc130c1e0ff9ecfa17098375826949cc9e2efc69b2daf2fb","impliedFormat":1},{"version":"f8cf9784854967e17fc09a0ef3f861a7d2f6228147af6bdfe035def611314ff1","impliedFormat":1},{"version":"af8ecfa6dd1d99be9c3829f142c0dfa932ab6892e7399c3bef0280b0e6eb9b42","impliedFormat":1},{"version":"32cfe506ca91cb16282efce472c0de913fa4b8fa937951aff70dc7c4e6ff60af","impliedFormat":1},{"version":"d5128291066411c82ee10e3a86836cb1642f2e957fbc7fcd58fdfac87a0bbdbc","impliedFormat":1},{"version":"1d3b944202b6bd0807f1f219b2b69576129cd358cca2fb91c39d8c8051776ce6","impliedFormat":1},{"version":"a64e0c54b268ac3a2681ad56883f75c66cba5866538db72eeb2940a75b00ce64","signature":"6e0ad9cfffb899a2afe6f592d362aa4769fc078d87ffd4e3fed790ddb2f5a23d"},{"version":"cdd349eacbdba5e99bb6a964730a88ae56d345e4e4b7ec431f0fba2a388c3fa7","signature":"726f054d27a53c3efbd91d9107e7de9ad7a3656f2c5a0fa8ea1f231b0b4639ef"},{"version":"6f28fa615d59b0ed4a06d8b0210d35af05403442b9ae2acdafc3394222805a53","signature":"2bfa1139c2eb88b5f23181bc6324ccd747acb70bf1d6370f8429813be3689de9"},{"version":"acf8f72e32114e5c11e8b32e6dbe6a09363b61b4e52f4cf2ae705aa79bd42705","signature":"e5a6286dad5913ab2714b6804286b074c9cde94943c4ea01e4db94b920aa2880"},{"version":"4157a53fd2c433399cd9fe6db68d1da00f345c253aeb478b49a750ffbf9f35bf","signature":"62176cf724ba9b24e250b40ddfefd428d8bcb9a21f41faed8d33f3c275ce0008"},{"version":"0c996be745af11ccf07b28eb3e007aa4277d01b16f53259cb355daafab167abf","impliedFormat":99},{"version":"27c1b57e01b13f914e9d3507202036d676222057d6fa1032332e2954296b9d45","impliedFormat":99},{"version":"7348c35ce10f8323a515ea6a6c237c0dc7c3fd5e491c4dacec2a7b93f0dfcd26","impliedFormat":1},{"version":"258e67b2638408b67fbf5fe6c953b8f2dd2a69f9171d31c9a976cd2329716e4c","impliedFormat":1},{"version":"a3d80d033a651259b2bbac8d0a03bc2e583c00e310a3829608ae781e4e689ca0","signature":"6b6cecb2fafe1e5163bffa9be0229c1f6821f6cec28022f8e6e50d163277a14b"},{"version":"8662560538394251a3975285b8609b5505d442a92ce710f866c2f48e17d186b4","signature":"084955dd9a619e88baedc4583e0bf2f5982c7889ea6b6c0e34ffd08d76aaecc8"},{"version":"1cdb7130ae272ba5c573f2f96d00344602bdbc6acefd5a198658e40ad793f5ff","signature":"dcdbb04792a2ec09fb7960f12e877b8696c489ffe664fc190ee113623370cab8"},{"version":"fe93c474ab38ac02e30e3af073412b4f92b740152cf3a751fdaee8cbea982341","impliedFormat":1},{"version":"476e83e2c9e398265eed2c38773ae9081932b08ea5597b579a7d2e0c690ead56","impliedFormat":1},{"version":"1e00b8bf9e3766c958218cd6144ffe08418286f89ff44ba5a2cc830c03dd22c7","impliedFormat":1},{"version":"ae00023c4fb6d8310666f6f047f455331ded1cd758182decd54d7f3f2bdc7e73","impliedFormat":1},{"version":"1e380bb9f7438543101f54ecd1b5c0b8216eea8d5650e98ec95e4c9aa116cdd5","impliedFormat":1},{"version":"d0b73f1df56fbd242fd78d55b29e1de340548048f19ac104fe2b201dc49529ff","impliedFormat":1},{"version":"287fa50a234cad0b96ebba3713fe57a7115f7b657dc44638fbce57c45ac71397","impliedFormat":1},{"version":"c42852405dff422a8b20dd3a9ada0130237ee9398a783151aa0f73474c246aeb","impliedFormat":1},{"version":"d3260c8d6fb8ab6b92c412c3c0b793dc524dbcc6737300cd4cf22198122479a4","impliedFormat":1},{"version":"f7ebfaa84846f84bd01665f4dd3773ff2b1c38c7992fd1042cd9132bf0afc82d","impliedFormat":1},{"version":"b03829b7141ddbc20c9da5de4f8021ef99b57b169e753d28ba5582d02bc9d5da","impliedFormat":1},{"version":"d1c49ba10ba80d18dc288f021c86c496d5581112ef6e107e9e9c20f746ee7b0a","impliedFormat":1},{"version":"f3c5ea78b54672f9440be1a2ae3f6aeb0184f6a4f641c3cca51949e9cd00a258","impliedFormat":1},{"version":"9ad68f979b78ae71d8cd991b87b5317b5959867dfe5970de811ec40a09d6e1f4","impliedFormat":1},{"version":"d91e9e625a2903192e9a63361b89330f0d95c340d9bb4602b89f485e9f93cdd6","impliedFormat":1},{"version":"176a47d228081ad51c1d62769b77b064abbeb6827115033cce1cdeb340a8d46c","impliedFormat":1},{"version":"b5eaf1cc561810ebfb369039a6e77a4d0f74bf3162d65421a52fc5b9b5158c2c","impliedFormat":1},{"version":"7d12ec184af986cc2a0fdc97f6c7f5a547ecdd8434856a323ea7ff064e15f858","impliedFormat":1},{"version":"8535298578313ba0f71a41619e193767baec9ccf6d8fad90bc144bcba444307a","impliedFormat":1},{"version":"50bfcce750d2a77d46e96e1d6c80f2a6309eb86f6ffee53ed07864b68af3d824","impliedFormat":1},{"version":"79b41324d28fb94f7304a0151990ad712346ceb1907fe1ce5e892145eae8f8eb","impliedFormat":1},{"version":"3239a3f8c29d2b0db0a4200b7e6513e95d16a183d4d823e54cb5c98f4c53e183","impliedFormat":1},{"version":"126633bdc6817bceb02df2973c1e4ee32b2084115d92c5a03e3b37791ca47126","signature":"9d07febeda5c46d0f000d47e92d98af2c877ee4b3006ad98b8d476103bb6b09f"},"d46d431e4b957d3e96ca1436c82de881945a23a860eb3db7558e0410122ed6b2",{"version":"9d7a386ef9d4e931625b194cc192ab2282c66d630b022b7f54fd73fadc056ea7","signature":"78785628635751d04e31bc8d06900c34be54e724100f4e2cf158af9fa110ea8d"},{"version":"329ab8d42829159ad84178d4b6c66117192628e28be80d7da010202ea66e0874","signature":"07627fe71cb70f4617e8471c7919fda7e13b5187daa70c21c73b60ca0f55d9b6"},{"version":"67a629f4bdb06d7ff9b788eacaf213fcb8cec66f0ab49a185919272eaf1d2999","signature":"dcf05a557d3591a75d84be523c2710d0511f38ea6f31c659153f3908c8aeaf29"},{"version":"42bb666c2ff708243bde790212d396f883aaf5951c421fc8ccc8ba04c2a7284f","signature":"217a48e44b57072db0592f7f4151676d95f921ccd0b19b43b29c90c4b1aa1dad"},"d5d98a4c583ec54c08710d9fb2cb78b13cf37ad73654de63892aaf703fbdda6f",{"version":"58b08aed1d93830e4839d18d2353a1e53acee22224f4d9cf78d4a04dbbd43676","signature":"e40e07dd2e95140343a34749a2e9bc385b0b4d613f63d70edf381d3128a3de11"},{"version":"0487f879c4e9d756b39de91655d534b04b14219622991d8b29c2ecfea0dac23d","signature":"2a9b6bbf44f0241ce153f5bbd4bc79390bb44f7f9fade2bbf7ea99eb7b8be23c"},"de725cfc1ae6654610a6435be06f99f56256a5ceaea0d975f183a664d5d27ef8",{"version":"07b24d3372c3e568f939bebba22f321bd99b8791e1a27167ddbfa3f7c1d8cec9","signature":"f813fc2d36dd21ee050013f01be25d6226a3fb08d7b505068b106835ab3b8b0d"},{"version":"0b7e8e97a1ccddc76628442b3abcb4d3871c82a75c4beefa0817a6a45f9e1b7f","signature":"519f2a55e630c58927ac6e86a9ed25cdbc3645b37875f84b08c6d88a0737880b"},"42fd787b1ce34f064429d88f3c1d097f544828567e0fb6b2feec65adce7da555",{"version":"c286e5ba6782f449d7a9c20cc2cb6d29e69587a8386527c534a9ebd19ae2019f","signature":"cf5546de6b03068d7572be4acc7f1f70d682f01d4eaee9325ffe10a65abe0130"},{"version":"865531ded473f776fe61562857baf43f0a5135300244f6c60f3a8443b4045ed7","signature":"c4c159fad47a87f6ff6247f863e504690b499e328848a407accb817dab9cf85f"},"af963b857f8fe42955adca2df05a1d5ec1a45d0050aa3c1a191060b4de9f3c3d",{"version":"713384f186240f37c9db30ca9f1bd0e57c51b37242f16ca3343cdd57b32cb69d","signature":"c2d05c6e88e3062dd5c4ac0d009b7133c1834733fcbe938304d6beadef346a42"},"557b12fea4bb7a097ab366fefb8ea8702b1d381abcb352cb0ff8b7232712a632",{"version":"8236726367c5526c6c1d709c74601628dddd92c51f52670ca4188e8ce24a5c50","signature":"d0d5449dc78a144ece9568f28ead7df6fbc5d158a4a5c262541a65f7270d8a21"},{"version":"e1197c161198f0668ccd10b816739d2290b9a309bbc8ee3669fa1f11c864fa29","signature":"5d632aa6f70e68f13a0cc9e7fe0f9d2a1aeda0beece411ca6645bf3e99500d51"},{"version":"0b22cac8f8316be536aa1ebc7c26b89675712e82d28efe708c0bf4e378dd78d6","signature":"50c09e0fd940256acc6d2500ad014c7692f96519a75e78e78bebd0ba39c2ad21"},{"version":"48a13d7b1bae9d0f4986f726f7770455bb41f65abe1443bf779118b9fe2a95b0","signature":"68dfc22d24a462e2344abc4d521b2b7191d8e1a719f72b5d92fe3eee76d18d20"},{"version":"ba847ef5fad418657e80d8c7fbe52f2686d8031c892fef012afff58995b4c491","signature":"6b961b79d53036ccc89f7fd54a21118f4a35ca748a27137a4909a809afb6f73b"},{"version":"a9be2f55e6aa568db6be9e8c8abd5291a324452cf655807d68ec070ff05042c2","signature":"1e7b5e88710a715154f36b27a9dada7830a3a73805d240e2cbbe3eeed0470792"},{"version":"155ead741865de4ee76471ebf29d8cc446be7ce4bdcb95f25fc071f6c48d5548","signature":"34b741d193f967d16d6de7225768c9b96837278e25768ae94ec8cc753c6239b5"},{"version":"88db397b645907bb691fb21e2db851fcf0af4147ef722367d24793425e80eda3","signature":"f5b31ea5c95342d542a85fa18b4535fd1d537dd5f51183bf9f4eb1de84a2ed7e"},{"version":"9234b90265bbecc51bfbe26285b504f03ce6e740992de0f2406911eb86c58cc4","signature":"8bea0d2144973adcd289740efffebda8d9e88ed968ed93b83db32049659cea9c"},"ef5f37dbddcf3b7ffaf0f587e593ba4d58d049270d6a305d4cd7ba6992a2f0b6",{"version":"cf41b71fc9ebb89ca6ade651890dd88cd7b58e0a883757a0a267ace1d494b60a","signature":"0ae1ff66496844371dad779d9c1252d5408f1c501484e0a61b77d58836cdfb43"},{"version":"2e92115ff5ff08aa0e667976ee5b0095decca799bb0aaad22dfa07f183fd3627","signature":"fadd7c397bf51fb5b4104cf67350eddc7fd3c6d87b4c056e0d0e2cef9edd8c2e"},{"version":"bd1682f5e4a07b3b31adc3eddb7815273680333312164d84cc24e60a24b8f897","signature":"119ba863570411256c384ec1fc0da843b436aa4fed0a500022d4f3dcf83c9db6"},{"version":"fb94cfa8d0679a6462d90f1e24afeab3d35d4a2b6b99ab8726401779fa9cdbaa","signature":"0a8ff7723198f7e297d1828b8610fbd0dc68f9562a76bbb82f9103b5c9d0fb4d"},{"version":"76ba49f9259bd1a1e6c995a0c6fc602b731604db4faf30eb04b6932f93cb8dda","signature":"ada89866bcbfcf70286a847ba4b359ad945a3764b1f48c58be169e86ca5c233e"},{"version":"74b0bdf820584ceeb68c8433b2bc864e61649b5bb32e8b24f67ae3e0cbc8aae7","signature":"1b3ce711b687ce4695cb8b8ce51689faa8b5358f4eda9d515d1f2fefbf5fe925"},{"version":"b7cf998df700d1c70c806ddf516718eb8fef3d59b928a0f2e71cf43be5b0b122","signature":"3eb6297db29f7a01c794d6cde913940a6e90a57e6910dfa97116c58a4eb62433"},{"version":"fcc0a50c5e3f90f359a8f92dedda852ecd49e601dbd142500a4e3776d7eab802","signature":"907aa9578e2661838e9d9f288d5e9871d6f462d3703d51adc4688a88dfa41bdc"},{"version":"3cb43cf2c5d5e62b4f4714aa07df5583088c26ea09bf18cece0ab20b7a9c6f99","signature":"620ad41781c5847e7ec69fe9c05b3905ead928ccfc8b976ebff2317a91c46b93"},{"version":"5b956919767ad0b1ee6440c1f40e9420168036256a66af2913ff4bfa40956475","signature":"7792154e93de1073eb1f32502c390d4b2e3453bd74cd45536e6c4e67c3446c60"},{"version":"3259de07d1721426e46b35565f8302df67890026c732537f7496594540061671","signature":"e94a0dc2d3aaf38d79575ef2ff61e8028dc30f2f50658190db79fadff5d2c62d"},{"version":"464017bb94589e81dfd49ac9597dceda39229895dbe7b47e57d802627c6f4fc0","signature":"231f159118b312c80f90d688bd93f0512c411ba9d2f18fc2f535aaec33b422dd"},{"version":"ea3b420d037086a0399b5f4c44e67012aa2da29145fb2828d5a67cf953e1c350","signature":"75c3bec8d605e8c23df450f9cb9d3adba5ef84ddaca0ef026b6bee6bf187d274"},{"version":"4149a842f7720d96336d691e44db068a2b1ef5a3ed77273da65fddb9c9dc54db","signature":"10707b8b90dccb1f296257a17d0ba61e1f4fd12ab253a5017b3c9e18c979fff3"},{"version":"c4cd03df5ad4b17c219c7dc083288ca02f9c2a0c9cd204fad7bd6ca340cfc0d4","signature":"450f92c18dacabb6def7bc222386b717e05c098401fa83efff0bfab5fb585d78"},{"version":"1011d862f18a04edcd1e070831c635391d93d4b43a20b70a867dd232baa69654","signature":"b9e72785cf996c11e31be2b6bb741097518b35459e67dfa4140bfef652e937c9"},{"version":"0b6bbf8f2472fd6165bb64ea496c276596f38e328c813739af57d076d92ad5f3","signature":"89c91899c3ce20d28d6d9adeb42e5f4981a61a02e2fd7762b67fe147c1ca56e5"},{"version":"856fe260bdc12d807f9cb9496135ed091cb6c17d481f2e8c454788a8be9b023f","signature":"0dd204bc08786865dd87c1b86fd4b9238775985c9e619807566bb9429e73171a"},{"version":"039032fb6ea12431603653567beb699625dfaa6e1c6b2823e2ab0c51512c178f","signature":"340fd007891fcc91aa77ae3c73eaf80b73b8b53b6a037541247af135d035b43b"},"c8c0b67db68d46041254706257cffc21e54982c8ede96ad2c5cb522635d752ce",{"version":"bdd1d8e9f98a0b8c787ff5a5ad1f80d22b3168f01923a101e668b45a30046461","signature":"9802128fc1d284c5e7426ea2e26badc156fe786e447d8211f30f3a3565112323"},{"version":"303be16f44b34c6b76e6b2d3baecafb5b09da6a6baceb99586ed0e0a416ce01e","signature":"1bebf7a5ff7c83409b711adc21cb6c484ca301cab2a3b5bba4ac5d9c3ca62fa8"},{"version":"f52582be414a74dfd8e7cbcba0eabf0a2a6419f7fecb3fe4096df11691056e6d","signature":"dbf9c26ec2912cb1081cea92460b93718a338da4f97f217a23949a5a9e24436c"},"cc9f3b500e0d30155e2ab3b573f633251ee9c4bc6e5c750d78715891481a15bb","6ce3c85f5d239f14e3500c8404d4b791ee5c0641453a1437609a64bc4debadb9",{"version":"4f32f195a07eb1f759d7a6e76d09b72a914fdd2931259531de5b557358300581","signature":"a74b1564f3086fa5a07b6f8676551a52937ebdea25878e21334247a454beca2b"},"5c13d5bd5fdd1c32cc6fc164540460c74e8678697a2a77925814a168b8e29790",{"version":"0b22fc196dafde3c55ad03d5c9cd90dfab0d0d8706f07892f9a2d2c9de8edf45","signature":"efe9f692e3950e8248d64046f8ebbf2e13e4f95869157c23b404fabe6ecf6305"},"d27fb55a4f127d78c1751c5ee62dadea5f09c788fc0923ce5bc2f380df1aa661","2523a19cd741f74b9bbf9303478f1bed1668bdbeecd8d3cf2671c4e7fe3329cb","92dd9b72c75f8654c6ef9ba91f1c9df50985bb1d6e1903bc1fb5596805f91fee","d672288c6a3541e3503efcf0d217a63a6f5559c9ce763654dad08f92762d5f92",{"version":"1e782b3c876c9e73bc703908d08cba7baa8e8e9b66adc2ec0fe89ceca1afb29f","signature":"2ca14924b821ebf515b4b75bf5e8729f56e558d0d6f7b6d2547ebd486720373a"},"a42173a51a60ce435800656ff8d25a123179682d5fc7246f6dd60a78568d62d8",{"version":"76835ee6817825e4475155bd14ed5df11e4109ead3f8e4634b750635241877f1","signature":"21ef79d3310744ff36549736d1f77492d1b1c99e6ab01fdc8a6c25b44fcf5d15"},"1d343369670133f7acdd3d61dfc9c391ee12fbdc6538c9f133262ab65605d1ff","1896aca0161402c9221f6f591d99572f47d020427d9268364711d481c174b7ff","9ef01bbd127fa96aebd049905832ce16e7b629c7e329ffb8607098fa2b033b7e",{"version":"884ae5e03e00513b74ee67df037050f8bbc9dab0cd8ebc722226a5e2a7c584a9","signature":"467af4cbaee3e98229da343c0227c8e7f692325f40220bf496a365d24530d92b"},{"version":"3a53b3612f3958d2c122bf5a344db69d703fa3c9044afb5dadd73bb652654fcd","signature":"3a5be081ec6e24ceeee6cdde5bd2a7a7c270e61fa1bee5fabf08663eb1454a50"},{"version":"743672a8c3549a555a4f30734bdaacb19c0979d156a8f3a4f5ff2ba9fe4dc54e","signature":"07c5942a5d558761b271f7b4b7530037617febe53bcbaea806cd9241f44961f4"},"d81a74e2c1b3df89a4ddfb45693f57fc6de6e07ff85fa85a2277a1e508218647",{"version":"4d202757d4a005e0b1f9ddb30f326c2cfe923ce9b364e36c5f56c43ff31ecad5","signature":"ae201b6a7ecf8e415450eee9cd2ec5ac373da31346c681c470500cfd1805c66c"},"c531ec4187cc04b720add8fa2dd014baa8ef3bae33bfc08b7d1dac58fc82d102","c410f031999ad0433b6912734446ab3c3dbed81e0a4f6fb55c6cd01fceae0bf6","243b13ed79878c0b9fac82a5ef53785a329e9f12f06666a6d8ddfcf704371fa7","81d67946387af1bfd26e24507f8d4dc2ade2e48d3495d195cdbdce64b8b188a9","68b2ac219fe8892112392206277667eec9a57eb62c2db43d3b45027c7016f159",{"version":"0751926a7e43de52ba0c74ae0a781d41555403cc868e13f6299e52c266a13ee2","signature":"66c91064979de77ec23e2146699fc2b952c3cf0367b87934021b50e046d41d40"},"481cb7ee7b2446414259be0b860f31c15b1874727321c325db7b294b86070138",{"version":"b32202fe9e35218b0a8d87c3bb16fa5ed4a93eddc2426964fbde3585161aa193","signature":"5e3aa6b1a42f3e1d42597f9cdabefb89bc883865f32fd0d9fedf82f6e415f416"},"6e71659f6b65aec852b18387a5f1415fad8f3ae612dbf17addb2e071e0a0b977",{"version":"12fb608964ee2a47c78053e8903b9384f508a71d2114e37ea8e66d77e90aed55","signature":"e41d642f0381d3873bf5b3afc26ee442d816a503ee98aabe42a40ecb8eecccd1"},"f1408a2ced63baf7db0d8de74aa41033ef062aaadb8848f87327c1ddef2a03fc",{"version":"02e6a92168e028ca9dfa6da732995018486fce21b27d59bcc51bd94a130a5852","signature":"4731a05cdbc90902ec899db277e37e5f2884a1de5e095446e1845c875340d72f"},{"version":"0f28d903d9961f77bfbd514935988df10a5a22e3aab8ed799251613d0e7821f7","signature":"2df9a7124c5951282528b142dd8140de662642620731b5869a7ff466773198ac"},{"version":"5e27110ae79ea157247bd15b5a682842d99e60f00ba3897522415835a5edaf1f","signature":"55f7e060e53e001f4de2cddf8c5a64b05b748cb37d035230460d57236de16399"},{"version":"4a345550c2e307241462d7292c39184b2d26f6245780047a9a733db3d66d8f34","signature":"2929aaa51d5e996f437d356fa63a9296dab88dc05399dccd50d92933f9795af6"},{"version":"984a76adcf001fe919b15167b840e8c49cde3f107d4434df1bb7d080c2d6ba05","signature":"a8e5e38e1a942a0339d643daf52316b72fbb1e9066f47559bab5ea3a8c5a8ab0"},{"version":"ca1f0f3a223eea5f791fc08ca19e32816a25cca94b5673fcddc706d0a41028b5","signature":"978ff61486f5ff685f7e0f01690d789cda9419bf95deed0e914a6326ece957b2"},{"version":"ab960709b0b47eb08f67f5b6531e44206edc1daad5281dd7bfe5cac186a354d1","signature":"f4351130a24f2f42413ca77537f35d31969f14b2975d2519a3b1e86ee1be2f7b"},"779c03a7b0368eb9df46d8508a9011cf8f8ceef826f8f00d68d61019f2cf5e82",{"version":"f3b20a242a43ac4472b4c60530e7edaf3989fd16128dd5413a7138198606a0a1","signature":"943aaf838f611dab905818c4606637f9df5439c87c6774a1cadfdcecfc465c72"},{"version":"8a6a3fa00026fd4feec9da4bdd655ce5ab60816d09df1857ded0760a09aae603","signature":"ec67da3d1af27d7f67e7a4ed6c2926c7205e7ee23401a9e6d09f95d62122d5e3"},{"version":"7f242578e52e03b4eaf029a8f5e8f160c18793d06878fc9e1d15893647858b96","signature":"2c4e4a33361906d6b8590c1f05cf4fa314e6ab1435bf4a0bf75c1aff57fc4110"},{"version":"8473e4af6a1ccfc7c658eb6cbc344fe101a1a46e5423a343623853c682d646f0","signature":"feb3c99dc72d797dcf39fe41834050a6f6194e72bd4ae653f5c44b497efeaaae"},{"version":"094e476b1981b2d857811b663f5b7a08d964e943d5aa38ac01c92bb72b523a32","signature":"5944a73ca520c4e81bddf2f283240e0c6a12324fbbc0c298ecffc08189d49d7c"},{"version":"3252193df18ef5f246a798e3957d4597096b40ea176397bc6df1c51310d40ef1","signature":"068023508e92f65c171decccc194ef81e1648a83420e025bc62cffebfe4b10d7"},{"version":"547a5260e8817dfde91badbffce9d81fb13c1754695d5c642b343995e009da77","signature":"781d69b754fc71a3a730d9d74d32d3f49d71a38c5a827199e4b4106929cfcb61"},"a5ee9a56efdfd1bb00b835a6adb138d258885114b46c8cc64899d46c560cc724",{"version":"47f111e2a8c5cc3df84fcffad3d72fbcaa976010fc0f82b4e493df268c04cc6e","signature":"d52bea618274ec22c5a07d8788dbc5f1be575cf59f94b084c3a53f77a6e31fb0"},{"version":"bda9a940cafaf73cab942a13c874fa754e09172e51262114523d567491a39f13","signature":"2b6cc1a42215f75f277baaa50b8d0fb562409d983f1b55ea7dfea308f5f40e41"},{"version":"3a79f5de999e061fad6833b7a11929907f44940b36b2102f8a4d01c1a3d28e1c","signature":"6319e10a0b439743508cddd066722c11f71bfb6b3816566f79448065e5133247"},{"version":"f0c2d65fba4fabaee53ecbcd9a2c1d58f7e2ac2bdeb4baa218beb186dd80019b","signature":"46df3b90500aa646e8ef62e459f6bb881545c69786b13b9d821db667dbc0dc79"},"a18572f3d33b5ad5c17fcf48b1e39d5918de94d3083758ea4c624ee5ac8c1614","94bfc49ec8b9c34ee50b3658fbeb7fff5f501f54eefbe11d229e22f04beb8725",{"version":"0163bf08ecb350a94213025ee0849f017df5a6b509ebe35b6ec3c6fd8f255fb7","signature":"fab32c8c3d3bc803a26acb296e12c47948f8249f09cf38e0fe6f3859ba362a5d"},{"version":"7b0043353b79fa93948463a3b812c041d03efc4a43272b37d860c0b7a3c86492","signature":"8ad6f8d83135def4e923ca0ab054ef4f55fb00fa7fd1a2f4fea752b17800d0bc"},{"version":"cb4448a47a4b1da5d8bc2ded78bf3df6049133bf97977ea5b7efcd78428441c2","signature":"3a5b0869f407f8b570ad9e74ee6a6a54e45378a7e09798f2dd50c9b67219b819"},{"version":"85d0db377f3d1de6402540415a4776eea70ae5b426e2f9ddc9546cc17ad98c86","signature":"e146540eccae50527bc9657d0b95cccdde222d9be2f4a321b55774a5cebaed68"},{"version":"4d4acf3cf1bab59440589f329514a73378b4592baa00f23ab2c14db2f7099d49","signature":"5649a6b58425403e6a91b5d3c792fa759c912adf033ee2dd979fe579ab83d002"},{"version":"d19ce91ad3460675a7da8fea4f9439c29749fcf0bb7689a086c9f4498ab6f170","signature":"960b113200860addfb6f9d69e34328a23fa5f393130b036e6cafabe9e1d09fb2"},{"version":"4584c9c08f3fa88aaca063fffbcde7974238840049e3106252772e9d46821818","signature":"ec2644121212afbf9cb045ef19a1d2697644c4967616b3374d1ae7888e22c9e9"},{"version":"5a58b484744ce9f58527278a0cee73131efc7261f25549ef6dda74fff834c67b","signature":"14092cccc419f225119fd920f565d2ba6b033fd006e3bd596b725053d5eb5b95"},{"version":"27d9ac3d95aea0572c09fd67554c982ed276531c30a1f8a6865b7b8ef5ea754f","signature":"abeb2c9cc4a1bb27c220535346424b1f8f3974cca6480df44cd9ea318de951fd"},{"version":"9470d2129e127207132c2f6e9c226a0794e953ef6dfbef7b42405e1405962545","signature":"830c7cbe0d60157a6fd995defda0675e90f4c3570221bb63d9d6e3a56d45b0ff"},{"version":"460da0c0a8f42d87b9275ebd21866532ae74db98e940b48dc5f05edab9a6f6cd","signature":"795012a5b28b1ff49150dd4d3fa6490e3372d675f0a8ac640150849cc4c441f8"},{"version":"2d8f92afaedf60a03e610e8a6e8f35c523d121286850b79ae6800698d56c4c9e","signature":"336fde69bccfaadb36974cc268028705ca2c9b75e36fcb070c6dae832480e4fd"},{"version":"70811d46037dd34c56560c1db7a64d75a9f47ac51d0ccc96ca9d74a3a5b1f226","signature":"7c181c8b6f319745f24094aa11f69cf3b0bfe22f80267df6ed4a8b5ed04c1a43"},{"version":"778078e02e6ad4190384108ec7762a03230dcab82cf3043182d3d4e8d1178a24","signature":"934f32a7071a572c867a2f946405c62aa8448f12fa452a45d1f0a4e9c27305e2"},{"version":"905fe999da37afdf2efe21ed5cdc643fff973a78a7f917745bc51b850e2ca3c9","signature":"985381138d7658ad2e05c482a722821180f6d366858ec19c03b5d42c901da917"},{"version":"b854e5ffb57531ef3726e25f01a9a8568db8f641c02bd4286b8366eec078fb64","signature":"8418309205cd7a30d2e8ea73ae671a37f919048475ab9d708cdcb554a4813a31"},{"version":"e692572fe821915447724bbabd3776957702616f86abe22da0d6ef271a506794","signature":"fc4a1909516c00b0a88e516f5564dba70d7c13db1fc6a650c424b4b81e67eac7"},{"version":"d30e67059f5c545c5f8f0cc328a36d2e03b8c4a091b4301bc1d6afb2b1491a3a","impliedFormat":1},{"version":"a356d9a0ba90d10ec6c0fa33386c0b0e2843fd6f0a49513c44f7809926ac25ff","impliedFormat":1},{"version":"f77db1be13db8dcf8c7a268c1f235c1ba1e4707e829175cdc237421b3c346f9d","impliedFormat":99},{"version":"05cb95655ecadfd1230547b84367d1c4d40a4bb6309545b8dc4d1638a3de1a50","impliedFormat":99},{"version":"e980a9cf8404a649ff3a2f0628d76e4469613c02b98bd3b922756d7d962476c9","impliedFormat":99},{"version":"f8adbcb59256526bc69d94fb5c826e812ebd1321b30ab35baa9997d74d45dd73","impliedFormat":99},{"version":"050a4570de5ad6e47cc9ac9fd9db7a26e57dbe1daadadbc19b20567941f8bf1a","impliedFormat":99},{"version":"5ed040255a4d5181f8ecb4ba90b8b38e0a6f1becf0ed860ca75b6e52c46db0bc","impliedFormat":99},{"version":"e22a49cd604cab3b62b1968a363d7b182edcb23d46793ed12cf5cfc6b1597f39","impliedFormat":99},{"version":"ff1b4730f5d49d37b73ee2db3443145daa0bfc7ff9c865134d871b08955e389b","impliedFormat":99},{"version":"8e64b72fa289b7f133b8cdb7d837f73e30ca7eb76ad88e1020d97c405c94fd7e","impliedFormat":99},{"version":"1f907507e41cc3df66b4521b80134bb8f7afada8d31c10f7100c93c90ab0f84e","impliedFormat":99},{"version":"6bb14070b70b4c9a897a4f5088af984e6e316b420d00d82fb962bad577896723","impliedFormat":99},{"version":"46e17953f7ffbf43d4328fcb5983e0ade2932fb56e84181e6929fcdcfa7c7aa6","impliedFormat":99},{"version":"113aef5576cd65f310927b17ae5f6ac8745c542a660bace5f019034d536fbd04","impliedFormat":99},{"version":"ddf0fdbb010c94978c1151441171f0aac236a23b6786e9f6332f745527d905e9","impliedFormat":99},{"version":"a2c1678ec68c42795e2ac068a7d026b61680357d2a881c9df211dd0f83d077fd","impliedFormat":99},{"version":"2fe207d2e8662abb709772fff1f3ec3116a4787b5caa4e862daa5dab2753edd7","impliedFormat":99},{"version":"a7af5f01007f450dc8cf2cdbbb11f4d4bf8bf3faa869d21267db5de74ebf665a","impliedFormat":99},{"version":"709cb4986cbe2b58ac3bbbad45dbfa24cda1b62c794c73b96e9ff1236dd0d5d1","impliedFormat":99},{"version":"afdc9b1fd1937d9b649bca2b377d1144cc9c48158403c17cfd21b6e1e8b25099","impliedFormat":99},{"version":"1d47324801b498d62f31ea179f58e1f3eaa1e607914504a7c92fb5465affb851","impliedFormat":99},{"version":"95fdf978302838125ac79d9d5e9485d8fa1ddd909664bf5cc3b45ec31f794fda","impliedFormat":99},{"version":"d92bf7d6d30c85e53b961236ceeb099e73a1a874849d038a348b51383087872f","impliedFormat":99},{"version":"e56e4a57ca5aa762d67fd3d16471c47592469944315fa5e92b3b09c83eabae91","impliedFormat":99},{"version":"f3d31927b7a3d0f2f119a05a102af2bdd1fc4f759fe43d508a64a80b3b341f6b","impliedFormat":99},{"version":"678700fba88589e28648a923e4b98ab60f3f7df4742412419e29f95966da4475","impliedFormat":99},{"version":"5a71b307074ef3d2794c4104248b7a3cad5f486df204da65862a7d24f698fc95","impliedFormat":99},{"version":"9a4496ad6d48bc801a122c11e94ee1e3f0710bda38b125573f67f5cb0add1733","impliedFormat":99},{"version":"afa5e16f2ad07d847701e3bde9e7ab36f87e0e3a5c0cb7998644791a1fa3c5b1","impliedFormat":99},{"version":"98cd9124b5d8438db4b4dbd247b2c68ac22b6366a43e6dc4945ae32972f157fc","impliedFormat":99},{"version":"dc21879e45f3a023b5fe459c3da5f2f3cf995f21a1ac533049d8950ce394c045","impliedFormat":99},{"version":"622d6ce66ac838d5d7e968daf4ae760cf49797e3fbfaa2b21d01e0fb5d625bc9","impliedFormat":99},{"version":"ecfa30418b2200ba6496b5f59b4c09a95cce9ea37c1daaf5a5db9bb306ee038f","impliedFormat":99},{"version":"3b56e30b1cbe1bfa7710e88e5e0b8fa6eddc7c2e67615f73bdf8637af68403e6","impliedFormat":99},{"version":"92a8de4f8f6595bf1eb24a19aebff7371c66ae8751f2e045edd9e25ca435e4a2","impliedFormat":99},{"version":"01810afb0ed31afdea0846cee91e85a474727d0966e5bb57c2a4a732854deab1","impliedFormat":99},{"version":"c874e98cd875727ea62fdcd978ac9e067ce07cf7493aa4b8b193fdc3b7318eea","impliedFormat":99},{"version":"455e843c1f8e0df452f101c9ec0b63ab8e749f296c947249f8bbc29bff58c83c","impliedFormat":99},{"version":"eadc4c556b494cc52676e084eadf0b60fb2cc6e2408d1411eeae5cb74068ca86","impliedFormat":99},{"version":"3b8689266e8fb628ca2068ff610ed0b842ff4e407c3a914358ef1895dabfcfcd","impliedFormat":99},{"version":"fc741907f6d8158b2c4722932d745b11dd41f9355a5b325c8cd3cdfbd966d76d","impliedFormat":99},{"version":"85ef9d9ed8eaca020810c33588676bb777d626dc6e7ab3340c716db2b94affc5","signature":"b7bdd0dd41019192624068d8ced8bee71c172ee5400be340fbc1981faaf9be11"},{"version":"759fb79de51cfc0dccb5ec8b3817290f99807016d13a8daf0caa3461ea8619db","signature":"0a6e8b8d8fb5c44978ebe6ee3b126173413eceaa26685cf6a655d4a3e045b1f4"},{"version":"e1863eee31f1e7fabe4d357b6ec1d4d27000473c1390023b71c3ec010de0cc17","signature":"02fddb3f9d305bfae364e1618d29f2b10ea82e7a3577f1a4f43bd8bd6a35fe26"},"dedd91828d887266e02f92fc6600685e2089300e1b2b251a9c9b4820c893307d",{"version":"d96e46cbb66f0d9ea20678665c46278c814b820a3ebd2b56b98a4ad4a7a13a4e","signature":"20e95c1a7cb1d725f42bfa7bbc6373bf01a51ba2a97abff843876425de6e81ff"},{"version":"16b19c70de269ae4b2bc315f6f8fb75232c0db323edf221da9fe89e1ff814c0d","signature":"2a2e7613ca538e6b4d761de332e77ceaa0892c1d1f957c9005c48f9a3339cf2d"},{"version":"ab909c7761bdc46b2aafaa28c96f88a4b55e288049697eab7c3641d69e61965f","signature":"ede9816729361897e2dd6720a4fd65e95a9b38f68b4b37e0b8d4e62aa1d179e6"},{"version":"d57fa1874e902fcd4b2425132c9d354133baf44b2d5a245db4f1409bc7c1a221","signature":"29ccdcae487d54fc1aab33bda0c11a2fe817fcb84e14abe6cba8286423ae9187"},{"version":"5a55460b8491bf0203854724b1cffe3d6d91de7e936b877424fcf42bb275643a","signature":"ad2dba18b42a48557e4da3ae490254ed306d6777266607c694f0569e6b901a88"},{"version":"679b613edb82faa67faf84e1977b4e5bb69b4021fa72d1564abfccb1a88ee453","signature":"3383d7720a22c25cdd627089c4486b5f55d6de17c8ad98d5e44e2922a205384a"},{"version":"d67107c86386306ae50d3d22f46f785cedab6ef14951ed0df08c9fd3eaabc175","signature":"abb42d09423a617eeb8a0e378b2747bf358d313e12d1d02ade80562685141399"},{"version":"a1947c9d6d132ee81f6e3d8c20a4ab6f968190d6a9404ce8137d47a57db23077","signature":"1f8739671eb4d4b7da809092317a5de94be2663bab6c00888cf5103d22fb6c48"},{"version":"a759579c15c6337995eec7beb36f2a716ee1a3a2554e70c27a2d0bc2bf230de7","signature":"eb2674849a6293cfd4d7b19d9d1d980e69af305319bf986e14e9fe84b9f3d0f5"},{"version":"98875dac45f10f45a4cfc4c5e32908cd4f926caeb9f77ab59a81cbca9ec1d39b","signature":"c50e79b6130f0690f2d77b3c1bdf1f71cefd48d43906ed06f1d3c409bf243abf"},{"version":"067222df0624bbe9a0e331b7018f2285f70de2a1c4623902f6d88d118338a443","signature":"a5d604c9bfd5b2f06cebaf49a136fccddae3eb781e6874ca407d2d10a367fcae"},{"version":"ae19f9f22c699e7c8da49497fbe230a299241eb159749418ec14c4ee7bbf1542","signature":"59ec1933725eb5cd08f95f737b735d2e679a0258e034ccdb02081e98441c5d1f"},{"version":"5c87657869976b5baf49689f8fd7c63057d3bd7cbd31f1aaf234e1a4d81c1a02","signature":"8c0f14735dd0136a27bd3689f2419cd48a63a7986553a14aced5f277452f307e"},{"version":"f4f5ecd259e37ca45d2c46cc77f145353da477e104bb354f341012ebce7c726f","signature":"36865f631fc6b253909172dfb3c412d782efb3cc11b1458f2da07780e7a480ad"},{"version":"73381941b607a32f8e4174c7fd7266271ce8e5031e2918e0422f418636e85159","signature":"99461177c87ee263d68711779b4f829e7938d620d68b396d6f9aef0c4245aaab"},{"version":"8e5d0313cca65ae8b6ba97100d99222d84c145cbcfbd21a163b4ac86889600f4","signature":"892526caba9bbcf54452f10a4a32952098a07ed7319308d619fecd3b34cc150a"},{"version":"4523b20726540a0da117b1eb365e987b6acd38959cd728f763f16c53160b0bc4","signature":"889bbd21a6948355d7436dbede293fe598639ad99c94b493d28cc4acdd129e6e"},{"version":"780af4457e897d4aead4ede3c4b353b1790ec7c3c10e5f0532b615e4fe19a9aa","signature":"0e29076b918e64964b59d37f3baeb4cc7142ed688fa9ed063eb0d29cbe7cc11c"},{"version":"a409cb812a758508ca4f687af6e1403538e325566bba01fa3d2ed4a564b771ad","impliedFormat":1},{"version":"1a3abd72da7f1cfd9fac33c8be5a7e1775e132ac0b63bc357663b6934d8a9554","signature":"00f64b8d5647f694767e32a6f73d537490af26d7bdc77a2c770e229f616588b2"},{"version":"fc01f6c90430c59fbe7044bcf9b903ec4592a46df566afba57be59b1472dff4d","signature":"ee99bcabca9700a81de9d736094a7bb71e34de4fa8500d86a0d2b35016b874ab"},{"version":"e7f8ffa507f115d0db092a69b16f0a7a9c0b1af3ce2216c3962375a749580453","signature":"95f0658fe83b2932e9aae526fa289f1f83df8af277fa6f5ed884030c58145b46"},"0a519dd11866738dff15344e6f61b570638090d14d4c3134f66d49765afb47c1",{"version":"d58affe96551545c160b5c1e97995b0a1389b0d83aeebdf121662d760be0b3a4","signature":"d9b01b7789f71152d477e3a1d78faba5ce1b9b5c7720ab86884d2629ed9c45ca"},{"version":"3cb0a73c4dcc0f14578aadb7cd64c9e6a525f642a3133e79140cc474a2e851e6","signature":"8de7423458e0d94d4d4bf94122119a2c40f183b696a20ef1603377c0a230d607"},{"version":"66f847958c8f4865fc4f7e17d645d1f9fbdfb8809adfe0b308d85ea0f436e8f7","signature":"2c31be273ceb93da6aa29fc5cd535c8dbe7f4d543dc73a997e18b8a1fc39929b"},{"version":"00e15d6ed67a8300b54e3423674e2c7ef126f83e959e6fab0ef72c2351c212ae","signature":"d48438e766db842d1f3e86e4bacdd3c14f92c25f87e5995142f0775f2d973d5b"},{"version":"25adb93f80886428e7cfc6dfe8409a7b0c28345ab2934424c5866a4a8c3fd4f2","signature":"ce5fc38c411fa1c43e3e743fad58f72d2c7886a10b17f18a419d34f0d1603d98"},"10a415d6879dc8bfda654ae5e4ddd7711c3eb4a4bd62f7dc28a093e1db3da50a",{"version":"b139a5359692b30e48193b1f0630cea0bc57434f6ef5299f5d9cd863b16e45f6","signature":"a0b2af97c922e06bd6037ba172e0880152b202c4ad63a90ca765c6687d6cffe7"},{"version":"4f4174ff122ad29be67f1a9ecc15a6a097abb75717f10f2eb7e2398d938f687e","signature":"c62c4f0e53738068501d4e44066fd5e51daa1ea5dc153aa5fdbb8faeefe7b341"},{"version":"39880b5db846d72e6ba4709a29f492b8c3dff6c013696a0cd19d62509ff7f3f6","signature":"0bcb3e12624b425b565508312bfe0260166d38e800a868429d36a8caac92ad8c"},"f4a624d8299473c3b5948f7baa55bc3e69c3c403dbbe2dbb61f502dbc75ac36a",{"version":"5b7582eacf206ffdb3186a8dbb92747662c83f6ba0141a683c21c92ae3f4cfb1","signature":"2ddb45d94d98284b96cac4ad6db85ef407d9b3457b5c0cf0af0d3c824e4798b7"},{"version":"d1cf676920260cf8c2a4f4bdaa1c5d82e88b83678b08a376431d33ab57a9851a","signature":"8581b29ac4393d65e14e6ba70c0e99195d0a6f65b9371b19432dfaccfd7e58ef"},"096b3b6e450b64b7e8675596d83897ec56e2622a42ecfd604730889ac300c548","7048be757297468dd2ea827383c7f78d32cec493dba5cea8c292110d873fcb11",{"version":"754668546097cc16c9b81d14fbb72ae38963abce9635b44d4733ea2e7dd30a5d","signature":"8ed514293595a647a7d0afca348d39766e199267bfe5afc0f30d7896c7d4748b"},{"version":"cdd6440ee9e17930aacc0ed528ca5be815508677dc20067ae7462cd5fff295a5","signature":"467af4cbaee3e98229da343c0227c8e7f692325f40220bf496a365d24530d92b"},{"version":"7e2cac0df63934401c5227d8e96cb3781bdb33c2c2c8aec4a9ac7f2347be715c","signature":"f2efe73facd77a16da52f90cb1cff57059fade454c5e1bf2f27912c4c81c263f"},"641c15b868fd5acbb1eec44d2759acb9a8c8c68f31595617af761bfbaf9e2398",{"version":"d788281fcfe7d405c9796acb20f250601ef55711cf5b316ad9546c18c7888b32","signature":"df225a1d7cb4b86a1dcd751c8ca2876e731ffdaaedf410d58b8e28109d2be78d"},{"version":"fb3012bb3f40669f1c66e9271bddf8e7f34863f0709fb14e5a7f6452113627a7","signature":"c8302d5e9c03df913953ea5d6c71894bba3c7da2300042fe4cae256afeef9f15"},"2d80215517ba7fa45b4e36416680db72bf369a69e175b891e9256272bb14a8f0",{"version":"978ae458625843cf01c8b5555f58e68d13917a75760aa16f4724506fec24fcb0","signature":"4e32311f21f4d967cc3d34b707cb99e0fc25724403cfaa582ba68b296110225b"},"4bbae4191bcc6c403b03c4aef97884c51e3377ff03c17bc726e44c39102e57a4",{"version":"71f81429370bc39d60a56c73864288e4827de2d2243136e7466a102c25f03b98","signature":"3c127278f7021cf39a457fd90272fbb2a29a2ad7b71f449f60089c06ab1dac8c"},"c5d0f5c874ef6b692be456d680530973723277bd356592bb39fa3a080ee9a21d","4d98a04b9bc90edbb9d211b6f63b28e7fac14fdb05eac76bf0188a01d8c93d73",{"version":"b3e6654a1a8411f9a04f741ebebfa99662493df86dd790333e6c3f25a9ce444d","signature":"24e4496d7c500d026ad5569d8913ad68485981140fd9f74084514c57e97610c5"},{"version":"9de6265e87fc95b775582e2b6ff7ff6ff9c169bf711c3cdb9cc85e4d2c1a59c4","signature":"96e4ffdcf88997c91fbef460d118c5c506bf61abc9bbd110dc4c47b56621cef6"},{"version":"b773a44812bffa3783671d179e20936e201def2942c9383ac067068dc596d4a3","signature":"19d752e91bb78b3e1055819bde4e070ee2c383eb6781c65a94e4504510254ef0"},{"version":"fdbd8aabded45b6e321aa7518b431f89b5dff38dea5ad26617e524104a00ad63","signature":"8ad5c6f0779f4038311ccba429c12f4c468ec47be41b81de781f35d2ce78ce32"},{"version":"3cb85796c812503915ba61e01eac7abb7ebaa680abe1d8366d21832f580faeff","signature":"31ba7ceb1a86423986699344bd5a409866c93e52f931d09354d8a888c4931d04"},{"version":"27a4608a6e8a01a12d99afe0ccd59eb120809e375dcc49459ebe7ebcf2af48fe","signature":"d32e971a40eaeff90f554fdff5fa4d790313934de31cd9b6d23111aa54c069d7"},{"version":"572451217c2f18e84f8d7525cc7d8c2fab7f352508304c3a91235d35be0995bc","signature":"a83543698d6732ebbb3ff6e94074caeeb773304ffff88f7d05f6c1c2034c5432"},{"version":"f8dadf0cee69fc8138c79dbaed0f4d81434181f01876285f879523fa76a2dcfb","signature":"65d444df655f0f9017edf684563f82115b7fc21793edd5aebe39db32bd38e58c"},"75d561557b77c2fffdb3ae3c51ad9ffb2cc17e23ca4ddacff9c9753358641317","dbdf55a7a4c984c49ae7d44521087a144896c2b5121523c8688caf61ca21e26e","3270e26de310e5e247299d0646b6d00da69456103d3ba8c5e01b40fa42b7be0b",{"version":"59a0fcd37943dab311d7e05d458a7fbae9da751b0b36d2d200b387eeb541aaa2","signature":"b443faeeeefea02a104fafa568fbb8c96a7c985f001163e181c856e5214d3052"},{"version":"eef56b423490400aa25fa2e8e53d139ed9851b11971cdb0764e9aa6026d8930d","signature":"ddad4215db4e65e26df643c77869ebdaa8a6a8b7f344b6f1be11a534e761f1c1"},{"version":"232ad2caab9c4d1a99d487907b6557249f91219cd17c09820bc8e7d335758e73","signature":"206cd066062626bb530a7cb094297bda2d47773f039124e4a2eb46e3d9462910"},{"version":"d5bc7702ae632b814f96e53dbef96c9523b257eeb554449363a88718f23f6d4d","signature":"7e4e4128b22c7378f6027c98a3f7e86b6256deeb4580ed80937ac492b26cff10"},"ebddf78f5679a763fbe33e6de2aea09d9341bb92616a1c3449eb1b7123a73c0a","ce272c524f77137235409ecca06a595cce5bbfc39927caacdd836c9a962fe8e9",{"version":"7613dd9f9a6369e40579fcfb6239234ad0fef79ef763603d12b1081cc83377af","signature":"3061c33024dc202baa290326b652acba49aa8524761cd8b05b732c53a84a809e"},{"version":"20b990bb50578f8f12d8ccc48d53c1151c939a4cdbe7e0c7666538e7da4dd9fa","signature":"cd9544655eac656831f2dbb996db075118b1d5e1a04582010ab3e79d7f1e8024"},{"version":"e3e0abe073e7a3b6e9421f4f61bcfa818689b60da45d7db28f4edccaf467928f","signature":"ee578405c47be054abb4f7e3f61c69ca8f84307cd534ae35453067a41fdafc53"},"abd59b14817c2c51c2030f5c190206de2b0906c6aec39c837e8d481d36de0a51","a5cbb226d808aead8764bcfadf6fd0f907c90a19b998c7fd542670cdd14c1535","0b379ffdc73fa83304f1d55713fd74ea42e10c4918130d07aafabc8f3b247ca8",{"version":"948d1ff585a5296583bca538a93ccdc6d8be6b8f3b70538cfddc38985d87f7ae","signature":"685752e808632b60525b0542096bf632df10cfe142a1786d01441e9b0cff18c7"},{"version":"7f81eb9bd68c02e7b2f6c6a566bc039cf8e53c5acba416546b462104a9922f6b","signature":"d849b4aba5b29e81051f8e733d6e15e87e9072712549d6ea52cc4adae538199d"},{"version":"b0d55672c507d172c549200f322ad7b4f273114717ea1d2a28a0a9d8e677f0f4","signature":"7877583d2968dc42e5a9ed506825ac661bec8502394efca99a5fbd95dc029288"},{"version":"151ff381ef9ff8da2da9b9663ebf657eac35c4c9a19183420c05728f31a6761d","impliedFormat":1},{"version":"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","impliedFormat":1},{"version":"96d14f21b7652903852eef49379d04dbda28c16ed36468f8c9fa08f7c14c9538","impliedFormat":1}],"root":[499,500,[525,550],[707,717],[732,736],[741,743],[766,886],[929,950],[952,1007]],"options":{"allowJs":true,"esModuleInterop":true,"jsx":1,"module":99,"skipLibCheck":true,"strict":true,"target":4},"referencedMap":[[785,1],[787,2],[792,3],[793,4],[794,5],[797,6],[799,7],[800,8],[802,9],[789,10],[803,8],[804,8],[805,8],[806,11],[807,12],[808,12],[790,8],[791,13],[801,14],[809,8],[811,15],[796,16],[817,17],[813,18],[530,6],[812,6],[814,19],[815,20],[816,21],[818,22],[825,23],[820,24],[821,19],[531,6],[819,6],[824,25],[822,26],[823,27],[833,28],[827,29],[828,19],[832,30],[829,31],[830,32],[831,33],[532,6],[826,6],[840,34],[835,35],[836,19],[839,36],[838,37],[837,38],[533,6],[834,6],[841,39],[847,40],[843,41],[844,19],[846,42],[845,43],[534,6],[842,6],[854,44],[852,45],[855,46],[535,6],[741,47],[856,48],[857,1],[858,49],[862,6],[861,50],[864,51],[859,6],[865,51],[860,52],[863,53],[539,54],[866,6],[867,55],[881,56],[527,6],[868,57],[869,58],[874,51],[875,6],[878,6],[880,52],[877,59],[871,6],[879,6],[872,52],[870,6],[876,51],[873,6],[742,19],[882,6],[883,60],[885,61],[884,62],[886,63],[540,6],[929,64],[930,65],[931,66],[743,6],[541,6],[932,67],[933,68],[934,69],[542,6],[778,70],[779,47],[783,71],[935,72],[936,1],[937,49],[938,73],[939,1],[940,49],[526,1],[950,54],[948,74],[954,75],[947,76],[956,54],[953,6],[946,77],[952,78],[945,79],[949,51],[955,80],[543,54],[544,6],[970,81],[546,6],[964,6],[965,82],[966,19],[968,83],[971,84],[969,85],[981,86],[547,6],[972,6],[973,87],[974,19],[978,88],[976,89],[980,90],[967,91],[977,92],[975,92],[798,8],[982,51],[958,51],[983,92],[957,93],[984,94],[985,92],[986,6],[810,51],[979,51],[992,95],[548,6],[987,6],[988,96],[989,19],[991,97],[990,98],[962,99],[998,100],[994,101],[549,6],[993,6],[995,19],[996,102],[997,103],[963,104],[960,105],[959,106],[961,107],[545,6],[1004,108],[1000,109],[1001,19],[1002,110],[1003,111],[550,6],[999,6],[529,112],[1005,1],[1006,49],[784,113],[1007,48],[777,114],[942,51],[772,42],[776,115],[943,51],[780,104],[781,116],[782,51],[770,117],[941,51],[795,104],[786,6],[775,118],[850,6],[851,51],[849,6],[848,6],[944,51],[771,51],[788,119],[709,120],[768,42],[710,51],[716,121],[766,122],[767,123],[769,51],[714,124],[712,125],[713,51],[717,126],[715,51],[732,127],[711,6],[708,6],[853,51],[774,128],[733,6],[734,129],[707,130],[528,6],[735,6],[736,6],[773,6],[499,131],[500,1],[674,132],[676,133],[677,134],[660,135],[664,136],[684,137],[663,137],[666,138],[658,6],[685,137],[659,137],[686,137],[665,139],[655,140],[675,132],[688,141],[679,142],[678,6],[681,143],[680,6],[687,144],[671,145],[670,6],[692,146],[654,147],[682,148],[653,149],[691,6],[667,141],[683,141],[672,141],[669,150],[668,141],[673,6],[650,150],[649,6],[651,141],[657,135],[662,141],[661,141],[689,151],[690,141],[652,152],[656,151],[573,153],[552,153],[608,6],[588,6],[620,6],[551,6],[599,154],[600,155],[566,156],[553,6],[562,6],[563,157],[564,6],[565,158],[561,159],[554,6],[558,6],[583,159],[581,160],[569,161],[595,162],[571,6],[576,6],[572,163],[567,159],[568,164],[570,164],[574,6],[575,6],[598,165],[587,166],[585,6],[586,167],[601,168],[597,169],[615,170],[609,171],[618,172],[619,173],[589,174],[605,6],[594,175],[591,159],[646,176],[592,177],[628,178],[627,6],[634,179],[633,6],[636,180],[635,6],[638,181],[637,6],[630,182],[629,6],[632,183],[631,183],[647,184],[642,185],[648,186],[560,187],[557,188],[556,6],[607,189],[621,190],[641,6],[626,6],[593,191],[611,192],[610,193],[613,194],[616,192],[617,195],[623,196],[596,6],[577,6],[612,197],[614,6],[643,198],[625,199],[603,6],[606,159],[580,200],[579,6],[644,201],[578,6],[645,202],[584,203],[582,6],[555,6],[622,204],[559,6],[640,205],[590,6],[624,206],[639,6],[602,6],[604,207],[698,208],[697,209],[699,208],[701,210],[703,211],[704,212],[702,213],[696,211],[706,214],[693,215],[694,215],[705,6],[695,130],[700,216],[726,217],[727,217],[729,218],[725,219],[724,220],[728,217],[730,217],[722,221],[719,6],[721,6],[720,6],[731,222],[747,6],[753,223],[749,224],[752,225],[757,226],[759,227],[754,228],[751,229],[750,6],[765,230],[758,6],[755,6],[748,6],[761,231],[760,232],[763,6],[756,6],[762,226],[764,233],[723,6],[718,6],[248,6],[891,234],[897,235],[899,236],[892,237],[900,238],[898,239],[901,6],[893,240],[894,238],[902,241],[903,234],[906,242],[895,243],[904,244],[905,245],[896,246],[1008,6],[887,6],[1009,6],[1010,6],[888,247],[145,248],[146,248],[147,249],[100,250],[148,251],[149,252],[150,253],[95,6],[98,254],[96,6],[97,6],[151,255],[152,256],[153,257],[154,258],[155,259],[156,260],[157,260],[158,261],[159,262],[160,263],[161,264],[101,6],[99,6],[162,265],[163,266],[164,267],[198,268],[165,269],[166,6],[167,270],[168,271],[169,272],[170,273],[171,274],[172,275],[173,276],[174,277],[175,278],[176,278],[177,279],[178,6],[179,280],[180,281],[182,282],[181,283],[183,284],[184,285],[185,286],[186,287],[187,288],[188,289],[189,290],[190,291],[191,292],[192,293],[193,294],[194,295],[195,296],[102,6],[103,6],[104,6],[142,297],[143,6],[144,6],[196,298],[197,299],[85,6],[202,300],[357,51],[203,301],[201,51],[358,302],[199,303],[200,304],[83,6],[86,305],[355,51],[266,51],[84,6],[951,6],[93,306],[445,307],[450,308],[452,309],[224,310],[252,311],[428,312],[247,313],[235,6],[216,6],[222,6],[418,314],[283,315],[223,6],[387,316],[257,317],[258,318],[354,319],[415,320],[370,321],[422,322],[423,323],[421,324],[420,6],[419,325],[254,326],[225,327],[304,6],[305,328],[220,6],[236,329],[226,330],[288,329],[285,329],[209,329],[250,331],[249,6],[427,332],[437,6],[215,6],[330,333],[331,334],[325,51],[473,6],[333,6],[334,335],[326,336],[479,337],[477,338],[472,6],[414,339],[413,6],[471,340],[327,51],[366,341],[364,342],[474,6],[478,6],[476,343],[475,6],[365,344],[466,345],[469,346],[295,347],[294,348],[293,349],[482,51],[292,350],[277,6],[485,6],[745,351],[744,6],[488,6],[737,352],[738,353],[487,51],[489,354],[205,6],[424,355],[425,356],[426,357],[238,6],[214,358],[204,6],[346,51],[207,359],[345,360],[344,361],[335,6],[336,6],[343,6],[338,6],[341,362],[337,6],[339,363],[342,364],[340,363],[221,6],[212,6],[213,329],[267,365],[268,366],[265,367],[263,368],[264,369],[260,6],[352,335],[372,335],[444,370],[453,371],[457,372],[431,373],[430,6],[280,6],[490,374],[440,375],[328,376],[329,377],[320,378],[310,6],[351,379],[311,380],[353,381],[348,382],[347,6],[349,6],[363,383],[432,384],[433,385],[313,386],[317,387],[308,388],[410,389],[439,390],[287,391],[388,392],[210,393],[438,394],[206,313],[261,6],[269,395],[399,396],[259,6],[398,397],[94,6],[393,398],[237,6],[306,399],[389,6],[211,6],[270,6],[397,400],[219,6],[275,401],[316,402],[429,403],[315,6],[396,6],[262,6],[401,404],[402,405],[217,6],[404,406],[406,407],[405,408],[240,6],[395,393],[408,409],[394,410],[400,411],[228,6],[231,6],[229,6],[233,6],[230,6],[232,6],[234,412],[227,6],[380,413],[379,6],[385,414],[381,415],[384,416],[383,416],[386,414],[382,415],[739,417],[274,418],[373,419],[436,420],[492,6],[461,421],[463,422],[312,6],[462,423],[434,384],[491,424],[332,384],[218,6],[314,425],[271,426],[272,427],[273,428],[303,429],[409,429],[289,429],[374,430],[290,430],[256,431],[255,6],[378,432],[377,433],[376,434],[375,435],[435,436],[324,437],[360,438],[323,439],[356,440],[359,441],[417,442],[416,443],[412,444],[369,445],[371,446],[368,447],[407,448],[362,6],[449,6],[361,449],[411,6],[276,450],[309,355],[307,451],[278,452],[281,453],[486,6],[279,454],[282,454],[447,6],[446,6],[448,6],[484,6],[284,455],[322,51],[92,6],[367,456],[253,6],[242,457],[318,6],[455,51],[465,458],[302,51],[459,335],[301,459],[442,460],[300,458],[208,6],[467,461],[298,51],[299,51],[291,6],[241,6],[297,462],[296,463],[239,464],[319,277],[286,277],[403,6],[391,465],[390,6],[451,6],[350,466],[321,51],[443,467],[87,51],[90,468],[91,469],[88,51],[89,6],[251,470],[246,471],[245,6],[244,472],[243,6],[441,473],[454,474],[456,475],[458,476],[746,477],[460,478],[464,479],[498,480],[468,480],[497,481],[470,482],[480,483],[740,484],[481,485],[483,486],[493,487],[496,358],[495,6],[494,488],[517,489],[515,490],[516,491],[504,492],[505,490],[512,493],[503,494],[508,495],[518,6],[509,496],[514,497],[520,498],[519,499],[502,500],[510,501],[511,502],[506,503],[513,489],[507,504],[890,237],[907,505],[908,505],[910,506],[911,507],[889,234],[912,505],[928,508],[909,505],[913,237],[914,237],[915,505],[916,51],[917,505],[918,509],[919,505],[920,505],[921,237],[922,505],[923,505],[924,505],[925,505],[926,505],[927,237],[392,510],[501,6],[523,511],[522,6],[521,6],[524,512],[81,6],[82,6],[13,6],[14,6],[16,6],[15,6],[2,6],[17,6],[18,6],[19,6],[20,6],[21,6],[22,6],[23,6],[24,6],[3,6],[25,6],[26,6],[4,6],[27,6],[31,6],[28,6],[29,6],[30,6],[32,6],[33,6],[34,6],[5,6],[35,6],[36,6],[37,6],[38,6],[6,6],[42,6],[39,6],[40,6],[41,6],[43,6],[7,6],[44,6],[49,6],[50,6],[45,6],[46,6],[47,6],[48,6],[8,6],[54,6],[51,6],[52,6],[53,6],[55,6],[9,6],[56,6],[57,6],[58,6],[60,6],[59,6],[61,6],[62,6],[10,6],[63,6],[64,6],[65,6],[11,6],[66,6],[67,6],[68,6],[69,6],[70,6],[1,6],[71,6],[72,6],[12,6],[76,6],[74,6],[79,6],[78,6],[73,6],[77,6],[75,6],[80,6],[120,513],[130,514],[119,513],[140,515],[111,516],[110,517],[139,488],[133,518],[138,519],[113,520],[127,521],[112,522],[136,523],[108,524],[107,488],[137,525],[109,526],[114,527],[115,6],[118,527],[105,6],[141,528],[131,529],[122,530],[123,531],[125,532],[121,533],[124,534],[134,488],[116,535],[117,536],[126,537],[106,538],[129,529],[128,527],[132,6],[135,539],[525,540],[537,6],[538,541],[536,6]],"affectedFilesPendingEmit":[785,787,792,793,794,797,799,800,802,789,803,804,805,806,807,808,790,791,801,809,811,796,817,813,530,812,814,815,816,818,825,820,821,531,819,824,822,823,833,827,828,832,829,830,831,532,826,840,835,836,839,838,837,533,834,841,847,843,844,846,845,534,842,854,852,855,535,741,856,857,858,862,861,864,859,865,860,863,539,866,867,881,527,868,869,874,875,878,880,877,871,879,872,870,876,873,742,882,883,885,884,886,540,929,930,931,743,541,932,933,934,542,778,779,783,935,936,937,938,939,940,526,950,948,954,947,956,953,946,952,945,949,955,543,544,970,546,964,965,966,968,971,969,981,547,972,973,974,978,976,980,967,977,975,798,982,958,983,957,984,985,986,810,979,992,548,987,988,989,991,990,962,998,994,549,993,995,996,997,963,960,959,961,545,1004,1000,1001,1002,1003,550,999,529,1005,1006,784,1007,777,942,772,776,943,780,781,782,770,941,795,786,775,850,851,849,848,944,771,788,709,768,710,716,766,767,769,714,712,713,717,715,732,711,708,853,774,733,734,707,528,735,736,773,500,525,537,538,536],"version":"5.9.3"} \ No newline at end of file +{"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.es2023.d.ts","./node_modules/typescript/lib/lib.es2024.d.ts","./node_modules/typescript/lib/lib.esnext.d.ts","./node_modules/typescript/lib/lib.dom.d.ts","./node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2016.intl.d.ts","./node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.es2022.regexp.d.ts","./node_modules/typescript/lib/lib.es2023.array.d.ts","./node_modules/typescript/lib/lib.es2023.collection.d.ts","./node_modules/typescript/lib/lib.es2023.intl.d.ts","./node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2024.collection.d.ts","./node_modules/typescript/lib/lib.es2024.object.d.ts","./node_modules/typescript/lib/lib.es2024.promise.d.ts","./node_modules/typescript/lib/lib.es2024.regexp.d.ts","./node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2024.string.d.ts","./node_modules/typescript/lib/lib.esnext.array.d.ts","./node_modules/typescript/lib/lib.esnext.collection.d.ts","./node_modules/typescript/lib/lib.esnext.intl.d.ts","./node_modules/typescript/lib/lib.esnext.disposable.d.ts","./node_modules/typescript/lib/lib.esnext.promise.d.ts","./node_modules/typescript/lib/lib.esnext.decorators.d.ts","./node_modules/typescript/lib/lib.esnext.iterator.d.ts","./node_modules/typescript/lib/lib.esnext.float16.d.ts","./node_modules/typescript/lib/lib.esnext.error.d.ts","./node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts","./node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/typescript/lib/lib.decorators.legacy.d.ts","./node_modules/@types/react/global.d.ts","./node_modules/csstype/index.d.ts","./node_modules/@types/prop-types/index.d.ts","./node_modules/@types/react/index.d.ts","./node_modules/next/dist/styled-jsx/types/css.d.ts","./node_modules/next/dist/styled-jsx/types/macro.d.ts","./node_modules/next/dist/styled-jsx/types/style.d.ts","./node_modules/next/dist/styled-jsx/types/global.d.ts","./node_modules/next/dist/styled-jsx/types/index.d.ts","./node_modules/next/dist/shared/lib/amp.d.ts","./node_modules/next/amp.d.ts","./node_modules/next/dist/server/get-page-files.d.ts","./node_modules/@types/node/compatibility/disposable.d.ts","./node_modules/@types/node/compatibility/indexable.d.ts","./node_modules/@types/node/compatibility/iterators.d.ts","./node_modules/@types/node/compatibility/index.d.ts","./node_modules/@types/node/globals.typedarray.d.ts","./node_modules/@types/node/buffer.buffer.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/web-globals/abortcontroller.d.ts","./node_modules/@types/node/web-globals/domexception.d.ts","./node_modules/@types/node/web-globals/events.d.ts","./node_modules/undici-types/header.d.ts","./node_modules/undici-types/readable.d.ts","./node_modules/undici-types/file.d.ts","./node_modules/undici-types/fetch.d.ts","./node_modules/undici-types/formdata.d.ts","./node_modules/undici-types/connector.d.ts","./node_modules/undici-types/client.d.ts","./node_modules/undici-types/errors.d.ts","./node_modules/undici-types/dispatcher.d.ts","./node_modules/undici-types/global-dispatcher.d.ts","./node_modules/undici-types/global-origin.d.ts","./node_modules/undici-types/pool-stats.d.ts","./node_modules/undici-types/pool.d.ts","./node_modules/undici-types/handlers.d.ts","./node_modules/undici-types/balanced-pool.d.ts","./node_modules/undici-types/agent.d.ts","./node_modules/undici-types/mock-interceptor.d.ts","./node_modules/undici-types/mock-agent.d.ts","./node_modules/undici-types/mock-client.d.ts","./node_modules/undici-types/mock-pool.d.ts","./node_modules/undici-types/mock-errors.d.ts","./node_modules/undici-types/proxy-agent.d.ts","./node_modules/undici-types/env-http-proxy-agent.d.ts","./node_modules/undici-types/retry-handler.d.ts","./node_modules/undici-types/retry-agent.d.ts","./node_modules/undici-types/api.d.ts","./node_modules/undici-types/interceptors.d.ts","./node_modules/undici-types/util.d.ts","./node_modules/undici-types/cookies.d.ts","./node_modules/undici-types/patch.d.ts","./node_modules/undici-types/websocket.d.ts","./node_modules/undici-types/eventsource.d.ts","./node_modules/undici-types/filereader.d.ts","./node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/undici-types/content-type.d.ts","./node_modules/undici-types/cache.d.ts","./node_modules/undici-types/index.d.ts","./node_modules/@types/node/web-globals/fetch.d.ts","./node_modules/@types/node/web-globals/navigator.d.ts","./node_modules/@types/node/web-globals/storage.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/inspector.generated.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/sea.d.ts","./node_modules/@types/node/sqlite.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/@types/react/canary.d.ts","./node_modules/@types/react/experimental.d.ts","./node_modules/@types/react-dom/index.d.ts","./node_modules/@types/react-dom/canary.d.ts","./node_modules/@types/react-dom/experimental.d.ts","./node_modules/next/dist/lib/fallback.d.ts","./node_modules/next/dist/compiled/webpack/webpack.d.ts","./node_modules/next/dist/server/config.d.ts","./node_modules/next/dist/lib/load-custom-routes.d.ts","./node_modules/next/dist/shared/lib/image-config.d.ts","./node_modules/next/dist/build/webpack/plugins/subresource-integrity-plugin.d.ts","./node_modules/next/dist/server/body-streams.d.ts","./node_modules/next/dist/server/lib/cache-control.d.ts","./node_modules/next/dist/lib/setup-exception-listeners.d.ts","./node_modules/next/dist/lib/worker.d.ts","./node_modules/next/dist/lib/constants.d.ts","./node_modules/next/dist/client/components/app-router-headers.d.ts","./node_modules/next/dist/build/rendering-mode.d.ts","./node_modules/next/dist/server/lib/router-utils/build-prefetch-segment-data-route.d.ts","./node_modules/next/dist/server/require-hook.d.ts","./node_modules/next/dist/server/lib/experimental/ppr.d.ts","./node_modules/next/dist/build/webpack/plugins/app-build-manifest-plugin.d.ts","./node_modules/next/dist/lib/page-types.d.ts","./node_modules/next/dist/build/segment-config/app/app-segment-config.d.ts","./node_modules/next/dist/build/segment-config/pages/pages-segment-config.d.ts","./node_modules/next/dist/build/analysis/get-page-static-info.d.ts","./node_modules/next/dist/build/webpack/loaders/get-module-build-info.d.ts","./node_modules/next/dist/build/webpack/plugins/middleware-plugin.d.ts","./node_modules/next/dist/server/node-polyfill-crypto.d.ts","./node_modules/next/dist/server/node-environment-baseline.d.ts","./node_modules/next/dist/server/node-environment-extensions/error-inspect.d.ts","./node_modules/next/dist/server/node-environment-extensions/random.d.ts","./node_modules/next/dist/server/node-environment-extensions/date.d.ts","./node_modules/next/dist/server/node-environment-extensions/web-crypto.d.ts","./node_modules/next/dist/server/node-environment-extensions/node-crypto.d.ts","./node_modules/next/dist/server/node-environment.d.ts","./node_modules/next/dist/build/page-extensions-type.d.ts","./node_modules/next/dist/build/webpack/plugins/flight-manifest-plugin.d.ts","./node_modules/next/dist/server/instrumentation/types.d.ts","./node_modules/next/dist/lib/coalesced-function.d.ts","./node_modules/next/dist/shared/lib/router/utils/middleware-route-matcher.d.ts","./node_modules/next/dist/server/lib/router-utils/types.d.ts","./node_modules/next/dist/shared/lib/modern-browserslist-target.d.ts","./node_modules/next/dist/shared/lib/constants.d.ts","./node_modules/next/dist/trace/types.d.ts","./node_modules/next/dist/trace/trace.d.ts","./node_modules/next/dist/trace/shared.d.ts","./node_modules/next/dist/trace/index.d.ts","./node_modules/next/dist/build/load-jsconfig.d.ts","./node_modules/@next/env/dist/index.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/use-cache-tracker-utils.d.ts","./node_modules/next/dist/build/webpack/plugins/telemetry-plugin/telemetry-plugin.d.ts","./node_modules/next/dist/telemetry/storage.d.ts","./node_modules/next/dist/build/build-context.d.ts","./node_modules/next/dist/shared/lib/bloom-filter.d.ts","./node_modules/next/dist/build/webpack-config.d.ts","./node_modules/next/dist/server/route-kind.d.ts","./node_modules/next/dist/server/route-definitions/route-definition.d.ts","./node_modules/next/dist/build/swc/generated-native.d.ts","./node_modules/next/dist/build/swc/types.d.ts","./node_modules/next/dist/server/dev/parse-version-info.d.ts","./node_modules/next/dist/next-devtools/shared/types.d.ts","./node_modules/next/dist/server/dev/dev-indicator-server-state.d.ts","./node_modules/next/dist/server/lib/parse-stack.d.ts","./node_modules/next/dist/next-devtools/server/shared.d.ts","./node_modules/next/dist/next-devtools/shared/stack-frame.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/utils/get-error-by-type.d.ts","./node_modules/@types/react/jsx-runtime.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/container/runtime-error/render-error.d.ts","./node_modules/next/dist/next-devtools/dev-overlay/shared.d.ts","./node_modules/next/dist/server/dev/hot-reloader-types.d.ts","./node_modules/next/dist/server/lib/cache-handlers/types.d.ts","./node_modules/next/dist/server/response-cache/types.d.ts","./node_modules/next/dist/server/resume-data-cache/cache-store.d.ts","./node_modules/next/dist/server/resume-data-cache/resume-data-cache.d.ts","./node_modules/next/dist/server/render-result.d.ts","./node_modules/next/dist/server/lib/i18n-provider.d.ts","./node_modules/next/dist/server/web/next-url.d.ts","./node_modules/next/dist/compiled/@edge-runtime/cookies/index.d.ts","./node_modules/next/dist/server/web/spec-extension/cookies.d.ts","./node_modules/next/dist/server/web/spec-extension/request.d.ts","./node_modules/next/dist/server/after/builtin-request-context.d.ts","./node_modules/next/dist/server/web/spec-extension/fetch-event.d.ts","./node_modules/next/dist/server/web/spec-extension/response.d.ts","./node_modules/next/dist/build/segment-config/middleware/middleware-config.d.ts","./node_modules/next/dist/server/web/types.d.ts","./node_modules/next/dist/build/webpack/plugins/pages-manifest-plugin.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-url.d.ts","./node_modules/next/dist/server/base-http/node.d.ts","./node_modules/next/dist/build/webpack/plugins/next-font-manifest-plugin.d.ts","./node_modules/next/dist/server/route-definitions/locale-route-definition.d.ts","./node_modules/next/dist/server/route-definitions/pages-route-definition.d.ts","./node_modules/next/dist/shared/lib/mitt.d.ts","./node_modules/next/dist/client/with-router.d.ts","./node_modules/next/dist/client/router.d.ts","./node_modules/next/dist/client/route-loader.d.ts","./node_modules/next/dist/client/page-loader.d.ts","./node_modules/next/dist/shared/lib/router/router.d.ts","./node_modules/next/dist/shared/lib/router-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/loadable.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/image-config-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/hooks-client-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/head-manager-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-definitions/app-page-route-definition.d.ts","./node_modules/next/dist/build/webpack/loaders/metadata/types.d.ts","./node_modules/next/dist/build/webpack/loaders/next-app-loader/index.d.ts","./node_modules/next/dist/server/lib/app-dir-module.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/request-cookies.d.ts","./node_modules/next/dist/server/async-storage/draft-mode-provider.d.ts","./node_modules/next/dist/server/web/spec-extension/adapters/headers.d.ts","./node_modules/next/dist/server/app-render/cache-signal.d.ts","./node_modules/next/dist/server/app-render/dynamic-rendering.d.ts","./node_modules/next/dist/server/request/fallback-params.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage-instance.d.ts","./node_modules/next/dist/server/response-cache/index.d.ts","./node_modules/next/dist/server/lib/lazy-result.d.ts","./node_modules/next/dist/server/lib/implicit-tags.d.ts","./node_modules/next/dist/server/app-render/work-unit-async-storage.external.d.ts","./node_modules/next/dist/shared/lib/deep-readonly.d.ts","./node_modules/next/dist/shared/lib/router/utils/parse-relative-url.d.ts","./node_modules/next/dist/server/app-render/app-render.d.ts","./node_modules/next/dist/shared/lib/server-inserted-html.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/amp-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.compiled.d.ts","./node_modules/next/dist/client/components/error-boundary.d.ts","./node_modules/next/dist/client/components/layout-router.d.ts","./node_modules/next/dist/client/components/render-from-template-context.d.ts","./node_modules/next/dist/server/app-render/action-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/action-async-storage.external.d.ts","./node_modules/next/dist/client/components/client-page.d.ts","./node_modules/next/dist/client/components/client-segment.d.ts","./node_modules/next/dist/server/request/search-params.d.ts","./node_modules/next/dist/client/components/hooks-server-context.d.ts","./node_modules/next/dist/client/components/http-access-fallback/error-boundary.d.ts","./node_modules/next/dist/lib/metadata/types/alternative-urls-types.d.ts","./node_modules/next/dist/lib/metadata/types/extra-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-types.d.ts","./node_modules/next/dist/lib/metadata/types/manifest-types.d.ts","./node_modules/next/dist/lib/metadata/types/opengraph-types.d.ts","./node_modules/next/dist/lib/metadata/types/twitter-types.d.ts","./node_modules/next/dist/lib/metadata/types/metadata-interface.d.ts","./node_modules/next/dist/lib/metadata/types/resolvers.d.ts","./node_modules/next/dist/lib/metadata/types/icons.d.ts","./node_modules/next/dist/lib/metadata/resolve-metadata.d.ts","./node_modules/next/dist/lib/metadata/metadata.d.ts","./node_modules/next/dist/lib/framework/boundary-components.d.ts","./node_modules/next/dist/server/app-render/rsc/preloads.d.ts","./node_modules/next/dist/server/app-render/rsc/postpone.d.ts","./node_modules/next/dist/server/app-render/rsc/taint.d.ts","./node_modules/next/dist/shared/lib/segment-cache/segment-value-encoding.d.ts","./node_modules/next/dist/server/app-render/collect-segment-data.d.ts","./node_modules/next/dist/next-devtools/userspace/app/segment-explorer-node.d.ts","./node_modules/next/dist/server/app-render/entry-base.d.ts","./node_modules/next/dist/build/templates/app-page.d.ts","./node_modules/@types/react/jsx-dev-runtime.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/rsc/entrypoints.d.ts","./node_modules/@types/react-dom/client.d.ts","./node_modules/@types/react-dom/server.d.ts","./node_modules/next/dist/server/route-modules/app-page/vendored/ssr/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/app-page/module.d.ts","./node_modules/next/dist/server/web/adapter.d.ts","./node_modules/next/dist/server/use-cache/cache-life.d.ts","./node_modules/next/dist/server/app-render/types.d.ts","./node_modules/next/dist/client/components/router-reducer/router-reducer-types.d.ts","./node_modules/next/dist/client/flight-data-helpers.d.ts","./node_modules/next/dist/client/components/router-reducer/fetch-server-response.d.ts","./node_modules/next/dist/shared/lib/app-router-context.shared-runtime.d.ts","./node_modules/next/dist/server/route-modules/pages/vendored/contexts/entrypoints.d.ts","./node_modules/next/dist/server/route-modules/pages/module.compiled.d.ts","./node_modules/next/dist/build/templates/pages.d.ts","./node_modules/next/dist/server/route-modules/pages/module.d.ts","./node_modules/next/dist/next-devtools/userspace/pages/pages-dev-overlay-setup.d.ts","./node_modules/next/dist/server/render.d.ts","./node_modules/next/dist/server/route-definitions/pages-api-route-definition.d.ts","./node_modules/next/dist/server/route-matches/pages-api-route-match.d.ts","./node_modules/next/dist/server/route-matchers/route-matcher.d.ts","./node_modules/next/dist/server/route-matcher-providers/route-matcher-provider.d.ts","./node_modules/next/dist/server/route-matcher-managers/route-matcher-manager.d.ts","./node_modules/next/dist/server/normalizers/normalizer.d.ts","./node_modules/next/dist/server/normalizers/locale-route-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/pathname-normalizer.d.ts","./node_modules/next/dist/server/normalizers/request/suffix.d.ts","./node_modules/next/dist/server/normalizers/request/rsc.d.ts","./node_modules/next/dist/server/normalizers/request/prefetch-rsc.d.ts","./node_modules/next/dist/server/normalizers/request/next-data.d.ts","./node_modules/next/dist/server/normalizers/request/segment-prefix-rsc.d.ts","./node_modules/next/dist/build/static-paths/types.d.ts","./node_modules/next/dist/server/base-server.d.ts","./node_modules/next/dist/server/lib/async-callback-set.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-regex.d.ts","./node_modules/next/dist/shared/lib/router/utils/route-matcher.d.ts","./node_modules/sharp/lib/index.d.ts","./node_modules/next/dist/server/image-optimizer.d.ts","./node_modules/next/dist/server/next-server.d.ts","./node_modules/next/dist/server/lib/types.d.ts","./node_modules/next/dist/server/lib/lru-cache.d.ts","./node_modules/next/dist/server/lib/dev-bundler-service.d.ts","./node_modules/next/dist/server/dev/static-paths-worker.d.ts","./node_modules/next/dist/server/dev/next-dev-server.d.ts","./node_modules/next/dist/server/next.d.ts","./node_modules/next/dist/server/lib/render-server.d.ts","./node_modules/next/dist/server/lib/router-server.d.ts","./node_modules/next/dist/shared/lib/router/utils/path-match.d.ts","./node_modules/next/dist/server/lib/router-utils/filesystem.d.ts","./node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.d.ts","./node_modules/next/dist/server/lib/router-utils/router-server-context.d.ts","./node_modules/next/dist/server/route-modules/route-module.d.ts","./node_modules/next/dist/server/load-components.d.ts","./node_modules/next/dist/server/route-definitions/app-route-route-definition.d.ts","./node_modules/next/dist/server/async-storage/work-store.d.ts","./node_modules/next/dist/server/web/http.d.ts","./node_modules/next/dist/server/route-modules/app-route/shared-modules.d.ts","./node_modules/next/dist/client/components/redirect-status-code.d.ts","./node_modules/next/dist/client/components/redirect-error.d.ts","./node_modules/next/dist/build/templates/app-route.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.d.ts","./node_modules/next/dist/server/route-modules/app-route/module.compiled.d.ts","./node_modules/next/dist/build/segment-config/app/app-segments.d.ts","./node_modules/next/dist/build/utils.d.ts","./node_modules/next/dist/build/turborepo-access-trace/types.d.ts","./node_modules/next/dist/build/turborepo-access-trace/result.d.ts","./node_modules/next/dist/build/turborepo-access-trace/helpers.d.ts","./node_modules/next/dist/build/turborepo-access-trace/index.d.ts","./node_modules/next/dist/export/routes/types.d.ts","./node_modules/next/dist/export/types.d.ts","./node_modules/next/dist/export/worker.d.ts","./node_modules/next/dist/build/worker.d.ts","./node_modules/next/dist/build/index.d.ts","./node_modules/next/dist/server/lib/incremental-cache/index.d.ts","./node_modules/next/dist/server/after/after.d.ts","./node_modules/next/dist/server/after/after-context.d.ts","./node_modules/next/dist/server/app-render/work-async-storage-instance.d.ts","./node_modules/next/dist/server/app-render/work-async-storage.external.d.ts","./node_modules/next/dist/server/request/params.d.ts","./node_modules/next/dist/server/route-matches/route-match.d.ts","./node_modules/next/dist/server/request-meta.d.ts","./node_modules/next/dist/cli/next-test.d.ts","./node_modules/next/dist/server/config-shared.d.ts","./node_modules/next/dist/server/base-http/index.d.ts","./node_modules/next/dist/server/api-utils/index.d.ts","./node_modules/next/dist/types.d.ts","./node_modules/next/dist/shared/lib/html-context.shared-runtime.d.ts","./node_modules/next/dist/shared/lib/utils.d.ts","./node_modules/next/dist/pages/_app.d.ts","./node_modules/next/app.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-cache.d.ts","./node_modules/next/dist/server/web/spec-extension/revalidate.d.ts","./node_modules/next/dist/server/web/spec-extension/unstable-no-store.d.ts","./node_modules/next/dist/server/use-cache/cache-tag.d.ts","./node_modules/next/cache.d.ts","./node_modules/next/dist/shared/lib/runtime-config.external.d.ts","./node_modules/next/config.d.ts","./node_modules/next/dist/pages/_document.d.ts","./node_modules/next/document.d.ts","./node_modules/next/dist/shared/lib/dynamic.d.ts","./node_modules/next/dynamic.d.ts","./node_modules/next/dist/pages/_error.d.ts","./node_modules/next/error.d.ts","./node_modules/next/dist/shared/lib/head.d.ts","./node_modules/next/head.d.ts","./node_modules/next/dist/server/request/cookies.d.ts","./node_modules/next/dist/server/request/headers.d.ts","./node_modules/next/dist/server/request/draft-mode.d.ts","./node_modules/next/headers.d.ts","./node_modules/next/dist/shared/lib/get-img-props.d.ts","./node_modules/next/dist/client/image-component.d.ts","./node_modules/next/dist/shared/lib/image-external.d.ts","./node_modules/next/image.d.ts","./node_modules/next/dist/client/link.d.ts","./node_modules/next/link.d.ts","./node_modules/next/dist/client/components/redirect.d.ts","./node_modules/next/dist/client/components/not-found.d.ts","./node_modules/next/dist/client/components/forbidden.d.ts","./node_modules/next/dist/client/components/unauthorized.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.server.d.ts","./node_modules/next/dist/client/components/unstable-rethrow.d.ts","./node_modules/next/dist/client/components/navigation.react-server.d.ts","./node_modules/next/dist/client/components/unrecognized-action-error.d.ts","./node_modules/next/dist/client/components/navigation.d.ts","./node_modules/next/navigation.d.ts","./node_modules/next/router.d.ts","./node_modules/next/dist/client/script.d.ts","./node_modules/next/script.d.ts","./node_modules/next/dist/server/web/spec-extension/user-agent.d.ts","./node_modules/next/dist/compiled/@edge-runtime/primitives/url.d.ts","./node_modules/next/dist/server/web/spec-extension/image-response.d.ts","./node_modules/next/dist/compiled/@vercel/og/satori/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/emoji/index.d.ts","./node_modules/next/dist/compiled/@vercel/og/types.d.ts","./node_modules/next/dist/server/after/index.d.ts","./node_modules/next/dist/server/request/root-params.d.ts","./node_modules/next/dist/server/request/connection.d.ts","./node_modules/next/server.d.ts","./node_modules/next/types/global.d.ts","./node_modules/next/types/compiled.d.ts","./node_modules/next/types.d.ts","./node_modules/next/index.d.ts","./node_modules/next/image-types/global.d.ts","./next-env.d.ts","./next.config.ts","./node_modules/source-map-js/source-map.d.ts","./node_modules/postcss/lib/previous-map.d.ts","./node_modules/postcss/lib/input.d.ts","./node_modules/postcss/lib/css-syntax-error.d.ts","./node_modules/postcss/lib/declaration.d.ts","./node_modules/postcss/lib/root.d.ts","./node_modules/postcss/lib/warning.d.ts","./node_modules/postcss/lib/lazy-result.d.ts","./node_modules/postcss/lib/no-work-result.d.ts","./node_modules/postcss/lib/processor.d.ts","./node_modules/postcss/lib/result.d.ts","./node_modules/postcss/lib/document.d.ts","./node_modules/postcss/lib/rule.d.ts","./node_modules/postcss/lib/node.d.ts","./node_modules/postcss/lib/comment.d.ts","./node_modules/postcss/lib/container.d.ts","./node_modules/postcss/lib/at-rule.d.ts","./node_modules/postcss/lib/list.d.ts","./node_modules/postcss/lib/postcss.d.ts","./node_modules/postcss/lib/postcss.d.mts","./node_modules/tailwindcss/types/generated/corepluginlist.d.ts","./node_modules/tailwindcss/types/generated/colors.d.ts","./node_modules/tailwindcss/types/config.d.ts","./node_modules/tailwindcss/types/index.d.ts","./tailwind.config.ts","./app/robots.ts","./app/docs/docsnavsections.ts","./lib/page-lastmod.generated.ts","./app/sitemap.ts","./app/admin/metrics/metricsnavsections.ts","./app/admin/reports/reportsnavsections.ts","./app/admin/security/securitynavsections.ts","./app/admin/settings/settingsnavsections.ts","./app/admin/tenants/tenantsnavsections.ts","./app/analyze-rules/types.ts","./types/session.ts","./types/enrollment.ts","./types/index.ts","./app/dashboard/types.ts","./lib/config.ts","./lib/api.ts","./lib/authenticatedfetch.ts","./contexts/notificationcontext.tsx","./app/dashboard/hooks/useblockdevice.ts","./node_modules/@nevware21/ts-utils/dist/types/ts-utils.d.ts","./node_modules/@microsoft/applicationinsights-shims/types/constants.d.ts","./node_modules/@microsoft/applicationinsights-shims/types/tslibshims.d.ts","./node_modules/@microsoft/applicationinsights-shims/types/tslibglobals.d.ts","./node_modules/@microsoft/applicationinsights-shims/types/applicationinsights-shims.d.ts","./node_modules/@nevware21/ts-async/dist/types/ts-async.d.ts","./node_modules/@microsoft/applicationinsights-core-js/types/applicationinsights-core-js.d.ts","./node_modules/@microsoft/applicationinsights-common/types/applicationinsights-common.d.ts","./node_modules/@microsoft/applicationinsights-analytics-js/types/applicationinsights-analytics-js.d.ts","./node_modules/@microsoft/applicationinsights-cfgsync-js/types/applicationinsights-cfgsync-js.d.ts","./node_modules/@microsoft/applicationinsights-dependencies-js/types/applicationinsights-dependencies-js.d.ts","./node_modules/@microsoft/applicationinsights-channel-js/types/applicationinsights-channel-js.d.ts","./node_modules/@microsoft/applicationinsights-properties-js/types/applicationinsights-properties-js.d.ts","./node_modules/@microsoft/applicationinsights-web/types/applicationinsights-web.d.ts","./lib/appinsights.ts","./app/dashboard/hooks/usedeletesession.ts","./app/gather-rules/types.ts","./app/go/[code]/route.ts","./app/ime-log-patterns/types.ts","./app/sessions/[sessionid]/hooks/useautoscroll.ts","./app/sessions/[sessionid]/hooks/usesessionanalysis.ts","./app/sessions/[sessionid]/utils/eventhelpers.ts","./app/sessions/[sessionid]/utils/phaseconstants.ts","./app/settings/types.ts","./app/settings/access/accessnavsections.ts","./app/settings/agent/agentnavsections.ts","./app/settings/integrations/integrationsnavsections.ts","./app/settings/management/managementnavsections.ts","./app/settings/validation/validationnavsections.ts","./hooks/useadminmode.ts","./node_modules/@azure/msal-common/dist/account/tokenclaims.d.ts","./node_modules/@azure/msal-common/dist/account/authtoken.d.ts","./node_modules/@azure/msal-common/dist/authority/authoritytype.d.ts","./node_modules/@azure/msal-common/dist/authority/openidconfigresponse.d.ts","./node_modules/@azure/msal-common/dist/url/iuri.d.ts","./node_modules/@azure/msal-common/dist/network/networkresponse.d.ts","./node_modules/@azure/msal-common/dist/network/inetworkmodule.d.ts","./node_modules/@azure/msal-common/dist/authority/protocolmode.d.ts","./node_modules/@azure/msal-common/dist/utils/constants.d.ts","./node_modules/@azure/msal-common/dist/logger/logger.d.ts","./node_modules/@azure/msal-common/dist/authority/oidcoptions.d.ts","./node_modules/@azure/msal-common/dist/authority/azureregion.d.ts","./node_modules/@azure/msal-common/dist/authority/azureregionconfiguration.d.ts","./node_modules/@azure/msal-common/dist/authority/clouddiscoverymetadata.d.ts","./node_modules/@azure/msal-common/dist/authority/cloudinstancediscoveryresponse.d.ts","./node_modules/@azure/msal-common/dist/authority/authorityoptions.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/credentialentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/idtokenentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/accesstokenentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/refreshtokenentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/appmetadataentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/cacherecord.d.ts","./node_modules/@azure/msal-common/dist/account/accountinfo.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/servertelemetryentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/throttlingentity.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/authoritymetadataentity.d.ts","./node_modules/@azure/msal-common/dist/request/storeincache.d.ts","./node_modules/@azure/msal-common/dist/telemetry/performance/performanceevent.d.ts","./node_modules/@azure/msal-common/dist/telemetry/performance/iperformancemeasurement.d.ts","./node_modules/@azure/msal-common/dist/telemetry/performance/iperformanceclient.d.ts","./node_modules/@azure/msal-common/dist/cache/cachemanager.d.ts","./node_modules/@azure/msal-common/dist/telemetry/server/servertelemetryrequest.d.ts","./node_modules/@azure/msal-common/dist/authority/regiondiscoverymetadata.d.ts","./node_modules/@azure/msal-common/dist/telemetry/server/servertelemetrymanager.d.ts","./node_modules/@azure/msal-common/dist/cache/interface/iserializabletokencache.d.ts","./node_modules/@azure/msal-common/dist/cache/persistence/tokencachecontext.d.ts","./node_modules/@azure/msal-common/dist/cache/interface/icacheplugin.d.ts","./node_modules/@azure/msal-common/dist/account/clientcredentials.d.ts","./node_modules/@azure/msal-common/dist/config/clientconfiguration.d.ts","./node_modules/@azure/msal-common/dist/utils/msaltypes.d.ts","./node_modules/@azure/msal-common/dist/crypto/joseheader.d.ts","./node_modules/@azure/msal-common/dist/crypto/signedhttprequest.d.ts","./node_modules/@azure/msal-common/dist/request/baseauthrequest.d.ts","./node_modules/@azure/msal-common/dist/crypto/icrypto.d.ts","./node_modules/@azure/msal-common/dist/cache/entities/accountentity.d.ts","./node_modules/@azure/msal-common/dist/request/scopeset.d.ts","./node_modules/@azure/msal-common/dist/cache/utils/cachetypes.d.ts","./node_modules/@azure/msal-common/dist/cache/interface/icachemanager.d.ts","./node_modules/@azure/msal-common/dist/authority/authority.d.ts","./node_modules/@azure/msal-common/dist/authority/authorityfactory.d.ts","./node_modules/@azure/msal-common/dist/cache/utils/cachehelpers.d.ts","./node_modules/@azure/msal-common/dist/utils/timeutils.d.ts","./node_modules/@azure/msal-common/dist/response/serverauthorizationcoderesponse.d.ts","./node_modules/@azure/msal-common/dist/utils/urlutils.d.ts","./node_modules/@azure/msal-common/dist/constants/aadserverparamkeys.d.ts","./node_modules/@azure/msal-common/dist/response/serverauthorizationtokenresponse.d.ts","./node_modules/@azure/msal-common/dist/network/requestthumbprint.d.ts","./node_modules/@azure/msal-common/dist/account/ccscredential.d.ts","./node_modules/@azure/msal-common/dist/client/baseclient.d.ts","./node_modules/@azure/msal-common/dist/request/commonauthorizationurlrequest.d.ts","./node_modules/@azure/msal-common/dist/request/commonauthorizationcoderequest.d.ts","./node_modules/@azure/msal-common/dist/response/authenticationresult.d.ts","./node_modules/@azure/msal-common/dist/request/commonendsessionrequest.d.ts","./node_modules/@azure/msal-common/dist/response/authorizationcodepayload.d.ts","./node_modules/@azure/msal-common/dist/client/authorizationcodeclient.d.ts","./node_modules/@azure/msal-common/dist/request/commonrefreshtokenrequest.d.ts","./node_modules/@azure/msal-common/dist/request/commonsilentflowrequest.d.ts","./node_modules/@azure/msal-common/dist/client/refreshtokenclient.d.ts","./node_modules/@azure/msal-common/dist/client/silentflowclient.d.ts","./node_modules/@azure/msal-common/dist/account/clientinfo.d.ts","./node_modules/@azure/msal-common/dist/network/throttlingutils.d.ts","./node_modules/@azure/msal-common/dist/url/urlstring.d.ts","./node_modules/@azure/msal-common/dist/request/requestparameterbuilder.d.ts","./node_modules/@azure/msal-common/dist/utils/protocolutils.d.ts","./node_modules/@azure/msal-common/dist/response/responsehandler.d.ts","./node_modules/@azure/msal-common/dist/request/authenticationheaderparser.d.ts","./node_modules/@azure/msal-common/dist/error/autherrorcodes.d.ts","./node_modules/@azure/msal-common/dist/error/autherror.d.ts","./node_modules/@azure/msal-common/dist/error/interactionrequiredautherrorcodes.d.ts","./node_modules/@azure/msal-common/dist/error/interactionrequiredautherror.d.ts","./node_modules/@azure/msal-common/dist/error/servererror.d.ts","./node_modules/@azure/msal-common/dist/error/networkerror.d.ts","./node_modules/@azure/msal-common/dist/error/cacheerrorcodes.d.ts","./node_modules/@azure/msal-common/dist/error/cacheerror.d.ts","./node_modules/@azure/msal-common/dist/error/clientautherrorcodes.d.ts","./node_modules/@azure/msal-common/dist/error/clientautherror.d.ts","./node_modules/@azure/msal-common/dist/error/clientconfigurationerrorcodes.d.ts","./node_modules/@azure/msal-common/dist/error/clientconfigurationerror.d.ts","./node_modules/@azure/msal-common/dist/utils/stringutils.d.ts","./node_modules/@azure/msal-common/dist/utils/functionwrappers.d.ts","./node_modules/@azure/msal-common/dist/packagemetadata.d.ts","./node_modules/@azure/msal-common/dist/exports-common.d.ts","./node_modules/@azure/msal-common/dist/response/externaltokenresponse.d.ts","./node_modules/@azure/msal-common/dist/telemetry/performance/performanceclient.d.ts","./node_modules/@azure/msal-common/dist/telemetry/performance/stubperformanceclient.d.ts","./node_modules/@azure/msal-common/dist/crypto/poptokengenerator.d.ts","./node_modules/@azure/msal-common/dist/exports-browser-only.d.ts","./node_modules/@azure/msal-common/dist/index-browser.d.ts","./node_modules/@azure/msal-browser/dist/request/popupwindowattributes.d.ts","./node_modules/@azure/msal-browser/dist/request/popuprequest.d.ts","./node_modules/@azure/msal-browser/dist/request/redirectrequest.d.ts","./node_modules/@azure/msal-browser/dist/utils/browserconstants.d.ts","./node_modules/@azure/msal-browser/dist/navigation/navigationoptions.d.ts","./node_modules/@azure/msal-browser/dist/navigation/inavigationclient.d.ts","./node_modules/@azure/msal-browser/dist/config/configuration.d.ts","./node_modules/@azure/msal-browser/dist/utils/browserutils.d.ts","./node_modules/@azure/msal-browser/dist/request/silentrequest.d.ts","./node_modules/@azure/msal-browser/dist/cache/iwindowstorage.d.ts","./node_modules/@azure/msal-browser/dist/cache/memorystorage.d.ts","./node_modules/@azure/msal-browser/dist/broker/nativebroker/nativerequest.d.ts","./node_modules/@azure/msal-browser/dist/response/authenticationresult.d.ts","./node_modules/@azure/msal-browser/dist/request/ssosilentrequest.d.ts","./node_modules/@azure/msal-browser/dist/cache/cookiestorage.d.ts","./node_modules/@azure/msal-browser/dist/cache/browsercachemanager.d.ts","./node_modules/@azure/msal-browser/dist/cache/tokencache.d.ts","./node_modules/@azure/msal-browser/dist/cache/itokencache.d.ts","./node_modules/@azure/msal-browser/dist/request/authorizationcoderequest.d.ts","./node_modules/@azure/msal-browser/dist/request/endsessionrequest.d.ts","./node_modules/@azure/msal-browser/dist/request/endsessionpopuprequest.d.ts","./node_modules/@azure/msal-browser/dist/event/eventtype.d.ts","./node_modules/@azure/msal-browser/dist/event/eventmessage.d.ts","./node_modules/@azure/msal-browser/dist/request/clearcacherequest.d.ts","./node_modules/@azure/msal-browser/dist/request/initializeapplicationrequest.d.ts","./node_modules/@azure/msal-browser/dist/app/ipublicclientapplication.d.ts","./node_modules/@azure/msal-browser/dist/controllers/icontroller.d.ts","./node_modules/@azure/msal-browser/dist/app/publicclientapplication.d.ts","./node_modules/@azure/msal-browser/dist/app/publicclientnext.d.ts","./node_modules/@azure/msal-browser/dist/error/browserautherrorcodes.d.ts","./node_modules/@azure/msal-browser/dist/error/browserautherror.d.ts","./node_modules/@azure/msal-browser/dist/error/browserconfigurationautherrorcodes.d.ts","./node_modules/@azure/msal-browser/dist/error/browserconfigurationautherror.d.ts","./node_modules/@azure/msal-browser/dist/navigation/navigationclient.d.ts","./node_modules/@azure/msal-browser/dist/request/authorizationurlrequest.d.ts","./node_modules/@azure/msal-browser/dist/cache/browserstorage.d.ts","./node_modules/@azure/msal-browser/dist/cache/localstorage.d.ts","./node_modules/@azure/msal-browser/dist/cache/sessionstorage.d.ts","./node_modules/@azure/msal-browser/dist/event/eventhandler.d.ts","./node_modules/@azure/msal-browser/dist/crypto/signedhttprequest.d.ts","./node_modules/@azure/msal-browser/dist/telemetry/browserperformanceclient.d.ts","./node_modules/@azure/msal-browser/dist/telemetry/browserperformancemeasurement.d.ts","./node_modules/@azure/msal-browser/dist/packagemetadata.d.ts","./node_modules/@azure/msal-browser/dist/index.d.ts","./node_modules/@azure/msal-react/dist/msalcontext.d.ts","./node_modules/@azure/msal-react/dist/msalprovider.d.ts","./node_modules/@azure/msal-react/dist/types/accountidentifiers.d.ts","./node_modules/@azure/msal-react/dist/hooks/usemsalauthentication.d.ts","./node_modules/@azure/msal-react/dist/components/msalauthenticationtemplate.d.ts","./node_modules/@azure/msal-react/dist/components/authenticatedtemplate.d.ts","./node_modules/@azure/msal-react/dist/components/unauthenticatedtemplate.d.ts","./node_modules/@azure/msal-react/dist/utils/utilities.d.ts","./node_modules/@azure/msal-react/dist/components/withmsal.d.ts","./node_modules/@azure/msal-react/dist/hooks/usemsal.d.ts","./node_modules/@azure/msal-react/dist/hooks/useaccount.d.ts","./node_modules/@azure/msal-react/dist/hooks/useisauthenticated.d.ts","./node_modules/@azure/msal-react/dist/packagemetadata.d.ts","./node_modules/@azure/msal-react/dist/index.d.ts","./lib/msalconfig.ts","./contexts/authcontext.tsx","./hooks/useauthenticatedfetch.ts","./hooks/usenotificationmessages.ts","./hooks/index.ts","./hooks/usesidebarstate.ts","./contexts/sidebarcontext.tsx","./hooks/usepagesections.ts","./lib/guardrails.generated.ts","./lib/guardvalidation.ts","./lib/rulepagehelpers.ts","./lib/sessionexportutils.ts","./node_modules/next/dist/compiled/@vercel/og/index.edge.d.ts","./node_modules/next/dist/compiled/@vercel/og/index.node.d.ts","./node_modules/next/dist/server/og/image-response.d.ts","./node_modules/next/og.d.ts","./app/apple-icon.tsx","./app/error.tsx","./app/global-error.tsx","./node_modules/next/dist/compiled/@next/font/dist/types.d.ts","./node_modules/next/dist/compiled/@next/font/dist/google/index.d.ts","./node_modules/next/font/google/index.d.ts","./node_modules/@microsoft/signalr/dist/esm/abortcontroller.d.ts","./node_modules/@microsoft/signalr/dist/esm/itransport.d.ts","./node_modules/@microsoft/signalr/dist/esm/errors.d.ts","./node_modules/@microsoft/signalr/dist/esm/ilogger.d.ts","./node_modules/@microsoft/signalr/dist/esm/ihubprotocol.d.ts","./node_modules/@microsoft/signalr/dist/esm/httpclient.d.ts","./node_modules/@microsoft/signalr/dist/esm/defaulthttpclient.d.ts","./node_modules/@microsoft/signalr/dist/esm/ihttpconnectionoptions.d.ts","./node_modules/@microsoft/signalr/dist/esm/istatefulreconnectoptions.d.ts","./node_modules/@microsoft/signalr/dist/esm/stream.d.ts","./node_modules/@microsoft/signalr/dist/esm/hubconnection.d.ts","./node_modules/@microsoft/signalr/dist/esm/iretrypolicy.d.ts","./node_modules/@microsoft/signalr/dist/esm/hubconnectionbuilder.d.ts","./node_modules/@microsoft/signalr/dist/esm/loggers.d.ts","./node_modules/@microsoft/signalr/dist/esm/jsonhubprotocol.d.ts","./node_modules/@microsoft/signalr/dist/esm/subject.d.ts","./node_modules/@microsoft/signalr/dist/esm/pkg-version.d.ts","./node_modules/@microsoft/signalr/dist/esm/utils.d.ts","./node_modules/@microsoft/signalr/dist/esm/index.d.ts","./contexts/signalrcontext.tsx","./contexts/tenantcontext.tsx","./contexts/globalnotificationcontext.tsx","./contexts/themecontext.tsx","./components/navbar.tsx","./components/scrolltotopbutton.tsx","./components/feedbackbubble.tsx","./lib/sidebaricons.tsx","./lib/globalnavconfig.tsx","./components/publicsitenavbar.tsx","./components/globalsidebar.tsx","./components/appinsightsinit.tsx","./app/layout.tsx","./app/opengraph-image.tsx","./components/landing/authgate.tsx","./components/landing/loginbutton.tsx","./components/landing/platformstats.tsx","./app/page.tsx","./app/twitter-image.tsx","./app/about/layout.tsx","./components/publicpageheader.tsx","./app/about/page.tsx","./components/validationindicator.tsx","./app/admin/components/diagnosticslogpathssection.tsx","./app/admin/components/tenantadminsection.tsx","./app/admin/components/tenantmanagementsection.tsx","./app/admin/adminconfigcontext.tsx","./app/admin/adminnotifications.tsx","./app/admin/adminpagesections.tsx","./components/protectedroute.tsx","./app/admin/layout.tsx","./app/admin/components/adminconfigsettingssection.tsx","./app/settings/components/apikeyssection.tsx","./app/admin/components/apikeyssection.tsx","./app/admin/components/configreseedsection.tsx","./app/admin/components/tenantsearchselect.tsx","./app/admin/components/deviceblocksection.tsx","./app/admin/components/feedbacksection.tsx","./app/admin/components/maintenancesection.tsx","./app/admin/components/maintenancetriggersection.tsx","./app/admin/components/sessionexportsection.tsx","./app/admin/components/sessionreportssection.tsx","./app/admin/components/softwaremappingsection.tsx","./app/admin/components/versionblocksection.tsx","./app/settings/components/saveresetbar.tsx","./app/admin/components/vulnerabilitydatasection.tsx","./app/admin/metrics/metricssidebar.tsx","./app/admin/metrics/layout.tsx","./app/admin/metrics/page.tsx","./app/admin/metrics/sections/sectionagentmetrics.tsx","./app/admin/metrics/sections/sectionplatformusage.tsx","./app/admin/metrics/[section]/page.tsx","./app/admin/ops/page.tsx","./app/admin/reports/reportssidebar.tsx","./app/admin/reports/layout.tsx","./app/admin/reports/page.tsx","./app/admin/reports/sections/sectionsessionreports.tsx","./app/admin/reports/sections/sectionuserfeedback.tsx","./app/admin/reports/sections/sectionsessionexport.tsx","./app/admin/reports/[section]/page.tsx","./app/admin/security/securitysidebar.tsx","./app/admin/security/layout.tsx","./app/admin/security/page.tsx","./app/admin/security/sections/sectiondeviceblock.tsx","./app/admin/security/sections/sectionversionblock.tsx","./app/admin/security/sections/sectionvulnerabilitydata.tsx","./app/admin/security/sections/sectionapikeys.tsx","./app/admin/security/[section]/page.tsx","./app/admin/settings/settingssidebar.tsx","./app/admin/settings/layout.tsx","./app/admin/settings/page.tsx","./app/admin/settings/sections/sectionglobalsettings.tsx","./app/admin/settings/sections/sectiondiagnosticslogpaths.tsx","./app/admin/settings/sections/sectionconfigreseed.tsx","./app/admin/settings/[section]/page.tsx","./app/admin/software/page.tsx","./app/admin/tenants/tenantssidebar.tsx","./app/admin/tenants/layout.tsx","./app/admin/tenants/page.tsx","./app/admin/tenants/sections/sectiontenantmanagement.tsx","./app/admin/tenants/sections/sectiontenantconfigreport.tsx","./app/admin/tenants/[section]/page.tsx","./components/rules/statcard.tsx","./components/rules/rulefilterbar.tsx","./components/rules/emptystate.tsx","./components/rules/formjsontoggle.tsx","./app/analyze-rules/components/analyzeruleformfields.tsx","./lib/formatinlinemarkdown.tsx","./app/analyze-rules/components/analyzerulecard.tsx","./app/analyze-rules/page.tsx","./app/audit/page.tsx","./app/changelog/layout.tsx","./app/changelog/page.tsx","./app/dashboard/components/statscards.tsx","./app/dashboard/components/welcomemessage.tsx","./app/dashboard/components/sessiontable.tsx","./app/dashboard/components/confirmationmodals.tsx","./app/dashboard/page.tsx","./app/dashboard/components/settingsmenu.tsx","./app/dashboard/components/usermenu.tsx","./app/diagnosis/[sessionid]/components/diagnosisbadges.tsx","./app/diagnosis/[sessionid]/page.tsx","./app/docs/docssidebar.tsx","./app/docs/layout.tsx","./app/docs/sections/sectionprivatepreview.tsx","./app/docs/sections/sectiongeneral.tsx","./app/docs/sections/sectionoverview.tsx","./app/docs/sections/sectionsetup.tsx","./app/docs/sections/sectionagent.tsx","./app/docs/sections/sectionagentsetup.tsx","./app/docs/sections/sectionsettings.tsx","./app/docs/sections/sectiongatherrules.tsx","./app/docs/sections/sectionanalyzerules.tsx","./app/docs/sections/sectionimelogpatterns.tsx","./app/docs/sections/sectionfaq.tsx","./app/docs/[section]/page.tsx","./app/fleet-health/components/fleetstatcard.tsx","./app/fleet-health/page.tsx","./app/gather-rules/components/gatherruleformfields.tsx","./app/gather-rules/components/gatherrulecard.tsx","./app/gather-rules/page.tsx","./node_modules/@types/geojson/index.d.ts","./node_modules/@types/leaflet/index.d.ts","./node_modules/react-leaflet/lib/hooks.d.ts","./node_modules/react-leaflet/lib/attributioncontrol.d.ts","./node_modules/@react-leaflet/core/lib/attribution.d.ts","./node_modules/@react-leaflet/core/lib/context.d.ts","./node_modules/@react-leaflet/core/lib/element.d.ts","./node_modules/@react-leaflet/core/lib/events.d.ts","./node_modules/@react-leaflet/core/lib/layer.d.ts","./node_modules/@react-leaflet/core/lib/path.d.ts","./node_modules/@react-leaflet/core/lib/circle.d.ts","./node_modules/@react-leaflet/core/lib/div-overlay.d.ts","./node_modules/@react-leaflet/core/lib/component.d.ts","./node_modules/@react-leaflet/core/lib/control.d.ts","./node_modules/@react-leaflet/core/lib/dom.d.ts","./node_modules/@react-leaflet/core/lib/generic.d.ts","./node_modules/@react-leaflet/core/lib/grid-layer.d.ts","./node_modules/@react-leaflet/core/lib/media-overlay.d.ts","./node_modules/@react-leaflet/core/lib/pane.d.ts","./node_modules/@react-leaflet/core/lib/index.d.ts","./node_modules/react-leaflet/lib/circle.d.ts","./node_modules/react-leaflet/lib/circlemarker.d.ts","./node_modules/react-leaflet/lib/layergroup.d.ts","./node_modules/react-leaflet/lib/featuregroup.d.ts","./node_modules/react-leaflet/lib/geojson.d.ts","./node_modules/react-leaflet/lib/imageoverlay.d.ts","./node_modules/react-leaflet/lib/layerscontrol.d.ts","./node_modules/react-leaflet/lib/mapcontainer.d.ts","./node_modules/react-leaflet/lib/marker.d.ts","./node_modules/react-leaflet/lib/pane.d.ts","./node_modules/react-leaflet/lib/polygon.d.ts","./node_modules/react-leaflet/lib/polyline.d.ts","./node_modules/react-leaflet/lib/popup.d.ts","./node_modules/react-leaflet/lib/rectangle.d.ts","./node_modules/react-leaflet/lib/scalecontrol.d.ts","./node_modules/react-leaflet/lib/svgoverlay.d.ts","./node_modules/react-leaflet/lib/tilelayer.d.ts","./node_modules/react-leaflet/lib/tooltip.d.ts","./node_modules/react-leaflet/lib/videooverlay.d.ts","./node_modules/react-leaflet/lib/wmstilelayer.d.ts","./node_modules/react-leaflet/lib/zoomcontrol.d.ts","./node_modules/react-leaflet/lib/index.d.ts","./app/geographic-performance/geomap.tsx","./app/geographic-performance/page.tsx","./app/geographic-performance/sessions/page.tsx","./app/health-check/page.tsx","./app/ime-log-patterns/components/imepatterncard.tsx","./app/ime-log-patterns/page.tsx","./app/preview/page.tsx","./app/privacy/layout.tsx","./app/privacy/page.tsx","./app/progress/page.tsx","./app/roadmap/layout.tsx","./app/roadmap/page.tsx","./components/performancechart.tsx","./components/downloadprogress.tsx","./components/installprogress.tsx","./components/scriptexecutions.tsx","./app/sessions/[sessionid]/components/sessioninfocard.tsx","./app/sessions/[sessionid]/components/phasetimeline.tsx","./app/sessions/[sessionid]/components/eventtimeline.tsx","./app/sessions/[sessionid]/components/analysisresultssection.tsx","./app/sessions/[sessionid]/components/vulnerabilityreportsection.tsx","./app/sessions/[sessionid]/components/adminoverridemodal.tsx","./node_modules/fflate/esm/browser.d.ts","./app/sessions/[sessionid]/components/reportsessionmodal.tsx","./app/sessions/[sessionid]/components/oobeconfigmodal.tsx","./app/sessions/[sessionid]/components/devicedetailscard.tsx","./app/sessions/[sessionid]/page.tsx","./app/sessions/[sessionid]/components/markfailedmodal.tsx","./app/settings/components/diagnosticssection.tsx","./app/settings/components/bootstrapsessionssection.tsx","./app/settings/tenantconfigcontext.tsx","./app/settings/settingspagesections.tsx","./app/settings/tenantnotifications.tsx","./app/settings/layout.tsx","./app/settings/page.tsx","./app/settings/access/accesssidebar.tsx","./app/settings/access/layout.tsx","./app/settings/access/page.tsx","./app/settings/components/adminmanagementsection.tsx","./app/settings/access/sections/sectionadminmanagement.tsx","./app/settings/access/sections/sectionbootstrapsessions.tsx","./app/settings/access/[section]/page.tsx","./app/settings/access/sections/sectionapikeys.tsx","./app/settings/agent/agentsidebar.tsx","./app/settings/agent/layout.tsx","./app/settings/agent/page.tsx","./app/settings/components/agentsettingssection.tsx","./app/settings/agent/sections/sectionagentsettings.tsx","./app/settings/components/agentanalyzerssection.tsx","./app/settings/agent/sections/sectionagentanalyzers.tsx","./app/settings/components/unrestrictedmodesection.tsx","./app/settings/agent/sections/sectionunrestrictedmode.tsx","./app/settings/agent/[section]/page.tsx","./app/settings/components/autopilotvalidationsection.tsx","./app/settings/components/datamanagementsection.tsx","./app/settings/components/hardwarewhitelistsection.tsx","./app/settings/components/notificationssection.tsx","./app/settings/components/offboardingsection.tsx","./app/settings/integrations/integrationssidebar.tsx","./app/settings/integrations/layout.tsx","./app/settings/integrations/page.tsx","./app/settings/integrations/sections/sectionnotifications.tsx","./app/settings/integrations/sections/sectiondiagnostics.tsx","./app/settings/integrations/[section]/page.tsx","./app/settings/management/managementsidebar.tsx","./app/settings/management/layout.tsx","./app/settings/management/page.tsx","./app/settings/management/sections/sectiondatamanagement.tsx","./app/settings/management/sections/sectionoffboarding.tsx","./app/settings/management/[section]/page.tsx","./app/settings/validation/validationsidebar.tsx","./app/settings/validation/layout.tsx","./app/settings/validation/page.tsx","./app/settings/validation/sections/sectionautopilotvalidation.tsx","./app/settings/validation/sections/sectionhardwarewhitelist.tsx","./app/settings/validation/[section]/page.tsx","./app/terms/layout.tsx","./app/terms/page.tsx","./app/usage-metrics/page.tsx","./node_modules/@types/estree/index.d.ts","./node_modules/@types/json-schema/index.d.ts","./node_modules/@types/json5/index.d.ts","./.next/types/routes.d.ts"],"fileIdsList":[[100,148,165,166,497],[100,148,165,166,470,792],[86,100,148,165,166,541,542,732,795,797],[100,148,165,166,798],[86,100,148,165,166,737,738,779],[100,148,165,166],[100,148,165,166,804],[86,100,148,165,166,541,542],[86,100,148,165,166,541,542,559,797,807],[86,100,148,165,166,740,794],[86,100,148,165,166,541,542,559,742,797,807],[86,100,148,165,166,541,542,559],[86,100,148,165,166,541,542,796],[86,100,148,165,166,797],[86,100,148,165,166,541,542,816],[86,100,148,165,166,480,732,798,801],[100,148,165,166,480,530,821,822],[100,148,165,166,818],[100,148,165,166,480],[86,100,148,165,166,480,541,542,543,732],[86,100,148,165,166,480,541,542,732],[100,148,165,166,798,799,811],[100,148,165,166,480,531,828,829,830],[100,148,165,166,825],[100,148,165,166,798,799,812],[100,148,165,166,798,799,813],[100,148,165,166,798,799,809],[100,148,165,166,480,532,835,836,837,838],[100,148,165,166,832],[100,148,165,166,798,799,805],[100,148,165,166,798,799,808],[100,148,165,166,798,799,815],[100,148,165,166,798,799,817],[100,148,165,166,480,533,843,844,845],[100,148,165,166,840],[100,148,165,166,798,799,806],[100,148,165,166,795,798,799],[100,148,165,166,798,799,803],[100,148,165,166,798,799,814],[100,148,165,166,480,534,851,852],[100,148,165,166,848],[86,100,148,165,166,541,542,732],[100,148,165,166,797,798],[86,100,148,165,166,535,741,857,858,859],[100,148,165,166,535],[86,100,148,165,166,470,480,535,541,542,559,574,732,735,741,773,801,854,855,856,857,858,860],[100,148,165,166,746],[86,100,148,165,166,480,541,542,543,574,732,773,801],[100,148,165,166,792],[86,100,148,165,166,480,539,559],[86,100,148,165,166],[100,148,165,166,470],[86,100,148,165,166,541,542,543],[86,100,148,165,166,541,542,543,559],[86,100,148,165,166,470,480,539,541,542,543,544,559,560,574,732,772,773,801,865,866,867,868],[100,148,165,166,538],[86,100,148,165,166,480,538,541,542,543,574,732,772,773,801,859,872],[100,148,165,166,480,497,527,876,877,878,879,880,881,882,883,884,885,886],[100,148,165,166,527,737,738,779],[100,148,165,166,497,874],[86,100,148,165,166,739],[86,100,148,165,166,480,538,541,542,543,574,732,772,773,801,888],[86,100,148,165,166,561,740,741,794,857,890],[86,100,148,165,166,561,740,794],[86,100,148,165,166,470,480,541,542,559,561,574,732,735,741,773,801,854,855,856,857,890,891],[86,100,148,165,166,934],[86,100,148,165,166,456,480,541,542,574,732,773,801,935],[86,100,148,165,166,480,541,542,574,732,773,801],[86,100,148,165,166,541,542,543,732,771,772,773],[86,100,148,165,166,563,741,857],[86,100,148,165,166,480,541,559,563,574,732,735,741,773,801,854,855,856,939],[100,148,165,166,497,543,732,737,752,772,773,774,775,776,777,778,782,783],[100,148,165,166,781,786,787,788],[86,100,148,165,166,480,541,732],[86,100,148,165,166,538,541,542,543,559,732,772,773,801],[86,100,148,165,166,538,859],[86,100,148,165,166,538,959],[86,100,148,165,166,538,566],[86,100,148,165,166,538,567],[86,100,148,165,166,538,957],[86,100,148,165,166,538],[86,100,148,165,166,538,541,542],[86,100,148,165,166,480,538,541,542,543,559,564,565,566,567,574,732,737,738,742,772,773,779,801,947,948,949,950,951,952,953,954,955,956,958,960],[100,148,165,166,480,569,974,975],[100,148,165,166,970],[100,148,165,166,965,967,973],[100,148,165,166,804,965,967],[100,148,165,166,964,965,967],[100,148,165,166,480,570,982,984,986],[100,148,165,166,978],[100,148,165,166,965,967,983],[100,148,165,166,965,967,981],[100,148,165,166,965,967,985],[100,148,165,166,568],[100,148,165,166,816],[86,100,148,165,166,568,740,794,816],[86,100,148,165,166,816],[100,148,165,166,480,571,996,997],[100,148,165,166,993],[100,148,165,166,963,965,967],[100,148,165,166,965,967,991],[86,100,148,165,166,480,732,801,965],[100,148,165,166,480,572,1002,1003],[100,148,165,166,999],[100,148,165,166,965,967,989],[100,148,165,166,965,967,992],[86,100,148,165,166,480,732],[86,100,148,165,166,737,738,779,965],[86,100,148,165,166,480,541,542,543,559,568,732,773,963,964],[100,148,165,166,965],[100,148,165,166,480,573,1008,1009],[100,148,165,166,1005],[100,148,165,166,965,967,988],[100,148,165,166,965,967,990],[100,148,165,166,497,527,528],[100,148,165,166,785],[86,100,148,165,166,559,732,773,775],[86,100,148,165,166,470,480,574,732,736,737,779,780,781],[100,148,165,166,732],[86,100,148,165,166,470,480,543,559,574,732,774,775],[100,148,165,166,470,732,775],[100,148,165,166,740],[86,100,148,165,166,541,716,730,731],[86,100,148,165,166,736],[86,100,148,165,166,541,542,559,732,771],[86,100,148,165,166,732],[100,148,165,166,574,733,734],[86,100,148,165,166,542,543,732],[86,100,148,165,166,737],[100,148,165,166,540],[100,148,165,166,558],[100,148,165,166,779],[100,148,165,166,739],[100,148,165,166,716],[100,148,165,166,497,498,1017],[100,148,165,166,672,674,675,676,678,679,681,685,686,690,691,692,693,694,695,696,697],[100,148,165,166,672,674,675,676,678,679,681,685,686,690,691,692,693,694,695,696,697,698,699],[100,148,165,166,672,674,675,676,678,679,681,685,686,690,691,692,694,695,696,698,699],[100,148,165,166,672,676],[100,148,165,166,672,674,675,676,679,681,682,683,684,685,686,687],[100,148,165,166,682],[100,148,165,166,672,681,685,689],[100,148,165,166,672,679,681,685,688,690],[100,148,165,166,672,676,678],[100,148,165,166,672],[100,148,165,166,672,702],[100,148,165,166,672,704],[100,148,165,166,672,676,694,695],[100,148,165,166,672,674,675,676,681,685,686,692,694],[100,148,165,166,672,673,674,675,676,677,678,679,680,681,682,683,685,686,689,690,691,692,693,694,695,696,697,698,699,700,701,703,705,706,707,708,709,710,711,712,713,714,715],[100,148,165,166,677],[100,148,165,166,677,678],[100,148,165,166,676],[100,148,165,166,672,673],[100,148,165,166,672,679],[100,148,165,166,674,675],[100,148,165,166,575],[100,148,165,166,577,578,579,581,582,584,588,590,604,607,613,622],[100,148,165,166,581,584,590,604,622,623],[100,148,165,166,582,585,587,589],[100,148,165,166,586],[100,148,165,166,588],[100,148,165,166,583],[100,148,165,166,584,590,592,593,594,595,596,597,598,599,600,601,604,617,618,619,621,622],[100,148,165,166,583,591],[100,148,165,166,575,577,584,597,618,623],[100,148,165,166,592,593,594,595,619],[100,148,165,166,591],[100,148,165,166,592,593,594,595,596,597,598,599,600,601,619,621],[100,148,165,166,610],[100,148,165,166,609],[100,148,165,166,578,583,588,591,592,593,594,595,600],[100,148,165,166,583,592,593,594,595,597,598,599,600,619,620],[100,148,165,166,604,613,627,633,634,635,636,637,638],[100,148,165,166,580,581,584,604,605,608,613,617,618,623,630,631,632],[100,148,165,166,604,613,633,636,640,641],[100,148,165,166,583,604,613,633,636,641],[100,148,165,166,581,584,590,605,608,609,611,612,618,623],[100,148,165,166,616,617],[100,148,165,166,584,604,618],[100,148,165,166,615],[100,148,165,166,651],[100,148,165,166,657],[100,148,165,166,652,659],[100,148,165,166,652,661],[100,148,165,166,652,653],[100,148,165,166,652],[100,148,165,166,602,603,604,615,616,667,668,669,670],[100,148,165,166,575,576,577,579,580,581,582,583,584,585,586,587,590,591,592,593,594,595,596,597,598,599,600,601,605,606,608,613,614,617,618,619,620,621,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,652,654,655,656,658,660,662,663,664,665],[100,148,165,166,666,671],[100,148,165,166,613],[100,148,165,166,580],[100,148,165,166,583,616],[100,148,165,166,580,605,617,630,631],[100,148,165,166,583,601,613,614,616],[100,148,165,166,614,617,632],[100,148,165,166,583,597,614,617],[100,148,165,166,597,614],[100,148,165,166,597,614,617],[100,148,165,166,583,604,608,613,614,644],[100,148,165,166,597],[100,148,165,166,630],[100,148,165,166,575,584,596,604,605,609,611,617,618,619,623,627,630,636,638,648],[100,148,165,166,602,603],[100,148,165,166,584,602,603,604,613],[100,148,165,166,602,603,604],[100,148,165,166,583,598,605,606,607],[100,148,165,166,579],[100,148,165,166,584,604],[100,148,165,166,618],[100,148,165,166,627],[86,100,148,165,166,719],[86,100,148,165,166,716,717,719,720],[86,100,148,165,166,717,724],[100,148,165,166,716,719],[100,148,165,166,719],[100,148,165,166,717],[100,148,165,166,717,718,719,720,721,722,723,724,725,726,727,728,729],[86,100,148,165,166,716],[86,100,148,165,166,716,719],[100,148,165,166,551,552],[100,148,165,166,550,551,552],[100,148,165,166,551],[100,148,165,166,545,549,550],[100,148,165,166,545,546,547,548],[100,148,165,166,550,551,552,553,554,555,556,557],[100,148,165,166,756,758],[100,148,165,166,754],[100,148,165,166,753,757],[100,148,165,166,762],[100,148,165,166,754,756,757,760,761,763,764],[100,148,165,166,754,756,757,758],[100,148,165,166,754,756],[100,148,165,166,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,770],[100,148,165,166,754,756,757],[100,148,165,166,756],[100,148,165,166,756,758,760,762,768,769],[100,148,165,166,894],[86,100,148,165,166,894,902],[86,100,148,165,166,899,904],[86,100,148,165,166,894],[100,148,165,166,894,899],[100,148,165,166,894,898,899,901],[86,100,148,165,166,898],[86,100,148,165,166,894,898,899,901,902,904,905],[100,148,165,166,897,898,899,900,901,902,903,904,905,906,907,908,909,910,911],[100,148,165,166,894,898,899,900],[100,148,165,166,894,901],[100,148,165,166,894,898],[100,148,165,166,894,899,901],[100,148,165,166,893],[100,145,146,148,165,166],[100,147,148,165,166],[148,165,166],[100,148,153,165,166,183],[100,148,149,154,159,165,166,168,180,191],[100,148,149,150,159,165,166,168],[95,96,97,100,148,165,166],[100,148,151,165,166,192],[100,148,152,153,160,165,166,169],[100,148,153,165,166,180,188],[100,148,154,156,159,165,166,168],[100,147,148,155,165,166],[100,148,156,157,165,166],[100,148,158,159,165,166],[100,147,148,159,165,166],[100,148,159,160,161,165,166,180,191],[100,148,159,160,161,165,166,175,180,183],[100,141,148,156,159,162,165,166,168,180,191],[100,148,159,160,162,163,165,166,168,180,188,191],[100,148,162,164,165,166,180,188,191],[98,99,100,101,102,103,104,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197],[100,148,159,165,166],[100,148,165,166,167,191],[100,148,156,159,165,166,168,180],[100,148,165,166,169],[100,148,165,166,170],[100,147,148,165,166,171],[100,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197],[100,148,165,166,173],[100,148,165,166,174],[100,148,159,165,166,175,176],[100,148,165,166,175,177,192,194],[100,148,160,165,166],[100,148,159,165,166,180,181,183],[100,148,165,166,182,183],[100,148,165,166,180,181],[100,148,165,166,183],[100,148,165,166,184],[100,145,148,165,166,180,185,191],[100,148,159,165,166,186,187],[100,148,165,166,186,187],[100,148,153,165,166,168,180,188],[100,148,165,166,189],[100,148,165,166,168,190],[100,148,162,165,166,174,191],[100,148,153,165,166,192],[100,148,165,166,180,193],[100,148,165,166,167,194],[100,148,165,166,195],[100,141,148,165,166],[100,141,148,159,161,165,166,171,180,183,191,193,194,196],[100,148,165,166,180,197],[86,100,148,165,166,201,202,203,357],[86,100,148,165,166,201,202],[86,100,148,165,166,202,357],[86,90,100,148,165,166,200,441,489],[86,90,100,148,165,166,199,441,489],[83,84,85,100,148,165,166],[92,100,148,165,166],[100,148,165,166,444],[100,148,165,166,446,447,448,449],[100,148,165,166,451],[100,148,165,166,207,221,222,223,225,438],[100,148,165,166,207,246,248,250,251,254,438,440],[100,148,165,166,207,211,213,214,215,216,217,427,438,440],[100,148,165,166,438],[100,148,165,166,222,324,408,417,434],[100,148,165,166,207],[100,148,165,166,204,434],[100,148,165,166,258],[100,148,165,166,257,438,440],[100,148,162,165,166,306,324,353,495],[100,148,162,165,166,317,333,417,433],[100,148,162,165,166,369],[100,148,165,166,421],[100,148,165,166,420,421,422],[100,148,165,166,420],[94,100,148,162,165,166,204,207,211,214,218,219,220,222,226,234,235,362,387,418,438,441],[100,148,165,166,207,224,242,246,247,252,253,438,495],[100,148,165,166,224,495],[100,148,165,166,235,242,304,438,495],[100,148,165,166,495],[100,148,165,166,207,224,225,495],[100,148,165,166,249,495],[100,148,165,166,218,419,426],[100,148,165,166,174,266,434],[100,148,165,166,266,434],[86,100,148,165,166,266],[86,100,148,165,166,325],[100,148,165,166,321,367,434,477,478],[100,148,165,166,414,471,472,473,474,476],[100,148,165,166,413],[100,148,165,166,413,414],[100,148,165,166,215,363,364,365],[100,148,165,166,363,366,367],[100,148,165,166,475],[100,148,165,166,363,367],[86,100,148,165,166,208,465],[86,100,148,165,166,191],[86,100,148,165,166,224,294],[86,100,148,165,166,224],[100,148,165,166,292,296],[86,100,148,165,166,293,443],[100,148,165,166,750],[86,100,148,165,166,489],[86,100,148,165,166,180,198,489,743],[86,90,100,148,162,165,166,198,199,200,441,487,488],[100,148,162,165,166],[100,148,162,165,166,211,273,363,373,388,408,423,424,438,439,495],[100,148,165,166,234,425],[100,148,165,166,441],[100,148,165,166,206],[86,100,148,165,166,306,320,332,342,344,433],[100,148,165,166,174,306,320,341,342,343,433,494],[100,148,165,166,335,336,337,338,339,340],[100,148,165,166,337],[100,148,165,166,341],[100,148,165,166,264,265,266,268],[86,100,148,165,166,259,260,261,267],[100,148,165,166,264,267],[100,148,165,166,262],[100,148,165,166,263],[86,100,148,165,166,266,293,443],[86,100,148,165,166,266,442,443],[86,100,148,165,166,266,443],[100,148,165,166,388,430],[100,148,165,166,430],[100,148,162,165,166,439,443],[100,148,165,166,329],[100,147,148,165,166,328],[100,148,165,166,236,274,312,314,316,317,318,319,360,363,433,436,439],[100,148,165,166,236,350,363,367],[100,148,165,166,317,433],[86,100,148,165,166,317,326,327,329,330,331,332,333,334,345,346,347,348,349,351,352,433,434,495],[100,148,165,166,311],[100,148,162,165,166,174,236,237,273,288,318,360,361,362,367,388,408,429,438,439,440,441,495],[100,148,165,166,433],[100,147,148,165,166,222,315,318,362,429,431,432,439],[100,148,165,166,317],[100,147,148,165,166,273,278,307,308,309,310,311,312,313,314,316,433,434],[100,148,162,165,166,278,279,307,439,440],[100,148,165,166,222,362,363,388,429,433,439],[100,148,162,165,166,438,440],[100,148,162,165,166,180,436,439,440],[100,148,162,165,166,174,191,204,211,224,236,237,239,274,275,280,285,288,314,318,363,373,375,378,380,383,384,385,386,387,408,428,429,434,436,438,439,440],[100,148,162,165,166,180],[100,148,165,166,207,208,209,211,216,219,224,242,428,436,437,441,443,495],[100,148,162,165,166,180,191,254,256,258,259,260,261,268,495],[100,148,165,166,174,191,204,246,256,284,285,286,287,314,363,378,387,388,394,397,398,408,429,434,436],[100,148,165,166,218,219,234,362,387,429,438],[100,148,162,165,166,191,208,211,314,392,436,438],[100,148,165,166,305],[100,148,162,165,166,395,396,405],[100,148,165,166,436,438],[100,148,165,166,312,315],[100,148,165,166,314,318,428,443],[100,148,162,165,166,174,240,246,287,378,388,394,397,400,436],[100,148,162,165,166,218,234,246,401],[100,148,165,166,207,239,403,428,438],[100,148,162,165,166,191,438],[100,148,162,165,166,224,238,239,240,251,269,402,404,428,438],[94,100,148,165,166,236,318,407,441,443],[100,148,162,165,166,174,191,211,218,226,234,237,274,280,284,285,286,287,288,314,363,375,388,389,391,393,408,428,429,434,435,436,443],[100,148,162,165,166,180,218,394,399,405,436],[100,148,165,166,229,230,231,232,233],[100,148,165,166,275,379],[100,148,165,166,381],[100,148,165,166,379],[100,148,165,166,381,382],[100,148,165,166,744],[100,148,162,165,166,211,214,215,273,439],[100,148,162,165,166,174,206,208,236,274,288,318,371,372,408,436,440,441,443],[100,148,162,165,166,174,191,210,215,314,372,435,439],[100,148,165,166,307],[100,148,165,166,308],[100,148,165,166,309],[100,148,165,166,434],[100,148,165,166,255,271],[100,148,162,165,166,211,255,274],[100,148,165,166,270,271],[100,148,165,166,272],[100,148,165,166,255,256],[100,148,165,166,255,289],[100,148,165,166,255],[100,148,165,166,275,377,435],[100,148,165,166,376],[100,148,165,166,256,434,435],[100,148,165,166,374,435],[100,148,165,166,256,434],[100,148,165,166,360],[100,148,165,166,211,216,274,303,306,312,314,318,320,323,354,356,359,363,407,428,436,439],[100,148,165,166,297,300,301,302,321,322,367],[86,100,148,165,166,201,202,203,266,355],[86,100,148,165,166,201,202,203,266,355,358],[100,148,165,166,416],[100,148,165,166,222,279,317,318,329,333,363,407,409,410,411,412,414,415,418,428,433,438],[100,148,165,166,367],[100,148,165,166,371],[100,148,162,165,166,274,290,368,370,373,407,436,441,443],[100,148,165,166,297,298,299,300,301,302,321,322,367,442],[94,100,148,162,165,166,174,191,237,255,256,288,314,318,405,406,408,428,429,438,439,441],[100,148,165,166,279,281,284,429],[100,148,162,165,166,275,438],[100,148,165,166,278,317],[100,148,165,166,277],[100,148,165,166,279,280],[100,148,165,166,276,278,438],[100,148,162,165,166,210,279,281,282,283,438,439],[86,100,148,165,166,363,364,366],[100,148,165,166,241],[86,100,148,165,166,208],[86,100,148,165,166,434],[86,94,100,148,165,166,288,318,441,443],[100,148,165,166,208,465,466],[86,100,148,165,166,296],[86,100,148,165,166,174,191,206,253,291,293,295,443],[100,148,165,166,224,434,439],[100,148,165,166,390,434],[100,148,165,166,363],[86,100,148,160,162,165,166,174,206,242,248,296,441,442],[86,100,148,165,166,199,200,441,489],[86,87,88,89,90,100,148,165,166],[100,148,153,165,166],[100,148,165,166,243,244,245],[100,148,165,166,243],[86,90,100,148,162,164,165,166,174,198,199,200,201,203,204,206,237,341,400,438,440,443,489],[100,148,165,166,453],[100,148,165,166,455],[100,148,165,166,457],[100,148,165,166,751],[100,148,165,166,459],[100,148,165,166,461,462,463],[100,148,165,166,467],[91,93,100,148,165,166,445,450,452,454,456,458,460,464,468,470,480,481,483,493,494,495,496],[100,148,165,166,469],[100,148,165,166,479],[100,148,165,166,745],[100,148,165,166,293],[100,148,165,166,482],[100,147,148,165,166,279,281,282,284,332,434,484,485,486,489,490,491,492],[100,148,165,166,198],[100,148,165,166,516],[100,148,165,166,514,516],[100,148,165,166,505,513,514,515,517,519],[100,148,165,166,503],[100,148,165,166,506,511,516,519],[100,148,165,166,502,519],[100,148,165,166,506,507,510,511,512,519],[100,148,165,166,506,507,508,510,511,519],[100,148,165,166,503,504,505,506,507,511,512,513,515,516,517,519],[100,148,165,166,519],[100,148,165,166,501,503,504,505,506,507,508,510,511,512,513,514,515,516,517,518],[100,148,165,166,501,519],[100,148,165,166,506,508,509,511,512,519],[100,148,165,166,510,519],[100,148,165,166,511,512,516,519],[100,148,165,166,504,514],[86,100,148,165,166,894,912],[86,100,148,165,166,894,912,915],[86,100,148,165,166,893,894,912,915],[100,148,165,166,895,896,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,930,931,932,933],[86,100,148,165,166,893,894,912],[100,148,165,166,180,198],[100,148,165,166,521,522],[100,148,165,166,520,523],[100,113,117,148,165,166,191],[100,113,148,165,166,180,191],[100,108,148,165,166],[100,110,113,148,165,166,188,191],[100,148,165,166,168,188],[100,108,148,165,166,198],[100,110,113,148,165,166,168,191],[100,105,106,109,112,148,159,165,166,180,191],[100,113,120,148,165,166],[100,105,111,148,165,166],[100,113,134,135,148,165,166],[100,109,113,148,165,166,183,191,198],[100,134,148,165,166,198],[100,107,108,148,165,166,198],[100,113,148,165,166],[100,107,108,109,110,111,112,113,114,115,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,135,136,137,138,139,140,148,165,166],[100,113,128,148,165,166],[100,113,120,121,148,165,166],[100,111,113,121,122,148,165,166],[100,112,148,165,166],[100,105,108,113,148,165,166],[100,113,117,121,122,148,165,166],[100,117,148,165,166],[100,111,113,116,148,165,166,191],[100,105,110,113,120,148,165,166],[100,148,165,166,180],[100,108,113,134,148,165,166,196,198],[100,148,165,166,524],[100,148,165,166,536,537]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"27bdc30a0e32783366a5abeda841bc22757c1797de8681bbe81fbc735eeb1c10","impliedFormat":1},{"version":"8fd575e12870e9944c7e1d62e1f5a73fcf23dd8d3a321f2a2c74c20d022283fe","impliedFormat":1},{"version":"2ab096661c711e4a81cc464fa1e6feb929a54f5340b46b0a07ac6bbf857471f0","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2e80ee7a49e8ac312cc11b77f1475804bee36b3b2bc896bead8b6e1266befb43","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"df83c2a6c73228b625b0beb6669c7ee2a09c914637e2d35170723ad49c0f5cd4","affectsGlobalScope":true,"impliedFormat":1},{"version":"436aaf437562f276ec2ddbee2f2cdedac7664c1e4c1d2c36839ddd582eeb3d0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e3c06ea092138bf9fa5e874a1fdbc9d54805d074bee1de31b99a11e2fec239d","affectsGlobalScope":true,"impliedFormat":1},{"version":"87dc0f382502f5bbce5129bdc0aea21e19a3abbc19259e0b43ae038a9fc4e326","affectsGlobalScope":true,"impliedFormat":1},{"version":"b1cb28af0c891c8c96b2d6b7be76bd394fddcfdb4709a20ba05a7c1605eea0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"2fef54945a13095fdb9b84f705f2b5994597640c46afeb2ce78352fab4cb3279","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac77cb3e8c6d3565793eb90a8373ee8033146315a3dbead3bde8db5eaf5e5ec6","affectsGlobalScope":true,"impliedFormat":1},{"version":"56e4ed5aab5f5920980066a9409bfaf53e6d21d3f8d020c17e4de584d29600ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ece9f17b3866cc077099c73f4983bddbcb1dc7ddb943227f1ec070f529dedd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a6282c8827e4b9a95f4bf4f5c205673ada31b982f50572d27103df8ceb8013c","affectsGlobalScope":true,"impliedFormat":1},{"version":"1c9319a09485199c1f7b0498f2988d6d2249793ef67edda49d1e584746be9032","affectsGlobalScope":true,"impliedFormat":1},{"version":"e3a2a0cee0f03ffdde24d89660eba2685bfbdeae955a6c67e8c4c9fd28928eeb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811c71eee4aa0ac5f7adf713323a5c41b0cf6c4e17367a34fbce379e12bbf0a4","affectsGlobalScope":true,"impliedFormat":1},{"version":"51ad4c928303041605b4d7ae32e0c1ee387d43a24cd6f1ebf4a2699e1076d4fa","affectsGlobalScope":true,"impliedFormat":1},{"version":"60037901da1a425516449b9a20073aa03386cce92f7a1fd902d7602be3a7c2e9","affectsGlobalScope":true,"impliedFormat":1},{"version":"d4b1d2c51d058fc21ec2629fff7a76249dec2e36e12960ea056e3ef89174080f","affectsGlobalScope":true,"impliedFormat":1},{"version":"22adec94ef7047a6c9d1af3cb96be87a335908bf9ef386ae9fd50eeb37f44c47","affectsGlobalScope":true,"impliedFormat":1},{"version":"196cb558a13d4533a5163286f30b0509ce0210e4b316c56c38d4c0fd2fb38405","affectsGlobalScope":true,"impliedFormat":1},{"version":"73f78680d4c08509933daf80947902f6ff41b6230f94dd002ae372620adb0f60","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5239f5c01bcfa9cd32f37c496cf19c61d69d37e48be9de612b541aac915805b","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb5b19b86227ace1d29ea4cf81387279d04bb34051e944bc53df69f58914b788","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"87d9d29dbc745f182683f63187bf3d53fd8673e5fca38ad5eaab69798ed29fbc","impliedFormat":1},{"version":"035312d4945d13efa134ae482f6dc56a1a9346f7ac3be7ccbad5741058ce87f3","affectsGlobalScope":true,"impliedFormat":1},{"version":"acd8fd5090ac73902278889c38336ff3f48af6ba03aa665eb34a75e7ba1dccc4","impliedFormat":1},{"version":"d6258883868fb2680d2ca96bc8b1352cab69874581493e6d52680c5ffecdb6cc","impliedFormat":1},{"version":"1b61d259de5350f8b1e5db06290d31eaebebc6baafd5f79d314b5af9256d7153","impliedFormat":1},{"version":"f258e3960f324a956fc76a3d3d9e964fff2244ff5859dcc6ce5951e5413ca826","impliedFormat":1},{"version":"643f7232d07bf75e15bd8f658f664d6183a0efaca5eb84b48201c7671a266979","impliedFormat":1},{"version":"0f6666b58e9276ac3a38fdc80993d19208442d6027ab885580d93aec76b4ef00","impliedFormat":1},{"version":"05fd364b8ef02fb1e174fbac8b825bdb1e5a36a016997c8e421f5fab0a6da0a0","impliedFormat":1},{"version":"631eff75b0e35d1b1b31081d55209abc43e16b49426546ab5a9b40bdd40b1f60","impliedFormat":1},{"version":"6c7176368037af28cb72f2392010fa1cef295d6d6744bca8cfb54985f3a18c3e","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"437e20f2ba32abaeb7985e0afe0002de1917bc74e949ba585e49feba65da6ca1","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"98cffbf06d6bab333473c70a893770dbe990783904002c4f1a960447b4b53dca","affectsGlobalScope":true,"impliedFormat":1},{"version":"3af97acf03cc97de58a3a4bc91f8f616408099bc4233f6d0852e72a8ffb91ac9","affectsGlobalScope":true,"impliedFormat":1},{"version":"808069bba06b6768b62fd22429b53362e7af342da4a236ed2d2e1c89fcca3b4a","affectsGlobalScope":true,"impliedFormat":1},{"version":"1db0b7dca579049ca4193d034d835f6bfe73096c73663e5ef9a0b5779939f3d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"9798340ffb0d067d69b1ae5b32faa17ab31b82466a3fc00d8f2f2df0c8554aaa","affectsGlobalScope":true,"impliedFormat":1},{"version":"f26b11d8d8e4b8028f1c7d618b22274c892e4b0ef5b3678a8ccbad85419aef43","affectsGlobalScope":true,"impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"b52476feb4a0cbcb25e5931b930fc73cb6643fb1a5060bf8a3dda0eeae5b4b68","affectsGlobalScope":true,"impliedFormat":1},{"version":"f9501cc13ce624c72b61f12b3963e84fad210fbdf0ffbc4590e08460a3f04eba","affectsGlobalScope":true,"impliedFormat":1},{"version":"e7721c4f69f93c91360c26a0a84ee885997d748237ef78ef665b153e622b36c1","affectsGlobalScope":true,"impliedFormat":1},{"version":"0fa06ada475b910e2106c98c68b10483dc8811d0c14a8a8dd36efb2672485b29","impliedFormat":1},{"version":"33e5e9aba62c3193d10d1d33ae1fa75c46a1171cf76fef750777377d53b0303f","impliedFormat":1},{"version":"2b06b93fd01bcd49d1a6bd1f9b65ddcae6480b9a86e9061634d6f8e354c1468f","impliedFormat":1},{"version":"6a0cd27e5dc2cfbe039e731cf879d12b0e2dded06d1b1dedad07f7712de0d7f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"13f5c844119c43e51ce777c509267f14d6aaf31eafb2c2b002ca35584cd13b29","impliedFormat":1},{"version":"e60477649d6ad21542bd2dc7e3d9ff6853d0797ba9f689ba2f6653818999c264","impliedFormat":1},{"version":"c2510f124c0293ab80b1777c44d80f812b75612f297b9857406468c0f4dafe29","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4c829ab315f57c5442c6667b53769975acbf92003a66aef19bce151987675bd1","affectsGlobalScope":true,"impliedFormat":1},{"version":"b2ade7657e2db96d18315694789eff2ddd3d8aea7215b181f8a0b303277cc579","impliedFormat":1},{"version":"9855e02d837744303391e5623a531734443a5f8e6e8755e018c41d63ad797db2","impliedFormat":1},{"version":"4d631b81fa2f07a0e63a9a143d6a82c25c5f051298651a9b69176ba28930756d","impliedFormat":1},{"version":"836a356aae992ff3c28a0212e3eabcb76dd4b0cc06bcb9607aeef560661b860d","impliedFormat":1},{"version":"1e0d1f8b0adfa0b0330e028c7941b5a98c08b600efe7f14d2d2a00854fb2f393","impliedFormat":1},{"version":"41670ee38943d9cbb4924e436f56fc19ee94232bc96108562de1a734af20dc2c","affectsGlobalScope":true,"impliedFormat":1},{"version":"c906fb15bd2aabc9ed1e3f44eb6a8661199d6c320b3aa196b826121552cb3695","impliedFormat":1},{"version":"22295e8103f1d6d8ea4b5d6211e43421fe4564e34d0dd8e09e520e452d89e659","impliedFormat":1},{"version":"f949f7f6c7802a338039cfc2156d1fe285cdd1e092c64437ebe15ae8edc854e0","impliedFormat":1},{"version":"6b4e081d55ac24fc8a4631d5dd77fe249fa25900abd7d046abb87d90e3b45645","impliedFormat":1},{"version":"a10f0e1854f3316d7ee437b79649e5a6ae3ae14ffe6322b02d4987071a95362e","impliedFormat":1},{"version":"e208f73ef6a980104304b0d2ca5f6bf1b85de6009d2c7e404028b875020fa8f2","impliedFormat":1},{"version":"d163b6bc2372b4f07260747cbc6c0a6405ab3fbcea3852305e98ac43ca59f5bc","impliedFormat":1},{"version":"e6fa9ad47c5f71ff733744a029d1dc472c618de53804eae08ffc243b936f87ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"83e63d6ccf8ec004a3bb6d58b9bb0104f60e002754b1e968024b320730cc5311","impliedFormat":1},{"version":"24826ed94a78d5c64bd857570fdbd96229ad41b5cb654c08d75a9845e3ab7dde","impliedFormat":1},{"version":"8b479a130ccb62e98f11f136d3ac80f2984fdc07616516d29881f3061f2dd472","impliedFormat":1},{"version":"928af3d90454bf656a52a48679f199f64c1435247d6189d1caf4c68f2eaf921f","affectsGlobalScope":true,"impliedFormat":1},{"version":"d2bc7425ef40526650d6db7e072c1ff4a51101c3ac2cc4b666623b19496a6e27","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f16a7e4deafa527ed9995a772bb380eb7d3c2c0fd4ae178c5263ed18394db2c","impliedFormat":1},{"version":"933921f0bb0ec12ef45d1062a1fc0f27635318f4d294e4d99de9a5493e618ca2","impliedFormat":1},{"version":"71a0f3ad612c123b57239a7749770017ecfe6b66411488000aba83e4546fde25","impliedFormat":1},{"version":"77fbe5eecb6fac4b6242bbf6eebfc43e98ce5ccba8fa44e0ef6a95c945ff4d98","impliedFormat":1},{"version":"4f9d8ca0c417b67b69eeb54c7ca1bedd7b56034bb9bfd27c5d4f3bc4692daca7","impliedFormat":1},{"version":"814118df420c4e38fe5ae1b9a3bafb6e9c2aa40838e528cde908381867be6466","impliedFormat":1},{"version":"a3fc63c0d7b031693f665f5494412ba4b551fe644ededccc0ab5922401079c95","impliedFormat":1},{"version":"f27524f4bef4b6519c604bdb23bf4465bddcccbf3f003abb901acbd0d7404d99","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"45650f47bfb376c8a8ed39d4bcda5902ab899a3150029684ee4c10676d9fbaee","impliedFormat":1},{"version":"6b039f55681caaf111d5eb84d292b9bee9e0131d0db1ad0871eef0964f533c73","affectsGlobalScope":true,"impliedFormat":1},{"version":"18fd40412d102c5564136f29735e5d1c3b455b8a37f920da79561f1fde068208","impliedFormat":1},{"version":"c8d3e5a18ba35629954e48c4cc8f11dc88224650067a172685c736b27a34a4dc","impliedFormat":1},{"version":"f0be1b8078cd549d91f37c30c222c2a187ac1cf981d994fb476a1adc61387b14","affectsGlobalScope":true,"impliedFormat":1},{"version":"0aaed1d72199b01234152f7a60046bc947f1f37d78d182e9ae09c4289e06a592","impliedFormat":1},{"version":"0dba70b3fb0dcd713fda33c2df64fa6751fff6460e536971cee917260fb17882","impliedFormat":1},{"version":"66ba1b2c3e3a3644a1011cd530fb444a96b1b2dfe2f5e837a002d41a1a799e60","impliedFormat":1},{"version":"7e514f5b852fdbc166b539fdd1f4e9114f29911592a5eb10a94bb3a13ccac3c4","impliedFormat":1},{"version":"5b7aa3c4c1a5d81b411e8cb302b45507fea9358d3569196b27eb1a27ae3a90ef","affectsGlobalScope":true,"impliedFormat":1},{"version":"5987a903da92c7462e0b35704ce7da94d7fdc4b89a984871c0e2b87a8aae9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"ea08a0345023ade2b47fbff5a76d0d0ed8bff10bc9d22b83f40858a8e941501c","impliedFormat":1},{"version":"47613031a5a31510831304405af561b0ffaedb734437c595256bb61a90f9311b","impliedFormat":1},{"version":"ae062ce7d9510060c5d7e7952ae379224fb3f8f2dd74e88959878af2057c143b","impliedFormat":1},{"version":"8a1a0d0a4a06a8d278947fcb66bf684f117bf147f89b06e50662d79a53be3e9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"9f663c2f91127ef7024e8ca4b3b4383ff2770e5f826696005de382282794b127","impliedFormat":1},{"version":"9f55299850d4f0921e79b6bf344b47c420ce0f507b9dcf593e532b09ea7eeea1","impliedFormat":1},{"version":"f9fd93190acb1ffe0bc0fb395df979452f8d625071e9ffc8636e4dfb86ab2508","impliedFormat":1},{"version":"5f41fd8732a89e940c58ce22206e3df85745feb8983e2b4c6257fb8cbb118493","impliedFormat":1},{"version":"17ed71200119e86ccef2d96b73b02ce8854b76ad6bd21b5021d4269bec527b5f","impliedFormat":1},{"version":"1cfa8647d7d71cb03847d616bd79320abfc01ddea082a49569fda71ac5ece66b","impliedFormat":1},{"version":"bb7a61dd55dc4b9422d13da3a6bb9cc5e89be888ef23bbcf6558aa9726b89a1c","impliedFormat":1},{"version":"413df52d4ea14472c2fa5bee62f7a40abd1eb49be0b9722ee01ee4e52e63beb2","impliedFormat":1},{"version":"db6d2d9daad8a6d83f281af12ce4355a20b9a3e71b82b9f57cddcca0a8964a96","impliedFormat":1},{"version":"829b9e6028b29e6a8b1c01ddb713efe59da04d857089298fa79acbdb3cfcfdef","impliedFormat":1},{"version":"24f8562308dd8ba6013120557fa7b44950b619610b2c6cb8784c79f11e3c4f90","impliedFormat":1},{"version":"5d8717b437b9d6afeb4da84b9082db35cafce3dfd025bc7c9ad7abbe50fa2778","impliedFormat":1},{"version":"a86f82d646a739041d6702101afa82dcb935c416dd93cbca7fd754fd0282ce1f","impliedFormat":1},{"version":"ad0d1d75d129b1c80f911be438d6b61bfa8703930a8ff2be2f0e1f8a91841c64","impliedFormat":1},{"version":"ce75b1aebb33d510ff28af960a9221410a3eaf7f18fc5f21f9404075fba77256","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"496bbf339f3838c41f164238543e9fe5f1f10659cb30b68903851618464b98ba","impliedFormat":1},{"version":"5178eb4415a172c287c711dc60a619e110c3fd0b7de01ed0627e51a5336aa09c","impliedFormat":1},{"version":"ca6e5264278b53345bc1ce95f42fb0a8b733a09e3d6479c6ccfca55cdc45038c","impliedFormat":1},{"version":"9e2739b32f741859263fdba0244c194ca8e96da49b430377930b8f721d77c000","impliedFormat":1},{"version":"fb1d8e814a3eeb5101ca13515e0548e112bd1ff3fb358ece535b93e94adf5a3a","impliedFormat":1},{"version":"ffa495b17a5ef1d0399586b590bd281056cee6ce3583e34f39926f8dcc6ecdb5","impliedFormat":1},{"version":"98b18458acb46072947aabeeeab1e410f047e0cacc972943059ca5500b0a5e95","impliedFormat":1},{"version":"361e2b13c6765d7f85bb7600b48fde782b90c7c41105b7dab1f6e7871071ba20","impliedFormat":1},{"version":"c86fe861cf1b4c46a0fb7d74dffe596cf679a2e5e8b1456881313170f092e3fa","impliedFormat":1},{"version":"b6db56e4903e9c32e533b78ac85522de734b3d3a8541bf24d256058d464bf04b","impliedFormat":1},{"version":"24daa0366f837d22c94a5c0bad5bf1fd0f6b29e1fae92dc47c3072c3fdb2fbd5","impliedFormat":1},{"version":"570bb5a00836ffad3e4127f6adf581bfc4535737d8ff763a4d6f4cc877e60d98","impliedFormat":1},{"version":"889c00f3d32091841268f0b994beba4dceaa5df7573be12c2c829d7c5fbc232c","impliedFormat":1},{"version":"65f43099ded6073336e697512d9b80f2d4fec3182b7b2316abf712e84104db00","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"acf5a2ac47b59ca07afa9abbd2b31d001bf7448b041927befae2ea5b1951d9f9","impliedFormat":1},{"version":"8e609bb71c20b858c77f0e9f90bb1319db8477b13f9f965f1a1e18524bf50881","impliedFormat":1},{"version":"d71291eff1e19d8762a908ba947e891af44749f3a2cbc5bd2ec4b72f72ea795f","impliedFormat":1},{"version":"c0480e03db4b816dff2682b347c95f2177699525c54e7e6f6aa8ded890b76be7","impliedFormat":1},{"version":"27ab780875bcbb65e09da7496f2ca36288b0c541abaa75c311450a077d54ec15","impliedFormat":1},{"version":"b620391fe8060cf9bedc176a4d01366e6574d7a71e0ac0ab344a4e76576fcbb8","impliedFormat":1},{"version":"380647d8f3b7f852cca6d154a376dbf8ac620a2f12b936594504a8a852e71d2f","impliedFormat":1},{"version":"208c9af9429dd3c76f5927b971263174aaa4bc7621ddec63f163640cbd3c473c","impliedFormat":1},{"version":"6459054aabb306821a043e02b89d54da508e3a6966601a41e71c166e4ea1474f","impliedFormat":1},{"version":"a23185bc5ef590c287c28a91baf280367b50ae4ea40327366ad01f6f4a8edbc5","impliedFormat":1},{"version":"bb37588926aba35c9283fe8d46ebf4e79ffe976343105f5c6d45f282793352b2","impliedFormat":1},{"version":"002eae065e6960458bda3cf695e578b0d1e2785523476f8a9170b103c709cd4f","impliedFormat":1},{"version":"c83bb0c9c5645a46c68356c2f73fdc9de339ce77f7f45a954f560c7e0b8d5ebb","impliedFormat":1},{"version":"05c97cddbaf99978f83d96de2d8af86aded9332592f08ce4a284d72d0952c391","impliedFormat":1},{"version":"72179f9dd22a86deaad4cc3490eb0fe69ee084d503b686985965654013f1391b","impliedFormat":1},{"version":"2e6114a7dd6feeef85b2c80120fdbfb59a5529c0dcc5bfa8447b6996c97a69f5","impliedFormat":1},{"version":"7b6ff760c8a240b40dab6e4419b989f06a5b782f4710d2967e67c695ef3e93c4","impliedFormat":1},{"version":"c8f004e6036aa1c764ad4ec543cf89a5c1893a9535c80ef3f2b653e370de45e6","impliedFormat":1},{"version":"dd80b1e600d00f5c6a6ba23f455b84a7db121219e68f89f10552c54ba46e4dc9","impliedFormat":1},{"version":"b064c36f35de7387d71c599bfcf28875849a1dbc733e82bd26cae3d1cd060521","impliedFormat":1},{"version":"6a148329edecbda07c21098639ef4254ef7869fb25a69f58e5d6a8b7b69d4236","impliedFormat":1},{"version":"8de9fe97fa9e00ec00666fa77ab6e91b35d25af8ca75dabcb01e14ad3299b150","impliedFormat":1},{"version":"f63ab283a1c8f5c79fabe7ca4ef85f9633339c4f0e822fce6a767f9d59282af2","impliedFormat":1},{"version":"dba114fb6a32b355a9cfc26ca2276834d72fe0e94cd2c3494005547025015369","impliedFormat":1},{"version":"a54c996c8870ef1728a2c1fa9b8eaec0bf4a8001cd2583c02dd5869289465b10","impliedFormat":1},{"version":"3e7efde639c6a6c3edb9847b3f61e308bf7a69685b92f665048c45132f51c218","impliedFormat":1},{"version":"df45ca1176e6ac211eae7ddf51336dc075c5314bc5c253651bae639defd5eec5","impliedFormat":1},{"version":"3754982006a3b32c502cff0867ca83584f7a43b1035989ca73603f400de13c96","impliedFormat":1},{"version":"a30ae9bb8a8fa7b90f24b8a0496702063ae4fe75deb27da731ed4a03b2eb6631","impliedFormat":1},{"version":"f974e4a06953682a2c15d5bd5114c0284d5abf8bc0fe4da25cb9159427b70072","impliedFormat":1},{"version":"50256e9c31318487f3752b7ac12ff365c8949953e04568009c8705db802776fb","impliedFormat":1},{"version":"7d73b24e7bf31dfb8a931ca6c4245f6bb0814dfae17e4b60c9e194a631fe5f7b","impliedFormat":1},{"version":"413586add0cfe7369b64979d4ec2ed56c3f771c0667fbde1bf1f10063ede0b08","impliedFormat":1},{"version":"06472528e998d152375ad3bd8ebcb69ff4694fd8d2effaf60a9d9f25a37a097a","impliedFormat":1},{"version":"50b5bc34ce6b12eccb76214b51aadfa56572aa6cc79c2b9455cdbb3d6c76af1d","impliedFormat":1},{"version":"b7e16ef7f646a50991119b205794ebfd3a4d8f8e0f314981ebbe991639023d0e","impliedFormat":1},{"version":"42c169fb8c2d42f4f668c624a9a11e719d5d07dacbebb63cbcf7ef365b0a75b3","impliedFormat":1},{"version":"a401617604fa1f6ce437b81689563dfdc377069e4c58465dbd8d16069aede0a5","impliedFormat":1},{"version":"e9dd71cf12123419c60dab867d44fbee5c358169f99529121eaef277f5c83531","impliedFormat":1},{"version":"5b6a189ba3a0befa1f5d9cb028eb9eec2af2089c32f04ff50e2411f63d70f25d","impliedFormat":1},{"version":"d6e73f8010935b7b4c7487b6fb13ea197cc610f0965b759bec03a561ccf8423a","impliedFormat":1},{"version":"174f3864e398f3f33f9a446a4f403d55a892aa55328cf6686135dfaf9e171657","impliedFormat":1},{"version":"824c76aec8d8c7e65769688cbee102238c0ef421ed6686f41b2a7d8e7e78a931","impliedFormat":1},{"version":"75b868be3463d5a8cfc0d9396f0a3d973b8c297401d00bfb008a42ab16643f13","impliedFormat":1},{"version":"15a234e5031b19c48a69ccc1607522d6e4b50f57d308ecb7fe863d44cd9f9eb3","impliedFormat":1},{"version":"d682336018141807fb602709e2d95a192828fcb8d5ba06dda3833a8ea98f69e3","impliedFormat":1},{"version":"6124e973eab8c52cabf3c07575204efc1784aca6b0a30c79eb85fe240a857efa","impliedFormat":1},{"version":"0d891735a21edc75df51f3eb995e18149e119d1ce22fd40db2b260c5960b914e","impliedFormat":1},{"version":"3b414b99a73171e1c4b7b7714e26b87d6c5cb03d200352da5342ab4088a54c85","impliedFormat":1},{"version":"4fbd3116e00ed3a6410499924b6403cc9367fdca303e34838129b328058ede40","impliedFormat":1},{"version":"b01bd582a6e41457bc56e6f0f9de4cb17f33f5f3843a7cf8210ac9c18472fb0f","impliedFormat":1},{"version":"0a437ae178f999b46b6153d79095b60c42c996bc0458c04955f1c996dc68b971","impliedFormat":1},{"version":"74b2a5e5197bd0f2e0077a1ea7c07455bbea67b87b0869d9786d55104006784f","impliedFormat":1},{"version":"4a7baeb6325920044f66c0f8e5e6f1f52e06e6d87588d837bdf44feb6f35c664","impliedFormat":1},{"version":"6dcf60530c25194a9ee0962230e874ff29d34c59605d8e069a49928759a17e0a","impliedFormat":1},{"version":"7274fbffbd7c9589d8d0ffba68157237afd5cecff1e99881ea3399127e60572f","impliedFormat":1},{"version":"1a42d2ec31a1fe62fdc51591768695ed4a2dc64c01be113e7ff22890bebb5e3f","impliedFormat":1},{"version":"1a82deef4c1d39f6882f28d275cad4c01f907b9b39be9cbc472fcf2cf051e05b","impliedFormat":1},{"version":"c5426dbfc1cf90532f66965a7aa8c1136a78d4d0f96d8180ecbfc11d7722f1a5","impliedFormat":1},{"version":"65a15fc47900787c0bd18b603afb98d33ede930bed1798fc984d5ebb78b26cf9","impliedFormat":1},{"version":"9d202701f6e0744adb6314d03d2eb8fc994798fc83d91b691b75b07626a69801","impliedFormat":1},{"version":"de9d2df7663e64e3a91bf495f315a7577e23ba088f2949d5ce9ec96f44fba37d","impliedFormat":1},{"version":"c7af78a2ea7cb1cd009cfb5bdb48cd0b03dad3b54f6da7aab615c2e9e9d570c5","impliedFormat":1},{"version":"1ee45496b5f8bdee6f7abc233355898e5bf9bd51255db65f5ff7ede617ca0027","impliedFormat":1},{"version":"0c7c947ff881c4274c0800deaa0086971e0bfe51f89a33bd3048eaa3792d4876","affectsGlobalScope":true,"impliedFormat":1},{"version":"db01d18853469bcb5601b9fc9826931cc84cc1a1944b33cad76fd6f1e3d8c544","affectsGlobalScope":true,"impliedFormat":1},{"version":"a8f8e6ab2fa07b45251f403548b78eaf2022f3c2254df3dc186cb2671fe4996d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fa6c12a7c0f6b84d512f200690bfc74819e99efae69e4c95c4cd30f6884c526e","impliedFormat":1},{"version":"f1c32f9ce9c497da4dc215c3bc84b722ea02497d35f9134db3bb40a8d918b92b","impliedFormat":1},{"version":"b73c319af2cc3ef8f6421308a250f328836531ea3761823b4cabbd133047aefa","affectsGlobalScope":true,"impliedFormat":1},{"version":"e433b0337b8106909e7953015e8fa3f2d30797cea27141d1c5b135365bb975a6","impliedFormat":1},{"version":"15b36126e0089bfef173ab61329e8286ce74af5e809d8a72edcafd0cc049057f","impliedFormat":1},{"version":"ddff7fc6edbdc5163a09e22bf8df7bef75f75369ebd7ecea95ba55c4386e2441","impliedFormat":1},{"version":"106c6025f1d99fd468fd8bf6e5bda724e11e5905a4076c5d29790b6c3745e50c","impliedFormat":1},{"version":"a57b1802794433adec9ff3fed12aa79d671faed86c49b09e02e1ac41b4f1d33a","impliedFormat":1},{"version":"ad10d4f0517599cdeca7755b930f148804e3e0e5b5a3847adce0f1f71bbccd74","impliedFormat":1},{"version":"1042064ece5bb47d6aba91648fbe0635c17c600ebdf567588b4ca715602f0a9d","impliedFormat":1},{"version":"c49469a5349b3cc1965710b5b0f98ed6c028686aa8450bcb3796728873eb923e","impliedFormat":1},{"version":"4a889f2c763edb4d55cb624257272ac10d04a1cad2ed2948b10ed4a7fda2a428","impliedFormat":1},{"version":"7bb79aa2fead87d9d56294ef71e056487e848d7b550c9a367523ee5416c44cfa","impliedFormat":1},{"version":"72d63643a657c02d3e51cd99a08b47c9b020a565c55f246907050d3c8a5e77fb","impliedFormat":1},{"version":"1d415445ea58f8033ba199703e55ff7483c52ac6742075b803bd3e7bbe9f5d61","impliedFormat":1},{"version":"d6406c629bb3efc31aedb2de809bef471e475c86c7e67f3ef9b676b5d7e0d6b2","impliedFormat":1},{"version":"27ff4196654e6373c9af16b6165120e2dd2169f9ad6abb5c935af5abd8c7938c","impliedFormat":1},{"version":"71d8ba39a9e024d9e4bb922464d18542ed8d2c25ee78efa7890c27213cc6e5d3","impliedFormat":1},{"version":"8c030e515014c10a2b98f9f48408e3ba18023dfd3f56e3312c6c2f3ae1f55a16","impliedFormat":1},{"version":"dafc31e9e8751f437122eb8582b93d477e002839864410ff782504a12f2a550c","impliedFormat":1},{"version":"754498c5208ce3c5134f6eabd49b25cf5e1a042373515718953581636491f3c3","impliedFormat":1},{"version":"9c82171d836c47486074e4ca8e059735bf97b205e70b196535b5efd40cbe1bc5","impliedFormat":1},{"version":"f56bdc6884648806d34bc66d31cdb787c4718d04105ce2cd88535db214631f82","impliedFormat":1},{"version":"633d58a237f4bb25ec7d565e4ffa32cecdcee8660ac12189c4351c52557cee9e","impliedFormat":1},{"version":"2e4f37ffe8862b14d8e24ae8763daaa8340c0df0b859d9a9733def0eee7562d9","impliedFormat":1},{"version":"13283350547389802aa35d9f2188effaeac805499169a06ef5cd77ce2a0bd63f","impliedFormat":1},{"version":"ce791f6ea807560f08065d1af6014581eeb54a05abd73294777a281b6dfd73c2","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"49f95e989b4632c6c2a578cc0078ee19a5831832d79cc59abecf5160ea71abad","impliedFormat":1},{"version":"9666533332f26e8995e4d6fe472bdeec9f15d405693723e6497bf94120c566c8","impliedFormat":1},{"version":"ce0df82a9ae6f914ba08409d4d883983cc08e6d59eb2df02d8e4d68309e7848b","impliedFormat":1},{"version":"796273b2edc72e78a04e86d7c58ae94d370ab93a0ddf40b1aa85a37a1c29ecd7","impliedFormat":1},{"version":"5df15a69187d737d6d8d066e189ae4f97e41f4d53712a46b2710ff9f8563ec9f","impliedFormat":1},{"version":"e17cd049a1448de4944800399daa4a64c5db8657cc9be7ef46be66e2a2cd0e7c","impliedFormat":1},{"version":"43fa6ea8714e18adc312b30450b13562949ba2f205a1972a459180fa54471018","impliedFormat":1},{"version":"6e89c2c177347d90916bad67714d0fb473f7e37fb3ce912f4ed521fe2892cd0d","impliedFormat":1},{"version":"43ba4f2fa8c698f5c304d21a3ef596741e8e85a810b7c1f9b692653791d8d97a","impliedFormat":1},{"version":"4d4927cbee21750904af7acf940c5e3c491b4d5ebc676530211e389dd375607a","impliedFormat":1},{"version":"72105519d0390262cf0abe84cf41c926ade0ff475d35eb21307b2f94de985778","impliedFormat":1},{"version":"8a97e578a9bc40eb4f1b0ca78f476f2e9154ecbbfd5567ee72943bab37fc156a","impliedFormat":1},{"version":"c857e0aae3f5f444abd791ec81206020fbcc1223e187316677e026d1c1d6fe08","impliedFormat":1},{"version":"ccf6dd45b708fb74ba9ed0f2478d4eb9195c9dfef0ff83a6092fa3cf2ff53b4f","impliedFormat":1},{"version":"2d7db1d73456e8c5075387d4240c29a2a900847f9c1bff106a2e490da8fbd457","impliedFormat":1},{"version":"2b15c805f48e4e970f8ec0b1915f22d13ca6212375e8987663e2ef5f0205e832","impliedFormat":1},{"version":"f22d05663d873ee7a600faf78abb67f3f719d32266803440cf11d5db7ac0cab2","impliedFormat":1},{"version":"d93c544ad20197b3976b0716c6d5cd5994e71165985d31dcab6e1f77feb4b8f2","impliedFormat":1},{"version":"35069c2c417bd7443ae7c7cafd1de02f665bf015479fec998985ffbbf500628c","impliedFormat":1},{"version":"a8b1c79a833ee148251e88a2553d02ce1641d71d2921cce28e79678f3d8b96aa","impliedFormat":1},{"version":"126d4f950d2bba0bd45b3a86c76554d4126c16339e257e6d2fabf8b6bf1ce00c","impliedFormat":1},{"version":"7e0b7f91c5ab6e33f511efc640d36e6f933510b11be24f98836a20a2dc914c2d","impliedFormat":1},{"version":"045b752f44bf9bbdcaffd882424ab0e15cb8d11fa94e1448942e338c8ef19fba","impliedFormat":1},{"version":"2894c56cad581928bb37607810af011764a2f511f575d28c9f4af0f2ef02d1ab","impliedFormat":1},{"version":"0a72186f94215d020cb386f7dca81d7495ab6c17066eb07d0f44a5bf33c1b21a","impliedFormat":1},{"version":"2d3cc2211f352f46ea6b7cf2c751c141ffcdf514d6e7ae7ee20b7b6742da313f","impliedFormat":1},{"version":"c75445151ff8b77d9923191efed7203985b1a9e09eccf4b054e7be864e27923d","impliedFormat":1},{"version":"0aedb02516baf3e66b2c1db9fef50666d6ed257edac0f866ea32f1aa05aa474f","impliedFormat":1},{"version":"fa8a8fbf91ee2a4779496225f0312aac6635b0f21aa09cdafa4283fe32d519c5","affectsGlobalScope":true,"impliedFormat":1},{"version":"0e8aef93d79b000deb6ec336b5645c87de167168e184e84521886f9ecc69a4b5","impliedFormat":1},{"version":"56ccb49443bfb72e5952f7012f0de1a8679f9f75fc93a5c1ac0bafb28725fc5f","impliedFormat":1},{"version":"d90b9f1520366d713a73bd30c5a9eb0040d0fb6076aff370796bc776fd705943","impliedFormat":1},{"version":"05321b823dd3781d0b6aac8700bfdc0c9181d56479fe52ba6a40c9196fd661a8","impliedFormat":1},{"version":"736a8712572e21ee73337055ce15edb08142fc0f59cd5410af4466d04beff0f9","affectsGlobalScope":true,"impliedFormat":1},{"version":"bef86adb77316505c6b471da1d9b8c9e428867c2566270e8894d4d773a1c4dc2","impliedFormat":1},{"version":"de7052bfee2981443498239a90c04ea5cc07065d5b9bb61b12cb6c84313ad4ef","impliedFormat":1},{"version":"a3e7d932dc9c09daa99141a8e4800fc6c58c625af0d4bbb017773dc36da75426","impliedFormat":1},{"version":"43e96a3d5d1411ab40ba2f61d6a3192e58177bcf3b133a80ad2a16591611726d","impliedFormat":1},{"version":"4a2edd238d9104eac35b60d727f1123de5062f452b70ed8e0366cb36387dfdfd","impliedFormat":1},{"version":"ca921bf56756cb6fe957f6af693a35251b134fb932dc13f3dfff0bb7106f80b4","impliedFormat":1},{"version":"fee92c97f1aa59eb7098a0cc34ff4df7e6b11bae71526aca84359a2575f313d8","impliedFormat":1},{"version":"0bd0297484aacea217d0b76e55452862da3c5d9e33b24430e0719d1161657225","impliedFormat":1},{"version":"2ab6d334bcbf2aff3acfc4fd8c73ecd82b981d3c3aa47b3f3b89281772286904","impliedFormat":1},{"version":"d07cbc787a997d83f7bde3877fec5fb5b12ce8c1b7047eb792996ed9726b4dde","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"4805f6161c2c8cefb8d3b8bd96a080c0fe8dbc9315f6ad2e53238f9a79e528a6","impliedFormat":1},{"version":"b83cb14474fa60c5f3ec660146b97d122f0735627f80d82dd03e8caa39b4388c","impliedFormat":1},{"version":"f374cb24e93e7798c4d9e83ff872fa52d2cdb36306392b840a6ddf46cb925cb6","impliedFormat":1},{"version":"49179c6a23701c642bd99abe30d996919748014848b738d8e85181fc159685ff","impliedFormat":1},{"version":"b73cbf0a72c8800cf8f96a9acfe94f3ad32ca71342a8908b8ae484d61113f647","impliedFormat":1},{"version":"bae6dd176832f6423966647382c0d7ba9e63f8c167522f09a982f086cd4e8b23","impliedFormat":1},{"version":"20865ac316b8893c1a0cc383ccfc1801443fbcc2a7255be166cf90d03fac88c9","impliedFormat":1},{"version":"c9958eb32126a3843deedda8c22fb97024aa5d6dd588b90af2d7f2bfac540f23","impliedFormat":1},{"version":"461d0ad8ae5f2ff981778af912ba71b37a8426a33301daa00f21c6ccb27f8156","impliedFormat":1},{"version":"e927c2c13c4eaf0a7f17e6022eee8519eb29ef42c4c13a31e81a611ab8c95577","impliedFormat":1},{"version":"fcafff163ca5e66d3b87126e756e1b6dfa8c526aa9cd2a2b0a9da837d81bbd72","impliedFormat":1},{"version":"70246ad95ad8a22bdfe806cb5d383a26c0c6e58e7207ab9c431f1cb175aca657","impliedFormat":1},{"version":"f00f3aa5d64ff46e600648b55a79dcd1333458f7a10da2ed594d9f0a44b76d0b","impliedFormat":1},{"version":"772d8d5eb158b6c92412c03228bd9902ccb1457d7a705b8129814a5d1a6308fc","impliedFormat":1},{"version":"45490817629431853543adcb91c0673c25af52a456479588b6486daba34f68bb","impliedFormat":1},{"version":"802e797bcab5663b2c9f63f51bdf67eff7c41bc64c0fd65e6da3e7941359e2f7","impliedFormat":1},{"version":"8b4327413e5af38cd8cb97c59f48c3c866015d5d642f28518e3a891c469f240e","impliedFormat":1},{"version":"8514c62ce38e58457d967e9e73f128eedc1378115f712b9eef7127f7c88f82ae","impliedFormat":1},{"version":"f1289e05358c546a5b664fbb35a27738954ec2cc6eb4137350353099d154fc62","impliedFormat":1},{"version":"4b20fcf10a5413680e39f5666464859fc56b1003e7dfe2405ced82371ebd49b6","impliedFormat":1},{"version":"1d17ba45cfbe77a9c7e0df92f7d95f3eefd49ee23d1104d0548b215be56945ad","impliedFormat":1},{"version":"f7d628893c9fa52ba3ab01bcb5e79191636c4331ee5667ecc6373cbccff8ae12","impliedFormat":1},{"version":"1d879125d1ec570bf04bc1f362fdbe0cb538315c7ac4bcfcdf0c1e9670846aa6","impliedFormat":1},{"version":"e16344db9b8ee59d41abdb3a61e4470955b5712c0ee869fb47112e152aabe142","impliedFormat":1},{"version":"46273e8c29816125d0d0b56ce9a849cc77f60f9a5ba627447501d214466f0ff3","impliedFormat":1},{"version":"d663134457d8d669ae0df34eabd57028bddc04fc444c4bc04bc5215afc91e1f4","impliedFormat":1},{"version":"144bc326e90b894d1ec78a2af3ffb2eb3733f4d96761db0ca0b6239a8285f972","impliedFormat":1},{"version":"3af3584f79c57853028ef9421ec172539e1fe01853296dc05a9d615ade4ffaf6","impliedFormat":1},{"version":"f82579d87701d639ff4e3930a9b24f4ee13ca74221a9a3a792feb47f01881a9c","impliedFormat":1},{"version":"d7e5d5245a8ba34a274717d085174b2c9827722778129b0081fefd341cca8f55","impliedFormat":1},{"version":"d9d32f94056181c31f553b32ce41d0ef75004912e27450738d57efcd2409c324","impliedFormat":1},{"version":"752513f35f6cff294ffe02d6027c41373adf7bfa35e593dbfd53d95c203635ee","impliedFormat":1},{"version":"6c800b281b9e89e69165fd11536195488de3ff53004e55905e6c0059a2d8591e","impliedFormat":1},{"version":"7d4254b4c6c67a29d5e7f65e67d72540480ac2cfb041ca484847f5ae70480b62","impliedFormat":1},{"version":"1a7e2ea171726446850ec72f4d1525d547ff7e86724cc9e7eec509725752a758","impliedFormat":1},{"version":"8c901126d73f09ecdea4785e9a187d1ac4e793e07da308009db04a7283ec2f37","impliedFormat":1},{"version":"db97922b767bd2675fdfa71e08b49c38b7d2c847a1cc4a7274cb77be23b026f1","impliedFormat":1},{"version":"aab290b8e4b7c399f2c09b957666fc95335eb4522b2dd9ead1bf0cb64da6d6ee","impliedFormat":1},{"version":"94fe3281392e1015b22f39535878610b4fa6f1388dc8d78746be3bc4e4bb8950","impliedFormat":1},{"version":"2652448ac55a2010a1f71dd141f828b682298d39728f9871e1cdf8696ef443fd","impliedFormat":1},{"version":"06c25ddfc2242bd06c19f66c9eae4c46d937349a267810f89783680a1d7b5259","impliedFormat":1},{"version":"120599fd965257b1f4d0ff794bc696162832d9d8467224f4665f713a3119078b","impliedFormat":1},{"version":"5433f33b0a20300cca35d2f229a7fc20b0e8477c44be2affeb21cb464af60c76","impliedFormat":1},{"version":"db036c56f79186da50af66511d37d9fe77fa6793381927292d17f81f787bb195","impliedFormat":1},{"version":"bd4131091b773973ca5d2326c60b789ab1f5e02d8843b3587effe6e1ea7c9d86","impliedFormat":1},{"version":"c7f6485931085bf010fbaf46880a9b9ec1a285ad9dc8c695a9e936f5a48f34b4","impliedFormat":1},{"version":"14f6b927888a1112d662877a5966b05ac1bf7ed25d6c84386db4c23c95a5363b","impliedFormat":1},{"version":"6ac6715916fa75a1f7ebdfeacac09513b4d904b667d827b7535e84ff59679aff","impliedFormat":1},{"version":"0427df5c06fafc5fe126d14b9becd24160a288deff40e838bfbd92a35f8d0d00","impliedFormat":1},{"version":"90c54a02432d04e4246c87736e53a6a83084357acfeeba7a489c5422b22f5c7a","impliedFormat":1},{"version":"49c346823ba6d4b12278c12c977fb3a31c06b9ca719015978cb145eb86da1c61","impliedFormat":1},{"version":"bfac6e50eaa7e73bb66b7e052c38fdc8ccfc8dbde2777648642af33cf349f7f1","impliedFormat":1},{"version":"92f7c1a4da7fbfd67a2228d1687d5c2e1faa0ba865a94d3550a3941d7527a45d","impliedFormat":1},{"version":"f53b120213a9289d9a26f5af90c4c686dd71d91487a0aa5451a38366c70dc64b","impliedFormat":1},{"version":"83fe880c090afe485a5c02262c0b7cdd76a299a50c48d9bde02be8e908fb4ae6","impliedFormat":1},{"version":"0a372c2d12a259da78e21b25974d2878502f14d89c6d16b97bd9c5017ab1bc12","impliedFormat":1},{"version":"57d67b72e06059adc5e9454de26bbfe567d412b962a501d263c75c2db430f40e","impliedFormat":1},{"version":"6511e4503cf74c469c60aafd6589e4d14d5eb0a25f9bf043dcbecdf65f261972","impliedFormat":1},{"version":"ec1ca97598eda26b7a5e6c8053623acbd88e43be7c4d29c77ccd57abc4c43999","impliedFormat":1},{"version":"6e2261cd9836b2c25eecb13940d92c024ebed7f8efe23c4b084145cd3a13b8a6","impliedFormat":1},{"version":"a67b87d0281c97dfc1197ef28dfe397fc2c865ccd41f7e32b53f647184cc7307","impliedFormat":1},{"version":"771ffb773f1ddd562492a6b9aaca648192ac3f056f0e1d997678ff97dbb6bf9b","impliedFormat":1},{"version":"232f70c0cf2b432f3a6e56a8dc3417103eb162292a9fd376d51a3a9ea5fbbf6f","impliedFormat":1},{"version":"a47e6d954d22dd9ebb802e7e431b560ed7c581e79fb885e44dc92ed4f60d4c07","impliedFormat":1},{"version":"f019e57d2491c159d47a107fd90219a1734bdd2e25cd8d1db3c8fae5c6b414c4","impliedFormat":1},{"version":"8a0e762ceb20c7e72504feef83d709468a70af4abccb304f32d6b9bac1129b2c","impliedFormat":1},{"version":"d1c9bf292a54312888a77bb19dba5e2503ad803f5393beafd45d78d2f4fe9b48","impliedFormat":1},{"version":"9252d498a77517aab5d8d4b5eb9d71e4b225bbc7123df9713e08181de63180f6","impliedFormat":1},{"version":"cb8d8ef7b9ce8ed3e6f1c814fcbf3f90dab0cb8863079236784fc350746e27c4","impliedFormat":1},{"version":"35e6379c3f7cb27b111ad4c1aa69538fd8e788ab737b8ff7596a1b40e96f4f90","impliedFormat":1},{"version":"1fffe726740f9787f15b532e1dc870af3cd964dbe29e191e76121aa3dd8693f2","impliedFormat":1},{"version":"3be035da7bee86b4c3abf392e0edaa44fc6e45092995eefe36b39118c8a84068","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f828825d077c2fa0ea606649faeb122749273a353daab23924fe674e98ba44c","impliedFormat":1},{"version":"2896c2e673a5d3bd9b4246811f79486a073cbb03950c3d252fba10003c57411a","impliedFormat":1},{"version":"616775f16134fa9d01fc677ad3f76e68c051a056c22ab552c64cc281a9686790","impliedFormat":1},{"version":"65c24a8baa2cca1de069a0ba9fba82a173690f52d7e2d0f1f7542d59d5eb4db0","impliedFormat":1},{"version":"f9fe6af238339a0e5f7563acee3178f51db37f32a2e7c09f85273098cee7ec49","impliedFormat":1},{"version":"407a06ba04eede4074eec470ecba2784cbb3bf4e7de56833b097dd90a2aa0651","impliedFormat":1},{"version":"77e71242e71ebf8528c5802993697878f0533db8f2299b4d36aa015bae08a79c","impliedFormat":1},{"version":"98a787be42bd92f8c2a37d7df5f13e5992da0d967fab794adbb7ee18370f9849","impliedFormat":1},{"version":"5c96bad5f78466785cdad664c056e9e2802d5482ca5f862ed19ba34ffbb7b3a4","impliedFormat":1},{"version":"81d8603ac527e75cfec72bb9391228b58f161c2b33514a9d814c7f3ebd3ef466","impliedFormat":1},{"version":"5f3dc10ae646f375776b4e028d2bed039a93eebbba105694d8b910feebbe8b9c","impliedFormat":1},{"version":"bb0cd7862b72f5eba39909c9889d566e198fcaddf7207c16737d0c2246112678","impliedFormat":1},{"version":"4545c1a1ceca170d5d83452dd7c4994644c35cf676a671412601689d9a62da35","impliedFormat":1},{"version":"320f4091e33548b554d2214ce5fc31c96631b513dffa806e2e3a60766c8c49d9","impliedFormat":1},{"version":"a2d648d333cf67b9aeac5d81a1a379d563a8ffa91ddd61c6179f68de724260ff","impliedFormat":1},{"version":"d90d5f524de38889d1e1dbc2aeef00060d779f8688c02766ddb9ca195e4a713d","impliedFormat":1},{"version":"a3f41ed1b4f2fc3049394b945a68ae4fdefd49fa1739c32f149d32c0545d67f5","impliedFormat":1},{"version":"bad68fd0401eb90fe7da408565c8aee9c7a7021c2577aec92fa1382e8876071a","impliedFormat":1},{"version":"47699512e6d8bebf7be488182427189f999affe3addc1c87c882d36b7f2d0b0e","impliedFormat":1},{"version":"fec01479923e169fb52bd4f668dbeef1d7a7ea6e6d491e15617b46f2cacfa37d","impliedFormat":1},{"version":"8a8fb3097ba52f0ae6530ec6ab34e43e316506eb1d9aa29420a4b1e92a81442d","impliedFormat":1},{"version":"44e09c831fefb6fe59b8e65ad8f68a7ecc0e708d152cfcbe7ba6d6080c31c61e","impliedFormat":1},{"version":"1c0a98de1323051010ce5b958ad47bc1c007f7921973123c999300e2b7b0ecc0","impliedFormat":1},{"version":"4655709c9cb3fd6db2b866cab7c418c40ed9533ce8ea4b66b5f17ec2feea46a9","impliedFormat":1},{"version":"87affad8e2243635d3a191fa72ef896842748d812e973b7510a55c6200b3c2a4","impliedFormat":1},{"version":"ad036a85efcd9e5b4f7dd5c1a7362c8478f9a3b6c3554654ca24a29aa850a9c5","impliedFormat":1},{"version":"fedebeae32c5cdd1a85b4e0504a01996e4a8adf3dfa72876920d3dd6e42978e7","impliedFormat":1},{"version":"3eecb25bb467a948c04874d70452b14ae7edb707660aac17dc053e42f2088b00","impliedFormat":1},{"version":"cdf21eee8007e339b1b9945abf4a7b44930b1d695cc528459e68a3adc39a622e","impliedFormat":1},{"version":"330896c1a2b9693edd617be24fbf9e5895d6e18c7955d6c08f028f272b37314d","impliedFormat":1},{"version":"1d9c0a9a6df4e8f29dc84c25c5aa0bb1da5456ebede7a03e03df08bb8b27bae6","impliedFormat":1},{"version":"84380af21da938a567c65ef95aefb5354f676368ee1a1cbb4cae81604a4c7d17","impliedFormat":1},{"version":"1af3e1f2a5d1332e136f8b0b95c0e6c0a02aaabd5092b36b64f3042a03debf28","impliedFormat":1},{"version":"30d8da250766efa99490fc02801047c2c6d72dd0da1bba6581c7e80d1d8842a4","impliedFormat":1},{"version":"03566202f5553bd2d9de22dfab0c61aa163cabb64f0223c08431fb3fc8f70280","impliedFormat":1},{"version":"5f0292a40df210ab94b9fb44c8b775c51e96777e14e073900e392b295ca1061b","impliedFormat":1},{"version":"bc9ee0192f056b3d5527bcd78dc3f9e527a9ba2bdc0a2c296fbc9027147df4b2","impliedFormat":1},{"version":"8627ad129bcf56e82adff0ab5951627c993937aa99f5949c33240d690088b803","impliedFormat":1},{"version":"1de80059b8078ea5749941c9f863aa970b4735bdbb003be4925c853a8b6b4450","impliedFormat":1},{"version":"1d079c37fa53e3c21ed3fa214a27507bda9991f2a41458705b19ed8c2b61173d","impliedFormat":1},{"version":"5bf5c7a44e779790d1eb54c234b668b15e34affa95e78eada73e5757f61ed76a","impliedFormat":1},{"version":"5835a6e0d7cd2738e56b671af0e561e7c1b4fb77751383672f4b009f4e161d70","impliedFormat":1},{"version":"5c634644d45a1b6bc7b05e71e05e52ec04f3d73d9ac85d5927f647a5f965181a","impliedFormat":1},{"version":"4b7f74b772140395e7af67c4841be1ab867c11b3b82a51b1aeb692822b76c872","impliedFormat":1},{"version":"27be6622e2922a1b412eb057faa854831b95db9db5035c3f6d4b677b902ab3b7","impliedFormat":1},{"version":"a68d4b3182e8d776cdede7ac9630c209a7bfbb59191f99a52479151816ef9f9e","impliedFormat":99},{"version":"39644b343e4e3d748344af8182111e3bbc594930fff0170256567e13bbdbebb0","impliedFormat":99},{"version":"ed7fd5160b47b0de3b1571c5c5578e8e7e3314e33ae0b8ea85a895774ee64749","impliedFormat":99},{"version":"63a7595a5015e65262557f883463f934904959da563b4f788306f699411e9bac","impliedFormat":1},{"version":"ecbaf0da125974be39c0aac869e403f72f033a4e7fd0d8cd821a8349b4159628","impliedFormat":1},{"version":"4ba137d6553965703b6b55fd2000b4e07ba365f8caeb0359162ad7247f9707a6","impliedFormat":1},{"version":"ceec3c81b2d81f5e3b855d9367c1d4c664ab5046dff8fd56552df015b7ccbe8f","affectsGlobalScope":true,"impliedFormat":1},{"version":"8fac4a15690b27612d8474fb2fc7cc00388df52d169791b78d1a3645d60b4c8b","affectsGlobalScope":true,"impliedFormat":1},{"version":"064ac1c2ac4b2867c2ceaa74bbdce0cb6a4c16e7c31a6497097159c18f74aa7c","impliedFormat":1},{"version":"3dc14e1ab45e497e5d5e4295271d54ff689aeae00b4277979fdd10fa563540ae","impliedFormat":1},{"version":"1d63055b690a582006435ddd3aa9c03aac16a696fac77ce2ed808f3e5a06efab","impliedFormat":1},{"version":"b789bf89eb19c777ed1e956dbad0925ca795701552d22e68fd130a032008b9f9","impliedFormat":1},"f4e8976c19fc926644d72610bf1058bd6bf52add97e46a02bc0b912a751625c0",{"version":"50471843ca66d943fe693f98e52a2df0dcac339cd804edf41e96964a22506026","signature":"435a1e418e8338be3f39614b96b81a9aa2700bc8c27bc6b98f064ff9ce17c363"},{"version":"402e5c534fb2b85fa771170595db3ac0dd532112c8fa44fc23f233bc6967488b","impliedFormat":1},{"version":"8885cf05f3e2abf117590bbb951dcf6359e3e5ac462af1c901cfd24c6a6472e2","impliedFormat":1},{"version":"333caa2bfff7f06017f114de738050dd99a765c7eb16571c6d25a38c0d5365dc","impliedFormat":1},{"version":"e61df3640a38d535fd4bc9f4a53aef17c296b58dc4b6394fd576b808dd2fe5e6","impliedFormat":1},{"version":"459920181700cec8cbdf2a5faca127f3f17fd8dd9d9e577ed3f5f3af5d12a2e4","impliedFormat":1},{"version":"4719c209b9c00b579553859407a7e5dcfaa1c472994bd62aa5dd3cc0757eb077","impliedFormat":1},{"version":"7ec359bbc29b69d4063fe7dad0baaf35f1856f914db16b3f4f6e3e1bca4099fa","impliedFormat":1},{"version":"70790a7f0040993ca66ab8a07a059a0f8256e7bb57d968ae945f696cbff4ac7a","impliedFormat":1},{"version":"d1b9a81e99a0050ca7f2d98d7eedc6cda768f0eb9fa90b602e7107433e64c04c","impliedFormat":1},{"version":"a022503e75d6953d0e82c2c564508a5c7f8556fad5d7f971372d2d40479e4034","impliedFormat":1},{"version":"b215c4f0096f108020f666ffcc1f072c81e9f2f95464e894a5d5f34c5ea2a8b1","impliedFormat":1},{"version":"644491cde678bd462bb922c1d0cfab8f17d626b195ccb7f008612dc31f445d2d","impliedFormat":1},{"version":"dfe54dab1fa4961a6bcfba68c4ca955f8b5bbeb5f2ab3c915aa7adaa2eabc03a","impliedFormat":1},{"version":"1251d53755b03cde02466064260bb88fd83c30006a46395b7d9167340bc59b73","impliedFormat":1},{"version":"47865c5e695a382a916b1eedda1b6523145426e48a2eae4647e96b3b5e52024f","impliedFormat":1},{"version":"4cdf27e29feae6c7826cdd5c91751cc35559125e8304f9e7aed8faef97dcf572","impliedFormat":1},{"version":"331b8f71bfae1df25d564f5ea9ee65a0d847c4a94baa45925b6f38c55c7039bf","impliedFormat":1},{"version":"2a771d907aebf9391ac1f50e4ad37952943515eeea0dcc7e78aa08f508294668","impliedFormat":1},{"version":"0146fd6262c3fd3da51cb0254bb6b9a4e42931eb2f56329edd4c199cb9aaf804","impliedFormat":1},{"version":"183f480885db5caa5a8acb833c2be04f98056bdcc5fb29e969ff86e07efe57ab","impliedFormat":99},{"version":"b558c9a18ea4e6e4157124465c3ef1063e64640da139e67be5edb22f534f2f08","impliedFormat":1},{"version":"01374379f82be05d25c08d2f30779fa4a4c41895a18b93b33f14aeef51768692","impliedFormat":1},{"version":"b0dee183d4e65cf938242efaf3d833c6b645afb35039d058496965014f158141","impliedFormat":1},{"version":"c0bbbf84d3fbd85dd60d040c81e8964cc00e38124a52e9c5dcdedf45fea3f213","impliedFormat":1},{"version":"8c62ca2967cfb122b2e4353ce4e385239843de4887de67c268d550c65f09644f","signature":"f65ce75c9085571e6321abf2bf9833709f4897e381f89e9925521833dbb7ab16"},{"version":"d4a6acf500a7b4bb6917c2fc36441e12af430115b8cae917d3bc750ae649380c","signature":"5f5303388c23daf221df682ba0e6ed13924ad3a925fae5ec71f4cdfb6adf1b79"},{"version":"cfb529c313b7d9115d4c371211f9928e8f3dc835be4d0aa1cfcab26dae5d8f9b","signature":"59d9f23a869497c75dd46911840b2c92b17933e5dd2307f10c9bf4b3de577963"},{"version":"8e7486e254a16bd20d0247345249d227427338687f4714c4a29240ea932f8fa7","signature":"14777230ffb55ee7064d86fa58eefc198cb75724404895fcd824897035aac65c"},{"version":"147c0ca36568495119564a3b99b929ccca7685990352863f362fdbf69439b40a","signature":"ebc450cf4888573aef03e1d85e34f8587789f7436e4c80a3f1417a66429a9a29"},{"version":"6898eb3e45c37a67417733b23cf8519cda3cf305046531bd318cdef48e52ca5a","signature":"6153aea1b490266dc2df16b75e79b79e25a8f7492b4d73fb89727a5682d6a6ec"},{"version":"ec21dd4a45e54073cb36e9b947f01843db6a4a09cdb997da341e76802fab95ae","signature":"23822a168bf160052857e23ddd08b388199c72abfaf1e9f96d3d041f6fa7b1fc"},{"version":"62d4a2668b5c731742c7f3bebf3851ade404a707906d47d381aa3605219b58c3","signature":"d8f43844bb7e36c06a6c296202eb9b2698eb08d4dfc5a616d40e03fa003182c6"},{"version":"32fd5fa462a08fe65e8ba09351bb41d861d558a7af2f722564a070a1972ad6b9","signature":"41afd29567caf0c9639c58a2d342a9a9a9920091e080a328789181491bcc6451"},{"version":"598f3baa219909577e28e5e78d0170a49761f6e39a733be304b1321095dc340b","signature":"bd20c80b2e92e71acb328641090529220e226a378124c9c3d0616e53f888f7ff"},{"version":"4654f66c69f3da8a2848cfd68b75a23230a8d62b6eceebfcf214e0d623b6e7b4","signature":"a8c7595b174fd808b6caeadc7a886d13d99c17acf3e110f04a47398699fe9e81"},{"version":"75c1eb2f4c9bf91c50fb19f24c5c891ad314b125903d1c68b50edd6d8e0de86e","signature":"72af78ebc4c7ca71f3cd76f38659d0dc231f4b8df8bda968cead637bd1633242"},{"version":"cf929500b6b1714ebfdf9086ed4820ee3942b72a332c56bc5a59039b85331410","signature":"98c1c9e92d1e062f56f2da277c8c555bd635af7dd5ddff9e6c61ac31ab214670"},{"version":"7e981d1ec28163343d9819bbb5eca9c0e6b6238bf7ed0cb3e19014a2016091c4","signature":"c86473483edfb9d5d810a3e1714a6bc5359901cb3f3b9dee3f274c7e4f1eb627"},{"version":"7191bc1ec67488659398391a42cc918a0fa79c624c6ca4d4a0099c3892eee401","signature":"b8005de76cc5b5f3af31f292491ac127f9738a0c022a967db0089e11980b3914"},{"version":"0eefc702c5de5c32835e290cbdcb5a76f6d98c956b87cdbf5da49c864d3ab88e","signature":"0a4895bce639e10d5ef215a48b4bbc4d73e444e9a3e214594ebae5e00a7140f8"},{"version":"18dcf24fa030fd040b0a2842eee9fe3a617fd933e2be607f8ed385c1425fe822","signature":"59e66195e348aa04b9111b199ec0e65e75c9f31355bc82cf7bc8436f7128593a"},{"version":"54f0fdce25f65dd46fea54a14ff0bfda9d1accb8cf13b208709ee7b527124abd","signature":"2277a245765dbac41e82b51724ea73eb058b58e261f7c67bad3a47924f48781b"},{"version":"88c305e239ed902480aca0f90537b2aab81b6a793eea9f05147c1f3269e3530b","signature":"81d4e18931396e11ea3a9238df2d578533292a7fbd3a21bea05fa1b5cf8b78f0"},{"version":"3726ca076fe8d78e3c7cdcf78b65f7fc2dc4d749842333fe45b7cda7324482dd","signature":"dd7d4358fd9fbf497584c0021b8853db9c763fef4ed20240dc5f0d6c7499466f"},{"version":"da68b20c2da4fe8fff85e09b6b996c46d322fa3236e9faad0772caa9ac3cfcf1","impliedFormat":1},{"version":"6de0ef73d95431a5386ca68289fc73e7184b347290450e5b3c43413cd5efa87d","impliedFormat":1},{"version":"176f067f0d4f5a475e549aafae513dacf4fb65eacbe7e8c53aec4507da0d532a","impliedFormat":1},{"version":"e84d2c363ddc1caeaa5dc07e68f0e8f6daf6f4de7129648065658205a45e7419","impliedFormat":1},{"version":"2eec47fd2fa59588762d2d32cd21e0fbb48bab959355748fa69fd726c831b4f9","impliedFormat":1},{"version":"25cf93cd7101a3b4ccc331ed92446a4327d2b60e3c13172f60f179d3a5ef4b8c","impliedFormat":1},{"version":"2a2c6e0c174335928d9a9e69473193b1338ca3f69db315cbb6f1f29982048be5","impliedFormat":1},{"version":"47c68c8eba9c2d1e5185c0c8941238e393ca0d25beb87712749b776152a9142a","impliedFormat":1},{"version":"d72de9fb566361f7fc130c1e0ff9ecfa17098375826949cc9e2efc69b2daf2fb","impliedFormat":1},{"version":"f8cf9784854967e17fc09a0ef3f861a7d2f6228147af6bdfe035def611314ff1","impliedFormat":1},{"version":"af8ecfa6dd1d99be9c3829f142c0dfa932ab6892e7399c3bef0280b0e6eb9b42","impliedFormat":1},{"version":"32cfe506ca91cb16282efce472c0de913fa4b8fa937951aff70dc7c4e6ff60af","impliedFormat":1},{"version":"d5128291066411c82ee10e3a86836cb1642f2e957fbc7fcd58fdfac87a0bbdbc","impliedFormat":1},{"version":"1d3b944202b6bd0807f1f219b2b69576129cd358cca2fb91c39d8c8051776ce6","impliedFormat":1},{"version":"a64e0c54b268ac3a2681ad56883f75c66cba5866538db72eeb2940a75b00ce64","signature":"6e0ad9cfffb899a2afe6f592d362aa4769fc078d87ffd4e3fed790ddb2f5a23d"},{"version":"3cb2cd882c0625d82e156905a850329fa913bdad2ceb452b45d96b74cf8ff78c","signature":"878e3262825784039dce11322ccfd0504d5880127a132ff576bc83c3734f0c41"},{"version":"07c8401bdd652da387c5bbfe80d786c3c59d101cdc6746408cfb8197f71bb7e4","signature":"759805e99c9e10dfbad43113e0a79ea634d265b2332e6d3f309026afdb66807b"},{"version":"a74cf061f6bd3b8209b82a1e118ca0d139ff08d0ff3c8a162ff3ac0e8cc698b1","signature":"c0a5e3199ce900caee714b0cc2ca870402dfff4b48f53553e18882ecb738047f"},{"version":"ffce762ea3b1bdd900efbb8f1cec0b8fb855691fa748d189f86ff0d60f3caa63","signature":"77c9adae7e0872bbd34729c05aa562718c0a3d603c9a436737327935f58ac85b"},{"version":"de1eee0e5ddb0cf05cc199b1d9488b62d1205e30bf2395e1a4a9f6746ec10b43","signature":"ed8310731bf4222d568dd9c616208dfe27263e3e49368627afbc5118764dfa97"},{"version":"ae0faf62b5b93426d4bf6098cb4be5ca7084836b29aac58606ca99c84f0e7466","signature":"3fb6f075567a908d5f112f999e3607da9581f078a2f881fcedf5b3602522c467"},{"version":"3ee27d2fec946ccc50cea576505083d2a8cfd2f14b0863fc0c52316832861425","signature":"1a4642f960483f0ec1c709530e93fc894b4f94209551e5116af84004defa47dd"},{"version":"0b21cc62f28c164ef131d6e5afc304b392b0f0e65ad7a3d0cfdd0a632fd1309f","signature":"bbcf21fdb47d0a821efd28199218b48935e166e6a1cca9df5c2c66f71bf20881"},{"version":"d6fac77c5ef87eb0a08edf3b689da72e2c0aeee114b4de2ef71c6329ef547cf2","signature":"661d2ed6167fef10beac4ebaeadbecdd04e3d896d792ae9920b726efd170cf5c"},{"version":"4fdd8077bbf3e5adae262c207e3e13cadc86f4984ae3ed4124753f5a7b6fd9f5","signature":"5bff26d05c0f3f8aa96be3f88f5dc5b4ec061a61fac4a8c40751222d23a34b3b"},{"version":"0f6d1ec7aa3b1e3d613c8399e2c82d8ec0d193ae275c596df554c6289279a1f5","signature":"6f16862d9aaee2956b25c81ca10ccbfb93d4f586c31a28c265638881d1fdee50"},{"version":"758c24255cc5409471c8c8a85c0436ee2da68747533087397ab330a0ec62ed10","signature":"f5d17a198ea4541a200e784f47fab41c2555e2b2a56ccc23a901a87941fb2723"},{"version":"0fcaf14631739afd726ac11e6450b7c0aaa3f70f7e1ea4af4b874295122c19c2","signature":"e7de8e5f8db75638a60eb39eac3f8d15a8c3315c5f924a250afd23213ccd4bfb"},{"version":"22104eadb81738a9c3951741e14e8ee4cb0414faa5b1a02c379e89cc800ae190","signature":"e92d492c348b2e8b3bec329abf7db30924ed500dc7ce5e4ae0220b16bee228bf"},{"version":"40db719e7f16737e22bb446289c647f19005d91a6ee42577fc8373808e346e6e","signature":"636c9c6dc03659ccda607d8a2e0c80df285571e589aac51600a3e06982b024a5"},{"version":"848b257bdc73b54c167bed01b2db42fd44c1aab77350c9b1fc3a2ce3ff08f899","impliedFormat":99},{"version":"642b071c4d865ff593c1794e06fa1781a465338a37796a7d0e2501daa20172bb","impliedFormat":99},{"version":"ff87d4d02bfc715a3a038c825bb80d6a6cfd1750bec3a0fa6f0e407133b1cd2f","impliedFormat":99},{"version":"0da67df9ad0b921385c37c0eef3de0390b8ef7b0b36cf616fdf3590a67fed1e4","impliedFormat":99},{"version":"8b28fc7010a1cd9c54201b6015c7d6a04fc6a4981acc9eaa5d71d4523325c525","impliedFormat":99},{"version":"e72fd44d087aac63727f05fe82c0c4a984c6295f23fdb9a6290d4d9fda47cfc6","impliedFormat":99},{"version":"fa2cd67056be92f91c496c134c19c4e0a074103d79ffe5dd879c7ad0f3036b75","impliedFormat":99},{"version":"a5e9994461de1736556049ad37857577a0c1238cda95baed68d5997c45f353bb","impliedFormat":99},{"version":"479ae2d0df8346600082dab7eae56c7557bc0436ab0647c31063f3a02d7cc6c7","impliedFormat":99},{"version":"1faf72b15dbf252373a1f4b2867a199800a97cc7079dd3b01087a2f3c11f4a45","impliedFormat":99},{"version":"4af8ba68f5b509c7a7d353e7a91a4014d194779c537acd3afd330980e9cb972e","impliedFormat":99},{"version":"c4a78ea6e862ed9913ecf9b95c8b4a8f77384f2cf583eee7fc4b27c52f4fbaf7","impliedFormat":99},{"version":"ee9c59f4fa245924e3328a2a6620fe107b0c41860367a47a90d07a932e3a084a","impliedFormat":99},{"version":"e2a62c1f16bfc7e305e78143c1eeedb71ad1f272761aa07ff2ad70bb97248b13","impliedFormat":99},{"version":"1c1ba22485be7577e2a73cc103bf6e7a692ae0a025216619a4de42186eb1687f","impliedFormat":99},{"version":"ebbaa82abb5a1a7179dff85377f99c666dfa3a68f8a2ea405bbcf4f5e50149be","impliedFormat":99},{"version":"37673287f8bc80af36be1c23275ed9416bec11ee361b320a57a0b3a2797260ef","impliedFormat":99},{"version":"39e217bc229493f7b355cb2ce07f8600f6266500a6feaad43c254cc0a0f140e6","impliedFormat":99},{"version":"a33d889bdb82f43cdcd8158107c0e25d295d1838d82ee8649390ca0b88e87a07","impliedFormat":99},{"version":"f289d98b575f84044465ab3b7ac81e9a11b4d97cf2a9e92a822e948bc2f0ba7c","impliedFormat":99},{"version":"787a6b0d92df1148c7da1e75d705652030078c19e79985a72e622dc5b54487bc","impliedFormat":99},{"version":"ad09a94413ba6d37b86beaf348b252b378608dec764b67efc9e65d1dc4dff808","impliedFormat":99},{"version":"534611552e459b47ea008079ec9d520fa87c7b229c8a3a08993e8be650a8df71","impliedFormat":99},{"version":"d4ddcacf48fe1a273c71f4b04818eb912fd62bd7c0da092742a7e37a30cbc726","impliedFormat":99},{"version":"83098570d4ae37e31d8c788901c5d094313176a23f26870e78a5e98e5edd7777","impliedFormat":99},{"version":"9a43bf14da8556f0484d20c93074fd98845c06c85587f6b580fedda82685dc04","impliedFormat":99},{"version":"6a36631027099eca036047ab3bf0f262e23239c950ec1c65de700300d223ec44","impliedFormat":99},{"version":"fabd5be6cc2f406cbfcddb145a91a0e341a25e509e1c7521762441a46e58780d","impliedFormat":99},{"version":"80a9eb1f4fd46c863aec7d9c8490702ec6aee2b63ada21bcf231d558f5f0863f","impliedFormat":99},{"version":"72932bf7599a75bdd02788593ec6f060422f0c6e316f19629c568e2473d37db3","impliedFormat":99},{"version":"2d6244e9b7d19e7650ceaf09033ada34ebc2d0590a770707cba8da87bc125d59","impliedFormat":99},{"version":"6e0ce9899346df5cf80e1b45172eb655855837cdcad4539acbfc9305d8fc8976","impliedFormat":99},{"version":"ec56ed06f0a89fa2e3a20d7f7521d017e92decaebfa4d53afa0fd3a7b7a2be3b","impliedFormat":99},{"version":"236b90e223fa7a458b8561e87327d3737c8c83cac9ce4cdfbf04b3098da851fc","impliedFormat":99},{"version":"d64b03d8342c4f4d51706659a835c45197b9940b8938b0656bdc4df15d06f630","impliedFormat":99},{"version":"8ff0f34466d5136ab068a15358b99a958095d1c6e7e11c67d607111f81933fc4","impliedFormat":99},{"version":"98a72afb1b77b1c3f15beaed5662feb608060ccc604fa1747fba9d9deb070f80","impliedFormat":99},{"version":"cd5189682a722b13ec340b2bd112bd48b899bfeecd69d629bfc78166c15b64fe","impliedFormat":99},{"version":"a4017a3045a75c68509bc69bd314d91f7d4e1ec3f255416a86efe7dadfc0ee64","impliedFormat":99},{"version":"19599db9634ba72f2663db5b76de48dfe250280ffb4bb158109c97eb4e5b5e0c","impliedFormat":99},{"version":"f5a0ae8b389c104a6655117a8e4ee1b563c4d7cb33e045e4ce433cd6c458adb4","impliedFormat":99},{"version":"566247adad3c04b6c5b7e496700f3f23d05b07f31d983ab47fae1aa684b048c9","impliedFormat":99},{"version":"d10e1723404ce7559b75ab341c7e85b1ee2c97a871fe41630e47edcfb1bb1621","impliedFormat":99},{"version":"19b360e4fd7cd6683ab5455093e02c7c42dbbbd63ae5bd50f91f55a8709feb98","impliedFormat":99},{"version":"ee5ac98eb5ccf9bee886f916ae88856ac220858f4363362c094add66a0d44780","impliedFormat":99},{"version":"02efcdd69ab7a028c7fc316316748723763f7d40073f5b74f5136f9ded5c3073","impliedFormat":99},{"version":"35c834f84dabbdc3b595dd35c2208876af77af86ec3e0f4b622ff7f901843e80","impliedFormat":99},{"version":"dde618b9a6b780c35bffa2075f11ee29adabeaff3dbb73136ac530fd45035692","impliedFormat":99},{"version":"6902d565ebbc9b4f27b81f50a769ebbb673d299090146fc4d645c59b4433b36e","impliedFormat":99},{"version":"ac0e664aa993f918ba1006ca2bc107bbe326ec96341a61195f9b3054a9571a84","impliedFormat":99},{"version":"b184444a122ee085c61df92f39b23414dbe7adece24558bfd1a0dcb22687119a","impliedFormat":99},{"version":"b8ae8c7a851b19aa288e08fbd70e734f5aef3d1bca3a5844dd31658f1bd18f62","impliedFormat":99},{"version":"85377ed2b6029c8c1e851e1acf848d31fcfcc5a9264e726a00e046ccd68288ce","impliedFormat":99},{"version":"aa096547941633cc25eb4b24af41984906ca9e502d9c06c88e0b4bdc2a54b602","impliedFormat":99},{"version":"2b69aa435fea74564e7388f7530a8ce8dd5c9f9c6a67cf74aef6f99922f05885","impliedFormat":99},{"version":"6853837d5850cfd5322fa38f190d4afb7b1ad9d37b137a7fef26a1f489a48b61","impliedFormat":99},{"version":"60bc42d137352b88caf900df4bacbfee40c73c02b56b853e0a6d23a3edab7815","impliedFormat":99},{"version":"d90817a097f2792dc8ebaf9bc08298f1ab6cb18b4287c8cfc1cea297263df6d8","impliedFormat":99},{"version":"3cbfe6b48a9c4b5b6283f7fbce0c1f5ccf0796ac8b1a077893eeab13fc17ef73","impliedFormat":99},{"version":"01e1e0a0c437c0c64b0e55fd5b3123398c25b058fae214ffce0ff9a345d58777","impliedFormat":99},{"version":"23e97994d2f64dd504174c02b5ed713093f1f8c0ee4c3b587c7f12a641b8bcd2","impliedFormat":99},{"version":"fff0fc0ee248874a1f8d12dd439f1c26a8be008a18b7e36ee65c3e8cd634fe18","impliedFormat":99},{"version":"7e6a11a7c6f9070215e73bbf9620d274ef45979eadc8de39d50ffe6fb67f095f","impliedFormat":99},{"version":"c34715ff893e99af41dcf4f63b3eca2a45088ef0e4a025355204c440772278c8","impliedFormat":99},{"version":"cbc0e98cf745d22c786862ea94c3566321c06e04109f461d8f657a3c1151d057","impliedFormat":99},{"version":"35a5955d275c446b47dcbd8347f41e8ef6e230c563efd38f62ff715f7994b767","impliedFormat":99},{"version":"2bb58f627a12841ae367d97ee15993590a5cee4a826326e2a8be2bd750fca9dc","impliedFormat":99},{"version":"646d361245ec8052afcc7b90acb3c7f6098bf1340b88f32455e63f0369ddf1c5","impliedFormat":99},{"version":"2f6f7ba3522444f3d3e1f6d4a74ac37a096fc3dd292f902773d761a9eee57620","impliedFormat":99},{"version":"921a2668977ae600f6de2a4c19f53b237ed196ae5ae3297043b38781c11d9af4","impliedFormat":99},{"version":"37072b862cae4c819e335ac9eb855cc398719a50ebc60376de9ddae801610a3f","impliedFormat":99},{"version":"6473fc970e5fb3f18fece3e8681e9ad4454adf295be54463ebd74688b8b5051c","impliedFormat":99},{"version":"4e54895c51ee23f08f62fb429dbf4cfc1772ce34f6ec77855a3bb805dd16637e","impliedFormat":99},{"version":"800509db7d0b61907f28dea506dea01b57d2aa3cfffff03c78ccad04e8ceb976","impliedFormat":99},{"version":"887778667559bb4b7c64b006650210ca831f903c055ada3a069a8f08790c5718","impliedFormat":99},{"version":"bd96c9f72e9a439499bf19a4405d205fb8c2da019fdc9fea988c25005e76c200","impliedFormat":99},{"version":"9fe617a1d5e7c5c4290dd355f1bdbe1a80574d765a2c03bbf49181b664f11f0a","impliedFormat":99},{"version":"9afd17a7e1d2b474eb24bb37007d0f89ccbfb362ce904cd962a1eca5a2699efe","impliedFormat":99},{"version":"2841695cc12ded91f69e66e4ef44be524ad02c54bbe257bfe5802e3f6b851b5f","impliedFormat":99},{"version":"1132807f0a56b00d253a76bc21aeb23e79c8ba8478c52ec75ba9fcbd81738b6c","impliedFormat":99},{"version":"effbcf17a843123b20a54ce8389b29a26d12c056872f0dfc76a27460b22f716c","impliedFormat":99},{"version":"0e052acd94182df2373f96e362f064715c7a782452166e2344c91a126fb41d28","impliedFormat":99},{"version":"b7bce6b962d325bdd11ca9f3394b411f37354bffc995e798ddf66a7ee3b9de42","impliedFormat":99},{"version":"96d66cb0b5b2a0b1e2e6172e6bc163b5345f189c699852c61cb866812bc5f3a8","impliedFormat":99},{"version":"31e4839e4dc630cf7bc9f86c1afdf3dc2cdb4b8f6c3e11d12ba38ea18f4c421c","impliedFormat":99},{"version":"5b94968e8400015a4904bc1ba26ebcada2fd366c8fdeeb873904af54ccd4b423","impliedFormat":99},{"version":"1513e36e2863b615eaccce129355da5f5d8e169d4416d25e71e47dea8d2d35c5","impliedFormat":99},{"version":"7a128061e6e84e9375c9b46f84a0cfded49f537e8a41b42db0c72133666ab9e8","impliedFormat":99},{"version":"1140a35eddf2e3b9d706eeaf28ea74e969ecbe52e0d0f6a180d0753d2b8272b6","impliedFormat":99},{"version":"5e9cf2a12f0d82d2bb5989cbe663707bf1f3bdccf7cf0fdb84105712b9788e0d","impliedFormat":99},{"version":"ad1a1db6939b787bd9ae09f997f9b209cf0e689c72414090fb9cb7989163df77","impliedFormat":99},{"version":"95e857dd9e4984d5694b721cfe2d66430805db29660e212c2f681515ea08e8e3","impliedFormat":99},{"version":"2e8932517228de42f8b3db669c4d04d177367283d2da199b1a59cd94d009e65b","impliedFormat":99},{"version":"5fada2edbc2264cc0d7ab6080e8e4d4e3d5dfb9ef494b4eac9c8e49b90f30bdd","impliedFormat":99},{"version":"615d06216e7aaba7e4011cee475b9ef6d1d873886118f178bca21bc38ecc10a8","impliedFormat":99},{"version":"7ddf86abeff5aa521f606f9ea9ba2dfa19df8ee1c76ea838d9081afad9b28f68","impliedFormat":99},{"version":"ebd25c9c141e447ee6ba794c80c6878ebb39c42ad135a0c363d275af9fa6799f","impliedFormat":99},{"version":"4132803c2f4af9b16bd01853bc98cf15ec1ec9d11529665bc6ccff35bb742774","impliedFormat":99},{"version":"efb8e27827124bc3bf96b81288c0278c722d10f2372a1bbbb9de1943e784022b","impliedFormat":99},{"version":"1400f49fbe68fc416c2d47e19f6bc29a99a5480910bd560090a27fb6b68fbb45","impliedFormat":99},{"version":"98312a773a489dd6b924350b9ef0eeb1f9646b7e1b294501b582b67dd735cb3f","impliedFormat":99},{"version":"a9410e9f7d26ad51166dc6e55de1f0efe893750b665a4169cce9a1c46d793d18","impliedFormat":99},{"version":"4218cc9758b6c35b4e98131e96d6be902fddbc194936e0ba71a95767e11072b8","impliedFormat":99},{"version":"6f29d6927bf60c969a6a5ef57231d63b81e6820b6a30c22eef57821b5c429ac0","impliedFormat":99},{"version":"0df226906c522ff1903482f4fbb83c039fbd0dca93bd1b3e56baf10ab58bfa15","impliedFormat":99},{"version":"02f4852cbefa35edd7752e35e228adc060a2c98251be70a9446f64e196029bf0","impliedFormat":99},{"version":"4b70362f8a653d862fb4e5b65aec7943cb237e89c2409c76e6aabbe52952507a","impliedFormat":99},{"version":"8c83218e92cb960a020ce6ccf208c7fdd29fdba50f824ec9f7804b9a47c175d0","impliedFormat":99},{"version":"1da27ab546abd20e493012d7088a55cf1a00c92b61eb06aeb7a25581c6f9ff87","impliedFormat":99},{"version":"be74c0d9577d80d8dd6fc04a8830a2bc3ddbbad2570551305072dfd985534876","impliedFormat":99},{"version":"de3347bf58d986a47125ca7bcda6268d55c78d6006e165f59a03c20be861d95f","impliedFormat":99},{"version":"b1ef1a2530ef3a4308488bd172252a506f35fe16622d3117573865c2b6ad3485","impliedFormat":99},{"version":"840d2806690ca5764b0b3393d63fb4f4eed660f2fd1c60ed5a8aec3a851e775e","impliedFormat":99},{"version":"b222f67a18cb2bf55641e911467ca5f1cc4ce664824a3d4e2ffcc1eb91729be7","impliedFormat":99},{"version":"5a191a0753935e35e8560d6dff2a0bcbeccd0850d11a7429283e3061fa8bc8e9","impliedFormat":99},{"version":"e933510d79c03cb4b5ae2b910b72056332955385cd91774913ab04c9f7fdf00a","impliedFormat":99},{"version":"3a3dee0f5e3155384690cf45b07a217a6b3de5e1edb4e98ec8be5fbf3e500868","impliedFormat":99},{"version":"db2ed9c0a4fd561f950cea441d7833cd5763720e91856f7521d3d5f29fc4b7e7","impliedFormat":99},{"version":"c8a7aaf671a49f7f836c4bc4aa4fed23e5c8da16eccf72ef2b2a52197663e6cc","impliedFormat":99},{"version":"10856b8f8c6dc7fa2da62848f65f977524b073c6fd167578f21edda81832687d","impliedFormat":99},{"version":"067de9fe31618932f08e63ff479248118a39461669a06b6f6d438e7ef364cf29","impliedFormat":99},{"version":"f67169b04c2c933f4368c15bcea7f744f05a134dad020c6d418f7cca2f9926bb","impliedFormat":99},{"version":"078af8b67c2d6de37753072c1759f1215fb9846cd4344cf83a266b10fbbcd790","impliedFormat":99},{"version":"e27b61cd6a2953ce7955274ed4dafde236be2051b1a89d10b5640306b7d3b86f","impliedFormat":99},{"version":"91beef8d07b44eb328aa9d9c3db98bd79bde320adc5d1556d3fa7f463a90c3ce","impliedFormat":99},{"version":"7f7f86c7d1bc4a9f9e4d68fe0702f91667419056e6746494a66a7fd2882c8660","impliedFormat":99},{"version":"b87d0cb8854aa7f797bcc7f46ab0522fd091828dcce0463d4dc58b78e1f6ac10","impliedFormat":99},{"version":"934478c63db3268cc99351178a969840b2b93a2d21a4d165813cebe5eb6dc419","impliedFormat":99},{"version":"e1ac2ee125d07e130dafcc5727922a802f33bd894b3bdec61a58653cb25a105f","impliedFormat":99},{"version":"80d81e5352828e06dd7d79a0ad35f07087aa0c4f2aa80f8df7e67855ab544997","impliedFormat":99},{"version":"d78aa09669af770ed71d8a0d5b1e2ef23abb7a17dca11e1bc02adc9cf9816fd1","impliedFormat":99},{"version":"acc4b06dfbe56e355495b3571be65265b7bcba54ae6addebfc4c34823a3e8201","impliedFormat":99},{"version":"80d964c6d3fd00733c20f85ee9fa70c52e3459f1960adb17e5bf812cf9604ad6","impliedFormat":99},{"version":"1df19943bbd19525aa3e18c3f98f49ecdd788e07b5705d99c8579073771dcc06","impliedFormat":99},{"version":"8c2a083fb5fb302c0954709938e53e7810da0aa2daf489757af9dc6baa2f3b7a","impliedFormat":99},{"version":"fcc4a7940475065b3291a15623bc4e8db0c22f23dc29be00ec377892a805eba3","impliedFormat":99},{"version":"16f35e4256a94b314c98eb75040cb33ad9c430075bc29c53b43ede6405705700","impliedFormat":99},{"version":"a257b94f9f5403f63026dee4f4a95b9015742f8e23ff6eed7837f97f2ae501d9","impliedFormat":99},{"version":"254175b582a422c45bd9701e93d6ef9f6cf242c6247793a9a2e05770e1add917","impliedFormat":99},{"version":"c4dcab273dad7aaf0d3b4e0ca48e948aeb3cc269ac359301181fdfbb2efde033","impliedFormat":99},{"version":"d21671ff0f21081ecb19567351dadc8be7ad9443e26183d971ac658684479777","impliedFormat":99},{"version":"617be44c8811d411b4efc7dd13e57851bb1ab71f7e9d1a9eca04b7d0db0e1b35","impliedFormat":99},{"version":"948af5f3081a8e683756251a3834ed5a4ae6e4faf16b66abcc44b8a13e72d08f","impliedFormat":99},{"version":"af437043c5e9a8105f0e9633fea7ae79d1f7f89357897e2df99c6f3697c744fb","impliedFormat":99},{"version":"d0bede428ef73b5da47f0f1bdc440480a863a1baff3e6a6b28db98535efcaa6d","impliedFormat":99},{"version":"44015602830f6f90e043f14702f04e7f48ec4f2ce8a9925116fceaea73a43b8b","impliedFormat":99},{"version":"edadfd0ecbfc573c016b93064b18ec0ab64b17ebd252e5636c2ee55f0f6cd82e","impliedFormat":99},{"version":"45ccec80a9c659104e28cbf3dbff13ab92c57c4e1fad9b38671a0c9299afd4f6","impliedFormat":99},{"version":"1b59bf4043df6f2b48ac1685a0a6c3953ccdb49b1c7affd3364624f77ff58f0b","impliedFormat":99},{"version":"ca4a3925cfe8fc5bac902ea30a5fd441987ee1776ddf5a353715dd1c6579722a","impliedFormat":99},{"version":"658f055f615e8232a1f5b30753a0a1ce369a70c1dcf0685953f48d7d4d508ba0","impliedFormat":99},{"version":"341aee100ffa277e0737387b9b9db69280e6dfd056166e18656de5bced0e7f01","impliedFormat":99},{"version":"2cac36c32274e1e7faf7fb3bd1666e69763b07b9f5330eee6911352d3e6eee96","impliedFormat":99},{"version":"aef33b3c102b63e7e89208ec4982f8eac7168774b08b05e8c43e967729ea91e5","impliedFormat":99},{"version":"5788b512a6212523eb032c6898beb98d56dd14c84e186a786901c1b3cae527cf","impliedFormat":99},{"version":"e2f146177df266680126ba19e4336ffc6639094feb27b37d276577f8c3d2c186","impliedFormat":99},{"version":"e616fc8dc6c82cb4d47ffd510e180c7ea96a0ade6702f011d56d36707cbe27b7","signature":"ffb3e6a6be2aed1862c98e13255a030ed6205c7c04676bb752f526703468f17b"},{"version":"6e2b7ca92eeae99563d7947d908030de1dd4b28412495913cd06e39b12590e7d","signature":"692f5fa6f306b8aac3a4df2868958c4e1667da176c9695c7f961a30f27aec54c"},"f05d3e578bce30cf813093d2f435bc47cd78159af50856e246c3fc1e34217ddc",{"version":"37b49ad60620db9db26ff31a64f5a70a1cbe9c4598ff5c236433043f9bc63f04","signature":"6a96f44bcdb3e22101416e1bbdf5bcc70ec23d5215186089857e82b1d72283b4"},"73a91588a99f175bbec275e0920d6df4031b954868cd260f1ed655c56d9ddeb8",{"version":"8f9ff94ef30f33846efdf40f521a79a9be87ac799dcbadde1d5c78a96e99151e","signature":"465474ec3bee370bcfb97e5467cb7f69af9f9815f65ece79d3252895357fe234"},{"version":"e10e48b0273e8e6f27618e9d9d3add55e9d93e00fe873516f61f3a639b7cd214","signature":"df93b3bbfc76a8c7d2583f152abeae935c9d36e878ff04c1c38b5a32e30c6ecf"},"b0f240b28e3760a1488d18190e11a8f888c689b42d220960e3d80b65c5554dd0",{"version":"cdd349eacbdba5e99bb6a964730a88ae56d345e4e4b7ec431f0fba2a388c3fa7","signature":"726f054d27a53c3efbd91d9107e7de9ad7a3656f2c5a0fa8ea1f231b0b4639ef"},{"version":"6f28fa615d59b0ed4a06d8b0210d35af05403442b9ae2acdafc3394222805a53","signature":"2bfa1139c2eb88b5f23181bc6324ccd747acb70bf1d6370f8429813be3689de9"},{"version":"acf8f72e32114e5c11e8b32e6dbe6a09363b61b4e52f4cf2ae705aa79bd42705","signature":"e5a6286dad5913ab2714b6804286b074c9cde94943c4ea01e4db94b920aa2880"},{"version":"4157a53fd2c433399cd9fe6db68d1da00f345c253aeb478b49a750ffbf9f35bf","signature":"62176cf724ba9b24e250b40ddfefd428d8bcb9a21f41faed8d33f3c275ce0008"},{"version":"0c996be745af11ccf07b28eb3e007aa4277d01b16f53259cb355daafab167abf","impliedFormat":99},{"version":"27c1b57e01b13f914e9d3507202036d676222057d6fa1032332e2954296b9d45","impliedFormat":99},{"version":"7348c35ce10f8323a515ea6a6c237c0dc7c3fd5e491c4dacec2a7b93f0dfcd26","impliedFormat":1},{"version":"258e67b2638408b67fbf5fe6c953b8f2dd2a69f9171d31c9a976cd2329716e4c","impliedFormat":1},{"version":"a3d80d033a651259b2bbac8d0a03bc2e583c00e310a3829608ae781e4e689ca0","signature":"6b6cecb2fafe1e5163bffa9be0229c1f6821f6cec28022f8e6e50d163277a14b"},{"version":"8662560538394251a3975285b8609b5505d442a92ce710f866c2f48e17d186b4","signature":"084955dd9a619e88baedc4583e0bf2f5982c7889ea6b6c0e34ffd08d76aaecc8"},{"version":"1cdb7130ae272ba5c573f2f96d00344602bdbc6acefd5a198658e40ad793f5ff","signature":"dcdbb04792a2ec09fb7960f12e877b8696c489ffe664fc190ee113623370cab8"},{"version":"fe93c474ab38ac02e30e3af073412b4f92b740152cf3a751fdaee8cbea982341","impliedFormat":1},{"version":"476e83e2c9e398265eed2c38773ae9081932b08ea5597b579a7d2e0c690ead56","impliedFormat":1},{"version":"1e00b8bf9e3766c958218cd6144ffe08418286f89ff44ba5a2cc830c03dd22c7","impliedFormat":1},{"version":"ae00023c4fb6d8310666f6f047f455331ded1cd758182decd54d7f3f2bdc7e73","impliedFormat":1},{"version":"1e380bb9f7438543101f54ecd1b5c0b8216eea8d5650e98ec95e4c9aa116cdd5","impliedFormat":1},{"version":"d0b73f1df56fbd242fd78d55b29e1de340548048f19ac104fe2b201dc49529ff","impliedFormat":1},{"version":"287fa50a234cad0b96ebba3713fe57a7115f7b657dc44638fbce57c45ac71397","impliedFormat":1},{"version":"c42852405dff422a8b20dd3a9ada0130237ee9398a783151aa0f73474c246aeb","impliedFormat":1},{"version":"d3260c8d6fb8ab6b92c412c3c0b793dc524dbcc6737300cd4cf22198122479a4","impliedFormat":1},{"version":"f7ebfaa84846f84bd01665f4dd3773ff2b1c38c7992fd1042cd9132bf0afc82d","impliedFormat":1},{"version":"b03829b7141ddbc20c9da5de4f8021ef99b57b169e753d28ba5582d02bc9d5da","impliedFormat":1},{"version":"d1c49ba10ba80d18dc288f021c86c496d5581112ef6e107e9e9c20f746ee7b0a","impliedFormat":1},{"version":"f3c5ea78b54672f9440be1a2ae3f6aeb0184f6a4f641c3cca51949e9cd00a258","impliedFormat":1},{"version":"9ad68f979b78ae71d8cd991b87b5317b5959867dfe5970de811ec40a09d6e1f4","impliedFormat":1},{"version":"d91e9e625a2903192e9a63361b89330f0d95c340d9bb4602b89f485e9f93cdd6","impliedFormat":1},{"version":"176a47d228081ad51c1d62769b77b064abbeb6827115033cce1cdeb340a8d46c","impliedFormat":1},{"version":"b5eaf1cc561810ebfb369039a6e77a4d0f74bf3162d65421a52fc5b9b5158c2c","impliedFormat":1},{"version":"7d12ec184af986cc2a0fdc97f6c7f5a547ecdd8434856a323ea7ff064e15f858","impliedFormat":1},{"version":"8535298578313ba0f71a41619e193767baec9ccf6d8fad90bc144bcba444307a","impliedFormat":1},{"version":"50bfcce750d2a77d46e96e1d6c80f2a6309eb86f6ffee53ed07864b68af3d824","impliedFormat":1},{"version":"79b41324d28fb94f7304a0151990ad712346ceb1907fe1ce5e892145eae8f8eb","impliedFormat":1},{"version":"3239a3f8c29d2b0db0a4200b7e6513e95d16a183d4d823e54cb5c98f4c53e183","impliedFormat":1},{"version":"fcd0f914ab3bc4c1f9be14537f8e5c3a541d3210160151a5224651b525c8c615","signature":"9d07febeda5c46d0f000d47e92d98af2c877ee4b3006ad98b8d476103bb6b09f"},"d46d431e4b957d3e96ca1436c82de881945a23a860eb3db7558e0410122ed6b2",{"version":"fdb4770d84f3553eeaff24b8edab19c1f3541c0b6a74209366f178df5639c84e","signature":"78785628635751d04e31bc8d06900c34be54e724100f4e2cf158af9fa110ea8d"},{"version":"329ab8d42829159ad84178d4b6c66117192628e28be80d7da010202ea66e0874","signature":"07627fe71cb70f4617e8471c7919fda7e13b5187daa70c21c73b60ca0f55d9b6"},{"version":"215dd17081473a3b02d6e83d0a11eec0d748d7232bc8b8f7f6d4069988440121","signature":"dcf05a557d3591a75d84be523c2710d0511f38ea6f31c659153f3908c8aeaf29"},{"version":"42bb666c2ff708243bde790212d396f883aaf5951c421fc8ccc8ba04c2a7284f","signature":"217a48e44b57072db0592f7f4151676d95f921ccd0b19b43b29c90c4b1aa1dad"},{"version":"bbe365d60fdfaaee3b33f3564cce299b50d2eae2353b4ab305c691c32528973c","signature":"f482709338acc2f7b98ad4161feaaf1bb82887ee3d6297177da66ed2a4babc74"},{"version":"58b08aed1d93830e4839d18d2353a1e53acee22224f4d9cf78d4a04dbbd43676","signature":"e40e07dd2e95140343a34749a2e9bc385b0b4d613f63d70edf381d3128a3de11"},{"version":"0487f879c4e9d756b39de91655d534b04b14219622991d8b29c2ecfea0dac23d","signature":"2a9b6bbf44f0241ce153f5bbd4bc79390bb44f7f9fade2bbf7ea99eb7b8be23c"},"de725cfc1ae6654610a6435be06f99f56256a5ceaea0d975f183a664d5d27ef8","eb98ccb2c071423a0322b7bd593af15bac9757f7d4fe6458f0b4b9163c9a1331","0b7e8e97a1ccddc76628442b3abcb4d3871c82a75c4beefa0817a6a45f9e1b7f","42fd787b1ce34f064429d88f3c1d097f544828567e0fb6b2feec65adce7da555",{"version":"c286e5ba6782f449d7a9c20cc2cb6d29e69587a8386527c534a9ebd19ae2019f","signature":"cf5546de6b03068d7572be4acc7f1f70d682f01d4eaee9325ffe10a65abe0130"},"865531ded473f776fe61562857baf43f0a5135300244f6c60f3a8443b4045ed7","af963b857f8fe42955adca2df05a1d5ec1a45d0050aa3c1a191060b4de9f3c3d",{"version":"713384f186240f37c9db30ca9f1bd0e57c51b37242f16ca3343cdd57b32cb69d","signature":"c2d05c6e88e3062dd5c4ac0d009b7133c1834733fcbe938304d6beadef346a42"},"557b12fea4bb7a097ab366fefb8ea8702b1d381abcb352cb0ff8b7232712a632",{"version":"8236726367c5526c6c1d709c74601628dddd92c51f52670ca4188e8ce24a5c50","signature":"d0d5449dc78a144ece9568f28ead7df6fbc5d158a4a5c262541a65f7270d8a21"},{"version":"e1197c161198f0668ccd10b816739d2290b9a309bbc8ee3669fa1f11c864fa29","signature":"5d632aa6f70e68f13a0cc9e7fe0f9d2a1aeda0beece411ca6645bf3e99500d51"},{"version":"0b22cac8f8316be536aa1ebc7c26b89675712e82d28efe708c0bf4e378dd78d6","signature":"50c09e0fd940256acc6d2500ad014c7692f96519a75e78e78bebd0ba39c2ad21"},{"version":"48a13d7b1bae9d0f4986f726f7770455bb41f65abe1443bf779118b9fe2a95b0","signature":"68dfc22d24a462e2344abc4d521b2b7191d8e1a719f72b5d92fe3eee76d18d20"},{"version":"ba847ef5fad418657e80d8c7fbe52f2686d8031c892fef012afff58995b4c491","signature":"6b961b79d53036ccc89f7fd54a21118f4a35ca748a27137a4909a809afb6f73b"},{"version":"a9be2f55e6aa568db6be9e8c8abd5291a324452cf655807d68ec070ff05042c2","signature":"1e7b5e88710a715154f36b27a9dada7830a3a73805d240e2cbbe3eeed0470792"},{"version":"4ac66d56ecfa2b98bcf5d8c7657f31ba68402dc9fe4f58a051df3513b2d4ebba","signature":"34b741d193f967d16d6de7225768c9b96837278e25768ae94ec8cc753c6239b5"},{"version":"7d84b1b077c7edab41068ed8c5f4e3061c1d951b74570891b54252df1010909a","signature":"f5b31ea5c95342d542a85fa18b4535fd1d537dd5f51183bf9f4eb1de84a2ed7e"},{"version":"9239966b831f530aa0ef65eaad60759e6d5325a8d72988802d1bdf8912fe0300","signature":"8bea0d2144973adcd289740efffebda8d9e88ed968ed93b83db32049659cea9c"},"ef5f37dbddcf3b7ffaf0f587e593ba4d58d049270d6a305d4cd7ba6992a2f0b6",{"version":"cf41b71fc9ebb89ca6ade651890dd88cd7b58e0a883757a0a267ace1d494b60a","signature":"0ae1ff66496844371dad779d9c1252d5408f1c501484e0a61b77d58836cdfb43"},"2e92115ff5ff08aa0e667976ee5b0095decca799bb0aaad22dfa07f183fd3627","bd1682f5e4a07b3b31adc3eddb7815273680333312164d84cc24e60a24b8f897",{"version":"fb94cfa8d0679a6462d90f1e24afeab3d35d4a2b6b99ab8726401779fa9cdbaa","signature":"0a8ff7723198f7e297d1828b8610fbd0dc68f9562a76bbb82f9103b5c9d0fb4d"},{"version":"acc21026dce1a15237551beef8cad60ddce94af9d6318cfd70e9ec69b6832036","signature":"ada89866bcbfcf70286a847ba4b359ad945a3764b1f48c58be169e86ca5c233e"},"74b0bdf820584ceeb68c8433b2bc864e61649b5bb32e8b24f67ae3e0cbc8aae7",{"version":"b254d327ba875ec10730f02cf49339012ce06b36d20144f0d6539cbc0fc0ffca","signature":"3eb6297db29f7a01c794d6cde913940a6e90a57e6910dfa97116c58a4eb62433"},"fcc0a50c5e3f90f359a8f92dedda852ecd49e601dbd142500a4e3776d7eab802",{"version":"a2154dcdaa3995005c51bd3b620a0cf5b0689ebc4b15e9cad383b7e6851a7140","signature":"620ad41781c5847e7ec69fe9c05b3905ead928ccfc8b976ebff2317a91c46b93"},{"version":"3cc139bec6e431116b3dd9c1093ecedb8c342eecbc810c239789aa230f1c7e5e","signature":"7792154e93de1073eb1f32502c390d4b2e3453bd74cd45536e6c4e67c3446c60"},{"version":"b3f1934da127803c71831466e54b0f7025bd5027cf55a8e2376a5fdb44a9d6b7","signature":"e94a0dc2d3aaf38d79575ef2ff61e8028dc30f2f50658190db79fadff5d2c62d"},{"version":"bb91a261934d24dc171ecb910faa11834d4cb5787c9f64ccaebee2bf34df8636","signature":"231f159118b312c80f90d688bd93f0512c411ba9d2f18fc2f535aaec33b422dd"},{"version":"8838eefccb48045b690e35d5b193645d7947de62a38c3d276a33f41a7c2b6098","signature":"75c3bec8d605e8c23df450f9cb9d3adba5ef84ddaca0ef026b6bee6bf187d274"},{"version":"7a5faad57685f84f7cdb930a4dbbed1575a7f26c3e6099b892a15039939435c4","signature":"10707b8b90dccb1f296257a17d0ba61e1f4fd12ab253a5017b3c9e18c979fff3"},{"version":"43083b6ba397838e2592e72788ab433810f2a24004311b1148351e3eb2a46084","signature":"450f92c18dacabb6def7bc222386b717e05c098401fa83efff0bfab5fb585d78"},{"version":"a9c84c4f6102d9f64bf82efb90ebee670833f331619afff5094ce0884359b620","signature":"b9e72785cf996c11e31be2b6bb741097518b35459e67dfa4140bfef652e937c9"},{"version":"0b6bbf8f2472fd6165bb64ea496c276596f38e328c813739af57d076d92ad5f3","signature":"89c91899c3ce20d28d6d9adeb42e5f4981a61a02e2fd7762b67fe147c1ca56e5"},{"version":"47b11f7d4624effbd6f1a38dcdf3b12074e395e53b4c823400da7d84f913322a","signature":"0dd204bc08786865dd87c1b86fd4b9238775985c9e619807566bb9429e73171a"},{"version":"039032fb6ea12431603653567beb699625dfaa6e1c6b2823e2ab0c51512c178f","signature":"340fd007891fcc91aa77ae3c73eaf80b73b8b53b6a037541247af135d035b43b"},"c8c0b67db68d46041254706257cffc21e54982c8ede96ad2c5cb522635d752ce",{"version":"bdd1d8e9f98a0b8c787ff5a5ad1f80d22b3168f01923a101e668b45a30046461","signature":"9802128fc1d284c5e7426ea2e26badc156fe786e447d8211f30f3a3565112323"},{"version":"e5504f426980dbabe3ceea7f70d52729b92c0f5e92fcfadffaba0cd9ca71ca00","signature":"1bebf7a5ff7c83409b711adc21cb6c484ca301cab2a3b5bba4ac5d9c3ca62fa8"},{"version":"aeed44198b656b855e5e19f7db8dc389b9332a9583d6d67804e5e4b7e41dad8b","signature":"dbf9c26ec2912cb1081cea92460b93718a338da4f97f217a23949a5a9e24436c"},"cc9f3b500e0d30155e2ab3b573f633251ee9c4bc6e5c750d78715891481a15bb","6ce3c85f5d239f14e3500c8404d4b791ee5c0641453a1437609a64bc4debadb9",{"version":"4f32f195a07eb1f759d7a6e76d09b72a914fdd2931259531de5b557358300581","signature":"a74b1564f3086fa5a07b6f8676551a52937ebdea25878e21334247a454beca2b"},"5c13d5bd5fdd1c32cc6fc164540460c74e8678697a2a77925814a168b8e29790",{"version":"0b22fc196dafde3c55ad03d5c9cd90dfab0d0d8706f07892f9a2d2c9de8edf45","signature":"efe9f692e3950e8248d64046f8ebbf2e13e4f95869157c23b404fabe6ecf6305"},"d27fb55a4f127d78c1751c5ee62dadea5f09c788fc0923ce5bc2f380df1aa661","2523a19cd741f74b9bbf9303478f1bed1668bdbeecd8d3cf2671c4e7fe3329cb","92dd9b72c75f8654c6ef9ba91f1c9df50985bb1d6e1903bc1fb5596805f91fee","d672288c6a3541e3503efcf0d217a63a6f5559c9ce763654dad08f92762d5f92",{"version":"1e782b3c876c9e73bc703908d08cba7baa8e8e9b66adc2ec0fe89ceca1afb29f","signature":"2ca14924b821ebf515b4b75bf5e8729f56e558d0d6f7b6d2547ebd486720373a"},"a42173a51a60ce435800656ff8d25a123179682d5fc7246f6dd60a78568d62d8",{"version":"76835ee6817825e4475155bd14ed5df11e4109ead3f8e4634b750635241877f1","signature":"21ef79d3310744ff36549736d1f77492d1b1c99e6ab01fdc8a6c25b44fcf5d15"},"1d343369670133f7acdd3d61dfc9c391ee12fbdc6538c9f133262ab65605d1ff","1896aca0161402c9221f6f591d99572f47d020427d9268364711d481c174b7ff","9ef01bbd127fa96aebd049905832ce16e7b629c7e329ffb8607098fa2b033b7e","884ae5e03e00513b74ee67df037050f8bbc9dab0cd8ebc722226a5e2a7c584a9","3a53b3612f3958d2c122bf5a344db69d703fa3c9044afb5dadd73bb652654fcd",{"version":"743672a8c3549a555a4f30734bdaacb19c0979d156a8f3a4f5ff2ba9fe4dc54e","signature":"07c5942a5d558761b271f7b4b7530037617febe53bcbaea806cd9241f44961f4"},"d81a74e2c1b3df89a4ddfb45693f57fc6de6e07ff85fa85a2277a1e508218647",{"version":"4d202757d4a005e0b1f9ddb30f326c2cfe923ce9b364e36c5f56c43ff31ecad5","signature":"ae201b6a7ecf8e415450eee9cd2ec5ac373da31346c681c470500cfd1805c66c"},"c531ec4187cc04b720add8fa2dd014baa8ef3bae33bfc08b7d1dac58fc82d102","c410f031999ad0433b6912734446ab3c3dbed81e0a4f6fb55c6cd01fceae0bf6","243b13ed79878c0b9fac82a5ef53785a329e9f12f06666a6d8ddfcf704371fa7","81d67946387af1bfd26e24507f8d4dc2ade2e48d3495d195cdbdce64b8b188a9","68b2ac219fe8892112392206277667eec9a57eb62c2db43d3b45027c7016f159",{"version":"0751926a7e43de52ba0c74ae0a781d41555403cc868e13f6299e52c266a13ee2","signature":"66c91064979de77ec23e2146699fc2b952c3cf0367b87934021b50e046d41d40"},"481cb7ee7b2446414259be0b860f31c15b1874727321c325db7b294b86070138",{"version":"b32202fe9e35218b0a8d87c3bb16fa5ed4a93eddc2426964fbde3585161aa193","signature":"5e3aa6b1a42f3e1d42597f9cdabefb89bc883865f32fd0d9fedf82f6e415f416"},"6e71659f6b65aec852b18387a5f1415fad8f3ae612dbf17addb2e071e0a0b977",{"version":"725e181b7ffef798a01f699ba7c72f7bc5bd548ce4ebbc98c1ab30b3faf3960d","signature":"e41d642f0381d3873bf5b3afc26ee442d816a503ee98aabe42a40ecb8eecccd1"},"f1408a2ced63baf7db0d8de74aa41033ef062aaadb8848f87327c1ddef2a03fc",{"version":"02e6a92168e028ca9dfa6da732995018486fce21b27d59bcc51bd94a130a5852","signature":"4731a05cdbc90902ec899db277e37e5f2884a1de5e095446e1845c875340d72f"},{"version":"0f28d903d9961f77bfbd514935988df10a5a22e3aab8ed799251613d0e7821f7","signature":"2df9a7124c5951282528b142dd8140de662642620731b5869a7ff466773198ac"},{"version":"5e27110ae79ea157247bd15b5a682842d99e60f00ba3897522415835a5edaf1f","signature":"55f7e060e53e001f4de2cddf8c5a64b05b748cb37d035230460d57236de16399"},{"version":"4a345550c2e307241462d7292c39184b2d26f6245780047a9a733db3d66d8f34","signature":"2929aaa51d5e996f437d356fa63a9296dab88dc05399dccd50d92933f9795af6"},{"version":"984a76adcf001fe919b15167b840e8c49cde3f107d4434df1bb7d080c2d6ba05","signature":"a8e5e38e1a942a0339d643daf52316b72fbb1e9066f47559bab5ea3a8c5a8ab0"},{"version":"ca1f0f3a223eea5f791fc08ca19e32816a25cca94b5673fcddc706d0a41028b5","signature":"978ff61486f5ff685f7e0f01690d789cda9419bf95deed0e914a6326ece957b2"},{"version":"ab960709b0b47eb08f67f5b6531e44206edc1daad5281dd7bfe5cac186a354d1","signature":"f4351130a24f2f42413ca77537f35d31969f14b2975d2519a3b1e86ee1be2f7b"},{"version":"9dc55885903b992eadcc7a9e2ec45a1d4d7a112010fc84615f344b208a5986f1","signature":"72fe197007d100723523beb4def1f7e6d19ad60ffa3c73f9100be9088a65ddb8"},{"version":"21e0cf26f35fdbc964dd8a5702ed1a1a1a81b9bcacf150e041b546fa4a48cc0f","signature":"943aaf838f611dab905818c4606637f9df5439c87c6774a1cadfdcecfc465c72"},{"version":"8a6a3fa00026fd4feec9da4bdd655ce5ab60816d09df1857ded0760a09aae603","signature":"ec67da3d1af27d7f67e7a4ed6c2926c7205e7ee23401a9e6d09f95d62122d5e3"},{"version":"7f242578e52e03b4eaf029a8f5e8f160c18793d06878fc9e1d15893647858b96","signature":"2c4e4a33361906d6b8590c1f05cf4fa314e6ab1435bf4a0bf75c1aff57fc4110"},{"version":"8473e4af6a1ccfc7c658eb6cbc344fe101a1a46e5423a343623853c682d646f0","signature":"feb3c99dc72d797dcf39fe41834050a6f6194e72bd4ae653f5c44b497efeaaae"},{"version":"094e476b1981b2d857811b663f5b7a08d964e943d5aa38ac01c92bb72b523a32","signature":"5944a73ca520c4e81bddf2f283240e0c6a12324fbbc0c298ecffc08189d49d7c"},{"version":"3252193df18ef5f246a798e3957d4597096b40ea176397bc6df1c51310d40ef1","signature":"068023508e92f65c171decccc194ef81e1648a83420e025bc62cffebfe4b10d7"},{"version":"547a5260e8817dfde91badbffce9d81fb13c1754695d5c642b343995e009da77","signature":"781d69b754fc71a3a730d9d74d32d3f49d71a38c5a827199e4b4106929cfcb61"},"dd564dfa7aecbef5bb8b9550d5fda3e4eaabe3d0c71041a268a330d84dc7bab0",{"version":"47f111e2a8c5cc3df84fcffad3d72fbcaa976010fc0f82b4e493df268c04cc6e","signature":"d52bea618274ec22c5a07d8788dbc5f1be575cf59f94b084c3a53f77a6e31fb0"},{"version":"bda9a940cafaf73cab942a13c874fa754e09172e51262114523d567491a39f13","signature":"2b6cc1a42215f75f277baaa50b8d0fb562409d983f1b55ea7dfea308f5f40e41"},{"version":"3a79f5de999e061fad6833b7a11929907f44940b36b2102f8a4d01c1a3d28e1c","signature":"6319e10a0b439743508cddd066722c11f71bfb6b3816566f79448065e5133247"},{"version":"9ebe5e41384858d2f30eab9f378a00ff2d1fbcb620961275f686a4b1eb2c9231","signature":"46df3b90500aa646e8ef62e459f6bb881545c69786b13b9d821db667dbc0dc79"},"a18572f3d33b5ad5c17fcf48b1e39d5918de94d3083758ea4c624ee5ac8c1614","94bfc49ec8b9c34ee50b3658fbeb7fff5f501f54eefbe11d229e22f04beb8725",{"version":"0163bf08ecb350a94213025ee0849f017df5a6b509ebe35b6ec3c6fd8f255fb7","signature":"fab32c8c3d3bc803a26acb296e12c47948f8249f09cf38e0fe6f3859ba362a5d"},{"version":"7b0043353b79fa93948463a3b812c041d03efc4a43272b37d860c0b7a3c86492","signature":"8ad6f8d83135def4e923ca0ab054ef4f55fb00fa7fd1a2f4fea752b17800d0bc"},{"version":"cb4448a47a4b1da5d8bc2ded78bf3df6049133bf97977ea5b7efcd78428441c2","signature":"3a5b0869f407f8b570ad9e74ee6a6a54e45378a7e09798f2dd50c9b67219b819"},{"version":"85d0db377f3d1de6402540415a4776eea70ae5b426e2f9ddc9546cc17ad98c86","signature":"e146540eccae50527bc9657d0b95cccdde222d9be2f4a321b55774a5cebaed68"},{"version":"4d4acf3cf1bab59440589f329514a73378b4592baa00f23ab2c14db2f7099d49","signature":"5649a6b58425403e6a91b5d3c792fa759c912adf033ee2dd979fe579ab83d002"},{"version":"d19ce91ad3460675a7da8fea4f9439c29749fcf0bb7689a086c9f4498ab6f170","signature":"960b113200860addfb6f9d69e34328a23fa5f393130b036e6cafabe9e1d09fb2"},{"version":"4584c9c08f3fa88aaca063fffbcde7974238840049e3106252772e9d46821818","signature":"ec2644121212afbf9cb045ef19a1d2697644c4967616b3374d1ae7888e22c9e9"},{"version":"5a58b484744ce9f58527278a0cee73131efc7261f25549ef6dda74fff834c67b","signature":"14092cccc419f225119fd920f565d2ba6b033fd006e3bd596b725053d5eb5b95"},{"version":"27d9ac3d95aea0572c09fd67554c982ed276531c30a1f8a6865b7b8ef5ea754f","signature":"abeb2c9cc4a1bb27c220535346424b1f8f3974cca6480df44cd9ea318de951fd"},{"version":"9470d2129e127207132c2f6e9c226a0794e953ef6dfbef7b42405e1405962545","signature":"830c7cbe0d60157a6fd995defda0675e90f4c3570221bb63d9d6e3a56d45b0ff"},{"version":"460da0c0a8f42d87b9275ebd21866532ae74db98e940b48dc5f05edab9a6f6cd","signature":"795012a5b28b1ff49150dd4d3fa6490e3372d675f0a8ac640150849cc4c441f8"},{"version":"2d8f92afaedf60a03e610e8a6e8f35c523d121286850b79ae6800698d56c4c9e","signature":"336fde69bccfaadb36974cc268028705ca2c9b75e36fcb070c6dae832480e4fd"},{"version":"70811d46037dd34c56560c1db7a64d75a9f47ac51d0ccc96ca9d74a3a5b1f226","signature":"7c181c8b6f319745f24094aa11f69cf3b0bfe22f80267df6ed4a8b5ed04c1a43"},{"version":"42c81746198542a0a2351b5cd02262ad985b4a16ba92ee58b3b01712d209e971","signature":"934f32a7071a572c867a2f946405c62aa8448f12fa452a45d1f0a4e9c27305e2"},{"version":"905fe999da37afdf2efe21ed5cdc643fff973a78a7f917745bc51b850e2ca3c9","signature":"985381138d7658ad2e05c482a722821180f6d366858ec19c03b5d42c901da917"},{"version":"b854e5ffb57531ef3726e25f01a9a8568db8f641c02bd4286b8366eec078fb64","signature":"8418309205cd7a30d2e8ea73ae671a37f919048475ab9d708cdcb554a4813a31"},{"version":"ad2932d1e211231e088762fe958b844d5c75bd97483086edb0e6a2803be74746","signature":"fc4a1909516c00b0a88e516f5564dba70d7c13db1fc6a650c424b4b81e67eac7"},{"version":"d30e67059f5c545c5f8f0cc328a36d2e03b8c4a091b4301bc1d6afb2b1491a3a","impliedFormat":1},{"version":"a356d9a0ba90d10ec6c0fa33386c0b0e2843fd6f0a49513c44f7809926ac25ff","impliedFormat":1},{"version":"f77db1be13db8dcf8c7a268c1f235c1ba1e4707e829175cdc237421b3c346f9d","impliedFormat":99},{"version":"05cb95655ecadfd1230547b84367d1c4d40a4bb6309545b8dc4d1638a3de1a50","impliedFormat":99},{"version":"e980a9cf8404a649ff3a2f0628d76e4469613c02b98bd3b922756d7d962476c9","impliedFormat":99},{"version":"f8adbcb59256526bc69d94fb5c826e812ebd1321b30ab35baa9997d74d45dd73","impliedFormat":99},{"version":"050a4570de5ad6e47cc9ac9fd9db7a26e57dbe1daadadbc19b20567941f8bf1a","impliedFormat":99},{"version":"5ed040255a4d5181f8ecb4ba90b8b38e0a6f1becf0ed860ca75b6e52c46db0bc","impliedFormat":99},{"version":"e22a49cd604cab3b62b1968a363d7b182edcb23d46793ed12cf5cfc6b1597f39","impliedFormat":99},{"version":"ff1b4730f5d49d37b73ee2db3443145daa0bfc7ff9c865134d871b08955e389b","impliedFormat":99},{"version":"8e64b72fa289b7f133b8cdb7d837f73e30ca7eb76ad88e1020d97c405c94fd7e","impliedFormat":99},{"version":"1f907507e41cc3df66b4521b80134bb8f7afada8d31c10f7100c93c90ab0f84e","impliedFormat":99},{"version":"6bb14070b70b4c9a897a4f5088af984e6e316b420d00d82fb962bad577896723","impliedFormat":99},{"version":"46e17953f7ffbf43d4328fcb5983e0ade2932fb56e84181e6929fcdcfa7c7aa6","impliedFormat":99},{"version":"113aef5576cd65f310927b17ae5f6ac8745c542a660bace5f019034d536fbd04","impliedFormat":99},{"version":"ddf0fdbb010c94978c1151441171f0aac236a23b6786e9f6332f745527d905e9","impliedFormat":99},{"version":"a2c1678ec68c42795e2ac068a7d026b61680357d2a881c9df211dd0f83d077fd","impliedFormat":99},{"version":"2fe207d2e8662abb709772fff1f3ec3116a4787b5caa4e862daa5dab2753edd7","impliedFormat":99},{"version":"a7af5f01007f450dc8cf2cdbbb11f4d4bf8bf3faa869d21267db5de74ebf665a","impliedFormat":99},{"version":"709cb4986cbe2b58ac3bbbad45dbfa24cda1b62c794c73b96e9ff1236dd0d5d1","impliedFormat":99},{"version":"afdc9b1fd1937d9b649bca2b377d1144cc9c48158403c17cfd21b6e1e8b25099","impliedFormat":99},{"version":"1d47324801b498d62f31ea179f58e1f3eaa1e607914504a7c92fb5465affb851","impliedFormat":99},{"version":"95fdf978302838125ac79d9d5e9485d8fa1ddd909664bf5cc3b45ec31f794fda","impliedFormat":99},{"version":"d92bf7d6d30c85e53b961236ceeb099e73a1a874849d038a348b51383087872f","impliedFormat":99},{"version":"e56e4a57ca5aa762d67fd3d16471c47592469944315fa5e92b3b09c83eabae91","impliedFormat":99},{"version":"f3d31927b7a3d0f2f119a05a102af2bdd1fc4f759fe43d508a64a80b3b341f6b","impliedFormat":99},{"version":"678700fba88589e28648a923e4b98ab60f3f7df4742412419e29f95966da4475","impliedFormat":99},{"version":"5a71b307074ef3d2794c4104248b7a3cad5f486df204da65862a7d24f698fc95","impliedFormat":99},{"version":"9a4496ad6d48bc801a122c11e94ee1e3f0710bda38b125573f67f5cb0add1733","impliedFormat":99},{"version":"afa5e16f2ad07d847701e3bde9e7ab36f87e0e3a5c0cb7998644791a1fa3c5b1","impliedFormat":99},{"version":"98cd9124b5d8438db4b4dbd247b2c68ac22b6366a43e6dc4945ae32972f157fc","impliedFormat":99},{"version":"dc21879e45f3a023b5fe459c3da5f2f3cf995f21a1ac533049d8950ce394c045","impliedFormat":99},{"version":"622d6ce66ac838d5d7e968daf4ae760cf49797e3fbfaa2b21d01e0fb5d625bc9","impliedFormat":99},{"version":"ecfa30418b2200ba6496b5f59b4c09a95cce9ea37c1daaf5a5db9bb306ee038f","impliedFormat":99},{"version":"3b56e30b1cbe1bfa7710e88e5e0b8fa6eddc7c2e67615f73bdf8637af68403e6","impliedFormat":99},{"version":"92a8de4f8f6595bf1eb24a19aebff7371c66ae8751f2e045edd9e25ca435e4a2","impliedFormat":99},{"version":"01810afb0ed31afdea0846cee91e85a474727d0966e5bb57c2a4a732854deab1","impliedFormat":99},{"version":"c874e98cd875727ea62fdcd978ac9e067ce07cf7493aa4b8b193fdc3b7318eea","impliedFormat":99},{"version":"455e843c1f8e0df452f101c9ec0b63ab8e749f296c947249f8bbc29bff58c83c","impliedFormat":99},{"version":"eadc4c556b494cc52676e084eadf0b60fb2cc6e2408d1411eeae5cb74068ca86","impliedFormat":99},{"version":"3b8689266e8fb628ca2068ff610ed0b842ff4e407c3a914358ef1895dabfcfcd","impliedFormat":99},{"version":"fc741907f6d8158b2c4722932d745b11dd41f9355a5b325c8cd3cdfbd966d76d","impliedFormat":99},{"version":"85ef9d9ed8eaca020810c33588676bb777d626dc6e7ab3340c716db2b94affc5","signature":"b7bdd0dd41019192624068d8ced8bee71c172ee5400be340fbc1981faaf9be11"},{"version":"9f9d5b2d9bafebb0bd2a8c06773bbb0dcfea3b4d4774b11bfbb9d5f3bb0e5253","signature":"0a6e8b8d8fb5c44978ebe6ee3b126173413eceaa26685cf6a655d4a3e045b1f4"},{"version":"77ea29002ea03c29e59665ed169988f24d5cfe1e692c00ba4b90ef9136740841","signature":"02fddb3f9d305bfae364e1618d29f2b10ea82e7a3577f1a4f43bd8bd6a35fe26"},{"version":"f40b5815c28b8b82e19ce8d998d3c31228d5da2ddac69fef4d531a97095dcd93","signature":"a74609c36a11ec7ee49d39f1180a3712c1d3b00c1de5f0dae5c494e6b396ee15"},{"version":"d96e46cbb66f0d9ea20678665c46278c814b820a3ebd2b56b98a4ad4a7a13a4e","signature":"20e95c1a7cb1d725f42bfa7bbc6373bf01a51ba2a97abff843876425de6e81ff"},{"version":"0b33bfa39a566015d65f5e1c315309ebf3db33cf9a70746bb85cce278e4beb7b","signature":"2a2e7613ca538e6b4d761de332e77ceaa0892c1d1f957c9005c48f9a3339cf2d"},{"version":"41f90731815f574646456002ede524a4ef0fa533b2334f27d0893e40eebff094","signature":"ede9816729361897e2dd6720a4fd65e95a9b38f68b4b37e0b8d4e62aa1d179e6"},{"version":"d57fa1874e902fcd4b2425132c9d354133baf44b2d5a245db4f1409bc7c1a221","signature":"29ccdcae487d54fc1aab33bda0c11a2fe817fcb84e14abe6cba8286423ae9187"},{"version":"5a55460b8491bf0203854724b1cffe3d6d91de7e936b877424fcf42bb275643a","signature":"ad2dba18b42a48557e4da3ae490254ed306d6777266607c694f0569e6b901a88"},{"version":"a6593a081f837d578cae81e3173c05d31858fe32c8adcce58605b34cd2bfe154","signature":"3383d7720a22c25cdd627089c4486b5f55d6de17c8ad98d5e44e2922a205384a"},{"version":"d67107c86386306ae50d3d22f46f785cedab6ef14951ed0df08c9fd3eaabc175","signature":"abb42d09423a617eeb8a0e378b2747bf358d313e12d1d02ade80562685141399"},{"version":"a1947c9d6d132ee81f6e3d8c20a4ab6f968190d6a9404ce8137d47a57db23077","signature":"1f8739671eb4d4b7da809092317a5de94be2663bab6c00888cf5103d22fb6c48"},{"version":"a759579c15c6337995eec7beb36f2a716ee1a3a2554e70c27a2d0bc2bf230de7","signature":"eb2674849a6293cfd4d7b19d9d1d980e69af305319bf986e14e9fe84b9f3d0f5"},{"version":"98875dac45f10f45a4cfc4c5e32908cd4f926caeb9f77ab59a81cbca9ec1d39b","signature":"c50e79b6130f0690f2d77b3c1bdf1f71cefd48d43906ed06f1d3c409bf243abf"},{"version":"067222df0624bbe9a0e331b7018f2285f70de2a1c4623902f6d88d118338a443","signature":"a5d604c9bfd5b2f06cebaf49a136fccddae3eb781e6874ca407d2d10a367fcae"},{"version":"ae19f9f22c699e7c8da49497fbe230a299241eb159749418ec14c4ee7bbf1542","signature":"59ec1933725eb5cd08f95f737b735d2e679a0258e034ccdb02081e98441c5d1f"},{"version":"5c87657869976b5baf49689f8fd7c63057d3bd7cbd31f1aaf234e1a4d81c1a02","signature":"8c0f14735dd0136a27bd3689f2419cd48a63a7986553a14aced5f277452f307e"},{"version":"f4f5ecd259e37ca45d2c46cc77f145353da477e104bb354f341012ebce7c726f","signature":"36865f631fc6b253909172dfb3c412d782efb3cc11b1458f2da07780e7a480ad"},"73381941b607a32f8e4174c7fd7266271ce8e5031e2918e0422f418636e85159",{"version":"8e5d0313cca65ae8b6ba97100d99222d84c145cbcfbd21a163b4ac86889600f4","signature":"892526caba9bbcf54452f10a4a32952098a07ed7319308d619fecd3b34cc150a"},{"version":"d966d794b466f6039ad23fad32e1893e777c587157bf6edb2b65ccd1d894449d","signature":"771d73b6e135dce76f2ee3f1242635da63d6bc5c735950db6814f913fa8a4e9c"},{"version":"780af4457e897d4aead4ede3c4b353b1790ec7c3c10e5f0532b615e4fe19a9aa","signature":"0e29076b918e64964b59d37f3baeb4cc7142ed688fa9ed063eb0d29cbe7cc11c"},{"version":"a409cb812a758508ca4f687af6e1403538e325566bba01fa3d2ed4a564b771ad","impliedFormat":1},{"version":"5c4e9734f897cb7e9f4ee599aa53c38761712c0dcc5b61b3cbae6afb69004506","signature":"00f64b8d5647f694767e32a6f73d537490af26d7bdc77a2c770e229f616588b2"},{"version":"fc01f6c90430c59fbe7044bcf9b903ec4592a46df566afba57be59b1472dff4d","signature":"ee99bcabca9700a81de9d736094a7bb71e34de4fa8500d86a0d2b35016b874ab"},{"version":"b16999073be5de5d73a1aed4fca18d63655078c35fa6e31f1e202640b49543cd","signature":"95f0658fe83b2932e9aae526fa289f1f83df8af277fa6f5ed884030c58145b46"},"09ff99a29e078c26372f959e6f86019e4bd641a36d67fc1da2fe02d2f64ba578",{"version":"d58affe96551545c160b5c1e97995b0a1389b0d83aeebdf121662d760be0b3a4","signature":"d9b01b7789f71152d477e3a1d78faba5ce1b9b5c7720ab86884d2629ed9c45ca"},{"version":"3cb0a73c4dcc0f14578aadb7cd64c9e6a525f642a3133e79140cc474a2e851e6","signature":"8de7423458e0d94d4d4bf94122119a2c40f183b696a20ef1603377c0a230d607"},{"version":"66f847958c8f4865fc4f7e17d645d1f9fbdfb8809adfe0b308d85ea0f436e8f7","signature":"2c31be273ceb93da6aa29fc5cd535c8dbe7f4d543dc73a997e18b8a1fc39929b"},{"version":"05d44afac75c1e73bf384df94114369ada04039e12164b4195d016772ec0d518","signature":"d48438e766db842d1f3e86e4bacdd3c14f92c25f87e5995142f0775f2d973d5b"},"25adb93f80886428e7cfc6dfe8409a7b0c28345ab2934424c5866a4a8c3fd4f2","10a415d6879dc8bfda654ae5e4ddd7711c3eb4a4bd62f7dc28a093e1db3da50a","b139a5359692b30e48193b1f0630cea0bc57434f6ef5299f5d9cd863b16e45f6","4f4174ff122ad29be67f1a9ecc15a6a097abb75717f10f2eb7e2398d938f687e",{"version":"39880b5db846d72e6ba4709a29f492b8c3dff6c013696a0cd19d62509ff7f3f6","signature":"0bcb3e12624b425b565508312bfe0260166d38e800a868429d36a8caac92ad8c"},"f4a624d8299473c3b5948f7baa55bc3e69c3c403dbbe2dbb61f502dbc75ac36a",{"version":"5b7582eacf206ffdb3186a8dbb92747662c83f6ba0141a683c21c92ae3f4cfb1","signature":"2ddb45d94d98284b96cac4ad6db85ef407d9b3457b5c0cf0af0d3c824e4798b7"},{"version":"d1cf676920260cf8c2a4f4bdaa1c5d82e88b83678b08a376431d33ab57a9851a","signature":"8581b29ac4393d65e14e6ba70c0e99195d0a6f65b9371b19432dfaccfd7e58ef"},"096b3b6e450b64b7e8675596d83897ec56e2622a42ecfd604730889ac300c548","7048be757297468dd2ea827383c7f78d32cec493dba5cea8c292110d873fcb11","754668546097cc16c9b81d14fbb72ae38963abce9635b44d4733ea2e7dd30a5d","cdd6440ee9e17930aacc0ed528ca5be815508677dc20067ae7462cd5fff295a5",{"version":"7e2cac0df63934401c5227d8e96cb3781bdb33c2c2c8aec4a9ac7f2347be715c","signature":"f2efe73facd77a16da52f90cb1cff57059fade454c5e1bf2f27912c4c81c263f"},"641c15b868fd5acbb1eec44d2759acb9a8c8c68f31595617af761bfbaf9e2398",{"version":"d788281fcfe7d405c9796acb20f250601ef55711cf5b316ad9546c18c7888b32","signature":"df225a1d7cb4b86a1dcd751c8ca2876e731ffdaaedf410d58b8e28109d2be78d"},{"version":"fb3012bb3f40669f1c66e9271bddf8e7f34863f0709fb14e5a7f6452113627a7","signature":"c8302d5e9c03df913953ea5d6c71894bba3c7da2300042fe4cae256afeef9f15"},"2d80215517ba7fa45b4e36416680db72bf369a69e175b891e9256272bb14a8f0",{"version":"978ae458625843cf01c8b5555f58e68d13917a75760aa16f4724506fec24fcb0","signature":"4e32311f21f4d967cc3d34b707cb99e0fc25724403cfaa582ba68b296110225b"},"4bbae4191bcc6c403b03c4aef97884c51e3377ff03c17bc726e44c39102e57a4",{"version":"71f81429370bc39d60a56c73864288e4827de2d2243136e7466a102c25f03b98","signature":"3c127278f7021cf39a457fd90272fbb2a29a2ad7b71f449f60089c06ab1dac8c"},"c5d0f5c874ef6b692be456d680530973723277bd356592bb39fa3a080ee9a21d","4d98a04b9bc90edbb9d211b6f63b28e7fac14fdb05eac76bf0188a01d8c93d73",{"version":"b3e6654a1a8411f9a04f741ebebfa99662493df86dd790333e6c3f25a9ce444d","signature":"24e4496d7c500d026ad5569d8913ad68485981140fd9f74084514c57e97610c5"},{"version":"9de6265e87fc95b775582e2b6ff7ff6ff9c169bf711c3cdb9cc85e4d2c1a59c4","signature":"96e4ffdcf88997c91fbef460d118c5c506bf61abc9bbd110dc4c47b56621cef6"},{"version":"b773a44812bffa3783671d179e20936e201def2942c9383ac067068dc596d4a3","signature":"19d752e91bb78b3e1055819bde4e070ee2c383eb6781c65a94e4504510254ef0"},{"version":"fdbd8aabded45b6e321aa7518b431f89b5dff38dea5ad26617e524104a00ad63","signature":"8ad5c6f0779f4038311ccba429c12f4c468ec47be41b81de781f35d2ce78ce32"},{"version":"3cb85796c812503915ba61e01eac7abb7ebaa680abe1d8366d21832f580faeff","signature":"31ba7ceb1a86423986699344bd5a409866c93e52f931d09354d8a888c4931d04"},{"version":"27a4608a6e8a01a12d99afe0ccd59eb120809e375dcc49459ebe7ebcf2af48fe","signature":"d32e971a40eaeff90f554fdff5fa4d790313934de31cd9b6d23111aa54c069d7"},{"version":"572451217c2f18e84f8d7525cc7d8c2fab7f352508304c3a91235d35be0995bc","signature":"a83543698d6732ebbb3ff6e94074caeeb773304ffff88f7d05f6c1c2034c5432"},{"version":"f8dadf0cee69fc8138c79dbaed0f4d81434181f01876285f879523fa76a2dcfb","signature":"65d444df655f0f9017edf684563f82115b7fc21793edd5aebe39db32bd38e58c"},"75d561557b77c2fffdb3ae3c51ad9ffb2cc17e23ca4ddacff9c9753358641317","dbdf55a7a4c984c49ae7d44521087a144896c2b5121523c8688caf61ca21e26e","3270e26de310e5e247299d0646b6d00da69456103d3ba8c5e01b40fa42b7be0b",{"version":"59a0fcd37943dab311d7e05d458a7fbae9da751b0b36d2d200b387eeb541aaa2","signature":"b443faeeeefea02a104fafa568fbb8c96a7c985f001163e181c856e5214d3052"},{"version":"eef56b423490400aa25fa2e8e53d139ed9851b11971cdb0764e9aa6026d8930d","signature":"ddad4215db4e65e26df643c77869ebdaa8a6a8b7f344b6f1be11a534e761f1c1"},{"version":"232ad2caab9c4d1a99d487907b6557249f91219cd17c09820bc8e7d335758e73","signature":"206cd066062626bb530a7cb094297bda2d47773f039124e4a2eb46e3d9462910"},"d5bc7702ae632b814f96e53dbef96c9523b257eeb554449363a88718f23f6d4d","ebddf78f5679a763fbe33e6de2aea09d9341bb92616a1c3449eb1b7123a73c0a","ce272c524f77137235409ecca06a595cce5bbfc39927caacdd836c9a962fe8e9",{"version":"7613dd9f9a6369e40579fcfb6239234ad0fef79ef763603d12b1081cc83377af","signature":"3061c33024dc202baa290326b652acba49aa8524761cd8b05b732c53a84a809e"},{"version":"20b990bb50578f8f12d8ccc48d53c1151c939a4cdbe7e0c7666538e7da4dd9fa","signature":"cd9544655eac656831f2dbb996db075118b1d5e1a04582010ab3e79d7f1e8024"},{"version":"e3e0abe073e7a3b6e9421f4f61bcfa818689b60da45d7db28f4edccaf467928f","signature":"ee578405c47be054abb4f7e3f61c69ca8f84307cd534ae35453067a41fdafc53"},"abd59b14817c2c51c2030f5c190206de2b0906c6aec39c837e8d481d36de0a51","a5cbb226d808aead8764bcfadf6fd0f907c90a19b998c7fd542670cdd14c1535","0b379ffdc73fa83304f1d55713fd74ea42e10c4918130d07aafabc8f3b247ca8",{"version":"948d1ff585a5296583bca538a93ccdc6d8be6b8f3b70538cfddc38985d87f7ae","signature":"685752e808632b60525b0542096bf632df10cfe142a1786d01441e9b0cff18c7"},{"version":"7f81eb9bd68c02e7b2f6c6a566bc039cf8e53c5acba416546b462104a9922f6b","signature":"d849b4aba5b29e81051f8e733d6e15e87e9072712549d6ea52cc4adae538199d"},{"version":"4aa5a4248799cf2329228a7c4f3ec7a188b9278c40ee778b1d10e281c92dc6b4","signature":"7877583d2968dc42e5a9ed506825ac661bec8502394efca99a5fbd95dc029288"},{"version":"151ff381ef9ff8da2da9b9663ebf657eac35c4c9a19183420c05728f31a6761d","impliedFormat":1},{"version":"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","impliedFormat":1},{"version":"96d14f21b7652903852eef49379d04dbda28c16ed36468f8c9fa08f7c14c9538","impliedFormat":1}],"root":[499,500,[525,544],[559,574],[731,742],[747,749],[772,892],[935,956],[958,1013]],"options":{"allowJs":true,"esModuleInterop":true,"jsx":1,"module":99,"skipLibCheck":true,"strict":true,"target":4},"referencedMap":[[791,1],[793,2],[798,3],[799,4],[800,5],[803,6],[805,7],[806,8],[808,9],[795,10],[809,8],[810,8],[811,8],[812,11],[813,12],[814,12],[796,8],[797,13],[807,14],[815,8],[817,15],[802,16],[823,17],[819,18],[530,6],[818,6],[820,19],[821,20],[822,21],[824,22],[831,23],[826,24],[827,19],[531,6],[825,6],[830,25],[828,26],[829,27],[839,28],[833,29],[834,19],[838,30],[835,31],[836,32],[837,33],[532,6],[832,6],[846,34],[841,35],[842,19],[845,36],[844,37],[843,38],[533,6],[840,6],[847,39],[853,40],[849,41],[850,19],[852,42],[851,43],[534,6],[848,6],[860,44],[858,45],[861,46],[535,6],[747,47],[862,48],[863,1],[864,49],[868,6],[867,50],[870,51],[865,6],[871,51],[866,52],[544,53],[560,54],[869,55],[539,56],[872,6],[873,57],[887,58],[527,6],[874,59],[875,60],[880,51],[881,6],[884,6],[886,52],[883,61],[877,6],[885,6],[878,52],[876,6],[882,51],[879,6],[748,19],[888,6],[889,62],[891,63],[890,64],[892,65],[561,6],[935,66],[936,67],[937,68],[749,6],[562,6],[938,69],[939,70],[940,71],[563,6],[784,72],[785,47],[789,73],[941,74],[942,1],[943,49],[944,75],[945,1],[946,49],[526,1],[956,56],[954,76],[960,77],[953,78],[962,56],[959,6],[952,79],[958,80],[951,81],[955,81],[564,81],[565,82],[961,83],[566,56],[567,6],[976,84],[569,6],[970,6],[971,85],[972,19],[974,86],[977,87],[975,88],[987,89],[570,6],[978,6],[979,90],[980,19],[984,91],[982,92],[986,93],[973,94],[983,95],[981,95],[804,8],[988,51],[964,51],[989,95],[963,96],[990,97],[991,95],[992,6],[816,51],[985,51],[998,98],[571,6],[993,6],[994,99],[995,19],[997,100],[996,101],[968,102],[1004,103],[1000,104],[572,6],[999,6],[1001,19],[1002,105],[1003,106],[969,107],[966,108],[965,109],[967,110],[568,6],[1010,111],[1006,112],[1007,19],[1008,113],[1009,114],[573,6],[1005,6],[529,115],[1011,1],[1012,49],[790,116],[1013,48],[783,117],[948,51],[778,42],[782,118],[949,51],[786,107],[787,119],[788,51],[776,120],[947,51],[801,107],[792,6],[781,121],[856,6],[857,51],[855,6],[854,6],[950,51],[777,51],[794,122],[732,123],[774,42],[543,51],[737,124],[772,125],[773,126],[775,51],[735,127],[574,51],[733,128],[734,51],[738,129],[736,51],[541,130],[559,131],[542,6],[540,6],[859,51],[780,132],[739,6],[740,133],[731,134],[528,6],[741,6],[742,6],[779,6],[499,135],[500,1],[698,136],[700,137],[701,138],[684,139],[688,140],[708,141],[687,141],[690,142],[682,6],[709,141],[683,141],[710,141],[689,143],[679,144],[699,136],[712,145],[703,146],[702,6],[705,147],[704,6],[711,148],[695,149],[694,6],[716,150],[678,151],[706,152],[677,153],[715,6],[691,145],[707,145],[696,145],[693,154],[692,145],[697,6],[674,154],[673,6],[675,145],[681,139],[686,145],[685,145],[713,155],[714,145],[676,156],[680,155],[597,157],[576,157],[632,6],[612,6],[644,6],[575,6],[623,158],[624,159],[590,160],[577,6],[586,6],[587,161],[588,6],[589,162],[585,163],[578,6],[582,6],[607,163],[605,164],[593,165],[619,166],[595,6],[600,6],[596,167],[591,163],[592,168],[594,168],[598,6],[599,6],[622,169],[611,170],[609,6],[610,171],[625,172],[621,173],[639,174],[633,175],[642,176],[643,177],[613,178],[629,6],[618,179],[615,163],[670,180],[616,181],[652,182],[651,6],[658,183],[657,6],[660,184],[659,6],[662,185],[661,6],[654,186],[653,6],[656,187],[655,187],[671,188],[666,189],[672,190],[584,191],[581,192],[580,6],[631,193],[645,194],[665,6],[650,6],[617,195],[635,196],[634,197],[637,198],[640,196],[641,199],[647,200],[620,6],[601,6],[636,201],[638,6],[667,202],[649,203],[627,6],[630,163],[604,204],[603,6],[668,205],[602,6],[669,206],[608,207],[606,6],[579,6],[646,208],[583,6],[664,209],[614,6],[648,210],[663,6],[626,6],[628,211],[722,212],[721,213],[723,212],[725,214],[727,215],[728,216],[726,217],[720,215],[730,218],[717,219],[718,219],[729,6],[719,134],[724,220],[553,221],[554,221],[556,222],[552,223],[551,224],[555,221],[557,221],[549,225],[546,6],[548,6],[547,6],[558,226],[753,6],[759,227],[755,228],[758,229],[763,230],[765,231],[760,232],[757,233],[756,6],[771,234],[764,6],[761,6],[754,6],[767,235],[766,236],[769,6],[762,6],[768,230],[770,237],[550,6],[545,6],[248,6],[897,238],[903,239],[905,240],[898,241],[906,242],[904,243],[907,6],[899,244],[900,242],[908,245],[909,238],[912,246],[901,247],[910,248],[911,249],[902,250],[1014,6],[893,6],[1015,6],[1016,6],[894,251],[145,252],[146,252],[147,253],[100,254],[148,255],[149,256],[150,257],[95,6],[98,258],[96,6],[97,6],[151,259],[152,260],[153,261],[154,262],[155,263],[156,264],[157,264],[158,265],[159,266],[160,267],[161,268],[101,6],[99,6],[162,269],[163,270],[164,271],[198,272],[165,273],[166,6],[167,274],[168,275],[169,276],[170,277],[171,278],[172,279],[173,280],[174,281],[175,282],[176,282],[177,283],[178,6],[179,284],[180,285],[182,286],[181,287],[183,288],[184,289],[185,290],[186,291],[187,292],[188,293],[189,294],[190,295],[191,296],[192,297],[193,298],[194,299],[195,300],[102,6],[103,6],[104,6],[142,301],[143,6],[144,6],[196,302],[197,303],[85,6],[202,304],[357,51],[203,305],[201,51],[358,306],[199,307],[200,308],[83,6],[86,309],[355,51],[266,51],[84,6],[957,6],[93,310],[445,311],[450,312],[452,313],[224,314],[252,315],[428,316],[247,317],[235,6],[216,6],[222,6],[418,318],[283,319],[223,6],[387,320],[257,321],[258,322],[354,323],[415,324],[370,325],[422,326],[423,327],[421,328],[420,6],[419,329],[254,330],[225,331],[304,6],[305,332],[220,6],[236,333],[226,334],[288,333],[285,333],[209,333],[250,335],[249,6],[427,336],[437,6],[215,6],[330,337],[331,338],[325,51],[473,6],[333,6],[334,339],[326,340],[479,341],[477,342],[472,6],[414,343],[413,6],[471,344],[327,51],[366,345],[364,346],[474,6],[478,6],[476,347],[475,6],[365,348],[466,349],[469,350],[295,351],[294,352],[293,353],[482,51],[292,354],[277,6],[485,6],[751,355],[750,6],[488,6],[743,356],[744,357],[487,51],[489,358],[205,6],[424,359],[425,360],[426,361],[238,6],[214,362],[204,6],[346,51],[207,363],[345,364],[344,365],[335,6],[336,6],[343,6],[338,6],[341,366],[337,6],[339,367],[342,368],[340,367],[221,6],[212,6],[213,333],[267,369],[268,370],[265,371],[263,372],[264,373],[260,6],[352,339],[372,339],[444,374],[453,375],[457,376],[431,377],[430,6],[280,6],[490,378],[440,379],[328,380],[329,381],[320,382],[310,6],[351,383],[311,384],[353,385],[348,386],[347,6],[349,6],[363,387],[432,388],[433,389],[313,390],[317,391],[308,392],[410,393],[439,394],[287,395],[388,396],[210,397],[438,398],[206,317],[261,6],[269,399],[399,400],[259,6],[398,401],[94,6],[393,402],[237,6],[306,403],[389,6],[211,6],[270,6],[397,404],[219,6],[275,405],[316,406],[429,407],[315,6],[396,6],[262,6],[401,408],[402,409],[217,6],[404,410],[406,411],[405,412],[240,6],[395,397],[408,413],[394,414],[400,415],[228,6],[231,6],[229,6],[233,6],[230,6],[232,6],[234,416],[227,6],[380,417],[379,6],[385,418],[381,419],[384,420],[383,420],[386,418],[382,419],[745,421],[274,422],[373,423],[436,424],[492,6],[461,425],[463,426],[312,6],[462,427],[434,388],[491,428],[332,388],[218,6],[314,429],[271,430],[272,431],[273,432],[303,433],[409,433],[289,433],[374,434],[290,434],[256,435],[255,6],[378,436],[377,437],[376,438],[375,439],[435,440],[324,441],[360,442],[323,443],[356,444],[359,445],[417,446],[416,447],[412,448],[369,449],[371,450],[368,451],[407,452],[362,6],[449,6],[361,453],[411,6],[276,454],[309,359],[307,455],[278,456],[281,457],[486,6],[279,458],[282,458],[447,6],[446,6],[448,6],[484,6],[284,459],[322,51],[92,6],[367,460],[253,6],[242,461],[318,6],[455,51],[465,462],[302,51],[459,339],[301,463],[442,464],[300,462],[208,6],[467,465],[298,51],[299,51],[291,6],[241,6],[297,466],[296,467],[239,468],[319,281],[286,281],[403,6],[391,469],[390,6],[451,6],[350,470],[321,51],[443,471],[87,51],[90,472],[91,473],[88,51],[89,6],[251,474],[246,475],[245,6],[244,476],[243,6],[441,477],[454,478],[456,479],[458,480],[752,481],[460,482],[464,483],[498,484],[468,484],[497,485],[470,486],[480,487],[746,488],[481,489],[483,490],[493,491],[496,362],[495,6],[494,492],[517,493],[515,494],[516,495],[504,496],[505,494],[512,497],[503,498],[508,499],[518,6],[509,500],[514,501],[520,502],[519,503],[502,504],[510,505],[511,506],[506,507],[513,493],[507,508],[896,241],[913,509],[914,509],[916,510],[917,511],[895,238],[918,509],[934,512],[915,509],[919,241],[920,241],[921,509],[922,51],[923,509],[924,513],[925,509],[926,509],[927,241],[928,509],[929,509],[930,509],[931,509],[932,509],[933,241],[392,514],[501,6],[523,515],[522,6],[521,6],[524,516],[81,6],[82,6],[13,6],[14,6],[16,6],[15,6],[2,6],[17,6],[18,6],[19,6],[20,6],[21,6],[22,6],[23,6],[24,6],[3,6],[25,6],[26,6],[4,6],[27,6],[31,6],[28,6],[29,6],[30,6],[32,6],[33,6],[34,6],[5,6],[35,6],[36,6],[37,6],[38,6],[6,6],[42,6],[39,6],[40,6],[41,6],[43,6],[7,6],[44,6],[49,6],[50,6],[45,6],[46,6],[47,6],[48,6],[8,6],[54,6],[51,6],[52,6],[53,6],[55,6],[9,6],[56,6],[57,6],[58,6],[60,6],[59,6],[61,6],[62,6],[10,6],[63,6],[64,6],[65,6],[11,6],[66,6],[67,6],[68,6],[69,6],[70,6],[1,6],[71,6],[72,6],[12,6],[76,6],[74,6],[79,6],[78,6],[73,6],[77,6],[75,6],[80,6],[120,517],[130,518],[119,517],[140,519],[111,520],[110,521],[139,492],[133,522],[138,523],[113,524],[127,525],[112,526],[136,527],[108,528],[107,492],[137,529],[109,530],[114,531],[115,6],[118,531],[105,6],[141,532],[131,533],[122,534],[123,535],[125,536],[121,537],[124,538],[134,492],[116,539],[117,540],[126,541],[106,542],[129,533],[128,531],[132,6],[135,543],[525,544],[537,6],[538,545],[536,6]],"affectedFilesPendingEmit":[791,793,798,799,800,803,805,806,808,795,809,810,811,812,813,814,796,797,807,815,817,802,823,819,530,818,820,821,822,824,831,826,827,531,825,830,828,829,839,833,834,838,835,836,837,532,832,846,841,842,845,844,843,533,840,847,853,849,850,852,851,534,848,860,858,861,535,747,862,863,864,868,867,870,865,871,866,544,560,869,539,872,873,887,527,874,875,880,881,884,886,883,877,885,878,876,882,879,748,888,889,891,890,892,561,935,936,937,749,562,938,939,940,563,784,785,789,941,942,943,944,945,946,526,956,954,960,953,962,959,952,958,951,955,564,565,961,566,567,976,569,970,971,972,974,977,975,987,570,978,979,980,984,982,986,973,983,981,804,988,964,989,963,990,991,992,816,985,998,571,993,994,995,997,996,968,1004,1000,572,999,1001,1002,1003,969,966,965,967,568,1010,1006,1007,1008,1009,573,1005,529,1011,1012,790,1013,783,948,778,782,949,786,787,788,776,947,801,792,781,856,857,855,854,950,777,794,732,774,543,737,772,773,775,735,574,733,734,738,736,541,559,542,540,859,780,739,740,731,528,741,742,779,500,525,537,538,536],"version":"5.9.3"} \ No newline at end of file