diff --git a/jobs/Backend/ArchitectureAndDecisions.md b/jobs/Backend/ArchitectureAndDecisions.md new file mode 100644 index 0000000000..dd1e58a48c --- /dev/null +++ b/jobs/Backend/ArchitectureAndDecisions.md @@ -0,0 +1,179 @@ +# Architecture & Decisions + +## Context and goals + +This document describes the architecture and key decisions made while implementing an `ExchangeRateProvider` for the Czech National Bank (CNB). The goal is to build a small but production-ready set of components that focus on clarity, testability, and resilience rather than on feature completeness. The solution is structured so that the core abstractions and CNB-specific implementation can be reused from different hosts. + +## Target framework choice (.NET 10) + +The original skeleton project was provided targeting .NET 6. For the implementation, I updated the target framework to .NET 10 (`net10.0`) for the following reasons: + +- .NET 10 is a Long Term Support (LTS) release, supported for three years, which makes it a stable choice for production-oriented components. +- It provides the latest runtime and library improvements, including performance and reliability enhancements. + + +## Project structure + +The solution is split into several projects to keep responsibilities clear and to mirror a realistic architecture: + +- `ExchangeRateUpdater.Abstraction` + Contains the core domain model and contracts: + - `Model/` with `Currency` and `ExchangeRate` as strongly-typed value objects. + - `Interfaces/` with `IExchangeRateClient`, `IExchangeRateProvider`, and `IExchangeRateService`. + This project has no external dependencies other than the base class library. + +- `ExchangeRateUpdater.CbnApiClient` + Encapsulates the integration with the Czech National Bank API: + - `Dto/` contains transport-level models (`ExchangeRatesResponse`, `ExchangeRateEntry`) that match the CNB API payload. + - `Implementation/ExchangeRateCnbApiClient` implements `IExchangeRateClient` using `HttpClient`. + - `Mapper/CnbExchangeRateMapperExtensions` converts CNB DTOs into domain `ExchangeRate` instances. + The `CnbApiInfo.md` file documents the chosen endpoint, format, and behaviour of `validFor`. + +- `ExchangeRateUpdater.Service` + Contains the application-level services: + - `ExchangeRateProvider` implements `IExchangeRateProvider` on top of `IExchangeRateClient`. It applies domain rules, filtering, and caching on top of the raw CNB data. + - `ExchangeRateService` implements `IExchangeRateService` and acts as an application service that maps input (currency codes as strings) to domain types and orchestrates calls to the provider. + +- `ExchangeRateUpdater.Api` + Hosts an ASP.NET Core Web API: + - `Controllers/ExchangeRateController` exposes a HTTP endpoint to retrieve exchange rates for a set of currency codes. + - `Middleware/ExceptionHandlingMiddleware` centralizes exception handling and error responses. + - `Program.cs` wires the DI container, logging, and middleware pipeline. + The API is intentionally thin: it focuses on HTTP concerns and delegates business logic to `IExchangeRateService`. + +- `ExchangeRateUpdater.DependencyInjection` + Provides a reusable DI setup: + - `ExchangeRateCnbServicesExtension` exposes an `AddExchangeRateServices(IServiceCollection)` extension method that registers `IExchangeRateProvider`, `IExchangeRateService`, and the CNB HTTP client with resilience policies. + - `DependencyInyection.md` documents why this configuration is kept in a reusable project. + This allows both the API and a console application to share the same wiring without duplicating configuration. + +- `ExchangeRateUpdater.Tests` + Contains automated tests organized by area: + - `Abstraction/`, `Api/`, `CnbApiClient/`, `Service/` and `IntegrationTests/`. + Unit tests target domain classes, mapping logic, and provider behaviour; integration tests cover the end-to-end path through the service and API layers. + +## Data source (Czech National Bank) + +The provider uses an official public data source published by the Czech National Bank. The chosen endpoint returns the full daily set of foreign exchange rates, each entry including a `validFor` date that indicates when the rate applies. + +Relevant characteristics: + +- Rates are published on business days (weekdays) and updated once per day, around 14:30 UTC, according to CNB documentation. +- The endpoint always returns the full set of available currency entries; there is no server-side filtering by currency. +- When queried on weekends or holidays, the API returns the most recently published rates, i.e., the latest `validFor` date prior to the request. + +Because of these characteristics, the client always requests the full daily rates payload and leaves filtering and caching to upper layers. + +## Domain model and contracts + +The domain model is intentionally small and focused: + +- `Currency` is a value object that represents a three-letter ISO 4217 currency code. It enforces its invariants in the constructor: the code must be non-empty, exactly three characters long, and composed of letters only. The code is normalized using `ToUpperInvariant()`, and equality/hash code use a case-insensitive comparison to avoid culture-specific issues. +- `ExchangeRate` represents a rate between a base currency (CZK in this case), a quoted currency, and a validity date. + +Contracts are defined in the `Interfaces` namespace: + +- `IExchangeRateClient` abstracts the CNB integration. It is responsible for retrieving raw exchange rate data from the external API, but it does not apply business rules or filtering. +- `IExchangeRateProvider` represents a domain-facing abstraction that returns exchange rates for a given date and set of currencies. +- `IExchangeRateService` is an application-level service used by the API. It accepts currency codes as strings, maps them to `Currency` objects, and delegates to `IExchangeRateProvider`. + +This separation allows the Web API to depend only on abstractions, while the CNB-specific details are encapsulated in infrastructure projects. + +## Solution design + +The solution follows a layered design aligned with clean architecture principles: + +- **Domain (Abstraction project)** + Contains the core types and contracts with no external dependencies. + +- **Infrastructure (CbnApiClient project)** + Integrates with CNB using `HttpClient`. The client: + - Calls the official endpoint to fetch the full daily exchange rates payload. + - Deserializes the response into `ExchangeRatesResponse` and `ExchangeRateEntry`. + - Maps DTOs into domain-level `ExchangeRate` instances via `CnbExchangeRateMapperExtensions`. + +- **Application services (Service project)** + - `ExchangeRateProvider` uses `IExchangeRateClient` to retrieve the latest or requested daily rates. It then: + - Filters the full set to the requested currencies. + - Applies basic caching to avoid repeated calls for the same date. + - `ExchangeRateService` provides a higher-level API for hosts: it converts comma-separated currency codes into `Currency` objects and delegates the actual rate retrieval to the provider. + +- **Presentation (Api project)** + - `ExchangeRateController` is a thin Web API controller that: + - Accepts a `currencyCodes` query parameter. + - Splits and trims the codes. + - Calls `IExchangeRateService` and returns the resulting exchange rates. + - `ExceptionHandlingMiddleware` converts unhandled exceptions into consistent HTTP responses and logs them. + +- **Composition (DependencyInjection project)** + - `ExchangeRateCnbServicesExtension` centralizes DI registration so that multiple hosts can share the same wiring and resilience configuration. + +This separation of concerns keeps each project focused on a single responsibility, makes the code easier to test, and makes it clear where to make changes when integrating a different data source. + +## Error handling and resilience + +Error handling is applied at several levels: + +- **Domain validation** + `Currency` validates its input in the constructor and throws `ArgumentException` for invalid codes (null/whitespace, wrong length, or invalid characters). This ensures that any `Currency` instance used by the provider is always in a valid state. + +- **HTTP resilience (CNB client)** + The CNB HTTP client is registered via `AddHttpClient()` and configured with a Polly retry policy: + - Transient HTTP errors (5xx, timeouts, etc.) are retried up to three times. + - The wait times use exponential backoff (2, 4, and 8 seconds). + This provides basic resilience against temporary CNB outages or network glitches without adding complex logic to the client itself. + +- **API-level exception handling** + In the Web API project, `ExceptionHandlingMiddleware` catches unhandled exceptions, logs them, and returns standardized error responses. This avoids leaking implementation details to clients. + +- **Input validation at the API boundary** + The API controller validates and normalizes the `currencyCodes` query parameter (split, trim, ignore empty entries) before delegating to the service. + +## Caching strategy + +Given CNB's update behaviour, caching is particularly effective for this use case. Daily FX rates are published once on business days around 14:30 UTC and remain valid for the entire day (and weekends/holidays until the next business day). The API always returns the latest available set of rates for the most recent `validFor` date. + +The `ExchangeRateProvider` uses an in-memory cache based on `IMemoryCache`. The cache stores the full set of CNB rates under a single key and applies time-based expiration: + +- When exchange rates are requested, the provider first checks the cache. +- On a cache miss, it calls `IExchangeRateClient` to fetch the latest daily rates from CNB and stores the result in the cache with an absolute expiration. +- On a cache hit, the provider simply filters the cached rates to the requested currencies, avoiding another HTTP call. + +The expiration is aligned with CNB’s daily publication schedule. The provider computes the next expected publication time (15:00 UTC with a small safety margin) and sets the cache entry to expire at that moment. This means: + +- For most of the day, repeated requests are served entirely from memory. +- Shortly after CNB publishes new rates, the next request will trigger a refresh and cache the new daily set. +- A minimum and maximum duration (between 1 minute and 24 hours) guard against edge cases in date/time calculations. + +This approach keeps the implementation simple while significantly reducing the number of external calls, which is a common recommendation for currency/exchange-rate APIs. + + +## Testing and validation + +Automated tests are an essential part of this solution. The goal is not only to demonstrate correctness for a few happy paths, but also to make the behaviour of the provider, services, and API predictable when the implementation evolves. + +The test suite covers domain types, CNB client mapping, caching behaviour, and the main API flow. External dependencies such as HTTP calls are abstracted behind interfaces (`IExchangeRateClient`), so tests run deterministically without hitting the real CNB endpoint. This makes it easy to validate edge cases (for example, unsupported currencies or malformed responses) in isolation. + +Code coverage is used as an additional feedback metric. A coverage report (`coveragereport/`) and a screenshot (`CodeCoverage.png`) are included at the root of the solution to make evaluation of the assignment easier. In a real production repository, these generated artefacts would typically not be committed, but produced by the build/CI pipeline instead. + +Most classes reach close to 100% coverage, and all core components have at least 85% coverage, ensuring that the critical paths of the system are exercised by tests. The only notable exception is `ExceptionHandlingMiddleware`, which currently has lower coverage as it mainly deals with cross-cutting concerns and framework integration, and is therefore less critical for the core domain logic. + + +## Maintainability and extensibility + +The design aims to make future changes as localized as possible: + +- Adding support for another bank or data source would typically involve: + - Introducing a new `IExchangeRateClient` implementation and mapper in a separate infrastructure project. + - Optionally adding another `IExchangeRateProvider` implementation if the semantics differ. +- The Web API depends only on abstractions (`IExchangeRateService`, `IExchangeRateProvider`, `IExchangeRateClient`), which makes it easier to extend or replace infrastructure without touching controllers. +- Configuration points such as base URLs, timeouts, and retry policies live in the DI setup and application configuration (`appsettings.json`), not in the core logic, so they can be adjusted without code changes. + +## Future improvements + +Potential future improvements include: + +- Introducing a more advanced caching strategy (e.g., configurable expiration or a distributed cache) if the service runs in a multi-instance environment. +- Exposing configuration for retry policies and resilience strategies (number of retries, backoff function) via configuration rather than hard-coding them. +- Adding richer logging and metrics around CNB requests (latency, failure rates, cache hit rates) to simplify diagnostics and capacity planning. +- Extending the API to support historical queries and additional CNB endpoints (for example, endpoints that allow querying by arbitrary date) as described in the CNB documentation. diff --git a/jobs/Backend/CodeCoverage.png b/jobs/Backend/CodeCoverage.png new file mode 100644 index 0000000000..7e06c33386 Binary files /dev/null and b/jobs/Backend/CodeCoverage.png differ diff --git a/jobs/Backend/ExchangeRateUpdater.API/Controllers/ExchangeRateController.cs b/jobs/Backend/ExchangeRateUpdater.API/Controllers/ExchangeRateController.cs new file mode 100644 index 0000000000..c74879bf67 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.API/Controllers/ExchangeRateController.cs @@ -0,0 +1,31 @@ +using ExchangeRateUpdater.Abstraction.Interfaces; +using ExchangeRateUpdater.Abstraction.Model; +using Microsoft.AspNetCore.Mvc; + +namespace ExchangeRateUpdater.Api.Controllers +{ + [ApiController] + [Route("[controller]")] + public class ExchangeRateController( + IExchangeRateService exchangeRateService, + ILogger logger) : ControllerBase + { + [HttpGet] + public async Task>> GetExchangeRates([FromQuery] string currencyCodes) + { + logger.LogInformation("Received request to fetch exchange rates for currencies: {CurrencyCodes}", currencyCodes); + + string[] codes = currencyCodes.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + + IEnumerable exchangeRates = await exchangeRateService.GetExchangeRatesFromStringList(codes); + if (exchangeRates.ToList().Count == 0) + { + logger.LogWarning("No exchange rates found for the provided currency codes: {CurrencyCodes}", currencyCodes); + return BadRequest("No exchange rates found for the provided currency codes."); + } + + return Ok(exchangeRates); + + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.API/ExchangeRateUpdater.Api.csproj b/jobs/Backend/ExchangeRateUpdater.API/ExchangeRateUpdater.Api.csproj new file mode 100644 index 0000000000..946f87b13e --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.API/ExchangeRateUpdater.Api.csproj @@ -0,0 +1,23 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + + + + + + diff --git a/jobs/Backend/ExchangeRateUpdater.API/Logs/log-20260215.txt b/jobs/Backend/ExchangeRateUpdater.API/Logs/log-20260215.txt new file mode 100644 index 0000000000..4a4f6face3 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.API/Logs/log-20260215.txt @@ -0,0 +1,7 @@ +2026-02-15 18:57:37.727 +01:00 [INF] Starting web host +2026-02-15 18:57:45.283 +01:00 [INF] Received request to fetch exchange rates for currencies: eur +2026-02-15 18:57:45.287 +01:00 [INF] Cache miss for CNB rates, fetching from upstream +2026-02-15 18:57:47.589 +01:00 [INF] Received request to fetch exchange rates for currencies: eur +2026-02-15 18:57:47.589 +01:00 [DBG] Cache hit for CNB rates +2026-02-15 18:58:04.413 +01:00 [INF] Received request to fetch exchange rates for currencies: eur,usd +2026-02-15 18:58:04.413 +01:00 [DBG] Cache hit for CNB rates diff --git a/jobs/Backend/ExchangeRateUpdater.API/Middleware/ExceptionHandlingMiddleware.cs b/jobs/Backend/ExchangeRateUpdater.API/Middleware/ExceptionHandlingMiddleware.cs new file mode 100644 index 0000000000..376fd04db1 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.API/Middleware/ExceptionHandlingMiddleware.cs @@ -0,0 +1,70 @@ +using System.Net; +using System.Text.Json; +using Microsoft.AspNetCore.Mvc; + +namespace ExchangeRateUpdater.Api.Middleware +{ + /// + /// Middleware that handles exceptions thrown during the processing of HTTP requests, logging the error and returning a + /// standardized JSON response. + /// + /// The delegate that represents the next middleware in the request processing pipeline. + /// The logger used to log unhandled exceptions that occur during request processing. + /// The web host environment that provides information about the hosting environment, such as whether the application is + /// in development mode. + public class ExceptionHandlingMiddleware(RequestDelegate next, ILogger logger, IWebHostEnvironment env) + { + private readonly Dictionary exceptionStatusCodes = new() + { + { typeof(ArgumentException), HttpStatusCode.BadRequest }, + { typeof(ArgumentNullException), HttpStatusCode.BadRequest }, + { typeof(InvalidOperationException), HttpStatusCode.InternalServerError } + }; + + /// + /// Invokes the next middleware in the HTTP request pipeline asynchronously and handles any exceptions that + /// occur during execution. + /// + /// The HttpContext for the current request, which encapsulates all HTTP-specific information about an + /// individual HTTP request. + /// A task that represents the asynchronous operation of invoking the next middleware and handling exceptions. + public async Task InvokeAsync(HttpContext context) + { + try + { + await next(context); + } + catch (Exception ex) + { + await HandleExceptionAsync(context, ex); + } + } + + /// + /// Handles exceptions that occur during the processing of an HTTP request by logging the error and generating a + /// standardized JSON error response. + /// + /// The HttpContext for the current HTTP request, used to set the response status code and write the error + /// response. + /// The exception that was thrown during request processing. + /// A task that represents the asynchronous operation. + private async Task HandleExceptionAsync(HttpContext context, Exception ex) + { + logger.LogError(ex, "Unhandled exception"); + + context.Response.ContentType = "application/json"; + var status = (int)exceptionStatusCodes.GetValueOrDefault(ex.GetType(), HttpStatusCode.InternalServerError); + context.Response.StatusCode = status; + + var problem = new ProblemDetails + { + Status = status, + Title = status == 500 ? "An internal error occurred." : "A request error occurred.", + Detail = env.IsDevelopment() ? ex.ToString() : null + }; + + var json = JsonSerializer.Serialize(problem); + await context.Response.WriteAsync(json); + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.API/Program.cs b/jobs/Backend/ExchangeRateUpdater.API/Program.cs new file mode 100644 index 0000000000..0ac88b0da4 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.API/Program.cs @@ -0,0 +1,55 @@ +using ExchangeRateUpdater.Api.Middleware; +using ExchangeRateUpdater.DependencyInjection; +using Serilog; + + +var builder = WebApplication.CreateBuilder(args); + +// Configure Serilog from configuration (appsettings.json) +Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(builder.Configuration) + .Enrich.FromLogContext() + .CreateLogger(); + +builder.Host.UseSerilog(); + +try +{ + Log.Information("Starting web host"); + + // Add services to the container. + builder.Services.AddControllers(); + builder.Services.AddExchangeRateServices(); + + // Add Swagger services + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + + + var app = builder.Build(); + + if (app.Environment.IsDevelopment()) + { + // Enable Swagger UI in development + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseMiddleware(); + + app.UseHttpsRedirection(); + + app.MapControllers(); + + app.Run(); +} +catch (Exception ex) +{ + // Catch startup exceptions + Log.Fatal(ex, "Host terminated unexpectedly"); + throw; +} +finally +{ + Log.CloseAndFlush(); +} diff --git a/jobs/Backend/ExchangeRateUpdater.API/Properties/launchSettings.json b/jobs/Backend/ExchangeRateUpdater.API/Properties/launchSettings.json new file mode 100644 index 0000000000..830eaee6a7 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.API/Properties/launchSettings.json @@ -0,0 +1,37 @@ +{ + "profiles": { + "http": { + "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:5165" + }, + "https": { + "commandName": "Project", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true, + "applicationUrl": "https://localhost:7059;http://localhost:5165" + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "launchUrl": "swagger" + } + }, + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:60161/", + "sslPort": 44391 + } + } +} \ No newline at end of file diff --git a/jobs/Backend/ExchangeRateUpdater.API/appsettings.Development.json b/jobs/Backend/ExchangeRateUpdater.API/appsettings.Development.json new file mode 100644 index 0000000000..8040cec346 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.API/appsettings.Development.json @@ -0,0 +1,28 @@ +{ + "Serilog": { + "Using": [], + "MinimumLevel": { + "Default": "Debug", + "Override": { + "Microsoft": "Warning", + "System": "Warning" + } + }, + "WriteTo": [ + { "Name": "Console" }, + { + "Name": "File", + "Args": { + "path": "Logs/log-.txt", + "rollingInterval": "Day", + "shared": true + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], + "Properties": { + "Application": "ExchangeRateUpdater.API" + } + }, + "CbnApiUrl": "https://api.cnb.cz/cnbapi/exrates/daily" +} diff --git a/jobs/Backend/ExchangeRateUpdater.API/appsettings.json b/jobs/Backend/ExchangeRateUpdater.API/appsettings.json new file mode 100644 index 0000000000..f66ebb2227 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.API/appsettings.json @@ -0,0 +1,27 @@ +{ + "Serilog": { + "Using": [], + "MinimumLevel": { + "Default": "Warning", + "Override": { + "Microsoft": "Warning", + "System": "Warning" + } + }, + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "Logs/log-.txt", + "rollingInterval": "Day", + "shared": true + } + } + ], + "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ], + "Properties": { + "Application": "ExchangeRateUpdater.API" + } + }, + "CbnApiUrl": "https://api.cnb.cz/cnbapi/exrates/daily" +} diff --git a/jobs/Backend/ExchangeRateUpdater.Abstraction/ExchangeRateUpdater.Abstraction.csproj b/jobs/Backend/ExchangeRateUpdater.Abstraction/ExchangeRateUpdater.Abstraction.csproj new file mode 100644 index 0000000000..b760144708 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Abstraction/ExchangeRateUpdater.Abstraction.csproj @@ -0,0 +1,9 @@ + + + + net10.0 + enable + enable + + + diff --git a/jobs/Backend/ExchangeRateUpdater.Abstraction/Interfaces/IExchangeRateClient.cs b/jobs/Backend/ExchangeRateUpdater.Abstraction/Interfaces/IExchangeRateClient.cs new file mode 100644 index 0000000000..4b668d485c --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Abstraction/Interfaces/IExchangeRateClient.cs @@ -0,0 +1,18 @@ +using ExchangeRateUpdater.Abstraction.Model; + +namespace ExchangeRateUpdater.Abstraction.Interfaces +{ + /// + /// Provides an abstraction for retrieving exchange rates for specified currencies from an external source. + /// + public interface IExchangeRateClient + { + /// + /// Retrieves the current exchange rates for the specified currencies from an external source. + /// + /// An optional date parameter to specify the date for which the exchange rates should be valid. If not provided, the method will + /// A task that represents the asynchronous operation. The task result contains an enumerable collection of + /// ExchangeRate objects. + Task> GetExchangeRatesAsync(DateTime? validDate = null); + } +} diff --git a/jobs/Backend/Task/ExchangeRateProvider.cs b/jobs/Backend/ExchangeRateUpdater.Abstraction/Interfaces/IExchangeRateProvider.cs similarity index 55% rename from jobs/Backend/Task/ExchangeRateProvider.cs rename to jobs/Backend/ExchangeRateUpdater.Abstraction/Interfaces/IExchangeRateProvider.cs index 6f82a97fbe..e3e48837a5 100644 --- a/jobs/Backend/Task/ExchangeRateProvider.cs +++ b/jobs/Backend/ExchangeRateUpdater.Abstraction/Interfaces/IExchangeRateProvider.cs @@ -1,9 +1,11 @@ -using System.Collections.Generic; -using System.Linq; +using ExchangeRateUpdater.Abstraction.Model; -namespace ExchangeRateUpdater +namespace ExchangeRateUpdater.Abstraction.Interfaces { - public class ExchangeRateProvider + /// + /// Represents a provider that supplies exchange rates for specified currencies as defined by an external source. + /// + public interface IExchangeRateProvider { /// /// Should return exchange rates among the specified currencies that are defined by the source. But only those defined @@ -11,9 +13,6 @@ public class ExchangeRateProvider /// do not return exchange rate "USD/CZK" with value calculated as 1 / "CZK/USD". If the source does not provide /// some of the currencies, ignore them. /// - public IEnumerable GetExchangeRates(IEnumerable currencies) - { - return Enumerable.Empty(); - } + Task> GetExchangeRatesAsync(IEnumerable currencies); } } diff --git a/jobs/Backend/ExchangeRateUpdater.Abstraction/Interfaces/IExchangeRateService.cs b/jobs/Backend/ExchangeRateUpdater.Abstraction/Interfaces/IExchangeRateService.cs new file mode 100644 index 0000000000..f02c7473c9 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Abstraction/Interfaces/IExchangeRateService.cs @@ -0,0 +1,22 @@ +using ExchangeRateUpdater.Abstraction.Model; + +namespace ExchangeRateUpdater.Abstraction.Interfaces +{ + /// + /// Provides methods to retrieve exchange rates for specified currency codes. + /// + public interface IExchangeRateService + { + /// + /// Retrieves a collection of exchange rates for the specified currency codes. + /// + /// If any of the provided currency codes are invalid, they will be ignored in the + /// result. The method may throw exceptions if the underlying service is unavailable or if there are issues with + /// the provided input. + /// An enumerable collection of currency codes for which exchange rates are to be retrieved. Each code must be a + /// valid ISO 4217 currency code. + /// A task that represents the asynchronous operation, containing an enumerable collection of ExchangeRate + /// objects corresponding to the provided currency codes. + Task> GetExchangeRatesFromStringList(IEnumerable currencyCodes); + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Abstraction/Model/Currency.cs b/jobs/Backend/ExchangeRateUpdater.Abstraction/Model/Currency.cs new file mode 100644 index 0000000000..e1db68ce61 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Abstraction/Model/Currency.cs @@ -0,0 +1,48 @@ +namespace ExchangeRateUpdater.Abstraction.Model +{ + public class Currency + { + /// + /// Initializes a new instance of the Currency class using the specified currency code. + /// + /// The currency code to represent. This value must be a non-empty string consisting of exactly three letters (e.g., "USD", "EUR"). It must not contain any whitespace or non-letter + /// characters. The code is trimmed and converted to uppercase. + /// Thrown if the specified is null, empty, or consists only of white-space characters. + /// Thrown if the specified does not have exactly three characters. + /// Thrown if the specified contains non-letter characters. + public Currency(string code) + { + if (string.IsNullOrWhiteSpace(code)) + throw new ArgumentException("Currency code must not be empty.", nameof(code)); + + code = code.Trim(); + if (code.Length != 3) + throw new ArgumentException("Currency code must be exactly three characters long.", nameof(code)); + + if (!code.All(char.IsLetter)) + throw new ArgumentException("Currency code must consist of letters only.", nameof(code)); + + Code = code.Trim().ToUpperInvariant(); + } + + /// + /// Three-letter ISO 4217 code of the currency. + /// + public string Code { get; } + + public override string ToString() + { + return Code; + } + + // Compare using OrdinalIgnoreCase so the comparison is + // culture-invariant and consistent across environments + // (e.g. Turkish dotted/dotless i behaviour). + public bool Equals(Currency other) => string.Equals(Code, other.Code, StringComparison.OrdinalIgnoreCase); + + public override bool Equals(object? obj) => obj is Currency other && Equals(other); + + // Use the same comparer for hash code to respect equality contract. + public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Code); + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Abstraction/Model/ExchangeRate.cs b/jobs/Backend/ExchangeRateUpdater.Abstraction/Model/ExchangeRate.cs new file mode 100644 index 0000000000..7dc4d53705 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Abstraction/Model/ExchangeRate.cs @@ -0,0 +1,55 @@ +namespace ExchangeRateUpdater.Abstraction.Model +{ + /// + /// Represents an exchange rate between two currencies, providing the source currency, target currency, and the + /// exchange rate value. + /// + public class ExchangeRate + { + + /// + /// Initializes a new instance of the ExchangeRate class using the specified source and target currencies and + /// the exchange rate value. + /// + /// The currency from which the exchange rate is calculated. + /// The currency to which the exchange rate is applied. + /// The exchange rate value. Must be greater than zero. + /// Thrown when the value parameter is less than or equal to zero. + public ExchangeRate(Currency sourceCurrency, Currency targetCurrency, decimal value, DateTime validFor) + { + if (value <= 0) + throw new ArgumentOutOfRangeException(nameof(value), "Exchange rate value must be greater than zero."); + + SourceCurrency = sourceCurrency; + TargetCurrency = targetCurrency; + Value = value; + ValidFor = validFor; + } + + /// + /// Gets the currency used as the source for conversion. + /// + public Currency SourceCurrency { get; } + + /// + /// Gets the currency to which the transaction amount will be converted. + /// + public Currency TargetCurrency { get; } + + /// + /// Gets the current exchange rate value represented by this instance. + /// How much of the target currency is equivalent to one unit of the source currency. + /// + public decimal Value { get; } + + /// + /// Gets the date and time until which the current entity is valid. + /// + public DateTime ValidFor { get; } + + public override string ToString() + { + return $"{SourceCurrency}/{TargetCurrency}={Value} (valid for {ValidFor})"; + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.CbnApiClient/CnbApiInfo.md b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/CnbApiInfo.md new file mode 100644 index 0000000000..9c02e9b167 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/CnbApiInfo.md @@ -0,0 +1,64 @@ +# CNB API - Daily Exchange Rates + +Base URL + +- `https://api.cnb.cz/cnbapi/exrates/daily` + +Description + +- This endpoint returns the full daily foreign exchange rates published by the Czech National Bank (CNB). +- The endpoint does not support filtering by currency: every request returns the whole set of available currency entries. +- Each entry contains a `validFor` property that indicates the date the rate is valid for. + +Update schedule & behaviour + +- Rates are published/updated on working days (weekdays) around 14:30 UTC (I will asume its Zulu time since they do not specify) according to the CNB documentation: https://www.cnb.cz/en/faq/Format-of-the-foreign-exchange-market-rates. +- If the API is queried on a weekend or holiday, the response contains the most recently published rates (the latest `validFor` date prior to the request). + +Response shape (representative) + +```json +{ + "rates": [ + { + "amount": 0, + "country": "string", + "currency": "string", + "currencyCode": "string", + "order": 0, + "rate": 0, + "validFor": "2026-02-15" + } + ] +} +``` + +Field meanings + +- `amount` (decimal): how many units of the foreign currency the `rate` corresponds to. +- `rate` (decimal): amount of CZK for the given `amount` units of the foreign currency. + - To obtain the per-1-unit rate in CZK: `rate / amount`. +- `currencyCode` (string): three-letter ISO 4217 currency code (e.g. `USD`, `EUR`). +- `currency` (string): localized currency name. +- `country` (string): country name associated with the currency. +- `order` (int): ordering index in the returned list (not used for calculations). +- `validFor` (date string): the calendar date that this rate is valid for (format `yyyy-MM-dd`). + +Errors + +- Error responses follow a small shape similar to: + +```json +{ + "description": "...", + "endPoint": "...", + "errorCode": "INTERNAL_SERVER_ERROR", + "happenedAt": "2026-02-15T15:46:07.643Z", + "messageId": "..." +} +``` + +References + +- CNB rates format FAQ: https://www.cnb.cz/en/faq/Format-of-the-foreign-exchange-market-rates +- CNB daily rates endpoint (used): https://api.cnb.cz/cnbapi/exrates/daily diff --git a/jobs/Backend/ExchangeRateUpdater.CbnApiClient/DTO/ExchangeRateEntry.cs b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/DTO/ExchangeRateEntry.cs new file mode 100644 index 0000000000..8c1157864e --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/DTO/ExchangeRateEntry.cs @@ -0,0 +1,36 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; + +namespace ExchangeRateUpdater.CbnApiClient.Dto +{ + /// + /// Represents an individual exchange rate entry as returned by the CBN API. + /// Each entry contains details about the currency, its exchange rate, and the date for which the rate is valid. + /// + [ExcludeFromCodeCoverage] + public class ExchangeRateEntry + { + [JsonPropertyName("amount")] + public decimal Amount { get; set; } + + [JsonPropertyName("country")] + public string Country { get; set; } = string.Empty; + + [JsonPropertyName("currency")] + public string Currency { get; set; } = string.Empty; + + [JsonPropertyName("currencyCode")] + public string CurrencyCode { get; set; } = string.Empty; + + [JsonPropertyName("order")] + public int Order { get; set; } + + [JsonPropertyName("rate")] + public decimal Rate { get; set; } + + // Date the rate is valid for. The API returns a date string (e.g. "2026-02-15"). + [JsonPropertyName("validFor")] + public DateTime ValidFor { get; set; } + + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.CbnApiClient/DTO/ExchangeRatesResponse.cs b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/DTO/ExchangeRatesResponse.cs new file mode 100644 index 0000000000..1760c82864 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/DTO/ExchangeRatesResponse.cs @@ -0,0 +1,18 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; + +namespace ExchangeRateUpdater.CbnApiClient.Dto +{ + /// + /// Represents the response returned by the CBN API containing a collection of exchange rate entries. + /// + [ExcludeFromCodeCoverage] + public class ExchangeRatesResponse + { + /// + /// Collection of rate entries returned by the CBN API. + /// + [JsonPropertyName("rates")] + public List Rates { get; set; } = []; + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.CbnApiClient/ExchangeRateUpdater.CbnApiClient.csproj b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/ExchangeRateUpdater.CbnApiClient.csproj new file mode 100644 index 0000000000..33984a114e --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/ExchangeRateUpdater.CbnApiClient.csproj @@ -0,0 +1,17 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + diff --git a/jobs/Backend/ExchangeRateUpdater.CbnApiClient/Implementation/ExchangeRateCnbApiClient.cs b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/Implementation/ExchangeRateCnbApiClient.cs new file mode 100644 index 0000000000..b4d03d1f05 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/Implementation/ExchangeRateCnbApiClient.cs @@ -0,0 +1,68 @@ +using ExchangeRateUpdater.Abstraction.Interfaces; +using ExchangeRateUpdater.Abstraction.Model; +using ExchangeRateUpdater.CbnApiClient.Dto; +using ExchangeRateUpdater.CbnApiClient.Mapper; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using System.Text.Json; + +namespace ExchangeRateUpdater.CbnApiClient.Implementation +{ + public class ExchangeRateCnbApiClient(IHttpClientFactory httpClientFactory, IConfiguration config, ILogger logger) : IExchangeRateClient + { + private readonly string CnbApiUrl = config.GetValue("CbnApiUrl") ?? throw new InvalidOperationException("CbnApiUrl configuration is missing."); + // Supports EN and CZ, CZ is the default if not specified. + private readonly string CnbLangToRequest = "EN"; + private readonly string CbnApiClientName = "CbnApi"; + + /// + /// Fetches exchange rates from the CBN API for the specified date. If no date is provided, it fetches today's rates. + /// + /// The date for which to fetch exchange rates. If null, today's rates will be fetched. + /// A collection of objects representing the exchange rates for the specified date. + /// Thrown when the HTTP request to the CBN API fails. + /// Thrown when the response from the CBN API is empty or cannot be deserialized. + public async Task> GetExchangeRatesAsync(DateTime? validDate = null) + { + // prepare the url, add today date as yyyy-MM-dd if specified and lang to "EN" + string urlWithParams = $"{CnbApiUrl}?lang={CnbLangToRequest}"; + // if no date is specified, the CBN API will return today as default + if (validDate.HasValue) + { + urlWithParams += $"&date={validDate.Value:yyyy-MM-dd}"; + } + // make the request to the CBN API using the named client so configured handlers/policies are applied + HttpClient httpClient = httpClientFactory.CreateClient(CbnApiClientName); + using HttpResponseMessage response = await httpClient.GetAsync(urlWithParams); + if (!response.IsSuccessStatusCode) + { + throw new HttpRequestException($"Failed to fetch exchange rates from CBN API. Status code: {response.StatusCode}"); + } + + // check content is not empty + string content = await response.Content.ReadAsStringAsync(); + if (string.IsNullOrWhiteSpace(content)) + { + string message = "Received empty response from CBN API."; + logger.LogError(message); + throw new InvalidOperationException(message); + } + + // deserialize the response. JsonSerializer.Deserialize may throw JsonException for invalid JSON; + ExchangeRatesResponse? dtoRates; + try + { + dtoRates = JsonSerializer.Deserialize(content); + } + catch (JsonException jex) + { + logger.LogError(jex, "Failed to deserialize CBN API response JSON."); + throw new InvalidOperationException("Failed to deserialize CBN API response.", jex); + } + + if (dtoRates is null) + throw new InvalidOperationException("Failed to deserialize CBN API response."); + return dtoRates.Rates.ToDomain(); + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.CbnApiClient/Mapper/CnbExchangeRateMapperExtensions.cs b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/Mapper/CnbExchangeRateMapperExtensions.cs new file mode 100644 index 0000000000..e62670f6a8 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.CbnApiClient/Mapper/CnbExchangeRateMapperExtensions.cs @@ -0,0 +1,53 @@ +using ExchangeRateUpdater.CbnApiClient.Dto; +using ExchangeRateUpdater.Abstraction.Model; + +namespace ExchangeRateUpdater.CbnApiClient.Mapper +{ + + /// + /// Extension methods to map CNB API DTOs to domain models. + /// + public static class CnbExchangeRateMapperExtensions + { + private const string TARGET_CURRENCY_CODE = "CZK"; + /// + /// Maps a single to a domain . + /// By convention the CNB API provides rates as an amount of CZK for a given + /// units of the foreign currency. This method maps the entry to an ExchangeRate where the source currency + /// is the foreign currency and the target currency is CZK. The resulting value is the rate for one unit of + /// the source currency (Rate / Amount). + /// + /// The DTO entry to map. + /// The mapped . + public static ExchangeRate ToDomain(this ExchangeRateEntry entry) + { + ArgumentNullException.ThrowIfNull(entry); + + // Avoid division by zero and ensure the amount is positive as expected by the CNB API. + if (entry.Amount <= 0) + throw new ArgumentException("Entry amount must be greater than zero.", nameof(entry)); + + // CNB returns the amount of CZK for 'Amount' units of the foreign currency. + // Normalize to a per-1-unit rate. + var valuePerUnit = entry.Rate / entry.Amount; + + var source = new Currency(entry.CurrencyCode); + var target = new Currency(TARGET_CURRENCY_CODE); + + return new ExchangeRate(source, target, valuePerUnit, entry.ValidFor); + } + + /// + /// Maps a sequence of to . + /// Null entries are ignored. + /// + public static IEnumerable ToDomain(this IEnumerable entries) + { + ArgumentNullException.ThrowIfNull(entries); + + return entries + .Where(e => e is not null) + .Select(e => e.ToDomain()); + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.DependencyInjection/DependencyInyection.md b/jobs/Backend/ExchangeRateUpdater.DependencyInjection/DependencyInyection.md new file mode 100644 index 0000000000..56c2fcb72b --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.DependencyInjection/DependencyInyection.md @@ -0,0 +1,20 @@ +# Dependency Injection Design + +## Purpose + +This project encapsulates the dependency injection configuration for the exchange rate services. Instead of registering all services directly inside a specific host (for example, the Web API), the setup is extracted into a shared extension method that can be reused by multiple applications. + +The main entry point is the `AddExchangeRateServices(IServiceCollection services)` extension method, which wires together: + +- The `IExchangeRateProvider` and `IExchangeRateService` implementations. +- The CNB HTTP client (`IExchangeRateClient`) configured with a basic resilience policy (retries with exponential backoff). + +## Why a separate project? + +There are several reasons for keeping this registration logic in a dedicated project rather than placing it directly inside the API project: + +- **Separation of concerns** + The host projects (API, console, etc.) focus on hosting concerns (endpoints, input/output, configuration), while this project focuses only on how the exchange rate domain and infrastructure are composed. This makes the startup code of each host simpler and easier to read. + +- **Reusability across hosts** + Any application can call the same `AddExchangeRateServices` method to get a fully configured exchange rate stack without duplicating registration code. diff --git a/jobs/Backend/ExchangeRateUpdater.DependencyInjection/ExchangeRateCnbServicesExtension.cs b/jobs/Backend/ExchangeRateUpdater.DependencyInjection/ExchangeRateCnbServicesExtension.cs new file mode 100644 index 0000000000..38c4f94e6f --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.DependencyInjection/ExchangeRateCnbServicesExtension.cs @@ -0,0 +1,37 @@ +using ExchangeRateUpdater.Abstraction.Interfaces; +using ExchangeRateUpdater.CbnApiClient.Implementation; +using ExchangeRateUpdater.Service; +using Microsoft.Extensions.DependencyInjection; +using Polly; +using Polly.Extensions.Http; + +namespace ExchangeRateUpdater.DependencyInjection +{ + /// + /// Provides extension methods for registering exchange rate client services with the dependency injection + /// container. + /// + /// This static class is intended to be used in application startup to ensure that the + /// IExchangeRateClient implementation is available for dependency injection. It simplifies the configuration of + /// exchange rate services by encapsulating the registration logic. + public static class ExchangeRateCnbServicesExtension + { + public static IServiceCollection AddExchangeRateServices(this IServiceCollection services) + { + services.AddMemoryCache(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + // Configure a named HttpClient for the CNB API with Polly-based retry policy. + // This will be available as httpClientFactory.CreateClient("CnbApi"). + services.AddHttpClient("CnbApi") + .AddPolicyHandler(HttpPolicyExtensions + .HandleTransientHttpError() + .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))) + ); + + return services; + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.DependencyInjection/ExchangeRateUpdater.DependencyInjection.csproj b/jobs/Backend/ExchangeRateUpdater.DependencyInjection/ExchangeRateUpdater.DependencyInjection.csproj new file mode 100644 index 0000000000..a4e7971419 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.DependencyInjection/ExchangeRateUpdater.DependencyInjection.csproj @@ -0,0 +1,22 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + + + + + diff --git a/jobs/Backend/ExchangeRateUpdater.Service/ExchangeRateProvider.cs b/jobs/Backend/ExchangeRateUpdater.Service/ExchangeRateProvider.cs new file mode 100644 index 0000000000..e3d0bc8812 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Service/ExchangeRateProvider.cs @@ -0,0 +1,75 @@ +using ExchangeRateUpdater.Abstraction.Interfaces; +using ExchangeRateUpdater.Abstraction.Model; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging; + +namespace ExchangeRateUpdater.Service +{ + /// + /// Provides methods for retrieving exchange rates for specified currencies from an external source. + /// + /// The client used to obtain exchange rate data from an external provider. + /// The logger used to record informational messages and errors related to exchange rate retrieval. + public class ExchangeRateProvider(IExchangeRateClient exchangeRateClient, ILogger logger, IMemoryCache cache) : IExchangeRateProvider + { + private const string CacheKey = "CnbRates"; + + public async Task> GetExchangeRatesAsync(IEnumerable currencies) + { + ArgumentNullException.ThrowIfNull(currencies); + + // Try get from cache first + if (!cache.TryGetValue>(CacheKey, out var cachedRates)) + { + logger.LogInformation("Cache miss for CNB rates, fetching from upstream"); + var fetched = await exchangeRateClient.GetExchangeRatesAsync(); + + var cacheExpiration = CalculateCacheExpiration(); + var options = new MemoryCacheEntryOptions() + .SetAbsoluteExpiration(cacheExpiration); + + cache.Set(CacheKey, fetched, options); + cachedRates = fetched; + } + else + { + logger.LogDebug("Cache hit for CNB rates"); + } + + var currencySet = currencies.ToHashSet(); + var filteredRates = cachedRates.Where(rate => currencySet.Contains(rate.SourceCurrency)); + return filteredRates; + } + + /// + /// Calculates the cache expiration duration based on CNB API publication schedule. + /// The CNB publishes new rates around 15:00 UTC on working days. + /// This method schedules the cache to expire shortly after the next expected publication. + /// + /// A TimeSpan representing the cache duration (minimum 1 minute, maximum 24 hours). + private static TimeSpan CalculateCacheExpiration() + { + var now = DateTime.UtcNow; + var nextPublication = new DateTime(now.Year, now.Month, now.Day, 15, 0, 0, DateTimeKind.Utc); + + if (now >= nextPublication) + { + // Already past today's publication time, schedule for next day + nextPublication = nextPublication.AddDays(1); + } + + var absoluteExpirationRelative = nextPublication - now; + + // Guard: ensure a minimum cache duration and reasonable maximum (24h) + // Cache will refresh even on non-working days, but that's acceptable because + // 1 unnecessary request a day is not a problem for CNB. + if (absoluteExpirationRelative < TimeSpan.FromMinutes(1)) + absoluteExpirationRelative = TimeSpan.FromMinutes(1); + + if (absoluteExpirationRelative > TimeSpan.FromHours(24)) + absoluteExpirationRelative = TimeSpan.FromHours(24); + + return absoluteExpirationRelative; + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Service/ExchangeRateService.cs b/jobs/Backend/ExchangeRateUpdater.Service/ExchangeRateService.cs new file mode 100644 index 0000000000..fdbaf8e51d --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Service/ExchangeRateService.cs @@ -0,0 +1,49 @@ +using ExchangeRateUpdater.Abstraction.Interfaces; +using ExchangeRateUpdater.Abstraction.Model; +using Microsoft.Extensions.Logging; + +namespace ExchangeRateUpdater.Service +{ + /// + /// Provides functionality to retrieve exchange rates for specified currency codes. + /// + /// The provider used to fetch exchange rate data. + /// The logger instance used to record informational and error messages for this service. + public class ExchangeRateService(IExchangeRateProvider exchangeRateProvider, ILogger logger) : IExchangeRateService + { + /// + /// Retrieves exchange rates for the specified collection of currency codes. + /// + /// An enumerable collection of currency code strings to retrieve exchange rates for. Each string must represent + /// a valid currency code. + /// A task that represents the asynchronous operation. The task result contains a collection of exchange rates + /// corresponding to the valid currency codes provided. Returns an empty collection if no valid codes are + /// supplied. + public async Task> GetExchangeRatesFromStringList(IEnumerable currencyCodes) + { + List currencyList = new(); + foreach (var currencyCode in currencyCodes) + { + try + { + var currency = new Currency(currencyCode); + currencyList.Add(currency); + } + catch (ArgumentException ex) + { + logger.LogWarning($"Invalid currency {currencyCode}: {ex.Message}"); + continue; + } + } + + if (currencyList.Count == 0) + { + logger.LogWarning("No valid currency codes provided."); + return []; + } + + IEnumerable exchangeRates = await exchangeRateProvider.GetExchangeRatesAsync(currencyList); + return exchangeRates; + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Service/ExchangeRateUpdater.Service.csproj b/jobs/Backend/ExchangeRateUpdater.Service/ExchangeRateUpdater.Service.csproj new file mode 100644 index 0000000000..4efb709549 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Service/ExchangeRateUpdater.Service.csproj @@ -0,0 +1,18 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + diff --git a/jobs/Backend/ExchangeRateUpdater.Tests/Abstraction/ModelTests.cs b/jobs/Backend/ExchangeRateUpdater.Tests/Abstraction/ModelTests.cs new file mode 100644 index 0000000000..97db54f8d6 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Tests/Abstraction/ModelTests.cs @@ -0,0 +1,66 @@ +using ExchangeRateUpdater.Abstraction.Model; + +namespace ExchangeRateUpdater.Tests.Abstraction +{ + [TestFixture] + public class ModelTests + { + [Test] + public void Currency_Constructor_NormalizesAndToString() + { + var c = new Currency(" usd "); + Assert.That(c.Code, Is.EqualTo("USD")); + Assert.That(c.ToString(), Is.EqualTo("USD")); + } + + [Test] + public void Currency_Constructor_InvalidInputs_Throw() + { + Assert.That(() => new Currency(null!), Throws.TypeOf()); + Assert.That(() => new Currency(string.Empty), Throws.TypeOf()); + Assert.That(() => new Currency(" "), Throws.TypeOf()); + Assert.That(() => new Currency("US"), Throws.TypeOf()); + Assert.That(() => new Currency("USDE"), Throws.TypeOf()); + Assert.That(() => new Currency("U$D"), Throws.TypeOf()); + } + + [Test] + public void Currency_Equals_IsCaseInsensitive() + { + var a = new Currency("usd"); + var b = new Currency("USD"); + + Assert.That(a, Is.EqualTo(b)); + Assert.That(b, Is.EqualTo(a)); + Assert.That(a.GetHashCode(), Is.EqualTo(b.GetHashCode())); + } + + [Test] + public void ExchangeRate_Constructor_SetsProperties() + { + var src = new Currency("USD"); + var tgt = new Currency("CZK"); + var validFor = new DateTime(2026, 02, 15); + + var rate = new ExchangeRate(src, tgt, 25.5m, validFor); + + Assert.That(rate.SourceCurrency, Is.EqualTo(src)); + Assert.That(rate.TargetCurrency, Is.EqualTo(tgt)); + Assert.That(rate.Value, Is.EqualTo(25.5m)); + Assert.That(rate.ValidFor, Is.EqualTo(validFor)); + Assert.That(rate.ToString(), Does.Contain("USD/CZK=")); + Assert.That(rate.ToString(), Does.Contain(validFor.ToString())); + } + + [Test] + public void ExchangeRate_InvalidValue_Throws() + { + var src = new Currency("USD"); + var tgt = new Currency("CZK"); + var validFor = DateTime.UtcNow; + + Assert.That(() => new ExchangeRate(src, tgt, 0m, validFor), Throws.TypeOf()); + Assert.That(() => new ExchangeRate(src, tgt, -1m, validFor), Throws.TypeOf()); + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Tests/Api/ExchangeRateControllerTests.cs b/jobs/Backend/ExchangeRateUpdater.Tests/Api/ExchangeRateControllerTests.cs new file mode 100644 index 0000000000..356ee66804 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Tests/Api/ExchangeRateControllerTests.cs @@ -0,0 +1,65 @@ +using ExchangeRateUpdater.Abstraction.Interfaces; +using ExchangeRateUpdater.Abstraction.Model; +using ExchangeRateUpdater.Api.Controllers; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using NSubstitute; + +namespace ExchangeRateUpdater.Tests.Api +{ + [TestFixture] + internal class ExchangeRateControllerTests + { + private IExchangeRateService service = null!; + private ILogger logger = null!; + private ExchangeRateController controller = null!; + + [SetUp] + public void SetUp() + { + service = Substitute.For(); + logger = Substitute.For>(); + controller = new ExchangeRateController(service, logger); + } + + [Test] + public async Task GetExchangeRates_ReturnsOkWithRates_WhenServiceReturnsRates() + { + var now = DateTime.UtcNow; + var rates = new[] { new ExchangeRate(new Currency("USD"), new Currency("CZK"), 25m, now) }; + service.GetExchangeRatesFromStringList(Arg.Any>()).Returns(Task.FromResult>(rates)); + + var result = await controller.GetExchangeRates("USD, EUR"); + + Assert.That(result.Result, Is.TypeOf()); + var ok = (OkObjectResult)result.Result!; + Assert.That(ok.Value, Is.InstanceOf>()); + var returned = ((IEnumerable)ok.Value!).ToArray(); + Assert.That(returned.Length, Is.EqualTo(1)); + Assert.That(returned[0].SourceCurrency.Code, Is.EqualTo("USD")); + + // Ensure service was called with the split and trimmed values + await service.Received(1).GetExchangeRatesFromStringList(Arg.Is>(s => s.SequenceEqual(new[] { "USD", "EUR" }))); + } + + [Test] + public async Task GetExchangeRates_ReturnsBadRequest_WhenNoRates() + { + service.GetExchangeRatesFromStringList(Arg.Any>()).Returns(Task.FromResult>(Array.Empty())); + + var result = await controller.GetExchangeRates("USD"); + + Assert.That(result.Result, Is.TypeOf()); + var bad = (BadRequestObjectResult)result.Result!; + Assert.That(bad.Value, Is.EqualTo("No exchange rates found for the provided currency codes.")); + + // Logger should have been called to warn + logger.Received().Log( + LogLevel.Warning, + Arg.Any(), + Arg.Any(), + Arg.Any(), + Arg.Any>()); + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Tests/CbnApiClient/CnbExchangeRateMapperExtensionsTests.cs b/jobs/Backend/ExchangeRateUpdater.Tests/CbnApiClient/CnbExchangeRateMapperExtensionsTests.cs new file mode 100644 index 0000000000..bc33d87558 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Tests/CbnApiClient/CnbExchangeRateMapperExtensionsTests.cs @@ -0,0 +1,74 @@ +using ExchangeRateUpdater.CbnApiClient.Dto; +using ExchangeRateUpdater.CbnApiClient.Mapper; + +namespace ExchangeRateUpdater.Tests.CbnApiClient +{ + [TestFixture] + public class CnbExchangeRateMapperExtensionsTests + { + [Test] + public void ToDomain_SingleEntry_MapsCorrectly() + { + var dto = new ExchangeRateEntry + { + Amount = 100, + Rate = 2500m, + CurrencyCode = "USD", + ValidFor = new DateTime(2026, 2, 15) + }; + + var domain = dto.ToDomain(); + + Assert.That(domain.SourceCurrency.Code, Is.EqualTo("USD")); + Assert.That(domain.TargetCurrency.Code, Is.EqualTo("CZK")); + Assert.That(domain.Value, Is.EqualTo(25.0m)); + Assert.That(domain.ValidFor, Is.EqualTo(new DateTime(2026, 2, 15))); + } + + [Test] + public void ToDomain_SingleEntry_Null_Throws() + { + ExchangeRateEntry? dto = null; + Assert.That(() => CnbExchangeRateMapperExtensions.ToDomain(dto!), Throws.TypeOf()); + } + + [Test] + public void ToDomain_SingleEntry_AmountZero_Throws() + { + var dto = new ExchangeRateEntry + { + Amount = 0, + Rate = 100m, + CurrencyCode = "EUR", + ValidFor = DateTime.UtcNow + }; + + Assert.That(() => dto.ToDomain(), Throws.TypeOf()); + } + + [Test] + public void ToDomain_Enumerable_MapsAndIgnoresNulls() + { + var list = new List + { + new ExchangeRateEntry { Amount = 1, Rate = 30m, CurrencyCode = "ABC", ValidFor = new DateTime(2026,1,1) }, + null, + new ExchangeRateEntry { Amount = 2, Rate = 100m, CurrencyCode = "DEF", ValidFor = new DateTime(2026,1,2) } + }; + + var mapped = CnbExchangeRateMapperExtensions.ToDomain(list.Where(e => e is not null).Select(e => e!)); + + var arr = mapped.ToArray(); + Assert.That(arr.Length, Is.EqualTo(2)); + Assert.That(arr[0].SourceCurrency.Code, Is.EqualTo("ABC")); + Assert.That(arr[1].SourceCurrency.Code, Is.EqualTo("DEF")); + } + + [Test] + public void ToDomain_Enumerable_Null_Throws() + { + IEnumerable? entries = null; + Assert.That(() => CnbExchangeRateMapperExtensions.ToDomain(entries!), Throws.TypeOf()); + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Tests/CbnApiClient/ExchangeRateCbnApiClientTests.cs b/jobs/Backend/ExchangeRateUpdater.Tests/CbnApiClient/ExchangeRateCbnApiClientTests.cs new file mode 100644 index 0000000000..96a0ffc58d --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Tests/CbnApiClient/ExchangeRateCbnApiClientTests.cs @@ -0,0 +1,133 @@ +using System.Net; +using ExchangeRateUpdater.CbnApiClient.Implementation; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using NSubstitute; + +namespace ExchangeRateUpdater.Tests.CbnApiClient +{ + public class ExchangeRateCbnApiClientTests + { + private IConfiguration config = null!; + private readonly ILogger logger = NullLogger.Instance; + + [SetUp] + public void SetUp() + { + config = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary { { "CbnApiUrl", "https://api.cnb.cz/cnbapi/exrates/daily" } }) + .Build(); + } + + private static IHttpClientFactory CreateHttpClientFactory(HttpResponseMessage response, Action? inspect = null) + { + // Create an in-memory HttpClient that uses a delegating handler returning the provided response. + // Do not set a real BaseAddress to avoid any accidental network usage in tests. + var handler = new DelegatingHandlerStub(response, inspect); + var client = new HttpClient(handler); + + // Use NSubstitute to create a test double for IHttpClientFactory that returns our client. + var factory = Substitute.For(); + factory.CreateClient(Arg.Any()).Returns(client); + return factory; + } + + [Test] + public async Task GetExchangeRatesAsync_ReturnsMappedRates() + { + var json = "{\"rates\":[{\"amount\":100,\"country\":\"United States\",\"currency\":\"Dollar\",\"currencyCode\":\"USD\",\"order\":1,\"rate\":2500,\"validFor\":\"2026-02-15\"}]}"; + var response = new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent(json) + }; + + var factory = CreateHttpClientFactory(response); + + var client = new ExchangeRateCnbApiClient(factory, config, logger); + var rates = await client.GetExchangeRatesAsync(); + + Assert.That(rates, Is.Not.Null); + var first = rates.First(); + Assert.That(first.SourceCurrency.Code, Is.EqualTo("USD")); + Assert.That(first.TargetCurrency.Code, Is.EqualTo("CZK")); + Assert.That(first.Value, Is.EqualTo(25.0m)); + Assert.That(first.ValidFor, Is.EqualTo(new DateTime(2026, 02, 15))); + } + + [Test] + public void GetExchangeRatesAsync_ThrowsOnNonSuccess() + { + var response = new HttpResponseMessage(HttpStatusCode.InternalServerError); + var factory = CreateHttpClientFactory(response); + + var client = new ExchangeRateCnbApiClient(factory, config, logger); + Assert.That(async () => await client.GetExchangeRatesAsync(), Throws.InstanceOf()); + } + + [Test] + public void GetExchangeRatesAsync_ThrowsOnEmptyContent() + { + var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(string.Empty) }; + var factory = CreateHttpClientFactory(response); + + var client = new ExchangeRateCnbApiClient(factory, config, logger); + Assert.That(async () => await client.GetExchangeRatesAsync(), Throws.InstanceOf()); + } + + [Test] + public void GetExchangeRatesAsync_ThrowsOnInvalidJson() + { + var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("not json") }; + var factory = CreateHttpClientFactory(response); + + var client = new ExchangeRateCnbApiClient(factory, config, logger); + Assert.That(async () => await client.GetExchangeRatesAsync(), Throws.InstanceOf()); + } + + [Test] + public async Task GetExchangeRatesAsync_IncludesDateParameterWhenRequested() + { + HttpRequestMessage? captured = null; + var json = "{\"rates\":[]}"; + var response = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(json) }; + var factory = CreateHttpClientFactory(response, req => captured = req); + + var client = new ExchangeRateCnbApiClient(factory, config, logger); + var date = new DateTime(2026, 02, 15); + await client.GetExchangeRatesAsync(date); + + Assert.That(captured, Is.Not.Null); + Assert.That(captured!.RequestUri!.ToString(), Does.Contain("date=2026-02-15")); + } + } + + // Simple IHttpClientFactory implementation for tests + internal class SimpleHttpClientFactory : IHttpClientFactory + { + private readonly HttpClient _client; + + public SimpleHttpClientFactory(HttpClient client) => _client = client; + + public HttpClient CreateClient(string name) => _client; + } + + // DelegatingHandler stub that returns a configured response and allows inspection of the request + internal class DelegatingHandlerStub : DelegatingHandler + { + private readonly HttpResponseMessage _response; + private readonly Action? _inspect; + + public DelegatingHandlerStub(HttpResponseMessage response, Action? inspect = null) + { + _response = response; + _inspect = inspect; + } + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + _inspect?.Invoke(request); + return Task.FromResult(_response); + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Tests/ExchangeRateUpdater.Tests.csproj b/jobs/Backend/ExchangeRateUpdater.Tests/ExchangeRateUpdater.Tests.csproj new file mode 100644 index 0000000000..a1111e3bb4 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Tests/ExchangeRateUpdater.Tests.csproj @@ -0,0 +1,32 @@ + + + + net10.0 + latest + enable + enable + false + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jobs/Backend/ExchangeRateUpdater.Tests/IntegrationTests/IntegrationTests.cs b/jobs/Backend/ExchangeRateUpdater.Tests/IntegrationTests/IntegrationTests.cs new file mode 100644 index 0000000000..93593d1d3d --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Tests/IntegrationTests/IntegrationTests.cs @@ -0,0 +1,161 @@ +using System.Net; +using System.Text.Json; +using ExchangeRateUpdater.Abstraction.Model; +using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.TestHost; +using Microsoft.Extensions.DependencyInjection; + +namespace ExchangeRateUpdater.Tests.IntegrationTests +{ + [TestFixture] + internal class IntegrationTests + { + private WebApplicationFactory factory = null!; + private HttpClient apiClient = null!; + + [SetUp] + public void SetUp() + { + // Reset the call counter before each test + MockCnbApiHandler.ResetCallCount(); + + factory = new WebApplicationFactory() + .WithWebHostBuilder(builder => + { + builder.ConfigureTestServices(services => + { + // Remove the real named HttpClient registration for "CbnApi" if already registered + var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(IHttpClientFactory)); + if (descriptor != null) + { + services.Remove(descriptor); + } + + // Register a mock HttpClient that returns a controlled response + services.AddSingleton(sp => new MockHttpClientFactory()); + }); + }); + + apiClient = factory.CreateClient(); + } + + [TearDown] + public void TearDown() + { + apiClient?.Dispose(); + factory?.Dispose(); + } + + [Test] + public async Task GetExchangeRates_EndToEnd_ReturnsFilteredRates() + { + // Call the actual API endpoint + var response = await apiClient.GetAsync("/ExchangeRate?currencyCodes=USD,EUR"); + + Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); + + var content = await response.Content.ReadAsStringAsync(); + var rates = JsonSerializer.Deserialize>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + + Assert.That(rates, Is.Not.Null); + Assert.That(rates!.Count, Is.GreaterThan(0)); + + // Verify that returned rates include USD and/or EUR (depends on mock response) + var codes = rates.Select(r => r.SourceCurrency.Code).ToList(); + Assert.That(codes, Does.Contain("USD").Or.Contain("EUR")); + } + + [Test] + public async Task GetExchangeRates_InvalidCurrencyCodes_ReturnsBadRequest() + { + // Request with invalid codes (e.g., empty, too short) + var response = await apiClient.GetAsync("/ExchangeRate?currencyCodes=US,E"); + + Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest).Or.EqualTo(HttpStatusCode.OK)); + } + + [Test] + public async Task GetExchangeRates_CachingWorks_OnlyOneUpstreamCall() + { + // First call + var response1 = await apiClient.GetAsync("/ExchangeRate?currencyCodes=USD"); + Assert.That(response1.StatusCode, Is.EqualTo(HttpStatusCode.OK)); + + // Verify one upstream call was made + Assert.That(MockCnbApiHandler.CallCount, Is.EqualTo(1)); + + // Second call (should hit cache if enabled) + var response2 = await apiClient.GetAsync("/ExchangeRate?currencyCodes=EUR"); + Assert.That(response2.StatusCode, Is.EqualTo(HttpStatusCode.OK)); + + // Verify still only one upstream call was made (second request hit cache) + Assert.That(MockCnbApiHandler.CallCount, Is.EqualTo(1), "Cache should prevent a second upstream call"); + } + } + + // Mock IHttpClientFactory that returns a mock HttpClient with a delegating handler + internal class MockHttpClientFactory : IHttpClientFactory + { + public HttpClient CreateClient(string name) + { + var handler = new MockCnbApiHandler(); + return new HttpClient(handler); + } + } + + // Mock delegating handler that returns a fake CNB API response + internal class MockCnbApiHandler : DelegatingHandler + { + private static int _callCount = 0; + + public static int CallCount => _callCount; + + public static void ResetCallCount() => _callCount = 0; + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + // Increment the call counter + Interlocked.Increment(ref _callCount); + + // Return a fake JSON response similar to CNB API + var fakeResponse = @"{ + ""rates"": [ + { + ""amount"": 1, + ""country"": ""United States"", + ""currency"": ""Dollar"", + ""currencyCode"": ""USD"", + ""order"": 1, + ""rate"": 25.5, + ""validFor"": ""2026-02-15"" + }, + { + ""amount"": 1, + ""country"": ""Eurozone"", + ""currency"": ""Euro"", + ""currencyCode"": ""EUR"", + ""order"": 2, + ""rate"": 27.0, + ""validFor"": ""2026-02-15"" + }, + { + ""amount"": 100, + ""country"": ""Japan"", + ""currency"": ""Yen"", + ""currencyCode"": ""JPY"", + ""order"": 3, + ""rate"": 22.0, + ""validFor"": ""2026-02-15"" + } + ] +}"; + + var response = new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent(fakeResponse, System.Text.Encoding.UTF8, "application/json") + }; + + return Task.FromResult(response); + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Tests/Service/ExchangeRateProviderTests.cs b/jobs/Backend/ExchangeRateUpdater.Tests/Service/ExchangeRateProviderTests.cs new file mode 100644 index 0000000000..f2fbbec929 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Tests/Service/ExchangeRateProviderTests.cs @@ -0,0 +1,67 @@ +using ExchangeRateUpdater.Abstraction.Interfaces; +using ExchangeRateUpdater.Abstraction.Model; +using ExchangeRateUpdater.Service; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Logging.Abstractions; +using NSubstitute; + +namespace ExchangeRateUpdater.Tests.Service +{ + [TestFixture] + public class ExchangeRateProviderTests + { + private IExchangeRateClient client = null!; + private IMemoryCache cache = null!; + + [SetUp] + public void SetUp() + { + client = Substitute.For(); + cache = new MemoryCache(new MemoryCacheOptions()); + } + + [TearDown] + public void TearDown() + { + cache.Dispose(); + } + + [Test] + public async Task GetExchangeRatesAsync_FetchesFromClientAndCaches() + { + var now = DateTime.UtcNow; + var usd = new ExchangeRate(new Currency("USD"), new Currency("CZK"), 25m, now); + var eur = new ExchangeRate(new Currency("EUR"), new Currency("CZK"), 27m, now); + + client.GetExchangeRatesAsync().Returns(Task.FromResult>(new[] { usd, eur })); + + var provider = new ExchangeRateProvider(client, NullLogger.Instance, cache); + + var requested = new[] { new Currency("usd") }; + + var firstCall = await provider.GetExchangeRatesAsync(requested); + Assert.That(firstCall, Is.Not.Null); + var arr1 = firstCall.ToArray(); + Assert.That(arr1.Length, Is.EqualTo(1)); + Assert.That(arr1[0].SourceCurrency.Code, Is.EqualTo("USD")); + + // Client should have been called once + await client.Received(1).GetExchangeRatesAsync(); + + // Call again: should hit cache and not call client again + var secondCall = await provider.GetExchangeRatesAsync(requested); + await client.Received(1).GetExchangeRatesAsync(); + var arr2 = secondCall.ToArray(); + Assert.That(arr2.Length, Is.EqualTo(1)); + Assert.That(arr2[0].SourceCurrency.Code, Is.EqualTo("USD")); + } + + [Test] + public void GetExchangeRatesAsync_NullCurrencies_Throws() + { + var provider = new ExchangeRateProvider(client, NullLogger.Instance, cache); + + Assert.That(async () => await provider.GetExchangeRatesAsync(null!), Throws.TypeOf()); + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Tests/Service/ExchangeRateServiceTests.cs b/jobs/Backend/ExchangeRateUpdater.Tests/Service/ExchangeRateServiceTests.cs new file mode 100644 index 0000000000..2a4f1776bd --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Tests/Service/ExchangeRateServiceTests.cs @@ -0,0 +1,90 @@ +using ExchangeRateUpdater.Abstraction.Interfaces; +using ExchangeRateUpdater.Abstraction.Model; +using ExchangeRateUpdater.Service; +using Microsoft.Extensions.Logging; +using NSubstitute; + +namespace ExchangeRateUpdater.Tests.Service +{ + [TestFixture] + internal class ExchangeRateServiceTests + { + private IExchangeRateProvider provider = null!; + private ILogger logger = null!; + + [SetUp] + public void SetUp() + { + provider = Substitute.For(); + logger = Substitute.For>(); + } + + [Test] + public async Task GetExchangeRatesFromStringList_ValidCodes_CallsProviderAndReturnsRates() + { + var now = DateTime.UtcNow; + var expected = new[] { new ExchangeRate(new Currency("USD"), new Currency("CZK"), 25m, now) }; + + provider.GetExchangeRatesAsync(Arg.Is>(list => list.Select(c => c.Code).SequenceEqual(new[] { "USD" }))) + .Returns(Task.FromResult>(expected)); + + var svc = new ExchangeRateService(provider, logger); + var result = await svc.GetExchangeRatesFromStringList(new[] { "USD" }); + + Assert.That(result, Is.Not.Null); + Assert.That(result.ToArray().Length, Is.EqualTo(1)); + Assert.That(result.First().SourceCurrency.Code, Is.EqualTo("USD")); + } + + [Test] + public async Task GetExchangeRatesFromStringList_InvalidCodes_SkipsInvalidAndLogsWarning() + { + var provider = Substitute.For(); + var logger = Substitute.For>(); + + var now = DateTime.UtcNow; + var expected = new[] { new ExchangeRate(new Currency("USD"), new Currency("CZK"), 25m, now) }; + + provider.GetExchangeRatesAsync(Arg.Is>(list => list.Select(c => c.Code).SequenceEqual(new[] { "USD" }))) + .Returns(Task.FromResult>(expected)); + + var svc = new ExchangeRateService(provider, logger); + + // "US" is invalid (length != 3) and should be skipped + var result = await svc.GetExchangeRatesFromStringList(new[] { "USD", "US" }); + + Assert.That(result, Is.Not.Null); + Assert.That(result.First().SourceCurrency.Code, Is.EqualTo("USD")); + + // Verify a warning was logged for the invalid code + logger.Received().Log( + LogLevel.Warning, + Arg.Any(), + Arg.Any(), + Arg.Any(), + Arg.Any>()); + } + + [Test] + public async Task GetExchangeRatesFromStringList_NoValidCodes_ReturnsEmptyAndLogsWarning() + { + var provider = Substitute.For(); + var logger = Substitute.For>(); + + var svc = new ExchangeRateService(provider, logger); + + var result = await svc.GetExchangeRatesFromStringList(new[] { "", " " }); + + Assert.That(result, Is.Not.Null); + Assert.That(result, Is.Empty); + + // Should have logged a warning about no valid currency codes + logger.Received().Log( + LogLevel.Warning, + Arg.Any(), + Arg.Any(), + Arg.Any(), + Arg.Any>()); + } + } +} diff --git a/jobs/Backend/ExchangeRateUpdater.Tests/TestResults/coverage.cobertura.xml b/jobs/Backend/ExchangeRateUpdater.Tests/TestResults/coverage.cobertura.xml new file mode 100644 index 0000000000..139f2b3944 --- /dev/null +++ b/jobs/Backend/ExchangeRateUpdater.Tests/TestResults/coverage.cobertura.xml @@ -0,0 +1,2434 @@ + + + + C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jobs/Backend/Task/Currency.cs b/jobs/Backend/Task/Currency.cs deleted file mode 100644 index f375776f25..0000000000 --- a/jobs/Backend/Task/Currency.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace ExchangeRateUpdater -{ - public class Currency - { - public Currency(string code) - { - Code = code; - } - - /// - /// Three-letter ISO 4217 code of the currency. - /// - public string Code { get; } - - public override string ToString() - { - return Code; - } - } -} diff --git a/jobs/Backend/Task/ExchangeRate.cs b/jobs/Backend/Task/ExchangeRate.cs deleted file mode 100644 index 58c5bb10e0..0000000000 --- a/jobs/Backend/Task/ExchangeRate.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace ExchangeRateUpdater -{ - public class ExchangeRate - { - public ExchangeRate(Currency sourceCurrency, Currency targetCurrency, decimal value) - { - SourceCurrency = sourceCurrency; - TargetCurrency = targetCurrency; - Value = value; - } - - public Currency SourceCurrency { get; } - - public Currency TargetCurrency { get; } - - public decimal Value { get; } - - public override string ToString() - { - return $"{SourceCurrency}/{TargetCurrency}={Value}"; - } - } -} diff --git a/jobs/Backend/Task/ExchangeRateUpdater.csproj b/jobs/Backend/Task/ExchangeRateUpdater.csproj index 2fc654a12b..1a9fa9d905 100644 --- a/jobs/Backend/Task/ExchangeRateUpdater.csproj +++ b/jobs/Backend/Task/ExchangeRateUpdater.csproj @@ -2,7 +2,11 @@ Exe - net6.0 + net10.0 + + + + \ No newline at end of file diff --git a/jobs/Backend/Task/ExchangeRateUpdater.sln b/jobs/Backend/Task/ExchangeRateUpdater.sln index 89be84daff..5fb81af470 100644 --- a/jobs/Backend/Task/ExchangeRateUpdater.sln +++ b/jobs/Backend/Task/ExchangeRateUpdater.sln @@ -1,9 +1,24 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +# Visual Studio Version 18 +VisualStudioVersion = 18.3.11505.172 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeRateUpdater", "ExchangeRateUpdater.csproj", "{7B2695D6-D24C-4460-A58E-A10F08550CE0}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Elementos de la solución", "Elementos de la solución", "{48B4E715-10EA-4BC9-A470-3772CDD8D796}" + ProjectSection(SolutionItems) = preProject + ..\ArchitectureAndDecisions.md = ..\ArchitectureAndDecisions.md + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeRateUpdater.Abstraction", "..\ExchangeRateUpdater.Abstraction\ExchangeRateUpdater.Abstraction.csproj", "{057474C6-1170-4F57-BBE0-6346DCFF15F3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeRateUpdater.Api", "..\ExchangeRateUpdater.API\ExchangeRateUpdater.Api.csproj", "{9C0F9D26-C60C-47F4-97EE-44CBAA8B1D70}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeRateUpdater.CbnApiClient", "..\ExchangeRateUpdater.CbnApiClient\ExchangeRateUpdater.CbnApiClient.csproj", "{DBF8A019-CB62-4501-853E-A2F880880B03}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeRateUpdater.DependencyInjection", "..\ExchangeRateUpdater.DependencyInjection\ExchangeRateUpdater.DependencyInjection.csproj", "{AAA4D713-37BE-48ED-802C-2CB5E7C64C50}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeRateUpdater.Service", "..\ExchangeRateUpdater.Service\ExchangeRateUpdater.Service.csproj", "{51ED7477-E620-4969-A450-572C5C4945AC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExchangeRateUpdater.Tests", "..\ExchangeRateUpdater.Tests\ExchangeRateUpdater.Tests.csproj", "{EEB3288A-C038-4EAC-877E-7E3862D4D8BA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,12 +26,35 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7B2695D6-D24C-4460-A58E-A10F08550CE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7B2695D6-D24C-4460-A58E-A10F08550CE0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7B2695D6-D24C-4460-A58E-A10F08550CE0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7B2695D6-D24C-4460-A58E-A10F08550CE0}.Release|Any CPU.Build.0 = Release|Any CPU + {057474C6-1170-4F57-BBE0-6346DCFF15F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {057474C6-1170-4F57-BBE0-6346DCFF15F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {057474C6-1170-4F57-BBE0-6346DCFF15F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {057474C6-1170-4F57-BBE0-6346DCFF15F3}.Release|Any CPU.Build.0 = Release|Any CPU + {9C0F9D26-C60C-47F4-97EE-44CBAA8B1D70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C0F9D26-C60C-47F4-97EE-44CBAA8B1D70}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C0F9D26-C60C-47F4-97EE-44CBAA8B1D70}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C0F9D26-C60C-47F4-97EE-44CBAA8B1D70}.Release|Any CPU.Build.0 = Release|Any CPU + {DBF8A019-CB62-4501-853E-A2F880880B03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBF8A019-CB62-4501-853E-A2F880880B03}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBF8A019-CB62-4501-853E-A2F880880B03}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBF8A019-CB62-4501-853E-A2F880880B03}.Release|Any CPU.Build.0 = Release|Any CPU + {AAA4D713-37BE-48ED-802C-2CB5E7C64C50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AAA4D713-37BE-48ED-802C-2CB5E7C64C50}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AAA4D713-37BE-48ED-802C-2CB5E7C64C50}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AAA4D713-37BE-48ED-802C-2CB5E7C64C50}.Release|Any CPU.Build.0 = Release|Any CPU + {51ED7477-E620-4969-A450-572C5C4945AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51ED7477-E620-4969-A450-572C5C4945AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51ED7477-E620-4969-A450-572C5C4945AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51ED7477-E620-4969-A450-572C5C4945AC}.Release|Any CPU.Build.0 = Release|Any CPU + {EEB3288A-C038-4EAC-877E-7E3862D4D8BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EEB3288A-C038-4EAC-877E-7E3862D4D8BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EEB3288A-C038-4EAC-877E-7E3862D4D8BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EEB3288A-C038-4EAC-877E-7E3862D4D8BA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0225AD9B-A542-4599-8171-46F69207D1DE} + EndGlobalSection EndGlobal diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.Abstraction_Currency.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.Abstraction_Currency.html new file mode 100644 index 0000000000..ec2224a7d5 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.Abstraction_Currency.html @@ -0,0 +1,231 @@ + + + + + + + +ExchangeRateUpdater.Abstraction.Model.Currency - Coverage Report + +
+

< Summary

+
+
+
Information
+
+
+ + + + + + + + + + + + + +
Class:ExchangeRateUpdater.Abstraction.Model.Currency
Assembly:ExchangeRateUpdater.Abstraction
File(s):C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.Abstraction\Model\Currency.cs
+
+
+
+
+
+
+
Line coverage
+
+
100%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:18
Uncovered lines:0
Coverable lines:18
Total lines:48
Line coverage:100%
+
+
+
+
+
Branch coverage
+
+
87%
+
+ + + + + + + + + + + + + +
Covered branches:7
Total branches:8
Branch coverage:87.5%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + + + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%66100%
get_Code()100%11100%
ToString()100%11100%
Equals(...)100%11100%
Equals(...)50%22100%
GetHashCode()100%11100%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.Abstraction\Model\Currency.cs

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#LineLine coverage
 1namespace ExchangeRateUpdater.Abstraction.Model
 2{
 3    public class Currency
 4    {
 5        /// <summary>
 6        /// Initializes a new instance of the Currency class using the specified currency code.
 7        /// </summary>
 8        /// <param name="code">The currency code to represent. This value must be a non-empty string consisting of exact
 9        /// characters. The code is trimmed and converted to uppercase.</param>
 10        /// <exception cref="ArgumentException">Thrown if the specified <paramref name="code"/> is null, empty, or consi
 11        /// <exception cref="ArgumentException">Thrown if the specified <paramref name="code"/> does not have exactly th
 12        /// <exception cref="ArgumentException">Thrown if the specified <paramref name="code"/> contains non-letter char
 8313        public Currency(string code)
 8314        {
 8315            if (string.IsNullOrWhiteSpace(code))
 516                throw new ArgumentException("Currency code must not be empty.", nameof(code));
 17
 7818            code = code.Trim();
 7819            if (code.Length != 3)
 520                throw new ArgumentException("Currency code must be exactly three characters long.", nameof(code));
 21
 7322            if (!code.All(char.IsLetter))
 123                throw new ArgumentException("Currency code must consist of letters only.", nameof(code));
 24
 7225            Code = code.Trim().ToUpperInvariant();
 7226        }
 27
 28        /// <summary>
 29        /// Three-letter ISO 4217 code of the currency.
 30        /// </summary>
 8331        public string Code { get; }
 32
 33        public override string ToString()
 534        {
 535            return Code;
 536        }
 37
 38        // Compare using OrdinalIgnoreCase so the comparison is
 39        // culture-invariant and consistent across environments
 40        // (e.g. Turkish dotted/dotless i behaviour).
 1241        public bool Equals(Currency other) => string.Equals(Code, other.Code, StringComparison.OrdinalIgnoreCase);
 42
 1243        public override bool Equals(object? obj) => obj is Currency other && Equals(other);
 44
 45        // Use the same comparer for hash code to respect equality contract.
 3046        public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Code);
 47    }
 48}
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.Abstraction_ExchangeRate.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.Abstraction_ExchangeRate.html new file mode 100644 index 0000000000..ea4cc9a204 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.Abstraction_ExchangeRate.html @@ -0,0 +1,238 @@ + + + + + + + +ExchangeRateUpdater.Abstraction.Model.ExchangeRate - Coverage Report + +
+

< Summary

+
+
+
Information
+
+
+ + + + + + + + + + + + + +
Class:ExchangeRateUpdater.Abstraction.Model.ExchangeRate
Assembly:ExchangeRateUpdater.Abstraction
File(s):C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.Abstraction\Model\ExchangeRate.cs
+
+
+
+
+
+
+
Line coverage
+
+
100%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:16
Uncovered lines:0
Coverable lines:16
Total lines:55
Line coverage:100%
+
+
+
+
+
Branch coverage
+
+
100%
+
+ + + + + + + + + + + + + +
Covered branches:2
Total branches:2
Branch coverage:100%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + + + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%22100%
get_SourceCurrency()100%11100%
get_TargetCurrency()100%11100%
get_Value()100%11100%
get_ValidFor()100%11100%
ToString()100%11100%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.Abstraction\Model\ExchangeRate.cs

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#LineLine coverage
 1namespace ExchangeRateUpdater.Abstraction.Model
 2{
 3    /// <summary>
 4    /// Represents an exchange rate between two currencies, providing the source currency, target currency, and the
 5    /// exchange rate value.
 6    /// </summary>
 7    public class ExchangeRate
 8    {
 9
 10        /// <summary>
 11        /// Initializes a new instance of the ExchangeRate class using the specified source and target currencies and
 12        /// the exchange rate value.
 13        /// </summary>
 14        /// <param name="sourceCurrency">The currency from which the exchange rate is calculated.</param>
 15        /// <param name="targetCurrency">The currency to which the exchange rate is applied.</param>
 16        /// <param name="value">The exchange rate value. Must be greater than zero.</param>
 17        /// <exception cref="ArgumentOutOfRangeException">Thrown when the value parameter is less than or equal to zero.
 3218        public ExchangeRate(Currency sourceCurrency, Currency targetCurrency, decimal value, DateTime validFor)
 3219        {
 3220            if (value <= 0)
 221                throw new ArgumentOutOfRangeException(nameof(value), "Exchange rate value must be greater than zero.");
 22
 3023            SourceCurrency = sourceCurrency;
 3024            TargetCurrency = targetCurrency;
 3025            Value = value;
 3026            ValidFor = validFor;
 3027        }
 28
 29        /// <summary>
 30        /// Gets the currency used as the source for conversion.
 31        /// </summary>
 4032        public Currency SourceCurrency { get; }
 33
 34        /// <summary>
 35        /// Gets the currency to which the transaction amount will be converted.
 36        /// </summary>
 937        public Currency TargetCurrency { get; }
 38
 39        /// <summary>
 40        /// Gets the current exchange rate value represented by this instance.
 41        /// How much of the target currency is equivalent to one unit of the source currency.
 42        /// </summary>
 943        public decimal Value { get; }
 44
 45        /// <summary>
 46        /// Gets the date and time until which the current entity is valid.
 47        /// </summary>
 948        public DateTime ValidFor { get; }
 49
 50        public override string ToString()
 251        {
 252            return $"{SourceCurrency}/{TargetCurrency}={Value} (valid for {ValidFor})";
 253        }
 54    }
 55}
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_CompilerServices.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_CompilerServices.html new file mode 100644 index 0000000000..12179610c7 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_CompilerServices.html @@ -0,0 +1,167 @@ + + + + + + + +System.Runtime.CompilerServices - Coverage Report + +
+

< Summary

+ +
+
+
Line coverage
+
+
0%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:0
Uncovered lines:3
Coverable lines:3
Total lines:23
Line coverage:0%
+
+
+
+
+
Branch coverage
+
+
N/A
+
+ + + + + + + + + + + + + +
Covered branches:0
Total branches:0
Branch coverage:N/A
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.API\obj\Debug\net10.0\Microsoft.AspNetCore.OpenApi.SourceGenerators\Microsoft.AspNetCore.OpenApi.SourceGenerators.XmlCommentGenerator\OpenApiXmlCommentSupport.generated.cs

+

File 'C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.API\obj\Debug\net10.0\Microsoft.AspNetCore.OpenApi.SourceGenerators\Microsoft.AspNetCore.OpenApi.SourceGenerators.XmlCommentGenerator\OpenApiXmlCommentSupport.generated.cs' does not exist (any more).

+
+
+
+

Methods/Properties

+.ctor(System.Int32,System.String)
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_ExceptionHandlingMiddleware.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_ExceptionHandlingMiddleware.html new file mode 100644 index 0000000000..4876303ea1 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_ExceptionHandlingMiddleware.html @@ -0,0 +1,247 @@ + + + + + + + +ExchangeRateUpdater.Api.Middleware.ExceptionHandlingMiddleware - Coverage Report + +
+

< Summary

+
+
+
Information
+
+
+ + + + + + + + + + + + + +
Class:ExchangeRateUpdater.Api.Middleware.ExceptionHandlingMiddleware
Assembly:ExchangeRateUpdater.Api
File(s):C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.API\Middleware\ExceptionHandlingMiddleware.cs
+
+
+
+
+
+
+
Line coverage
+
+
40%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:12
Uncovered lines:18
Coverable lines:30
Total lines:70
Line coverage:40%
+
+
+
+
+
Branch coverage
+
+
0%
+
+ + + + + + + + + + + + + +
Covered branches:0
Total branches:4
Branch coverage:0%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
InvokeAsync()100%1155.55%
HandleExceptionAsync()0%2040%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.API\Middleware\ExceptionHandlingMiddleware.cs

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#LineLine coverage
 1using System.Net;
 2using System.Text.Json;
 3using Microsoft.AspNetCore.Mvc;
 4
 5namespace ExchangeRateUpdater.Api.Middleware
 6{
 7    /// <summary>
 8    /// Middleware that handles exceptions thrown during the processing of HTTP requests, logging the error and returnin
 9    /// standardized JSON response.
 10    /// </summary>
 11    /// <param name="next">The delegate that represents the next middleware in the request processing pipeline.</param>
 12    /// <param name="logger">The logger used to log unhandled exceptions that occur during request processing.</param>
 13    /// <param name="env">The web host environment that provides information about the hosting environment, such as whet
 14    /// in development mode.</param>
 315    public class ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger, IWebHost
 16    {
 317        private readonly Dictionary<Type, HttpStatusCode> exceptionStatusCodes = new()
 318        {
 319            { typeof(ArgumentException), HttpStatusCode.BadRequest },
 320            { typeof(ArgumentNullException), HttpStatusCode.BadRequest },
 321            { typeof(InvalidOperationException), HttpStatusCode.InternalServerError  }
 322        };
 23
 24        /// <summary>
 25        /// Invokes the next middleware in the HTTP request pipeline asynchronously and handles any exceptions that
 26        /// occur during execution.
 27        /// </summary>
 28        /// <param name="context">The HttpContext for the current request, which encapsulates all HTTP-specific informat
 29        /// individual HTTP request.</param>
 30        /// <returns>A task that represents the asynchronous operation of invoking the next middleware and handling exce
 31        public async Task InvokeAsync(HttpContext context)
 432        {
 33            try
 434            {
 435                await next(context);
 436            }
 037            catch (Exception ex)
 038            {
 039                await HandleExceptionAsync(context, ex);
 040            }
 441        }
 42
 43        /// <summary>
 44        /// Handles exceptions that occur during the processing of an HTTP request by logging the error and generating a
 45        /// standardized JSON error response.
 46        /// </summary>
 47        /// <param name="context">The HttpContext for the current HTTP request, used to set the response status code and
 48        /// response.</param>
 49        /// <param name="ex">The exception that was thrown during request processing.</param>
 50        /// <returns>A task that represents the asynchronous operation.</returns>
 51        private async Task HandleExceptionAsync(HttpContext context, Exception ex)
 052        {
 053            logger.LogError(ex, "Unhandled exception");
 54
 055            context.Response.ContentType = "application/json";
 056            var status = (int)exceptionStatusCodes.GetValueOrDefault(ex.GetType(), HttpStatusCode.InternalServerError);
 057            context.Response.StatusCode = status;
 58
 059            var problem = new ProblemDetails
 060            {
 061                Status = status,
 062                Title = status == 500 ? "An internal error occurred." : "A request error occurred.",
 063                Detail = env.IsDevelopment() ? ex.ToString() : null
 064            };
 65
 066            var json = JsonSerializer.Serialize(problem);
 067            await context.Response.WriteAsync(json);
 068        }
 69    }
 70}
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_ExchangeRateController.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_ExchangeRateController.html new file mode 100644 index 0000000000..95ecd194f6 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_ExchangeRateController.html @@ -0,0 +1,206 @@ + + + + + + + +ExchangeRateUpdater.Api.Controllers.ExchangeRateController - Coverage Report + +
+

< Summary

+
+
+
Information
+
+
+ + + + + + + + + + + + + +
Class:ExchangeRateUpdater.Api.Controllers.ExchangeRateController
Assembly:ExchangeRateUpdater.Api
File(s):C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.API\Controllers\ExchangeRateController.cs
+
+
+
+
+
+
+
Line coverage
+
+
100%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:13
Uncovered lines:0
Coverable lines:13
Total lines:31
Line coverage:100%
+
+
+
+
+
Branch coverage
+
+
100%
+
+ + + + + + + + + + + + + +
Covered branches:2
Total branches:2
Branch coverage:100%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetExchangeRates()100%22100%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.API\Controllers\ExchangeRateController.cs

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#LineLine coverage
 1using ExchangeRateUpdater.Abstraction.Interfaces;
 2using ExchangeRateUpdater.Abstraction.Model;
 3using Microsoft.AspNetCore.Mvc;
 4
 5namespace ExchangeRateUpdater.Api.Controllers
 6{
 7    [ApiController]
 8    [Route("[controller]")]
 69    public class ExchangeRateController(
 610        IExchangeRateService exchangeRateService,
 611        ILogger<ExchangeRateController> logger) : ControllerBase
 12    {
 13        [HttpGet]
 14        public async Task<ActionResult<IEnumerable<ExchangeRate>>> GetExchangeRates([FromQuery] string currencyCodes)
 615        {
 616            logger.LogInformation("Received request to fetch exchange rates for currencies: {CurrencyCodes}", currencyCo
 17
 618            string[] codes = currencyCodes.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEnt
 19
 620            IEnumerable<ExchangeRate> exchangeRates = await exchangeRateService.GetExchangeRatesFromStringList(codes);
 621            if (exchangeRates.ToList().Count == 0)
 222            {
 223                logger.LogWarning("No exchange rates found for the provided currency codes: {CurrencyCodes}", currencyCo
 224                return BadRequest("No exchange rates found for the provided currency codes.");
 25            }
 26
 427            return Ok(exchangeRates);
 28
 629        }
 30    }
 31}
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_Generated.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_Generated.html new file mode 100644 index 0000000000..b68cbeacd8 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_Generated.html @@ -0,0 +1,211 @@ + + + + + + + +Microsoft.AspNetCore.OpenApi.Generated - Coverage Report + +
+

< Summary

+ +
+
+
Line coverage
+
+
0%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:0
Uncovered lines:374
Coverable lines:374
Total lines:592
Line coverage:0%
+
+
+
+
+
Branch coverage
+
+
0%
+
+ + + + + + + + + + + + + +
Covered branches:0
Total branches:206
Branch coverage:0%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Summary()100%210%
get_Description()100%210%
get_Remarks()100%210%
get_Returns()100%210%
get_Value()100%210%
get_Deprecated()100%210%
get_Examples()100%210%
get_Parameters()100%210%
get_Responses()100%210%
get_Name()100%210%
get_Code()100%210%
get_Cache()0%620%
GenerateCacheEntries()100%210%
CreateDocumentationId(...)0%620%
CreateDocumentationId(...)0%110100%
CreateDocumentationId(...)0%2040%
CreateDocumentationId(...)0%342180%
GetTypeDocId(...)0%812280%
NormalizeDocId(...)0%4260%
TransformAsync(...)0%8930940%
UnwrapOpenApiParameter(...)0%4260%
TransformAsync(...)0%1190340%
Parse(...)0%620%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.API\obj\Debug\net10.0\Microsoft.AspNetCore.OpenApi.SourceGenerators\Microsoft.AspNetCore.OpenApi.SourceGenerators.XmlCommentGenerator\OpenApiXmlCommentSupport.generated.cs

+

File 'C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.API\obj\Debug\net10.0\Microsoft.AspNetCore.OpenApi.SourceGenerators\Microsoft.AspNetCore.OpenApi.SourceGenerators.XmlCommentGenerator\OpenApiXmlCommentSupport.generated.cs' does not exist (any more).

+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_Program.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_Program.html new file mode 100644 index 0000000000..c37e5ed8a1 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.Api_Program.html @@ -0,0 +1,228 @@ + + + + + + + +Program - Coverage Report + +
+

< Summary

+
+
+
Information
+
+
+ + + + + + + + + + + + + +
Class:Program
Assembly:ExchangeRateUpdater.Api
File(s):C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.API\Program.cs
+
+
+
+
+
+
+
Line coverage
+
+
86%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:26
Uncovered lines:4
Coverable lines:30
Total lines:55
Line coverage:86.6%
+
+
+
+
+
Branch coverage
+
+
100%
+
+ + + + + + + + + + + + + +
Covered branches:2
Total branches:2
Branch coverage:100%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
<Main>$(...)100%2286.66%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.API\Program.cs

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#LineLine coverage
 1using ExchangeRateUpdater.Api.Middleware;
 2using ExchangeRateUpdater.DependencyInjection;
 3using Serilog;
 4
 5
 36var builder = WebApplication.CreateBuilder(args);
 7
 8// Configure Serilog from configuration (appsettings.json)
 39Log.Logger = new LoggerConfiguration()
 310    .ReadFrom.Configuration(builder.Configuration)
 311    .Enrich.FromLogContext()
 312    .CreateLogger();
 13
 314builder.Host.UseSerilog();
 15
 16try
 317{
 318    Log.Information("Starting web host");
 19
 20    // Add services to the container.
 321    builder.Services.AddControllers();
 322    builder.Services.AddExchangeRateServices();
 23
 24    // Add Swagger services
 325    builder.Services.AddEndpointsApiExplorer();
 326    builder.Services.AddSwaggerGen();
 27
 28
 329    var app = builder.Build();
 30
 331    if (app.Environment.IsDevelopment())
 332    {
 33        // Enable Swagger UI in development
 334        app.UseSwagger();
 335        app.UseSwaggerUI();
 336    }
 37
 338    app.UseMiddleware<ExceptionHandlingMiddleware>();
 39
 340    app.UseHttpsRedirection();
 41
 342    app.MapControllers();
 43
 344    app.Run();
 345}
 046catch (Exception ex)
 047{
 48    // Catch startup exceptions
 049    Log.Fatal(ex, "Host terminated unexpectedly");
 050    throw;
 51}
 52finally
 353{
 354    Log.CloseAndFlush();
 355}
+
+
+
+
+

Methods/Properties

+<Main>$(System.String[])
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.CbnApiClient_CnbExchangeRateMapperExtensions.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.CbnApiClient_CnbExchangeRateMapperExtensions.html new file mode 100644 index 0000000000..eca99233fa --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.CbnApiClient_CnbExchangeRateMapperExtensions.html @@ -0,0 +1,228 @@ + + + + + + + +ExchangeRateUpdater.CbnApiClient.Mapper.CnbExchangeRateMapperExtensions - Coverage Report + +
+

< Summary

+
+
+
Information
+
+
+ + + + + + + + + + + + + +
Class:ExchangeRateUpdater.CbnApiClient.Mapper.CnbExchangeRateMapperExtensions
Assembly:ExchangeRateUpdater.CbnApiClient
File(s):C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.CbnApiClient\Mapper\CnbExchangeRateMapperExtensions.cs
+
+
+
+
+
+
+
Line coverage
+
+
100%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:15
Uncovered lines:0
Coverable lines:15
Total lines:53
Line coverage:100%
+
+
+
+
+
Branch coverage
+
+
100%
+
+ + + + + + + + + + + + + +
Covered branches:2
Total branches:2
Branch coverage:100%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ToDomain(...)100%22100%
ToDomain(...)100%11100%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.CbnApiClient\Mapper\CnbExchangeRateMapperExtensions.cs

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#LineLine coverage
 1using ExchangeRateUpdater.CbnApiClient.Dto;
 2using ExchangeRateUpdater.Abstraction.Model;
 3
 4namespace ExchangeRateUpdater.CbnApiClient.Mapper
 5{
 6
 7    /// <summary>
 8    /// Extension methods to map CNB API DTOs to domain models.
 9    /// </summary>
 10    public static class CnbExchangeRateMapperExtensions
 11    {
 12        private const string TARGET_CURRENCY_CODE = "CZK";
 13        /// <summary>
 14        /// Maps a single <see cref="ExchangeRateEntry"/> to a domain <see cref="ExchangeRate"/>.
 15        /// By convention the CNB API provides rates as an amount of CZK for a given <see cref="ExchangeRateEntry.Amount
 16        /// units of the foreign currency. This method maps the entry to an ExchangeRate where the source currency
 17        /// is the foreign currency and the target currency is CZK. The resulting value is the rate for one unit of
 18        /// the source currency (Rate / Amount).
 19        /// </summary>
 20        /// <param name="entry">The DTO entry to map.</param>
 21        /// <returns>The mapped <see cref="ExchangeRate"/>.</returns>
 22        public static ExchangeRate ToDomain(this ExchangeRateEntry entry)
 2423        {
 2424            ArgumentNullException.ThrowIfNull(entry);
 25
 26            // Avoid division by zero and ensure the amount is positive as expected by the CNB API.
 2327            if (entry.Amount <= 0)
 128                throw new ArgumentException("Entry amount must be greater than zero.", nameof(entry));
 29
 30            // CNB returns the amount of CZK for 'Amount' units of the foreign currency.
 31            // Normalize to a per-1-unit rate.
 2232            var valuePerUnit = entry.Rate / entry.Amount;
 33
 2234            var source = new Currency(entry.CurrencyCode);
 2235            var target = new Currency(TARGET_CURRENCY_CODE);
 36
 2237            return new ExchangeRate(source, target, valuePerUnit, entry.ValidFor);
 2238        }
 39
 40        /// <summary>
 41        /// Maps a sequence of <see cref="ExchangeRateEntry"/> to <see cref="IEnumerable{ExchangeRate}"/>.
 42        /// Null entries are ignored.
 43        /// </summary>
 44        public static IEnumerable<ExchangeRate> ToDomain(this IEnumerable<ExchangeRateEntry> entries)
 645        {
 646            ArgumentNullException.ThrowIfNull(entries);
 47
 548            return entries
 2149                .Where(e => e is not null)
 2650                .Select(e => e.ToDomain());
 551        }
 52    }
 53}
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.CbnApiClient_ExchangeRateCnbApiClient.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.CbnApiClient_ExchangeRateCnbApiClient.html new file mode 100644 index 0000000000..2becb63862 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.CbnApiClient_ExchangeRateCnbApiClient.html @@ -0,0 +1,243 @@ + + + + + + + +ExchangeRateUpdater.CbnApiClient.Implementation.ExchangeRateCnbApiClient - Coverage Report + +
+

< Summary

+
+
+
Information
+
+
+ + + + + + + + + + + + + +
Class:ExchangeRateUpdater.CbnApiClient.Implementation.ExchangeRateCnbApiClient
Assembly:ExchangeRateUpdater.CbnApiClient
File(s):C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.CbnApiClient\Implementation\ExchangeRateCnbApiClient.cs
+
+
+
+
+
+
+
Line coverage
+
+
96%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:31
Uncovered lines:1
Coverable lines:32
Total lines:68
Line coverage:96.8%
+
+
+
+
+
Branch coverage
+
+
80%
+
+ + + + + + + + + + + + + +
Covered branches:8
Total branches:10
Branch coverage:80%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%22100%
GetExchangeRatesAsync()87.5%8896.42%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.CbnApiClient\Implementation\ExchangeRateCnbApiClient.cs

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#LineLine coverage
 1using ExchangeRateUpdater.Abstraction.Interfaces;
 2using ExchangeRateUpdater.Abstraction.Model;
 3using ExchangeRateUpdater.CbnApiClient.Dto;
 4using ExchangeRateUpdater.CbnApiClient.Mapper;
 5using Microsoft.Extensions.Configuration;
 6using Microsoft.Extensions.Logging;
 7using System.Text.Json;
 8
 9namespace ExchangeRateUpdater.CbnApiClient.Implementation
 10{
 911    public class ExchangeRateCnbApiClient(IHttpClientFactory httpClientFactory, IConfiguration config, ILogger<ExchangeR
 12    {
 913        private readonly string CnbApiUrl = config.GetValue<string>("CbnApiUrl") ?? throw new InvalidOperationException(
 14        // Supports EN and CZ, CZ is the default if not specified.
 915        private readonly string CnbLangToRequest = "EN";
 916        private readonly string CbnApiClientName = "CbnApi";
 17
 18        /// <summary>
 19        /// Fetches exchange rates from the CBN API for the specified date. If no date is provided, it fetches today's r
 20        /// </summary>
 21        /// <param name="validDate">The date for which to fetch exchange rates. If null, today's rates will be fetched.<
 22        /// <returns>A collection of <see cref="ExchangeRate"/> objects representing the exchange rates for the specifie
 23        /// <exception cref="HttpRequestException">Thrown when the HTTP request to the CBN API fails.</exception>
 24        /// <exception cref="InvalidOperationException">Thrown when the response from the CBN API is empty or cannot be 
 25        public async Task<IEnumerable<ExchangeRate>> GetExchangeRatesAsync(DateTime? validDate = null)
 726        {
 27            // prepare the url, add today date as yyyy-MM-dd if specified and lang to "EN"
 728            string urlWithParams = $"{CnbApiUrl}?lang={CnbLangToRequest}";
 29            // if no date is specified, the CBN API will return today as default
 730            if (validDate.HasValue)
 131            {
 132                urlWithParams += $"&date={validDate.Value:yyyy-MM-dd}";
 133            }
 34            // make the request to the CBN API using the named client so configured handlers/policies are applied
 735            HttpClient httpClient = httpClientFactory.CreateClient(CbnApiClientName);
 736            using HttpResponseMessage response = await httpClient.GetAsync(urlWithParams);
 737            if (!response.IsSuccessStatusCode)
 138            {
 139                throw new HttpRequestException($"Failed to fetch exchange rates from CBN API. Status code: {response.Sta
 40            }
 41
 42            // check content is not empty
 643            string content = await response.Content.ReadAsStringAsync();
 644            if (string.IsNullOrWhiteSpace(content))
 145            {
 146                string message = "Received empty response from CBN API.";
 147                logger.LogError(message);
 148                throw new InvalidOperationException(message);
 49            }
 50
 51            // deserialize the response. JsonSerializer.Deserialize may throw JsonException for invalid JSON;
 52            ExchangeRatesResponse? dtoRates;
 53            try
 554            {
 555                dtoRates = JsonSerializer.Deserialize<ExchangeRatesResponse>(content);
 456            }
 157            catch (JsonException jex)
 158            {
 159                logger.LogError(jex, "Failed to deserialize CBN API response JSON.");
 160                throw new InvalidOperationException("Failed to deserialize CBN API response.", jex);
 61            }
 62
 463            if (dtoRates is null)
 064                throw new InvalidOperationException("Failed to deserialize CBN API response.");
 465            return dtoRates.Rates.ToDomain();
 466        }
 67    }
 68}
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.DependencyInjection_ExchangeRateCnbServicesExtension.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.DependencyInjection_ExchangeRateCnbServicesExtension.html new file mode 100644 index 0000000000..5ea6112149 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.DependencyInjection_ExchangeRateCnbServicesExtension.html @@ -0,0 +1,210 @@ + + + + + + + +ExchangeRateUpdater.DependencyInjection.ExchangeRateCnbServicesExtension - Coverage Report + +
+

< Summary

+
+
+
Information
+
+
+ + + + + + + + + + + + + +
Class:ExchangeRateUpdater.DependencyInjection.ExchangeRateCnbServicesExtension
Assembly:ExchangeRateUpdater.DependencyInjection
File(s):C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.DependencyInjection\ExchangeRateCnbServicesExtension.cs
+
+
+
+
+
+
+
Line coverage
+
+
91%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:11
Uncovered lines:1
Coverable lines:12
Total lines:37
Line coverage:91.6%
+
+
+
+
+
Branch coverage
+
+
N/A
+
+ + + + + + + + + + + + + +
Covered branches:0
Total branches:0
Branch coverage:N/A
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
AddExchangeRateServices(...)100%1191.66%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.DependencyInjection\ExchangeRateCnbServicesExtension.cs

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#LineLine coverage
 1using ExchangeRateUpdater.Abstraction.Interfaces;
 2using ExchangeRateUpdater.CbnApiClient.Implementation;
 3using ExchangeRateUpdater.Service;
 4using Microsoft.Extensions.DependencyInjection;
 5using Polly;
 6using Polly.Extensions.Http;
 7
 8namespace ExchangeRateUpdater.DependencyInjection
 9{
 10    /// <summary>
 11    /// Provides extension methods for registering exchange rate client services with the dependency injection
 12    /// container.
 13    /// </summary>
 14    /// <remarks>This static class is intended to be used in application startup to ensure that the
 15    /// IExchangeRateClient implementation is available for dependency injection. It simplifies the configuration of
 16    /// exchange rate services by encapsulating the registration logic.</remarks>
 17    public static class ExchangeRateCnbServicesExtension
 18    {
 19        public static IServiceCollection AddExchangeRateServices(this IServiceCollection services)
 320        {
 321            services.AddMemoryCache();
 322            services.AddScoped<IExchangeRateProvider, ExchangeRateProvider>();
 323            services.AddScoped<IExchangeRateService, ExchangeRateService>();
 324            services.AddScoped<IExchangeRateClient, ExchangeRateCnbApiClient>();
 25
 26            // Configure a named HttpClient for the CNB API with Polly-based retry policy.
 27            // This will be available as httpClientFactory.CreateClient("CnbApi").
 328            services.AddHttpClient("CnbApi")
 329                .AddPolicyHandler(HttpPolicyExtensions
 330                    .HandleTransientHttpError()
 031                    .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)))
 332                );
 33
 334            return services;
 335        }
 36    }
 37}
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.Service_ExchangeRateProvider.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.Service_ExchangeRateProvider.html new file mode 100644 index 0000000000..c2e3a16f97 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.Service_ExchangeRateProvider.html @@ -0,0 +1,234 @@ + + + + + + + +ExchangeRateUpdater.Service.ExchangeRateProvider - Coverage Report + +
+

< Summary

+
+
+
Information
+
+
+ + + + + + + + + + + + + +
Class:ExchangeRateUpdater.Service.ExchangeRateProvider
Assembly:ExchangeRateUpdater.Service
File(s):C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.Service\ExchangeRateProvider.cs
+
+
+
+
+
+
+
Line coverage
+
+
89%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:25
Uncovered lines:3
Coverable lines:28
Total lines:59
Line coverage:89.2%
+
+
+
+
+
Branch coverage
+
+
62%
+
+ + + + + + + + + + + + + +
Covered branches:5
Total branches:8
Branch coverage:62.5%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetExchangeRatesAsync()62.5%8888.46%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.Service\ExchangeRateProvider.cs

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#LineLine coverage
 1using ExchangeRateUpdater.Abstraction.Interfaces;
 2using ExchangeRateUpdater.Abstraction.Model;
 3using Microsoft.Extensions.Caching.Memory;
 4using Microsoft.Extensions.Logging;
 5
 6namespace ExchangeRateUpdater.Service
 7{
 8    /// <summary>
 9    /// Provides methods for retrieving exchange rates for specified currencies from an external source.
 10    /// </summary>
 11    /// <param name="exchangeRateClient">The client used to obtain exchange rate data from an external provider.</param>
 12    /// <param name="logger">The logger used to record informational messages and errors related to exchange rate retrie
 613    public class ExchangeRateProvider(IExchangeRateClient exchangeRateClient, ILogger<ExchangeRateProvider> logger, IMem
 14    {
 15        private const string CacheKey = "CnbRates";
 16
 17        public async Task<IEnumerable<ExchangeRate>> GetExchangeRatesAsync(IEnumerable<Currency> currencies)
 618        {
 619            ArgumentNullException.ThrowIfNull(currencies);
 20
 21            // Try get from cache first
 522            if (!cache.TryGetValue<IEnumerable<ExchangeRate>>(CacheKey, out var cachedRates))
 323            {
 324                logger.LogInformation("Cache miss for CNB rates, fetching from upstream");
 325                var fetched = await exchangeRateClient.GetExchangeRatesAsync();
 26
 27                // Determine cache expiration: CNB publishes new rates around 14:30 UTC on working days.
 28                // Set 30 minutes margin to ensure we get the new rates after publication.
 329                var now = DateTime.UtcNow;
 330                var nextPublication = new DateTime(now.Year, now.Month, now.Day, 15, 0, 0, DateTimeKind.Utc);
 331                if (now >= nextPublication)
 032                {
 33                    // already past today's publication time, schedule for next day
 034                    nextPublication = nextPublication.AddDays(1);
 035                }
 36
 337                var absoluteExpirationRelative = nextPublication - now;
 38                // Guard: ensure a minimum cache duration and reasonable maximum (24h)
 39                // Cache will refresh even on non-working days, but that's acceptable because 1 unnecessary request a da
 340                if (absoluteExpirationRelative < TimeSpan.FromMinutes(1)) absoluteExpirationRelative = TimeSpan.FromMinu
 341                if (absoluteExpirationRelative > TimeSpan.FromHours(24)) absoluteExpirationRelative = TimeSpan.FromHours
 42
 343                var options = new MemoryCacheEntryOptions()
 344                    .SetAbsoluteExpiration(absoluteExpirationRelative);
 45
 346                cache.Set(CacheKey, fetched, options);
 347                cachedRates = fetched;
 348            }
 49            else
 250            {
 251                logger.LogDebug("Cache hit for CNB rates");
 252            }
 53
 554            var currencySet = currencies.ToHashSet();
 2755            var filteredRates = cachedRates.Where(rate => currencySet.Contains(rate.SourceCurrency));
 556            return filteredRates;
 557        }
 58    }
 59}
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/ExchangeRateUpdater.Service_ExchangeRateService.html b/jobs/Backend/coveragereport/ExchangeRateUpdater.Service_ExchangeRateService.html new file mode 100644 index 0000000000..9d60a79cc5 --- /dev/null +++ b/jobs/Backend/coveragereport/ExchangeRateUpdater.Service_ExchangeRateService.html @@ -0,0 +1,224 @@ + + + + + + + +ExchangeRateUpdater.Service.ExchangeRateService - Coverage Report + +
+

< Summary

+
+
+
Information
+
+
+ + + + + + + + + + + + + +
Class:ExchangeRateUpdater.Service.ExchangeRateService
Assembly:ExchangeRateUpdater.Service
File(s):C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.Service\ExchangeRateService.cs
+
+
+
+
+
+
+
Line coverage
+
+
100%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:21
Uncovered lines:0
Coverable lines:21
Total lines:49
Line coverage:100%
+
+
+
+
+
Branch coverage
+
+
100%
+
+ + + + + + + + + + + + + +
Covered branches:4
Total branches:4
Branch coverage:100%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Metrics

+
+ +++++++ + + + + + +
MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetExchangeRatesFromStringList()100%44100%
+
+

File(s)

+

C:\Users\alvar\Documents\MEWS-TASK\developers\jobs\Backend\ExchangeRateUpdater.Service\ExchangeRateService.cs

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#LineLine coverage
 1using ExchangeRateUpdater.Abstraction.Interfaces;
 2using ExchangeRateUpdater.Abstraction.Model;
 3using Microsoft.Extensions.Logging;
 4
 5namespace ExchangeRateUpdater.Service
 6{
 7    /// <summary>
 8    /// Provides functionality to retrieve exchange rates for specified currency codes.
 9    /// </summary>
 10    /// <param name="exchangeRateProvider">The provider used to fetch exchange rate data.</param>
 11    /// <param name="logger">The logger instance used to record informational and error messages for this service.</para
 712    public class ExchangeRateService(IExchangeRateProvider exchangeRateProvider, ILogger<ExchangeRateService> logger) : 
 13    {
 14        /// <summary>
 15        /// Retrieves exchange rates for the specified collection of currency codes.
 16        /// </summary>
 17        /// <param name="currencyCodes">An enumerable collection of currency code strings to retrieve exchange rates for
 18        /// a valid currency code.</param>
 19        /// <returns>A task that represents the asynchronous operation. The task result contains a collection of exchang
 20        /// corresponding to the valid currency codes provided. Returns an empty collection if no valid codes are
 21        /// supplied.</returns>
 22        public async Task<IEnumerable<ExchangeRate>> GetExchangeRatesFromStringList(IEnumerable<string> currencyCodes)
 723        {
 724            List<Currency> currencyList = new();
 4325            foreach (var currencyCode in currencyCodes)
 1126            {
 27                try
 1128                {
 1129                    var currency = new Currency(currencyCode);
 630                    currencyList.Add(currency);
 631                }
 532                catch (ArgumentException ex)
 533                {
 534                    logger.LogWarning($"Invalid currency {currencyCode}: {ex.Message}");
 535                    continue;
 36                }
 637            }
 38
 739            if (currencyList.Count == 0)
 240            {
 241                logger.LogWarning("No valid currency codes provided.");
 242                return [];
 43            }
 44
 545            IEnumerable<ExchangeRate> exchangeRates = await exchangeRateProvider.GetExchangeRatesAsync(currencyList);
 546            return exchangeRates;
 747        }
 48    }
 49}
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/class.js b/jobs/Backend/coveragereport/class.js new file mode 100644 index 0000000000..3976a9714d --- /dev/null +++ b/jobs/Backend/coveragereport/class.js @@ -0,0 +1,210 @@ +/* Chartist.js 0.11.4 + * Copyright © 2019 Gion Kunz + * Free to use under either the WTFPL license or the MIT license. + * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-WTFPL + * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-MIT + */ + +!function (e, t) { "function" == typeof define && define.amd ? define("Chartist", [], (function () { return e.Chartist = t() })) : "object" == typeof module && module.exports ? module.exports = t() : e.Chartist = t() }(this, (function () { var e = { version: "0.11.4" }; return function (e, t) { "use strict"; var i = e.window, n = e.document; t.namespaces = { svg: "http://www.w3.org/2000/svg", xmlns: "http://www.w3.org/2000/xmlns/", xhtml: "http://www.w3.org/1999/xhtml", xlink: "http://www.w3.org/1999/xlink", ct: "http://gionkunz.github.com/chartist-js/ct" }, t.noop = function (e) { return e }, t.alphaNumerate = function (e) { return String.fromCharCode(97 + e % 26) }, t.extend = function (e) { var i, n, s, r; for (e = e || {}, i = 1; i < arguments.length; i++)for (var a in n = arguments[i], r = Object.getPrototypeOf(e), n) "__proto__" === a || "constructor" === a || null !== r && a in r || (s = n[a], e[a] = "object" != typeof s || null === s || s instanceof Array ? s : t.extend(e[a], s)); return e }, t.replaceAll = function (e, t, i) { return e.replace(new RegExp(t, "g"), i) }, t.ensureUnit = function (e, t) { return "number" == typeof e && (e += t), e }, t.quantity = function (e) { if ("string" == typeof e) { var t = /^(\d+)\s*(.*)$/g.exec(e); return { value: +t[1], unit: t[2] || void 0 } } return { value: e } }, t.querySelector = function (e) { return e instanceof Node ? e : n.querySelector(e) }, t.times = function (e) { return Array.apply(null, new Array(e)) }, t.sum = function (e, t) { return e + (t || 0) }, t.mapMultiply = function (e) { return function (t) { return t * e } }, t.mapAdd = function (e) { return function (t) { return t + e } }, t.serialMap = function (e, i) { var n = [], s = Math.max.apply(null, e.map((function (e) { return e.length }))); return t.times(s).forEach((function (t, s) { var r = e.map((function (e) { return e[s] })); n[s] = i.apply(null, r) })), n }, t.roundWithPrecision = function (e, i) { var n = Math.pow(10, i || t.precision); return Math.round(e * n) / n }, t.precision = 8, t.escapingMap = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }, t.serialize = function (e) { return null == e ? e : ("number" == typeof e ? e = "" + e : "object" == typeof e && (e = JSON.stringify({ data: e })), Object.keys(t.escapingMap).reduce((function (e, i) { return t.replaceAll(e, i, t.escapingMap[i]) }), e)) }, t.deserialize = function (e) { if ("string" != typeof e) return e; e = Object.keys(t.escapingMap).reduce((function (e, i) { return t.replaceAll(e, t.escapingMap[i], i) }), e); try { e = void 0 !== (e = JSON.parse(e)).data ? e.data : e } catch (e) { } return e }, t.createSvg = function (e, i, n, s) { var r; return i = i || "100%", n = n || "100%", Array.prototype.slice.call(e.querySelectorAll("svg")).filter((function (e) { return e.getAttributeNS(t.namespaces.xmlns, "ct") })).forEach((function (t) { e.removeChild(t) })), (r = new t.Svg("svg").attr({ width: i, height: n }).addClass(s))._node.style.width = i, r._node.style.height = n, e.appendChild(r._node), r }, t.normalizeData = function (e, i, n) { var s, r = { raw: e, normalized: {} }; return r.normalized.series = t.getDataArray({ series: e.series || [] }, i, n), s = r.normalized.series.every((function (e) { return e instanceof Array })) ? Math.max.apply(null, r.normalized.series.map((function (e) { return e.length }))) : r.normalized.series.length, r.normalized.labels = (e.labels || []).slice(), Array.prototype.push.apply(r.normalized.labels, t.times(Math.max(0, s - r.normalized.labels.length)).map((function () { return "" }))), i && t.reverseData(r.normalized), r }, t.safeHasProperty = function (e, t) { return null !== e && "object" == typeof e && e.hasOwnProperty(t) }, t.isDataHoleValue = function (e) { return null == e || "number" == typeof e && isNaN(e) }, t.reverseData = function (e) { e.labels.reverse(), e.series.reverse(); for (var t = 0; t < e.series.length; t++)"object" == typeof e.series[t] && void 0 !== e.series[t].data ? e.series[t].data.reverse() : e.series[t] instanceof Array && e.series[t].reverse() }, t.getDataArray = function (e, i, n) { return e.series.map((function e(i) { if (t.safeHasProperty(i, "value")) return e(i.value); if (t.safeHasProperty(i, "data")) return e(i.data); if (i instanceof Array) return i.map(e); if (!t.isDataHoleValue(i)) { if (n) { var s = {}; return "string" == typeof n ? s[n] = t.getNumberOrUndefined(i) : s.y = t.getNumberOrUndefined(i), s.x = i.hasOwnProperty("x") ? t.getNumberOrUndefined(i.x) : s.x, s.y = i.hasOwnProperty("y") ? t.getNumberOrUndefined(i.y) : s.y, s } return t.getNumberOrUndefined(i) } })) }, t.normalizePadding = function (e, t) { return t = t || 0, "number" == typeof e ? { top: e, right: e, bottom: e, left: e } : { top: "number" == typeof e.top ? e.top : t, right: "number" == typeof e.right ? e.right : t, bottom: "number" == typeof e.bottom ? e.bottom : t, left: "number" == typeof e.left ? e.left : t } }, t.getMetaData = function (e, t) { var i = e.data ? e.data[t] : e[t]; return i ? i.meta : void 0 }, t.orderOfMagnitude = function (e) { return Math.floor(Math.log(Math.abs(e)) / Math.LN10) }, t.projectLength = function (e, t, i) { return t / i.range * e }, t.getAvailableHeight = function (e, i) { return Math.max((t.quantity(i.height).value || e.height()) - (i.chartPadding.top + i.chartPadding.bottom) - i.axisX.offset, 0) }, t.getHighLow = function (e, i, n) { var s = { high: void 0 === (i = t.extend({}, i, n ? i["axis" + n.toUpperCase()] : {})).high ? -Number.MAX_VALUE : +i.high, low: void 0 === i.low ? Number.MAX_VALUE : +i.low }, r = void 0 === i.high, a = void 0 === i.low; return (r || a) && function e(t) { if (void 0 !== t) if (t instanceof Array) for (var i = 0; i < t.length; i++)e(t[i]); else { var o = n ? +t[n] : +t; r && o > s.high && (s.high = o), a && o < s.low && (s.low = o) } }(e), (i.referenceValue || 0 === i.referenceValue) && (s.high = Math.max(i.referenceValue, s.high), s.low = Math.min(i.referenceValue, s.low)), s.high <= s.low && (0 === s.low ? s.high = 1 : s.low < 0 ? s.high = 0 : (s.high > 0 || (s.high = 1), s.low = 0)), s }, t.isNumeric = function (e) { return null !== e && isFinite(e) }, t.isFalseyButZero = function (e) { return !e && 0 !== e }, t.getNumberOrUndefined = function (e) { return t.isNumeric(e) ? +e : void 0 }, t.isMultiValue = function (e) { return "object" == typeof e && ("x" in e || "y" in e) }, t.getMultiValue = function (e, i) { return t.isMultiValue(e) ? t.getNumberOrUndefined(e[i || "y"]) : t.getNumberOrUndefined(e) }, t.rho = function (e) { if (1 === e) return e; function t(e, i) { return e % i == 0 ? i : t(i, e % i) } function i(e) { return e * e + 1 } var n, s = 2, r = 2; if (e % 2 == 0) return 2; do { s = i(s) % e, r = i(i(r)) % e, n = t(Math.abs(s - r), e) } while (1 === n); return n }, t.getBounds = function (e, i, n, s) { var r, a, o, l = 0, h = { high: i.high, low: i.low }; h.valueRange = h.high - h.low, h.oom = t.orderOfMagnitude(h.valueRange), h.step = Math.pow(10, h.oom), h.min = Math.floor(h.low / h.step) * h.step, h.max = Math.ceil(h.high / h.step) * h.step, h.range = h.max - h.min, h.numberOfSteps = Math.round(h.range / h.step); var u = t.projectLength(e, h.step, h) < n, c = s ? t.rho(h.range) : 0; if (s && t.projectLength(e, 1, h) >= n) h.step = 1; else if (s && c < h.step && t.projectLength(e, c, h) >= n) h.step = c; else for (; ;) { if (u && t.projectLength(e, h.step, h) <= n) h.step *= 2; else { if (u || !(t.projectLength(e, h.step / 2, h) >= n)) break; if (h.step /= 2, s && h.step % 1 != 0) { h.step *= 2; break } } if (l++ > 1e3) throw new Error("Exceeded maximum number of iterations while optimizing scale step!") } var d = 2221e-19; function p(e, t) { return e === (e += t) && (e *= 1 + (t > 0 ? d : -d)), e } for (h.step = Math.max(h.step, d), a = h.min, o = h.max; a + h.step <= h.low;)a = p(a, h.step); for (; o - h.step >= h.high;)o = p(o, -h.step); h.min = a, h.max = o, h.range = h.max - h.min; var f = []; for (r = h.min; r <= h.max; r = p(r, h.step)) { var m = t.roundWithPrecision(r); m !== f[f.length - 1] && f.push(m) } return h.values = f, h }, t.polarToCartesian = function (e, t, i, n) { var s = (n - 90) * Math.PI / 180; return { x: e + i * Math.cos(s), y: t + i * Math.sin(s) } }, t.createChartRect = function (e, i, n) { var s = !(!i.axisX && !i.axisY), r = s ? i.axisY.offset : 0, a = s ? i.axisX.offset : 0, o = e.width() || t.quantity(i.width).value || 0, l = e.height() || t.quantity(i.height).value || 0, h = t.normalizePadding(i.chartPadding, n); o = Math.max(o, r + h.left + h.right), l = Math.max(l, a + h.top + h.bottom); var u = { padding: h, width: function () { return this.x2 - this.x1 }, height: function () { return this.y1 - this.y2 } }; return s ? ("start" === i.axisX.position ? (u.y2 = h.top + a, u.y1 = Math.max(l - h.bottom, u.y2 + 1)) : (u.y2 = h.top, u.y1 = Math.max(l - h.bottom - a, u.y2 + 1)), "start" === i.axisY.position ? (u.x1 = h.left + r, u.x2 = Math.max(o - h.right, u.x1 + 1)) : (u.x1 = h.left, u.x2 = Math.max(o - h.right - r, u.x1 + 1))) : (u.x1 = h.left, u.x2 = Math.max(o - h.right, u.x1 + 1), u.y2 = h.top, u.y1 = Math.max(l - h.bottom, u.y2 + 1)), u }, t.createGrid = function (e, i, n, s, r, a, o, l) { var h = {}; h[n.units.pos + "1"] = e, h[n.units.pos + "2"] = e, h[n.counterUnits.pos + "1"] = s, h[n.counterUnits.pos + "2"] = s + r; var u = a.elem("line", h, o.join(" ")); l.emit("draw", t.extend({ type: "grid", axis: n, index: i, group: a, element: u }, h)) }, t.createGridBackground = function (e, t, i, n) { var s = e.elem("rect", { x: t.x1, y: t.y2, width: t.width(), height: t.height() }, i, !0); n.emit("draw", { type: "gridBackground", group: e, element: s }) }, t.createLabel = function (e, i, s, r, a, o, l, h, u, c, d) { var p, f = {}; if (f[a.units.pos] = e + l[a.units.pos], f[a.counterUnits.pos] = l[a.counterUnits.pos], f[a.units.len] = i, f[a.counterUnits.len] = Math.max(0, o - 10), c) { var m = n.createElement("span"); m.className = u.join(" "), m.setAttribute("xmlns", t.namespaces.xhtml), m.innerText = r[s], m.style[a.units.len] = Math.round(f[a.units.len]) + "px", m.style[a.counterUnits.len] = Math.round(f[a.counterUnits.len]) + "px", p = h.foreignObject(m, t.extend({ style: "overflow: visible;" }, f)) } else p = h.elem("text", f, u.join(" ")).text(r[s]); d.emit("draw", t.extend({ type: "label", axis: a, index: s, group: h, element: p, text: r[s] }, f)) }, t.getSeriesOption = function (e, t, i) { if (e.name && t.series && t.series[e.name]) { var n = t.series[e.name]; return n.hasOwnProperty(i) ? n[i] : t[i] } return t[i] }, t.optionsProvider = function (e, n, s) { var r, a, o = t.extend({}, e), l = []; function h(e) { var l = r; if (r = t.extend({}, o), n) for (a = 0; a < n.length; a++) { i.matchMedia(n[a][0]).matches && (r = t.extend(r, n[a][1])) } s && e && s.emit("optionsChanged", { previousOptions: l, currentOptions: r }) } if (!i.matchMedia) throw "window.matchMedia not found! Make sure you're using a polyfill."; if (n) for (a = 0; a < n.length; a++) { var u = i.matchMedia(n[a][0]); u.addListener(h), l.push(u) } return h(), { removeMediaQueryListeners: function () { l.forEach((function (e) { e.removeListener(h) })) }, getCurrentOptions: function () { return t.extend({}, r) } } }, t.splitIntoSegments = function (e, i, n) { n = t.extend({}, { increasingX: !1, fillHoles: !1 }, n); for (var s = [], r = !0, a = 0; a < e.length; a += 2)void 0 === t.getMultiValue(i[a / 2].value) ? n.fillHoles || (r = !0) : (n.increasingX && a >= 2 && e[a] <= e[a - 2] && (r = !0), r && (s.push({ pathCoordinates: [], valueData: [] }), r = !1), s[s.length - 1].pathCoordinates.push(e[a], e[a + 1]), s[s.length - 1].valueData.push(i[a / 2])); return s } }(this || global, e), function (e, t) { "use strict"; t.Interpolation = {}, t.Interpolation.none = function (e) { return e = t.extend({}, { fillHoles: !1 }, e), function (i, n) { for (var s = new t.Svg.Path, r = !0, a = 0; a < i.length; a += 2) { var o = i[a], l = i[a + 1], h = n[a / 2]; void 0 !== t.getMultiValue(h.value) ? (r ? s.move(o, l, !1, h) : s.line(o, l, !1, h), r = !1) : e.fillHoles || (r = !0) } return s } }, t.Interpolation.simple = function (e) { e = t.extend({}, { divisor: 2, fillHoles: !1 }, e); var i = 1 / Math.max(1, e.divisor); return function (n, s) { for (var r, a, o, l = new t.Svg.Path, h = 0; h < n.length; h += 2) { var u = n[h], c = n[h + 1], d = (u - r) * i, p = s[h / 2]; void 0 !== p.value ? (void 0 === o ? l.move(u, c, !1, p) : l.curve(r + d, a, u - d, c, u, c, !1, p), r = u, a = c, o = p) : e.fillHoles || (r = u = o = void 0) } return l } }, t.Interpolation.cardinal = function (e) { e = t.extend({}, { tension: 1, fillHoles: !1 }, e); var i = Math.min(1, Math.max(0, e.tension)), n = 1 - i; return function s(r, a) { var o = t.splitIntoSegments(r, a, { fillHoles: e.fillHoles }); if (o.length) { if (o.length > 1) { var l = []; return o.forEach((function (e) { l.push(s(e.pathCoordinates, e.valueData)) })), t.Svg.Path.join(l) } if (r = o[0].pathCoordinates, a = o[0].valueData, r.length <= 4) return t.Interpolation.none()(r, a); for (var h = (new t.Svg.Path).move(r[0], r[1], !1, a[0]), u = 0, c = r.length; c - 2 > u; u += 2) { var d = [{ x: +r[u - 2], y: +r[u - 1] }, { x: +r[u], y: +r[u + 1] }, { x: +r[u + 2], y: +r[u + 3] }, { x: +r[u + 4], y: +r[u + 5] }]; c - 4 === u ? d[3] = d[2] : u || (d[0] = { x: +r[u], y: +r[u + 1] }), h.curve(i * (-d[0].x + 6 * d[1].x + d[2].x) / 6 + n * d[2].x, i * (-d[0].y + 6 * d[1].y + d[2].y) / 6 + n * d[2].y, i * (d[1].x + 6 * d[2].x - d[3].x) / 6 + n * d[2].x, i * (d[1].y + 6 * d[2].y - d[3].y) / 6 + n * d[2].y, d[2].x, d[2].y, !1, a[(u + 2) / 2]) } return h } return t.Interpolation.none()([]) } }, t.Interpolation.monotoneCubic = function (e) { return e = t.extend({}, { fillHoles: !1 }, e), function i(n, s) { var r = t.splitIntoSegments(n, s, { fillHoles: e.fillHoles, increasingX: !0 }); if (r.length) { if (r.length > 1) { var a = []; return r.forEach((function (e) { a.push(i(e.pathCoordinates, e.valueData)) })), t.Svg.Path.join(a) } if (n = r[0].pathCoordinates, s = r[0].valueData, n.length <= 4) return t.Interpolation.none()(n, s); var o, l, h = [], u = [], c = n.length / 2, d = [], p = [], f = [], m = []; for (o = 0; o < c; o++)h[o] = n[2 * o], u[o] = n[2 * o + 1]; for (o = 0; o < c - 1; o++)f[o] = u[o + 1] - u[o], m[o] = h[o + 1] - h[o], p[o] = f[o] / m[o]; for (d[0] = p[0], d[c - 1] = p[c - 2], o = 1; o < c - 1; o++)0 === p[o] || 0 === p[o - 1] || p[o - 1] > 0 != p[o] > 0 ? d[o] = 0 : (d[o] = 3 * (m[o - 1] + m[o]) / ((2 * m[o] + m[o - 1]) / p[o - 1] + (m[o] + 2 * m[o - 1]) / p[o]), isFinite(d[o]) || (d[o] = 0)); for (l = (new t.Svg.Path).move(h[0], u[0], !1, s[0]), o = 0; o < c - 1; o++)l.curve(h[o] + m[o] / 3, u[o] + d[o] * m[o] / 3, h[o + 1] - m[o] / 3, u[o + 1] - d[o + 1] * m[o] / 3, h[o + 1], u[o + 1], !1, s[o + 1]); return l } return t.Interpolation.none()([]) } }, t.Interpolation.step = function (e) { return e = t.extend({}, { postpone: !0, fillHoles: !1 }, e), function (i, n) { for (var s, r, a, o = new t.Svg.Path, l = 0; l < i.length; l += 2) { var h = i[l], u = i[l + 1], c = n[l / 2]; void 0 !== c.value ? (void 0 === a ? o.move(h, u, !1, c) : (e.postpone ? o.line(h, r, !1, a) : o.line(s, u, !1, c), o.line(h, u, !1, c)), s = h, r = u, a = c) : e.fillHoles || (s = r = a = void 0) } return o } } }(this || global, e), function (e, t) { "use strict"; t.EventEmitter = function () { var e = []; return { addEventHandler: function (t, i) { e[t] = e[t] || [], e[t].push(i) }, removeEventHandler: function (t, i) { e[t] && (i ? (e[t].splice(e[t].indexOf(i), 1), 0 === e[t].length && delete e[t]) : delete e[t]) }, emit: function (t, i) { e[t] && e[t].forEach((function (e) { e(i) })), e["*"] && e["*"].forEach((function (e) { e(t, i) })) } } } }(this || global, e), function (e, t) { "use strict"; t.Class = { extend: function (e, i) { var n = i || this.prototype || t.Class, s = Object.create(n); t.Class.cloneDefinitions(s, e); var r = function () { var e, i = s.constructor || function () { }; return e = this === t ? Object.create(s) : this, i.apply(e, Array.prototype.slice.call(arguments, 0)), e }; return r.prototype = s, r.super = n, r.extend = this.extend, r }, cloneDefinitions: function () { var e = function (e) { var t = []; if (e.length) for (var i = 0; i < e.length; i++)t.push(e[i]); return t }(arguments), t = e[0]; return e.splice(1, e.length - 1).forEach((function (e) { Object.getOwnPropertyNames(e).forEach((function (i) { delete t[i], Object.defineProperty(t, i, Object.getOwnPropertyDescriptor(e, i)) })) })), t } } }(this || global, e), function (e, t) { "use strict"; var i = e.window; function n() { i.addEventListener("resize", this.resizeListener), this.optionsProvider = t.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter), this.eventEmitter.addEventHandler("optionsChanged", function () { this.update() }.bind(this)), this.options.plugins && this.options.plugins.forEach(function (e) { e instanceof Array ? e[0](this, e[1]) : e(this) }.bind(this)), this.eventEmitter.emit("data", { type: "initial", data: this.data }), this.createChart(this.optionsProvider.getCurrentOptions()), this.initializeTimeoutId = void 0 } t.Base = t.Class.extend({ constructor: function (e, i, s, r, a) { this.container = t.querySelector(e), this.data = i || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.defaultOptions = s, this.options = r, this.responsiveOptions = a, this.eventEmitter = t.EventEmitter(), this.supportsForeignObject = t.Svg.isSupported("Extensibility"), this.supportsAnimations = t.Svg.isSupported("AnimationEventsAttribute"), this.resizeListener = function () { this.update() }.bind(this), this.container && (this.container.__chartist__ && this.container.__chartist__.detach(), this.container.__chartist__ = this), this.initializeTimeoutId = setTimeout(n.bind(this), 0) }, optionsProvider: void 0, container: void 0, svg: void 0, eventEmitter: void 0, createChart: function () { throw new Error("Base chart type can't be instantiated!") }, update: function (e, i, n) { return e && (this.data = e || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.eventEmitter.emit("data", { type: "update", data: this.data })), i && (this.options = t.extend({}, n ? this.options : this.defaultOptions, i), this.initializeTimeoutId || (this.optionsProvider.removeMediaQueryListeners(), this.optionsProvider = t.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter))), this.initializeTimeoutId || this.createChart(this.optionsProvider.getCurrentOptions()), this }, detach: function () { return this.initializeTimeoutId ? i.clearTimeout(this.initializeTimeoutId) : (i.removeEventListener("resize", this.resizeListener), this.optionsProvider.removeMediaQueryListeners()), this }, on: function (e, t) { return this.eventEmitter.addEventHandler(e, t), this }, off: function (e, t) { return this.eventEmitter.removeEventHandler(e, t), this }, version: t.version, supportsForeignObject: !1 }) }(this || global, e), function (e, t) { "use strict"; var i = e.document; t.Svg = t.Class.extend({ constructor: function (e, n, s, r, a) { e instanceof Element ? this._node = e : (this._node = i.createElementNS(t.namespaces.svg, e), "svg" === e && this.attr({ "xmlns:ct": t.namespaces.ct })), n && this.attr(n), s && this.addClass(s), r && (a && r._node.firstChild ? r._node.insertBefore(this._node, r._node.firstChild) : r._node.appendChild(this._node)) }, attr: function (e, i) { return "string" == typeof e ? i ? this._node.getAttributeNS(i, e) : this._node.getAttribute(e) : (Object.keys(e).forEach(function (i) { if (void 0 !== e[i]) if (-1 !== i.indexOf(":")) { var n = i.split(":"); this._node.setAttributeNS(t.namespaces[n[0]], i, e[i]) } else this._node.setAttribute(i, e[i]) }.bind(this)), this) }, elem: function (e, i, n, s) { return new t.Svg(e, i, n, this, s) }, parent: function () { return this._node.parentNode instanceof SVGElement ? new t.Svg(this._node.parentNode) : null }, root: function () { for (var e = this._node; "svg" !== e.nodeName;)e = e.parentNode; return new t.Svg(e) }, querySelector: function (e) { var i = this._node.querySelector(e); return i ? new t.Svg(i) : null }, querySelectorAll: function (e) { var i = this._node.querySelectorAll(e); return i.length ? new t.Svg.List(i) : null }, getNode: function () { return this._node }, foreignObject: function (e, n, s, r) { if ("string" == typeof e) { var a = i.createElement("div"); a.innerHTML = e, e = a.firstChild } e.setAttribute("xmlns", t.namespaces.xmlns); var o = this.elem("foreignObject", n, s, r); return o._node.appendChild(e), o }, text: function (e) { return this._node.appendChild(i.createTextNode(e)), this }, empty: function () { for (; this._node.firstChild;)this._node.removeChild(this._node.firstChild); return this }, remove: function () { return this._node.parentNode.removeChild(this._node), this.parent() }, replace: function (e) { return this._node.parentNode.replaceChild(e._node, this._node), e }, append: function (e, t) { return t && this._node.firstChild ? this._node.insertBefore(e._node, this._node.firstChild) : this._node.appendChild(e._node), this }, classes: function () { return this._node.getAttribute("class") ? this._node.getAttribute("class").trim().split(/\s+/) : [] }, addClass: function (e) { return this._node.setAttribute("class", this.classes(this._node).concat(e.trim().split(/\s+/)).filter((function (e, t, i) { return i.indexOf(e) === t })).join(" ")), this }, removeClass: function (e) { var t = e.trim().split(/\s+/); return this._node.setAttribute("class", this.classes(this._node).filter((function (e) { return -1 === t.indexOf(e) })).join(" ")), this }, removeAllClasses: function () { return this._node.setAttribute("class", ""), this }, height: function () { return this._node.getBoundingClientRect().height }, width: function () { return this._node.getBoundingClientRect().width }, animate: function (e, i, n) { return void 0 === i && (i = !0), Object.keys(e).forEach(function (s) { function r(e, i) { var r, a, o, l = {}; e.easing && (o = e.easing instanceof Array ? e.easing : t.Svg.Easing[e.easing], delete e.easing), e.begin = t.ensureUnit(e.begin, "ms"), e.dur = t.ensureUnit(e.dur, "ms"), o && (e.calcMode = "spline", e.keySplines = o.join(" "), e.keyTimes = "0;1"), i && (e.fill = "freeze", l[s] = e.from, this.attr(l), a = t.quantity(e.begin || 0).value, e.begin = "indefinite"), r = this.elem("animate", t.extend({ attributeName: s }, e)), i && setTimeout(function () { try { r._node.beginElement() } catch (t) { l[s] = e.to, this.attr(l), r.remove() } }.bind(this), a), n && r._node.addEventListener("beginEvent", function () { n.emit("animationBegin", { element: this, animate: r._node, params: e }) }.bind(this)), r._node.addEventListener("endEvent", function () { n && n.emit("animationEnd", { element: this, animate: r._node, params: e }), i && (l[s] = e.to, this.attr(l), r.remove()) }.bind(this)) } e[s] instanceof Array ? e[s].forEach(function (e) { r.bind(this)(e, !1) }.bind(this)) : r.bind(this)(e[s], i) }.bind(this)), this } }), t.Svg.isSupported = function (e) { return i.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#" + e, "1.1") }; t.Svg.Easing = { easeInSine: [.47, 0, .745, .715], easeOutSine: [.39, .575, .565, 1], easeInOutSine: [.445, .05, .55, .95], easeInQuad: [.55, .085, .68, .53], easeOutQuad: [.25, .46, .45, .94], easeInOutQuad: [.455, .03, .515, .955], easeInCubic: [.55, .055, .675, .19], easeOutCubic: [.215, .61, .355, 1], easeInOutCubic: [.645, .045, .355, 1], easeInQuart: [.895, .03, .685, .22], easeOutQuart: [.165, .84, .44, 1], easeInOutQuart: [.77, 0, .175, 1], easeInQuint: [.755, .05, .855, .06], easeOutQuint: [.23, 1, .32, 1], easeInOutQuint: [.86, 0, .07, 1], easeInExpo: [.95, .05, .795, .035], easeOutExpo: [.19, 1, .22, 1], easeInOutExpo: [1, 0, 0, 1], easeInCirc: [.6, .04, .98, .335], easeOutCirc: [.075, .82, .165, 1], easeInOutCirc: [.785, .135, .15, .86], easeInBack: [.6, -.28, .735, .045], easeOutBack: [.175, .885, .32, 1.275], easeInOutBack: [.68, -.55, .265, 1.55] }, t.Svg.List = t.Class.extend({ constructor: function (e) { var i = this; this.svgElements = []; for (var n = 0; n < e.length; n++)this.svgElements.push(new t.Svg(e[n])); Object.keys(t.Svg.prototype).filter((function (e) { return -1 === ["constructor", "parent", "querySelector", "querySelectorAll", "replace", "append", "classes", "height", "width"].indexOf(e) })).forEach((function (e) { i[e] = function () { var n = Array.prototype.slice.call(arguments, 0); return i.svgElements.forEach((function (i) { t.Svg.prototype[e].apply(i, n) })), i } })) } }) }(this || global, e), function (e, t) { "use strict"; var i = { m: ["x", "y"], l: ["x", "y"], c: ["x1", "y1", "x2", "y2", "x", "y"], a: ["rx", "ry", "xAr", "lAf", "sf", "x", "y"] }, n = { accuracy: 3 }; function s(e, i, n, s, r, a) { var o = t.extend({ command: r ? e.toLowerCase() : e.toUpperCase() }, i, a ? { data: a } : {}); n.splice(s, 0, o) } function r(e, t) { e.forEach((function (n, s) { i[n.command.toLowerCase()].forEach((function (i, r) { t(n, i, s, r, e) })) })) } t.Svg.Path = t.Class.extend({ constructor: function (e, i) { this.pathElements = [], this.pos = 0, this.close = e, this.options = t.extend({}, n, i) }, position: function (e) { return void 0 !== e ? (this.pos = Math.max(0, Math.min(this.pathElements.length, e)), this) : this.pos }, remove: function (e) { return this.pathElements.splice(this.pos, e), this }, move: function (e, t, i, n) { return s("M", { x: +e, y: +t }, this.pathElements, this.pos++, i, n), this }, line: function (e, t, i, n) { return s("L", { x: +e, y: +t }, this.pathElements, this.pos++, i, n), this }, curve: function (e, t, i, n, r, a, o, l) { return s("C", { x1: +e, y1: +t, x2: +i, y2: +n, x: +r, y: +a }, this.pathElements, this.pos++, o, l), this }, arc: function (e, t, i, n, r, a, o, l, h) { return s("A", { rx: +e, ry: +t, xAr: +i, lAf: +n, sf: +r, x: +a, y: +o }, this.pathElements, this.pos++, l, h), this }, scale: function (e, t) { return r(this.pathElements, (function (i, n) { i[n] *= "x" === n[0] ? e : t })), this }, translate: function (e, t) { return r(this.pathElements, (function (i, n) { i[n] += "x" === n[0] ? e : t })), this }, transform: function (e) { return r(this.pathElements, (function (t, i, n, s, r) { var a = e(t, i, n, s, r); (a || 0 === a) && (t[i] = a) })), this }, parse: function (e) { var n = e.replace(/([A-Za-z])([0-9])/g, "$1 $2").replace(/([0-9])([A-Za-z])/g, "$1 $2").split(/[\s,]+/).reduce((function (e, t) { return t.match(/[A-Za-z]/) && e.push([]), e[e.length - 1].push(t), e }), []); "Z" === n[n.length - 1][0].toUpperCase() && n.pop(); var s = n.map((function (e) { var n = e.shift(), s = i[n.toLowerCase()]; return t.extend({ command: n }, s.reduce((function (t, i, n) { return t[i] = +e[n], t }), {})) })), r = [this.pos, 0]; return Array.prototype.push.apply(r, s), Array.prototype.splice.apply(this.pathElements, r), this.pos += s.length, this }, stringify: function () { var e = Math.pow(10, this.options.accuracy); return this.pathElements.reduce(function (t, n) { var s = i[n.command.toLowerCase()].map(function (t) { return this.options.accuracy ? Math.round(n[t] * e) / e : n[t] }.bind(this)); return t + n.command + s.join(",") }.bind(this), "") + (this.close ? "Z" : "") }, clone: function (e) { var i = new t.Svg.Path(e || this.close); return i.pos = this.pos, i.pathElements = this.pathElements.slice().map((function (e) { return t.extend({}, e) })), i.options = t.extend({}, this.options), i }, splitByCommand: function (e) { var i = [new t.Svg.Path]; return this.pathElements.forEach((function (n) { n.command === e.toUpperCase() && 0 !== i[i.length - 1].pathElements.length && i.push(new t.Svg.Path), i[i.length - 1].pathElements.push(n) })), i } }), t.Svg.Path.elementDescriptions = i, t.Svg.Path.join = function (e, i, n) { for (var s = new t.Svg.Path(i, n), r = 0; r < e.length; r++)for (var a = e[r], o = 0; o < a.pathElements.length; o++)s.pathElements.push(a.pathElements[o]); return s } }(this || global, e), function (e, t) { "use strict"; e.window, e.document; var i = { x: { pos: "x", len: "width", dir: "horizontal", rectStart: "x1", rectEnd: "x2", rectOffset: "y2" }, y: { pos: "y", len: "height", dir: "vertical", rectStart: "y2", rectEnd: "y1", rectOffset: "x1" } }; t.Axis = t.Class.extend({ constructor: function (e, t, n, s) { this.units = e, this.counterUnits = e === i.x ? i.y : i.x, this.chartRect = t, this.axisLength = t[e.rectEnd] - t[e.rectStart], this.gridOffset = t[e.rectOffset], this.ticks = n, this.options = s }, createGridAndLabels: function (e, i, n, s, r) { var a = s["axis" + this.units.pos.toUpperCase()], o = this.ticks.map(this.projectValue.bind(this)), l = this.ticks.map(a.labelInterpolationFnc); o.forEach(function (h, u) { var c, d = { x: 0, y: 0 }; c = o[u + 1] ? o[u + 1] - h : Math.max(this.axisLength - h, 30), t.isFalseyButZero(l[u]) && "" !== l[u] || ("x" === this.units.pos ? (h = this.chartRect.x1 + h, d.x = s.axisX.labelOffset.x, "start" === s.axisX.position ? d.y = this.chartRect.padding.top + s.axisX.labelOffset.y + (n ? 5 : 20) : d.y = this.chartRect.y1 + s.axisX.labelOffset.y + (n ? 5 : 20)) : (h = this.chartRect.y1 - h, d.y = s.axisY.labelOffset.y - (n ? c : 0), "start" === s.axisY.position ? d.x = n ? this.chartRect.padding.left + s.axisY.labelOffset.x : this.chartRect.x1 - 10 : d.x = this.chartRect.x2 + s.axisY.labelOffset.x + 10), a.showGrid && t.createGrid(h, u, this, this.gridOffset, this.chartRect[this.counterUnits.len](), e, [s.classNames.grid, s.classNames[this.units.dir]], r), a.showLabel && t.createLabel(h, c, u, l, this, a.offset, d, i, [s.classNames.label, s.classNames[this.units.dir], "start" === a.position ? s.classNames[a.position] : s.classNames.end], n, r)) }.bind(this)) }, projectValue: function (e, t, i) { throw new Error("Base axis can't be instantiated!") } }), t.Axis.units = i }(this || global, e), function (e, t) { "use strict"; e.window, e.document; t.AutoScaleAxis = t.Axis.extend({ constructor: function (e, i, n, s) { var r = s.highLow || t.getHighLow(i, s, e.pos); this.bounds = t.getBounds(n[e.rectEnd] - n[e.rectStart], r, s.scaleMinSpace || 20, s.onlyInteger), this.range = { min: this.bounds.min, max: this.bounds.max }, t.AutoScaleAxis.super.constructor.call(this, e, n, this.bounds.values, s) }, projectValue: function (e) { return this.axisLength * (+t.getMultiValue(e, this.units.pos) - this.bounds.min) / this.bounds.range } }) }(this || global, e), function (e, t) { "use strict"; e.window, e.document; t.FixedScaleAxis = t.Axis.extend({ constructor: function (e, i, n, s) { var r = s.highLow || t.getHighLow(i, s, e.pos); this.divisor = s.divisor || 1, this.ticks = s.ticks || t.times(this.divisor).map(function (e, t) { return r.low + (r.high - r.low) / this.divisor * t }.bind(this)), this.ticks.sort((function (e, t) { return e - t })), this.range = { min: r.low, max: r.high }, t.FixedScaleAxis.super.constructor.call(this, e, n, this.ticks, s), this.stepLength = this.axisLength / this.divisor }, projectValue: function (e) { return this.axisLength * (+t.getMultiValue(e, this.units.pos) - this.range.min) / (this.range.max - this.range.min) } }) }(this || global, e), function (e, t) { "use strict"; e.window, e.document; t.StepAxis = t.Axis.extend({ constructor: function (e, i, n, s) { t.StepAxis.super.constructor.call(this, e, n, s.ticks, s); var r = Math.max(1, s.ticks.length - (s.stretch ? 1 : 0)); this.stepLength = this.axisLength / r }, projectValue: function (e, t) { return this.stepLength * t } }) }(this || global, e), function (e, t) { "use strict"; e.window, e.document; var i = { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: t.noop, type: void 0 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: t.noop, type: void 0, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, showLine: !0, showPoint: !0, showArea: !1, areaBase: 0, lineSmooth: !0, showGridBackground: !1, low: void 0, high: void 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, fullWidth: !1, reverseData: !1, classNames: { chart: "ct-chart-line", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", line: "ct-line", point: "ct-point", area: "ct-area", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }; t.Line = t.Base.extend({ constructor: function (e, n, s, r) { t.Line.super.constructor.call(this, e, n, i, t.extend({}, i, s), r) }, createChart: function (e) { var n = t.normalizeData(this.data, e.reverseData, !0); this.svg = t.createSvg(this.container, e.width, e.height, e.classNames.chart); var s, r, a = this.svg.elem("g").addClass(e.classNames.gridGroup), o = this.svg.elem("g"), l = this.svg.elem("g").addClass(e.classNames.labelGroup), h = t.createChartRect(this.svg, e, i.padding); s = void 0 === e.axisX.type ? new t.StepAxis(t.Axis.units.x, n.normalized.series, h, t.extend({}, e.axisX, { ticks: n.normalized.labels, stretch: e.fullWidth })) : e.axisX.type.call(t, t.Axis.units.x, n.normalized.series, h, e.axisX), r = void 0 === e.axisY.type ? new t.AutoScaleAxis(t.Axis.units.y, n.normalized.series, h, t.extend({}, e.axisY, { high: t.isNumeric(e.high) ? e.high : e.axisY.high, low: t.isNumeric(e.low) ? e.low : e.axisY.low })) : e.axisY.type.call(t, t.Axis.units.y, n.normalized.series, h, e.axisY), s.createGridAndLabels(a, l, this.supportsForeignObject, e, this.eventEmitter), r.createGridAndLabels(a, l, this.supportsForeignObject, e, this.eventEmitter), e.showGridBackground && t.createGridBackground(a, h, e.classNames.gridBackground, this.eventEmitter), n.raw.series.forEach(function (i, a) { var l = o.elem("g"); l.attr({ "ct:series-name": i.name, "ct:meta": t.serialize(i.meta) }), l.addClass([e.classNames.series, i.className || e.classNames.series + "-" + t.alphaNumerate(a)].join(" ")); var u = [], c = []; n.normalized.series[a].forEach(function (e, o) { var l = { x: h.x1 + s.projectValue(e, o, n.normalized.series[a]), y: h.y1 - r.projectValue(e, o, n.normalized.series[a]) }; u.push(l.x, l.y), c.push({ value: e, valueIndex: o, meta: t.getMetaData(i, o) }) }.bind(this)); var d = { lineSmooth: t.getSeriesOption(i, e, "lineSmooth"), showPoint: t.getSeriesOption(i, e, "showPoint"), showLine: t.getSeriesOption(i, e, "showLine"), showArea: t.getSeriesOption(i, e, "showArea"), areaBase: t.getSeriesOption(i, e, "areaBase") }, p = ("function" == typeof d.lineSmooth ? d.lineSmooth : d.lineSmooth ? t.Interpolation.monotoneCubic() : t.Interpolation.none())(u, c); if (d.showPoint && p.pathElements.forEach(function (n) { var o = l.elem("line", { x1: n.x, y1: n.y, x2: n.x + .01, y2: n.y }, e.classNames.point).attr({ "ct:value": [n.data.value.x, n.data.value.y].filter(t.isNumeric).join(","), "ct:meta": t.serialize(n.data.meta) }); this.eventEmitter.emit("draw", { type: "point", value: n.data.value, index: n.data.valueIndex, meta: n.data.meta, series: i, seriesIndex: a, axisX: s, axisY: r, group: l, element: o, x: n.x, y: n.y }) }.bind(this)), d.showLine) { var f = l.elem("path", { d: p.stringify() }, e.classNames.line, !0); this.eventEmitter.emit("draw", { type: "line", values: n.normalized.series[a], path: p.clone(), chartRect: h, index: a, series: i, seriesIndex: a, seriesMeta: i.meta, axisX: s, axisY: r, group: l, element: f }) } if (d.showArea && r.range) { var m = Math.max(Math.min(d.areaBase, r.range.max), r.range.min), g = h.y1 - r.projectValue(m); p.splitByCommand("M").filter((function (e) { return e.pathElements.length > 1 })).map((function (e) { var t = e.pathElements[0], i = e.pathElements[e.pathElements.length - 1]; return e.clone(!0).position(0).remove(1).move(t.x, g).line(t.x, t.y).position(e.pathElements.length + 1).line(i.x, g) })).forEach(function (t) { var o = l.elem("path", { d: t.stringify() }, e.classNames.area, !0); this.eventEmitter.emit("draw", { type: "area", values: n.normalized.series[a], path: t.clone(), series: i, seriesIndex: a, axisX: s, axisY: r, chartRect: h, index: a, group: l, element: o }) }.bind(this)) } }.bind(this)), this.eventEmitter.emit("created", { bounds: r.bounds, chartRect: h, axisX: s, axisY: r, svg: this.svg, options: e }) } }) }(this || global, e), function (e, t) { "use strict"; e.window, e.document; var i = { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: t.noop, scaleMinSpace: 30, onlyInteger: !1 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: t.noop, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, high: void 0, low: void 0, referenceValue: 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, seriesBarDistance: 15, stackBars: !1, stackMode: "accumulate", horizontalBars: !1, distributeSeries: !1, reverseData: !1, showGridBackground: !1, classNames: { chart: "ct-chart-bar", horizontalBars: "ct-horizontal-bars", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", bar: "ct-bar", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }; t.Bar = t.Base.extend({ constructor: function (e, n, s, r) { t.Bar.super.constructor.call(this, e, n, i, t.extend({}, i, s), r) }, createChart: function (e) { var n, s; e.distributeSeries ? (n = t.normalizeData(this.data, e.reverseData, e.horizontalBars ? "x" : "y")).normalized.series = n.normalized.series.map((function (e) { return [e] })) : n = t.normalizeData(this.data, e.reverseData, e.horizontalBars ? "x" : "y"), this.svg = t.createSvg(this.container, e.width, e.height, e.classNames.chart + (e.horizontalBars ? " " + e.classNames.horizontalBars : "")); var r = this.svg.elem("g").addClass(e.classNames.gridGroup), a = this.svg.elem("g"), o = this.svg.elem("g").addClass(e.classNames.labelGroup); if (e.stackBars && 0 !== n.normalized.series.length) { var l = t.serialMap(n.normalized.series, (function () { return Array.prototype.slice.call(arguments).map((function (e) { return e })).reduce((function (e, t) { return { x: e.x + (t && t.x) || 0, y: e.y + (t && t.y) || 0 } }), { x: 0, y: 0 }) })); s = t.getHighLow([l], e, e.horizontalBars ? "x" : "y") } else s = t.getHighLow(n.normalized.series, e, e.horizontalBars ? "x" : "y"); s.high = +e.high || (0 === e.high ? 0 : s.high), s.low = +e.low || (0 === e.low ? 0 : s.low); var h, u, c, d, p, f = t.createChartRect(this.svg, e, i.padding); u = e.distributeSeries && e.stackBars ? n.normalized.labels.slice(0, 1) : n.normalized.labels, e.horizontalBars ? (h = d = void 0 === e.axisX.type ? new t.AutoScaleAxis(t.Axis.units.x, n.normalized.series, f, t.extend({}, e.axisX, { highLow: s, referenceValue: 0 })) : e.axisX.type.call(t, t.Axis.units.x, n.normalized.series, f, t.extend({}, e.axisX, { highLow: s, referenceValue: 0 })), c = p = void 0 === e.axisY.type ? new t.StepAxis(t.Axis.units.y, n.normalized.series, f, { ticks: u }) : e.axisY.type.call(t, t.Axis.units.y, n.normalized.series, f, e.axisY)) : (c = d = void 0 === e.axisX.type ? new t.StepAxis(t.Axis.units.x, n.normalized.series, f, { ticks: u }) : e.axisX.type.call(t, t.Axis.units.x, n.normalized.series, f, e.axisX), h = p = void 0 === e.axisY.type ? new t.AutoScaleAxis(t.Axis.units.y, n.normalized.series, f, t.extend({}, e.axisY, { highLow: s, referenceValue: 0 })) : e.axisY.type.call(t, t.Axis.units.y, n.normalized.series, f, t.extend({}, e.axisY, { highLow: s, referenceValue: 0 }))); var m = e.horizontalBars ? f.x1 + h.projectValue(0) : f.y1 - h.projectValue(0), g = []; c.createGridAndLabels(r, o, this.supportsForeignObject, e, this.eventEmitter), h.createGridAndLabels(r, o, this.supportsForeignObject, e, this.eventEmitter), e.showGridBackground && t.createGridBackground(r, f, e.classNames.gridBackground, this.eventEmitter), n.raw.series.forEach(function (i, s) { var r, o, l = s - (n.raw.series.length - 1) / 2; r = e.distributeSeries && !e.stackBars ? c.axisLength / n.normalized.series.length / 2 : e.distributeSeries && e.stackBars ? c.axisLength / 2 : c.axisLength / n.normalized.series[s].length / 2, (o = a.elem("g")).attr({ "ct:series-name": i.name, "ct:meta": t.serialize(i.meta) }), o.addClass([e.classNames.series, i.className || e.classNames.series + "-" + t.alphaNumerate(s)].join(" ")), n.normalized.series[s].forEach(function (a, u) { var v, x, y, b; if (b = e.distributeSeries && !e.stackBars ? s : e.distributeSeries && e.stackBars ? 0 : u, v = e.horizontalBars ? { x: f.x1 + h.projectValue(a && a.x ? a.x : 0, u, n.normalized.series[s]), y: f.y1 - c.projectValue(a && a.y ? a.y : 0, b, n.normalized.series[s]) } : { x: f.x1 + c.projectValue(a && a.x ? a.x : 0, b, n.normalized.series[s]), y: f.y1 - h.projectValue(a && a.y ? a.y : 0, u, n.normalized.series[s]) }, c instanceof t.StepAxis && (c.options.stretch || (v[c.units.pos] += r * (e.horizontalBars ? -1 : 1)), v[c.units.pos] += e.stackBars || e.distributeSeries ? 0 : l * e.seriesBarDistance * (e.horizontalBars ? -1 : 1)), y = g[u] || m, g[u] = y - (m - v[c.counterUnits.pos]), void 0 !== a) { var w = {}; w[c.units.pos + "1"] = v[c.units.pos], w[c.units.pos + "2"] = v[c.units.pos], !e.stackBars || "accumulate" !== e.stackMode && e.stackMode ? (w[c.counterUnits.pos + "1"] = m, w[c.counterUnits.pos + "2"] = v[c.counterUnits.pos]) : (w[c.counterUnits.pos + "1"] = y, w[c.counterUnits.pos + "2"] = g[u]), w.x1 = Math.min(Math.max(w.x1, f.x1), f.x2), w.x2 = Math.min(Math.max(w.x2, f.x1), f.x2), w.y1 = Math.min(Math.max(w.y1, f.y2), f.y1), w.y2 = Math.min(Math.max(w.y2, f.y2), f.y1); var E = t.getMetaData(i, u); x = o.elem("line", w, e.classNames.bar).attr({ "ct:value": [a.x, a.y].filter(t.isNumeric).join(","), "ct:meta": t.serialize(E) }), this.eventEmitter.emit("draw", t.extend({ type: "bar", value: a, index: u, meta: E, series: i, seriesIndex: s, axisX: d, axisY: p, chartRect: f, group: o, element: x }, w)) } }.bind(this)) }.bind(this)), this.eventEmitter.emit("created", { bounds: h.bounds, chartRect: f, axisX: d, axisY: p, svg: this.svg, options: e }) } }) }(this || global, e), function (e, t) { "use strict"; e.window, e.document; var i = { width: void 0, height: void 0, chartPadding: 5, classNames: { chartPie: "ct-chart-pie", chartDonut: "ct-chart-donut", series: "ct-series", slicePie: "ct-slice-pie", sliceDonut: "ct-slice-donut", sliceDonutSolid: "ct-slice-donut-solid", label: "ct-label" }, startAngle: 0, total: void 0, donut: !1, donutSolid: !1, donutWidth: 60, showLabel: !0, labelOffset: 0, labelPosition: "inside", labelInterpolationFnc: t.noop, labelDirection: "neutral", reverseData: !1, ignoreEmptyValues: !1 }; function n(e, t, i) { var n = t.x > e.x; return n && "explode" === i || !n && "implode" === i ? "start" : n && "implode" === i || !n && "explode" === i ? "end" : "middle" } t.Pie = t.Base.extend({ constructor: function (e, n, s, r) { t.Pie.super.constructor.call(this, e, n, i, t.extend({}, i, s), r) }, createChart: function (e) { var s, r, a, o, l, h = t.normalizeData(this.data), u = [], c = e.startAngle; this.svg = t.createSvg(this.container, e.width, e.height, e.donut ? e.classNames.chartDonut : e.classNames.chartPie), r = t.createChartRect(this.svg, e, i.padding), a = Math.min(r.width() / 2, r.height() / 2), l = e.total || h.normalized.series.reduce((function (e, t) { return e + t }), 0); var d = t.quantity(e.donutWidth); "%" === d.unit && (d.value *= a / 100), a -= e.donut && !e.donutSolid ? d.value / 2 : 0, o = "outside" === e.labelPosition || e.donut && !e.donutSolid ? a : "center" === e.labelPosition ? 0 : e.donutSolid ? a - d.value / 2 : a / 2, o += e.labelOffset; var p = { x: r.x1 + r.width() / 2, y: r.y2 + r.height() / 2 }, f = 1 === h.raw.series.filter((function (e) { return e.hasOwnProperty("value") ? 0 !== e.value : 0 !== e })).length; h.raw.series.forEach(function (e, t) { u[t] = this.svg.elem("g", null, null) }.bind(this)), e.showLabel && (s = this.svg.elem("g", null, null)), h.raw.series.forEach(function (i, r) { if (0 !== h.normalized.series[r] || !e.ignoreEmptyValues) { u[r].attr({ "ct:series-name": i.name }), u[r].addClass([e.classNames.series, i.className || e.classNames.series + "-" + t.alphaNumerate(r)].join(" ")); var m = l > 0 ? c + h.normalized.series[r] / l * 360 : 0, g = Math.max(0, c - (0 === r || f ? 0 : .2)); m - g >= 359.99 && (m = g + 359.99); var v, x, y, b = t.polarToCartesian(p.x, p.y, a, g), w = t.polarToCartesian(p.x, p.y, a, m), E = new t.Svg.Path(!e.donut || e.donutSolid).move(w.x, w.y).arc(a, a, 0, m - c > 180, 0, b.x, b.y); e.donut ? e.donutSolid && (y = a - d.value, v = t.polarToCartesian(p.x, p.y, y, c - (0 === r || f ? 0 : .2)), x = t.polarToCartesian(p.x, p.y, y, m), E.line(v.x, v.y), E.arc(y, y, 0, m - c > 180, 1, x.x, x.y)) : E.line(p.x, p.y); var S = e.classNames.slicePie; e.donut && (S = e.classNames.sliceDonut, e.donutSolid && (S = e.classNames.sliceDonutSolid)); var A = u[r].elem("path", { d: E.stringify() }, S); if (A.attr({ "ct:value": h.normalized.series[r], "ct:meta": t.serialize(i.meta) }), e.donut && !e.donutSolid && (A._node.style.strokeWidth = d.value + "px"), this.eventEmitter.emit("draw", { type: "slice", value: h.normalized.series[r], totalDataSum: l, index: r, meta: i.meta, series: i, group: u[r], element: A, path: E.clone(), center: p, radius: a, startAngle: c, endAngle: m }), e.showLabel) { var z, M; z = 1 === h.raw.series.length ? { x: p.x, y: p.y } : t.polarToCartesian(p.x, p.y, o, c + (m - c) / 2), M = h.normalized.labels && !t.isFalseyButZero(h.normalized.labels[r]) ? h.normalized.labels[r] : h.normalized.series[r]; var O = e.labelInterpolationFnc(M, r); if (O || 0 === O) { var C = s.elem("text", { dx: z.x, dy: z.y, "text-anchor": n(p, z, e.labelDirection) }, e.classNames.label).text("" + O); this.eventEmitter.emit("draw", { type: "label", index: r, group: s, element: C, text: "" + O, x: z.x, y: z.y }) } } c = m } }.bind(this)), this.eventEmitter.emit("created", { chartRect: r, svg: this.svg, options: e }) }, determineAnchorPosition: n }) }(this || global, e), e })); + +var i, l, selectedLine = null; + +/* Navigate to hash without browser history entry */ +var navigateToHash = function () { + if (window.history !== undefined && window.history.replaceState !== undefined) { + window.history.replaceState(undefined, undefined, this.getAttribute("href")); + } +}; + +var hashLinks = document.getElementsByClassName('navigatetohash'); +for (i = 0, l = hashLinks.length; i < l; i++) { + hashLinks[i].addEventListener('click', navigateToHash); +} + +/* Switch test method */ +var switchTestMethod = function () { + var method = this.getAttribute("value"); + console.log("Selected test method: " + method); + + var lines, i, l, coverageData, lineAnalysis, cells; + + lines = document.querySelectorAll('.lineAnalysis tr'); + + for (i = 1, l = lines.length; i < l; i++) { + coverageData = JSON.parse(lines[i].getAttribute('data-coverage').replace(/'/g, '"')); + lineAnalysis = coverageData[method]; + cells = lines[i].querySelectorAll('td'); + if (lineAnalysis === undefined) { + lineAnalysis = coverageData.AllTestMethods; + if (lineAnalysis.LVS !== 'gray') { + cells[0].setAttribute('class', 'red'); + cells[1].innerText = cells[1].textContent = '0'; + cells[4].setAttribute('class', 'lightred'); + } + } else { + cells[0].setAttribute('class', lineAnalysis.LVS); + cells[1].innerText = cells[1].textContent = lineAnalysis.VC; + cells[4].setAttribute('class', 'light' + lineAnalysis.LVS); + } + } +}; + +var testMethods = document.getElementsByClassName('switchtestmethod'); +for (i = 0, l = testMethods.length; i < l; i++) { + testMethods[i].addEventListener('change', switchTestMethod); +} + +/* Highlight test method by line */ +var toggleLine = function () { + if (selectedLine === this) { + selectedLine = null; + } else { + selectedLine = null; + unhighlightTestMethods(); + highlightTestMethods.call(this); + selectedLine = this; + } + +}; +var highlightTestMethods = function () { + if (selectedLine !== null) { + return; + } + + var lineAnalysis; + var coverageData = JSON.parse(this.getAttribute('data-coverage').replace(/'/g, '"')); + var testMethods = document.getElementsByClassName('testmethod'); + + for (i = 0, l = testMethods.length; i < l; i++) { + lineAnalysis = coverageData[testMethods[i].id]; + if (lineAnalysis === undefined) { + testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, ""); + } else { + testMethods[i].className += ' light' + lineAnalysis.LVS; + } + } +}; +var unhighlightTestMethods = function () { + if (selectedLine !== null) { + return; + } + + var testMethods = document.getElementsByClassName('testmethod'); + for (i = 0, l = testMethods.length; i < l; i++) { + testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, ""); + } +}; +var coverableLines = document.getElementsByClassName('coverableline'); +for (i = 0, l = coverableLines.length; i < l; i++) { + coverableLines[i].addEventListener('click', toggleLine); + coverableLines[i].addEventListener('mouseenter', highlightTestMethods); + coverableLines[i].addEventListener('mouseleave', unhighlightTestMethods); +} + +/* History charts */ +var renderChart = function (chart) { + // Remove current children (e.g. PNG placeholder) + while (chart.firstChild) { + chart.firstChild.remove(); + } + + var chartData = window[chart.getAttribute('data-data')]; + var options = { + axisY: { + type: undefined, + onlyInteger: true + }, + lineSmooth: false, + low: 0, + high: 100, + scaleMinSpace: 20, + onlyInteger: true, + fullWidth: true + }; + var lineChart = new Chartist.Line(chart, { + labels: [], + series: chartData.series + }, options); + + /* Zoom */ + var zoomButtonDiv = document.createElement("div"); + zoomButtonDiv.className = "toggleZoom"; + var zoomButtonLink = document.createElement("a"); + zoomButtonLink.setAttribute("href", ""); + var zoomButtonText = document.createElement("i"); + zoomButtonText.className = "icon-search-plus"; + + zoomButtonLink.appendChild(zoomButtonText); + zoomButtonDiv.appendChild(zoomButtonLink); + + chart.appendChild(zoomButtonDiv); + + zoomButtonDiv.addEventListener('click', function (event) { + event.preventDefault(); + + if (options.axisY.type === undefined) { + options.axisY.type = Chartist.AutoScaleAxis; + zoomButtonText.className = "icon-search-minus"; + } else { + options.axisY.type = undefined; + zoomButtonText.className = "icon-search-plus"; + } + + lineChart.update(null, options); + }); + + var tooltip = document.createElement("div"); + tooltip.className = "tooltip"; + + chart.appendChild(tooltip); + + /* Tooltips */ + var showToolTip = function () { + var index = this.getAttribute('ct:meta'); + + tooltip.innerHTML = chartData.tooltips[index]; + tooltip.style.display = 'block'; + }; + + var moveToolTip = function (event) { + var box = chart.getBoundingClientRect(); + var left = event.pageX - box.left - window.pageXOffset; + var top = event.pageY - box.top - window.pageYOffset; + + left = left + 20; + top = top - tooltip.offsetHeight / 2; + + if (left + tooltip.offsetWidth > box.width) { + left -= tooltip.offsetWidth + 40; + } + + if (top < 0) { + top = 0; + } + + if (top + tooltip.offsetHeight > box.height) { + top = box.height - tooltip.offsetHeight; + } + + tooltip.style.left = left + 'px'; + tooltip.style.top = top + 'px'; + }; + + var hideToolTip = function () { + tooltip.style.display = 'none'; + }; + chart.addEventListener('mousemove', moveToolTip); + + lineChart.on('created', function () { + var chartPoints = chart.getElementsByClassName('ct-point'); + for (i = 0, l = chartPoints.length; i < l; i++) { + chartPoints[i].addEventListener('mousemove', showToolTip); + chartPoints[i].addEventListener('mouseout', hideToolTip); + } + }); +}; + +var charts = document.getElementsByClassName('historychart'); +for (i = 0, l = charts.length; i < l; i++) { + renderChart(charts[i]); +} \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_cog.svg b/jobs/Backend/coveragereport/icon_cog.svg new file mode 100644 index 0000000000..d730bf1266 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_cog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_cog_dark.svg b/jobs/Backend/coveragereport/icon_cog_dark.svg new file mode 100644 index 0000000000..ccbcd9b00b --- /dev/null +++ b/jobs/Backend/coveragereport/icon_cog_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_cube.svg b/jobs/Backend/coveragereport/icon_cube.svg new file mode 100644 index 0000000000..3302443cc6 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_cube.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_cube_dark.svg b/jobs/Backend/coveragereport/icon_cube_dark.svg new file mode 100644 index 0000000000..3e7f0fa882 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_cube_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_fork.svg b/jobs/Backend/coveragereport/icon_fork.svg new file mode 100644 index 0000000000..f0148b3a36 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_fork.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_fork_dark.svg b/jobs/Backend/coveragereport/icon_fork_dark.svg new file mode 100644 index 0000000000..11930c9b67 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_fork_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_info-circled.svg b/jobs/Backend/coveragereport/icon_info-circled.svg new file mode 100644 index 0000000000..252166bba9 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_info-circled.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_info-circled_dark.svg b/jobs/Backend/coveragereport/icon_info-circled_dark.svg new file mode 100644 index 0000000000..252166bba9 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_info-circled_dark.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_minus.svg b/jobs/Backend/coveragereport/icon_minus.svg new file mode 100644 index 0000000000..3c30c365e6 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_minus.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_minus_dark.svg b/jobs/Backend/coveragereport/icon_minus_dark.svg new file mode 100644 index 0000000000..2516b6fc5c --- /dev/null +++ b/jobs/Backend/coveragereport/icon_minus_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_plus.svg b/jobs/Backend/coveragereport/icon_plus.svg new file mode 100644 index 0000000000..79327232c6 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_plus.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_plus_dark.svg b/jobs/Backend/coveragereport/icon_plus_dark.svg new file mode 100644 index 0000000000..6ed4edd0a4 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_plus_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_search-minus.svg b/jobs/Backend/coveragereport/icon_search-minus.svg new file mode 100644 index 0000000000..c174eb5e14 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_search-minus.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_search-minus_dark.svg b/jobs/Backend/coveragereport/icon_search-minus_dark.svg new file mode 100644 index 0000000000..9caaffbc36 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_search-minus_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_search-plus.svg b/jobs/Backend/coveragereport/icon_search-plus.svg new file mode 100644 index 0000000000..04b24ecc3b --- /dev/null +++ b/jobs/Backend/coveragereport/icon_search-plus.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_search-plus_dark.svg b/jobs/Backend/coveragereport/icon_search-plus_dark.svg new file mode 100644 index 0000000000..53241945e5 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_search-plus_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_sponsor.svg b/jobs/Backend/coveragereport/icon_sponsor.svg new file mode 100644 index 0000000000..bf6d959139 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_sponsor.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_star.svg b/jobs/Backend/coveragereport/icon_star.svg new file mode 100644 index 0000000000..b23c54ea0f --- /dev/null +++ b/jobs/Backend/coveragereport/icon_star.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_star_dark.svg b/jobs/Backend/coveragereport/icon_star_dark.svg new file mode 100644 index 0000000000..49c0d03431 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_star_dark.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_up-dir.svg b/jobs/Backend/coveragereport/icon_up-dir.svg new file mode 100644 index 0000000000..567c11f3e2 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_up-dir.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_up-dir_active.svg b/jobs/Backend/coveragereport/icon_up-dir_active.svg new file mode 100644 index 0000000000..bb225544a8 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_up-dir_active.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_up-down-dir.svg b/jobs/Backend/coveragereport/icon_up-down-dir.svg new file mode 100644 index 0000000000..62a3f9ccd9 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_up-down-dir.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_up-down-dir_dark.svg b/jobs/Backend/coveragereport/icon_up-down-dir_dark.svg new file mode 100644 index 0000000000..2820a250a0 --- /dev/null +++ b/jobs/Backend/coveragereport/icon_up-down-dir_dark.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_wrench.svg b/jobs/Backend/coveragereport/icon_wrench.svg new file mode 100644 index 0000000000..b6aa318cef --- /dev/null +++ b/jobs/Backend/coveragereport/icon_wrench.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/icon_wrench_dark.svg b/jobs/Backend/coveragereport/icon_wrench_dark.svg new file mode 100644 index 0000000000..5c77a9c87a --- /dev/null +++ b/jobs/Backend/coveragereport/icon_wrench_dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jobs/Backend/coveragereport/index.htm b/jobs/Backend/coveragereport/index.htm new file mode 100644 index 0000000000..b5926d239e --- /dev/null +++ b/jobs/Backend/coveragereport/index.htm @@ -0,0 +1,254 @@ + + + + + + + +Summary - Coverage Report + +
+

SummaryStarSponsor

+
+
+
Information
+
+
+ + + + + + + + + + + + + + + + + + + + + +
Parser:Cobertura
Assemblies:5
Classes:12
Files:11
Coverage date:16/02/2026 - 11:45:19
+
+
+
+
+
Line coverage
+
+
31%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:188
Uncovered lines:404
Coverable lines:592
Total lines:1117
Line coverage:31.7%
+
+
+
+
+
Branch coverage
+
+
12%
+
+ + + + + + + + + + + + + +
Covered branches:32
Total branches:248
Branch coverage:12.9%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Risk Hotspots

+ +
+ +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AssemblyClassMethodCrap Score Cyclomatic complexity
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedTransformAsync(...)893094
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedTransformAsync(...)119034
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedGetTypeDocId(...)81228
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedCreateDocumentationId(...)34218
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedCreateDocumentationId(...)11010
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedNormalizeDocId(...)426
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedUnwrapOpenApiParameter(...)426
+
+
+

Coverage

+ +
+ +++++++++++++ + + + + + + + + + + + + + + + + + + + + + + +
Line coverageBranch coverage
NameCoveredUncoveredCoverableTotalPercentageCoveredTotalPercentage
ExchangeRateUpdater.Abstraction34034103100%
 
91090%
  
ExchangeRateUpdater.Abstraction.Model.Currency1801848100%
 
7887.5%
  
ExchangeRateUpdater.Abstraction.Model.ExchangeRate1601655100%
 
22100%
 
ExchangeRateUpdater.Api5139945077111.3%
  
42141.8%
  
ExchangeRateUpdater.Api.Controllers.ExchangeRateController1301331100%
 
22100%
 
ExchangeRateUpdater.Api.Middleware.ExceptionHandlingMiddleware1218307040%
  
040%
 
Microsoft.AspNetCore.OpenApi.Generated03743745920%
 
02060%
 
Program264305586.6%
  
22100%
 
System.Runtime.CompilerServices033230%
 
00
 
ExchangeRateUpdater.CbnApiClient4614712197.8%
  
101283.3%
  
ExchangeRateUpdater.CbnApiClient.Implementation.ExchangeRateCnbApiClient311326896.8%
  
81080%
  
ExchangeRateUpdater.CbnApiClient.Mapper.CnbExchangeRateMapperExtensions1501553100%
 
22100%
 
ExchangeRateUpdater.DependencyInjection111123791.6%
  
00
 
ExchangeRateUpdater.DependencyInjection.ExchangeRateCnbServicesExtension111123791.6%
  
00
 
ExchangeRateUpdater.Service4634910893.8%
  
91275%
  
ExchangeRateUpdater.Service.ExchangeRateProvider253285989.2%
  
5862.5%
  
ExchangeRateUpdater.Service.ExchangeRateService2102149100%
 
44100%
 
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/index.html b/jobs/Backend/coveragereport/index.html new file mode 100644 index 0000000000..b5926d239e --- /dev/null +++ b/jobs/Backend/coveragereport/index.html @@ -0,0 +1,254 @@ + + + + + + + +Summary - Coverage Report + +
+

SummaryStarSponsor

+
+
+
Information
+
+
+ + + + + + + + + + + + + + + + + + + + + +
Parser:Cobertura
Assemblies:5
Classes:12
Files:11
Coverage date:16/02/2026 - 11:45:19
+
+
+
+
+
Line coverage
+
+
31%
+
+ + + + + + + + + + + + + + + + + + + + + +
Covered lines:188
Uncovered lines:404
Coverable lines:592
Total lines:1117
Line coverage:31.7%
+
+
+
+
+
Branch coverage
+
+
12%
+
+ + + + + + + + + + + + + +
Covered branches:32
Total branches:248
Branch coverage:12.9%
+
+
+
+
+
Method coverage
+
+
+

Feature is only available for sponsors

+Upgrade to PRO version +
+
+
+
+

Risk Hotspots

+ +
+ +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AssemblyClassMethodCrap Score Cyclomatic complexity
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedTransformAsync(...)893094
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedTransformAsync(...)119034
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedGetTypeDocId(...)81228
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedCreateDocumentationId(...)34218
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedCreateDocumentationId(...)11010
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedNormalizeDocId(...)426
ExchangeRateUpdater.ApiMicrosoft.AspNetCore.OpenApi.GeneratedUnwrapOpenApiParameter(...)426
+
+
+

Coverage

+ +
+ +++++++++++++ + + + + + + + + + + + + + + + + + + + + + + +
Line coverageBranch coverage
NameCoveredUncoveredCoverableTotalPercentageCoveredTotalPercentage
ExchangeRateUpdater.Abstraction34034103100%
 
91090%
  
ExchangeRateUpdater.Abstraction.Model.Currency1801848100%
 
7887.5%
  
ExchangeRateUpdater.Abstraction.Model.ExchangeRate1601655100%
 
22100%
 
ExchangeRateUpdater.Api5139945077111.3%
  
42141.8%
  
ExchangeRateUpdater.Api.Controllers.ExchangeRateController1301331100%
 
22100%
 
ExchangeRateUpdater.Api.Middleware.ExceptionHandlingMiddleware1218307040%
  
040%
 
Microsoft.AspNetCore.OpenApi.Generated03743745920%
 
02060%
 
Program264305586.6%
  
22100%
 
System.Runtime.CompilerServices033230%
 
00
 
ExchangeRateUpdater.CbnApiClient4614712197.8%
  
101283.3%
  
ExchangeRateUpdater.CbnApiClient.Implementation.ExchangeRateCnbApiClient311326896.8%
  
81080%
  
ExchangeRateUpdater.CbnApiClient.Mapper.CnbExchangeRateMapperExtensions1501553100%
 
22100%
 
ExchangeRateUpdater.DependencyInjection111123791.6%
  
00
 
ExchangeRateUpdater.DependencyInjection.ExchangeRateCnbServicesExtension111123791.6%
  
00
 
ExchangeRateUpdater.Service4634910893.8%
  
91275%
  
ExchangeRateUpdater.Service.ExchangeRateProvider253285989.2%
  
5862.5%
  
ExchangeRateUpdater.Service.ExchangeRateService2102149100%
 
44100%
 
+
+
+
+ \ No newline at end of file diff --git a/jobs/Backend/coveragereport/main.js b/jobs/Backend/coveragereport/main.js new file mode 100644 index 0000000000..36a864dd2f --- /dev/null +++ b/jobs/Backend/coveragereport/main.js @@ -0,0 +1,356 @@ +/* Chartist.js 0.11.4 + * Copyright © 2019 Gion Kunz + * Free to use under either the WTFPL license or the MIT license. + * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-WTFPL + * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-MIT + */ + +!function (e, t) { "function" == typeof define && define.amd ? define("Chartist", [], (function () { return e.Chartist = t() })) : "object" == typeof module && module.exports ? module.exports = t() : e.Chartist = t() }(this, (function () { var e = { version: "0.11.4" }; return function (e, t) { "use strict"; var i = e.window, n = e.document; t.namespaces = { svg: "http://www.w3.org/2000/svg", xmlns: "http://www.w3.org/2000/xmlns/", xhtml: "http://www.w3.org/1999/xhtml", xlink: "http://www.w3.org/1999/xlink", ct: "http://gionkunz.github.com/chartist-js/ct" }, t.noop = function (e) { return e }, t.alphaNumerate = function (e) { return String.fromCharCode(97 + e % 26) }, t.extend = function (e) { var i, n, s, r; for (e = e || {}, i = 1; i < arguments.length; i++)for (var a in n = arguments[i], r = Object.getPrototypeOf(e), n) "__proto__" === a || "constructor" === a || null !== r && a in r || (s = n[a], e[a] = "object" != typeof s || null === s || s instanceof Array ? s : t.extend(e[a], s)); return e }, t.replaceAll = function (e, t, i) { return e.replace(new RegExp(t, "g"), i) }, t.ensureUnit = function (e, t) { return "number" == typeof e && (e += t), e }, t.quantity = function (e) { if ("string" == typeof e) { var t = /^(\d+)\s*(.*)$/g.exec(e); return { value: +t[1], unit: t[2] || void 0 } } return { value: e } }, t.querySelector = function (e) { return e instanceof Node ? e : n.querySelector(e) }, t.times = function (e) { return Array.apply(null, new Array(e)) }, t.sum = function (e, t) { return e + (t || 0) }, t.mapMultiply = function (e) { return function (t) { return t * e } }, t.mapAdd = function (e) { return function (t) { return t + e } }, t.serialMap = function (e, i) { var n = [], s = Math.max.apply(null, e.map((function (e) { return e.length }))); return t.times(s).forEach((function (t, s) { var r = e.map((function (e) { return e[s] })); n[s] = i.apply(null, r) })), n }, t.roundWithPrecision = function (e, i) { var n = Math.pow(10, i || t.precision); return Math.round(e * n) / n }, t.precision = 8, t.escapingMap = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }, t.serialize = function (e) { return null == e ? e : ("number" == typeof e ? e = "" + e : "object" == typeof e && (e = JSON.stringify({ data: e })), Object.keys(t.escapingMap).reduce((function (e, i) { return t.replaceAll(e, i, t.escapingMap[i]) }), e)) }, t.deserialize = function (e) { if ("string" != typeof e) return e; e = Object.keys(t.escapingMap).reduce((function (e, i) { return t.replaceAll(e, t.escapingMap[i], i) }), e); try { e = void 0 !== (e = JSON.parse(e)).data ? e.data : e } catch (e) { } return e }, t.createSvg = function (e, i, n, s) { var r; return i = i || "100%", n = n || "100%", Array.prototype.slice.call(e.querySelectorAll("svg")).filter((function (e) { return e.getAttributeNS(t.namespaces.xmlns, "ct") })).forEach((function (t) { e.removeChild(t) })), (r = new t.Svg("svg").attr({ width: i, height: n }).addClass(s))._node.style.width = i, r._node.style.height = n, e.appendChild(r._node), r }, t.normalizeData = function (e, i, n) { var s, r = { raw: e, normalized: {} }; return r.normalized.series = t.getDataArray({ series: e.series || [] }, i, n), s = r.normalized.series.every((function (e) { return e instanceof Array })) ? Math.max.apply(null, r.normalized.series.map((function (e) { return e.length }))) : r.normalized.series.length, r.normalized.labels = (e.labels || []).slice(), Array.prototype.push.apply(r.normalized.labels, t.times(Math.max(0, s - r.normalized.labels.length)).map((function () { return "" }))), i && t.reverseData(r.normalized), r }, t.safeHasProperty = function (e, t) { return null !== e && "object" == typeof e && e.hasOwnProperty(t) }, t.isDataHoleValue = function (e) { return null == e || "number" == typeof e && isNaN(e) }, t.reverseData = function (e) { e.labels.reverse(), e.series.reverse(); for (var t = 0; t < e.series.length; t++)"object" == typeof e.series[t] && void 0 !== e.series[t].data ? e.series[t].data.reverse() : e.series[t] instanceof Array && e.series[t].reverse() }, t.getDataArray = function (e, i, n) { return e.series.map((function e(i) { if (t.safeHasProperty(i, "value")) return e(i.value); if (t.safeHasProperty(i, "data")) return e(i.data); if (i instanceof Array) return i.map(e); if (!t.isDataHoleValue(i)) { if (n) { var s = {}; return "string" == typeof n ? s[n] = t.getNumberOrUndefined(i) : s.y = t.getNumberOrUndefined(i), s.x = i.hasOwnProperty("x") ? t.getNumberOrUndefined(i.x) : s.x, s.y = i.hasOwnProperty("y") ? t.getNumberOrUndefined(i.y) : s.y, s } return t.getNumberOrUndefined(i) } })) }, t.normalizePadding = function (e, t) { return t = t || 0, "number" == typeof e ? { top: e, right: e, bottom: e, left: e } : { top: "number" == typeof e.top ? e.top : t, right: "number" == typeof e.right ? e.right : t, bottom: "number" == typeof e.bottom ? e.bottom : t, left: "number" == typeof e.left ? e.left : t } }, t.getMetaData = function (e, t) { var i = e.data ? e.data[t] : e[t]; return i ? i.meta : void 0 }, t.orderOfMagnitude = function (e) { return Math.floor(Math.log(Math.abs(e)) / Math.LN10) }, t.projectLength = function (e, t, i) { return t / i.range * e }, t.getAvailableHeight = function (e, i) { return Math.max((t.quantity(i.height).value || e.height()) - (i.chartPadding.top + i.chartPadding.bottom) - i.axisX.offset, 0) }, t.getHighLow = function (e, i, n) { var s = { high: void 0 === (i = t.extend({}, i, n ? i["axis" + n.toUpperCase()] : {})).high ? -Number.MAX_VALUE : +i.high, low: void 0 === i.low ? Number.MAX_VALUE : +i.low }, r = void 0 === i.high, a = void 0 === i.low; return (r || a) && function e(t) { if (void 0 !== t) if (t instanceof Array) for (var i = 0; i < t.length; i++)e(t[i]); else { var o = n ? +t[n] : +t; r && o > s.high && (s.high = o), a && o < s.low && (s.low = o) } }(e), (i.referenceValue || 0 === i.referenceValue) && (s.high = Math.max(i.referenceValue, s.high), s.low = Math.min(i.referenceValue, s.low)), s.high <= s.low && (0 === s.low ? s.high = 1 : s.low < 0 ? s.high = 0 : (s.high > 0 || (s.high = 1), s.low = 0)), s }, t.isNumeric = function (e) { return null !== e && isFinite(e) }, t.isFalseyButZero = function (e) { return !e && 0 !== e }, t.getNumberOrUndefined = function (e) { return t.isNumeric(e) ? +e : void 0 }, t.isMultiValue = function (e) { return "object" == typeof e && ("x" in e || "y" in e) }, t.getMultiValue = function (e, i) { return t.isMultiValue(e) ? t.getNumberOrUndefined(e[i || "y"]) : t.getNumberOrUndefined(e) }, t.rho = function (e) { if (1 === e) return e; function t(e, i) { return e % i == 0 ? i : t(i, e % i) } function i(e) { return e * e + 1 } var n, s = 2, r = 2; if (e % 2 == 0) return 2; do { s = i(s) % e, r = i(i(r)) % e, n = t(Math.abs(s - r), e) } while (1 === n); return n }, t.getBounds = function (e, i, n, s) { var r, a, o, l = 0, h = { high: i.high, low: i.low }; h.valueRange = h.high - h.low, h.oom = t.orderOfMagnitude(h.valueRange), h.step = Math.pow(10, h.oom), h.min = Math.floor(h.low / h.step) * h.step, h.max = Math.ceil(h.high / h.step) * h.step, h.range = h.max - h.min, h.numberOfSteps = Math.round(h.range / h.step); var u = t.projectLength(e, h.step, h) < n, c = s ? t.rho(h.range) : 0; if (s && t.projectLength(e, 1, h) >= n) h.step = 1; else if (s && c < h.step && t.projectLength(e, c, h) >= n) h.step = c; else for (; ;) { if (u && t.projectLength(e, h.step, h) <= n) h.step *= 2; else { if (u || !(t.projectLength(e, h.step / 2, h) >= n)) break; if (h.step /= 2, s && h.step % 1 != 0) { h.step *= 2; break } } if (l++ > 1e3) throw new Error("Exceeded maximum number of iterations while optimizing scale step!") } var d = 2221e-19; function p(e, t) { return e === (e += t) && (e *= 1 + (t > 0 ? d : -d)), e } for (h.step = Math.max(h.step, d), a = h.min, o = h.max; a + h.step <= h.low;)a = p(a, h.step); for (; o - h.step >= h.high;)o = p(o, -h.step); h.min = a, h.max = o, h.range = h.max - h.min; var f = []; for (r = h.min; r <= h.max; r = p(r, h.step)) { var m = t.roundWithPrecision(r); m !== f[f.length - 1] && f.push(m) } return h.values = f, h }, t.polarToCartesian = function (e, t, i, n) { var s = (n - 90) * Math.PI / 180; return { x: e + i * Math.cos(s), y: t + i * Math.sin(s) } }, t.createChartRect = function (e, i, n) { var s = !(!i.axisX && !i.axisY), r = s ? i.axisY.offset : 0, a = s ? i.axisX.offset : 0, o = e.width() || t.quantity(i.width).value || 0, l = e.height() || t.quantity(i.height).value || 0, h = t.normalizePadding(i.chartPadding, n); o = Math.max(o, r + h.left + h.right), l = Math.max(l, a + h.top + h.bottom); var u = { padding: h, width: function () { return this.x2 - this.x1 }, height: function () { return this.y1 - this.y2 } }; return s ? ("start" === i.axisX.position ? (u.y2 = h.top + a, u.y1 = Math.max(l - h.bottom, u.y2 + 1)) : (u.y2 = h.top, u.y1 = Math.max(l - h.bottom - a, u.y2 + 1)), "start" === i.axisY.position ? (u.x1 = h.left + r, u.x2 = Math.max(o - h.right, u.x1 + 1)) : (u.x1 = h.left, u.x2 = Math.max(o - h.right - r, u.x1 + 1))) : (u.x1 = h.left, u.x2 = Math.max(o - h.right, u.x1 + 1), u.y2 = h.top, u.y1 = Math.max(l - h.bottom, u.y2 + 1)), u }, t.createGrid = function (e, i, n, s, r, a, o, l) { var h = {}; h[n.units.pos + "1"] = e, h[n.units.pos + "2"] = e, h[n.counterUnits.pos + "1"] = s, h[n.counterUnits.pos + "2"] = s + r; var u = a.elem("line", h, o.join(" ")); l.emit("draw", t.extend({ type: "grid", axis: n, index: i, group: a, element: u }, h)) }, t.createGridBackground = function (e, t, i, n) { var s = e.elem("rect", { x: t.x1, y: t.y2, width: t.width(), height: t.height() }, i, !0); n.emit("draw", { type: "gridBackground", group: e, element: s }) }, t.createLabel = function (e, i, s, r, a, o, l, h, u, c, d) { var p, f = {}; if (f[a.units.pos] = e + l[a.units.pos], f[a.counterUnits.pos] = l[a.counterUnits.pos], f[a.units.len] = i, f[a.counterUnits.len] = Math.max(0, o - 10), c) { var m = n.createElement("span"); m.className = u.join(" "), m.setAttribute("xmlns", t.namespaces.xhtml), m.innerText = r[s], m.style[a.units.len] = Math.round(f[a.units.len]) + "px", m.style[a.counterUnits.len] = Math.round(f[a.counterUnits.len]) + "px", p = h.foreignObject(m, t.extend({ style: "overflow: visible;" }, f)) } else p = h.elem("text", f, u.join(" ")).text(r[s]); d.emit("draw", t.extend({ type: "label", axis: a, index: s, group: h, element: p, text: r[s] }, f)) }, t.getSeriesOption = function (e, t, i) { if (e.name && t.series && t.series[e.name]) { var n = t.series[e.name]; return n.hasOwnProperty(i) ? n[i] : t[i] } return t[i] }, t.optionsProvider = function (e, n, s) { var r, a, o = t.extend({}, e), l = []; function h(e) { var l = r; if (r = t.extend({}, o), n) for (a = 0; a < n.length; a++) { i.matchMedia(n[a][0]).matches && (r = t.extend(r, n[a][1])) } s && e && s.emit("optionsChanged", { previousOptions: l, currentOptions: r }) } if (!i.matchMedia) throw "window.matchMedia not found! Make sure you're using a polyfill."; if (n) for (a = 0; a < n.length; a++) { var u = i.matchMedia(n[a][0]); u.addListener(h), l.push(u) } return h(), { removeMediaQueryListeners: function () { l.forEach((function (e) { e.removeListener(h) })) }, getCurrentOptions: function () { return t.extend({}, r) } } }, t.splitIntoSegments = function (e, i, n) { n = t.extend({}, { increasingX: !1, fillHoles: !1 }, n); for (var s = [], r = !0, a = 0; a < e.length; a += 2)void 0 === t.getMultiValue(i[a / 2].value) ? n.fillHoles || (r = !0) : (n.increasingX && a >= 2 && e[a] <= e[a - 2] && (r = !0), r && (s.push({ pathCoordinates: [], valueData: [] }), r = !1), s[s.length - 1].pathCoordinates.push(e[a], e[a + 1]), s[s.length - 1].valueData.push(i[a / 2])); return s } }(this || global, e), function (e, t) { "use strict"; t.Interpolation = {}, t.Interpolation.none = function (e) { return e = t.extend({}, { fillHoles: !1 }, e), function (i, n) { for (var s = new t.Svg.Path, r = !0, a = 0; a < i.length; a += 2) { var o = i[a], l = i[a + 1], h = n[a / 2]; void 0 !== t.getMultiValue(h.value) ? (r ? s.move(o, l, !1, h) : s.line(o, l, !1, h), r = !1) : e.fillHoles || (r = !0) } return s } }, t.Interpolation.simple = function (e) { e = t.extend({}, { divisor: 2, fillHoles: !1 }, e); var i = 1 / Math.max(1, e.divisor); return function (n, s) { for (var r, a, o, l = new t.Svg.Path, h = 0; h < n.length; h += 2) { var u = n[h], c = n[h + 1], d = (u - r) * i, p = s[h / 2]; void 0 !== p.value ? (void 0 === o ? l.move(u, c, !1, p) : l.curve(r + d, a, u - d, c, u, c, !1, p), r = u, a = c, o = p) : e.fillHoles || (r = u = o = void 0) } return l } }, t.Interpolation.cardinal = function (e) { e = t.extend({}, { tension: 1, fillHoles: !1 }, e); var i = Math.min(1, Math.max(0, e.tension)), n = 1 - i; return function s(r, a) { var o = t.splitIntoSegments(r, a, { fillHoles: e.fillHoles }); if (o.length) { if (o.length > 1) { var l = []; return o.forEach((function (e) { l.push(s(e.pathCoordinates, e.valueData)) })), t.Svg.Path.join(l) } if (r = o[0].pathCoordinates, a = o[0].valueData, r.length <= 4) return t.Interpolation.none()(r, a); for (var h = (new t.Svg.Path).move(r[0], r[1], !1, a[0]), u = 0, c = r.length; c - 2 > u; u += 2) { var d = [{ x: +r[u - 2], y: +r[u - 1] }, { x: +r[u], y: +r[u + 1] }, { x: +r[u + 2], y: +r[u + 3] }, { x: +r[u + 4], y: +r[u + 5] }]; c - 4 === u ? d[3] = d[2] : u || (d[0] = { x: +r[u], y: +r[u + 1] }), h.curve(i * (-d[0].x + 6 * d[1].x + d[2].x) / 6 + n * d[2].x, i * (-d[0].y + 6 * d[1].y + d[2].y) / 6 + n * d[2].y, i * (d[1].x + 6 * d[2].x - d[3].x) / 6 + n * d[2].x, i * (d[1].y + 6 * d[2].y - d[3].y) / 6 + n * d[2].y, d[2].x, d[2].y, !1, a[(u + 2) / 2]) } return h } return t.Interpolation.none()([]) } }, t.Interpolation.monotoneCubic = function (e) { return e = t.extend({}, { fillHoles: !1 }, e), function i(n, s) { var r = t.splitIntoSegments(n, s, { fillHoles: e.fillHoles, increasingX: !0 }); if (r.length) { if (r.length > 1) { var a = []; return r.forEach((function (e) { a.push(i(e.pathCoordinates, e.valueData)) })), t.Svg.Path.join(a) } if (n = r[0].pathCoordinates, s = r[0].valueData, n.length <= 4) return t.Interpolation.none()(n, s); var o, l, h = [], u = [], c = n.length / 2, d = [], p = [], f = [], m = []; for (o = 0; o < c; o++)h[o] = n[2 * o], u[o] = n[2 * o + 1]; for (o = 0; o < c - 1; o++)f[o] = u[o + 1] - u[o], m[o] = h[o + 1] - h[o], p[o] = f[o] / m[o]; for (d[0] = p[0], d[c - 1] = p[c - 2], o = 1; o < c - 1; o++)0 === p[o] || 0 === p[o - 1] || p[o - 1] > 0 != p[o] > 0 ? d[o] = 0 : (d[o] = 3 * (m[o - 1] + m[o]) / ((2 * m[o] + m[o - 1]) / p[o - 1] + (m[o] + 2 * m[o - 1]) / p[o]), isFinite(d[o]) || (d[o] = 0)); for (l = (new t.Svg.Path).move(h[0], u[0], !1, s[0]), o = 0; o < c - 1; o++)l.curve(h[o] + m[o] / 3, u[o] + d[o] * m[o] / 3, h[o + 1] - m[o] / 3, u[o + 1] - d[o + 1] * m[o] / 3, h[o + 1], u[o + 1], !1, s[o + 1]); return l } return t.Interpolation.none()([]) } }, t.Interpolation.step = function (e) { return e = t.extend({}, { postpone: !0, fillHoles: !1 }, e), function (i, n) { for (var s, r, a, o = new t.Svg.Path, l = 0; l < i.length; l += 2) { var h = i[l], u = i[l + 1], c = n[l / 2]; void 0 !== c.value ? (void 0 === a ? o.move(h, u, !1, c) : (e.postpone ? o.line(h, r, !1, a) : o.line(s, u, !1, c), o.line(h, u, !1, c)), s = h, r = u, a = c) : e.fillHoles || (s = r = a = void 0) } return o } } }(this || global, e), function (e, t) { "use strict"; t.EventEmitter = function () { var e = []; return { addEventHandler: function (t, i) { e[t] = e[t] || [], e[t].push(i) }, removeEventHandler: function (t, i) { e[t] && (i ? (e[t].splice(e[t].indexOf(i), 1), 0 === e[t].length && delete e[t]) : delete e[t]) }, emit: function (t, i) { e[t] && e[t].forEach((function (e) { e(i) })), e["*"] && e["*"].forEach((function (e) { e(t, i) })) } } } }(this || global, e), function (e, t) { "use strict"; t.Class = { extend: function (e, i) { var n = i || this.prototype || t.Class, s = Object.create(n); t.Class.cloneDefinitions(s, e); var r = function () { var e, i = s.constructor || function () { }; return e = this === t ? Object.create(s) : this, i.apply(e, Array.prototype.slice.call(arguments, 0)), e }; return r.prototype = s, r.super = n, r.extend = this.extend, r }, cloneDefinitions: function () { var e = function (e) { var t = []; if (e.length) for (var i = 0; i < e.length; i++)t.push(e[i]); return t }(arguments), t = e[0]; return e.splice(1, e.length - 1).forEach((function (e) { Object.getOwnPropertyNames(e).forEach((function (i) { delete t[i], Object.defineProperty(t, i, Object.getOwnPropertyDescriptor(e, i)) })) })), t } } }(this || global, e), function (e, t) { "use strict"; var i = e.window; function n() { i.addEventListener("resize", this.resizeListener), this.optionsProvider = t.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter), this.eventEmitter.addEventHandler("optionsChanged", function () { this.update() }.bind(this)), this.options.plugins && this.options.plugins.forEach(function (e) { e instanceof Array ? e[0](this, e[1]) : e(this) }.bind(this)), this.eventEmitter.emit("data", { type: "initial", data: this.data }), this.createChart(this.optionsProvider.getCurrentOptions()), this.initializeTimeoutId = void 0 } t.Base = t.Class.extend({ constructor: function (e, i, s, r, a) { this.container = t.querySelector(e), this.data = i || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.defaultOptions = s, this.options = r, this.responsiveOptions = a, this.eventEmitter = t.EventEmitter(), this.supportsForeignObject = t.Svg.isSupported("Extensibility"), this.supportsAnimations = t.Svg.isSupported("AnimationEventsAttribute"), this.resizeListener = function () { this.update() }.bind(this), this.container && (this.container.__chartist__ && this.container.__chartist__.detach(), this.container.__chartist__ = this), this.initializeTimeoutId = setTimeout(n.bind(this), 0) }, optionsProvider: void 0, container: void 0, svg: void 0, eventEmitter: void 0, createChart: function () { throw new Error("Base chart type can't be instantiated!") }, update: function (e, i, n) { return e && (this.data = e || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.eventEmitter.emit("data", { type: "update", data: this.data })), i && (this.options = t.extend({}, n ? this.options : this.defaultOptions, i), this.initializeTimeoutId || (this.optionsProvider.removeMediaQueryListeners(), this.optionsProvider = t.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter))), this.initializeTimeoutId || this.createChart(this.optionsProvider.getCurrentOptions()), this }, detach: function () { return this.initializeTimeoutId ? i.clearTimeout(this.initializeTimeoutId) : (i.removeEventListener("resize", this.resizeListener), this.optionsProvider.removeMediaQueryListeners()), this }, on: function (e, t) { return this.eventEmitter.addEventHandler(e, t), this }, off: function (e, t) { return this.eventEmitter.removeEventHandler(e, t), this }, version: t.version, supportsForeignObject: !1 }) }(this || global, e), function (e, t) { "use strict"; var i = e.document; t.Svg = t.Class.extend({ constructor: function (e, n, s, r, a) { e instanceof Element ? this._node = e : (this._node = i.createElementNS(t.namespaces.svg, e), "svg" === e && this.attr({ "xmlns:ct": t.namespaces.ct })), n && this.attr(n), s && this.addClass(s), r && (a && r._node.firstChild ? r._node.insertBefore(this._node, r._node.firstChild) : r._node.appendChild(this._node)) }, attr: function (e, i) { return "string" == typeof e ? i ? this._node.getAttributeNS(i, e) : this._node.getAttribute(e) : (Object.keys(e).forEach(function (i) { if (void 0 !== e[i]) if (-1 !== i.indexOf(":")) { var n = i.split(":"); this._node.setAttributeNS(t.namespaces[n[0]], i, e[i]) } else this._node.setAttribute(i, e[i]) }.bind(this)), this) }, elem: function (e, i, n, s) { return new t.Svg(e, i, n, this, s) }, parent: function () { return this._node.parentNode instanceof SVGElement ? new t.Svg(this._node.parentNode) : null }, root: function () { for (var e = this._node; "svg" !== e.nodeName;)e = e.parentNode; return new t.Svg(e) }, querySelector: function (e) { var i = this._node.querySelector(e); return i ? new t.Svg(i) : null }, querySelectorAll: function (e) { var i = this._node.querySelectorAll(e); return i.length ? new t.Svg.List(i) : null }, getNode: function () { return this._node }, foreignObject: function (e, n, s, r) { if ("string" == typeof e) { var a = i.createElement("div"); a.innerHTML = e, e = a.firstChild } e.setAttribute("xmlns", t.namespaces.xmlns); var o = this.elem("foreignObject", n, s, r); return o._node.appendChild(e), o }, text: function (e) { return this._node.appendChild(i.createTextNode(e)), this }, empty: function () { for (; this._node.firstChild;)this._node.removeChild(this._node.firstChild); return this }, remove: function () { return this._node.parentNode.removeChild(this._node), this.parent() }, replace: function (e) { return this._node.parentNode.replaceChild(e._node, this._node), e }, append: function (e, t) { return t && this._node.firstChild ? this._node.insertBefore(e._node, this._node.firstChild) : this._node.appendChild(e._node), this }, classes: function () { return this._node.getAttribute("class") ? this._node.getAttribute("class").trim().split(/\s+/) : [] }, addClass: function (e) { return this._node.setAttribute("class", this.classes(this._node).concat(e.trim().split(/\s+/)).filter((function (e, t, i) { return i.indexOf(e) === t })).join(" ")), this }, removeClass: function (e) { var t = e.trim().split(/\s+/); return this._node.setAttribute("class", this.classes(this._node).filter((function (e) { return -1 === t.indexOf(e) })).join(" ")), this }, removeAllClasses: function () { return this._node.setAttribute("class", ""), this }, height: function () { return this._node.getBoundingClientRect().height }, width: function () { return this._node.getBoundingClientRect().width }, animate: function (e, i, n) { return void 0 === i && (i = !0), Object.keys(e).forEach(function (s) { function r(e, i) { var r, a, o, l = {}; e.easing && (o = e.easing instanceof Array ? e.easing : t.Svg.Easing[e.easing], delete e.easing), e.begin = t.ensureUnit(e.begin, "ms"), e.dur = t.ensureUnit(e.dur, "ms"), o && (e.calcMode = "spline", e.keySplines = o.join(" "), e.keyTimes = "0;1"), i && (e.fill = "freeze", l[s] = e.from, this.attr(l), a = t.quantity(e.begin || 0).value, e.begin = "indefinite"), r = this.elem("animate", t.extend({ attributeName: s }, e)), i && setTimeout(function () { try { r._node.beginElement() } catch (t) { l[s] = e.to, this.attr(l), r.remove() } }.bind(this), a), n && r._node.addEventListener("beginEvent", function () { n.emit("animationBegin", { element: this, animate: r._node, params: e }) }.bind(this)), r._node.addEventListener("endEvent", function () { n && n.emit("animationEnd", { element: this, animate: r._node, params: e }), i && (l[s] = e.to, this.attr(l), r.remove()) }.bind(this)) } e[s] instanceof Array ? e[s].forEach(function (e) { r.bind(this)(e, !1) }.bind(this)) : r.bind(this)(e[s], i) }.bind(this)), this } }), t.Svg.isSupported = function (e) { return i.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#" + e, "1.1") }; t.Svg.Easing = { easeInSine: [.47, 0, .745, .715], easeOutSine: [.39, .575, .565, 1], easeInOutSine: [.445, .05, .55, .95], easeInQuad: [.55, .085, .68, .53], easeOutQuad: [.25, .46, .45, .94], easeInOutQuad: [.455, .03, .515, .955], easeInCubic: [.55, .055, .675, .19], easeOutCubic: [.215, .61, .355, 1], easeInOutCubic: [.645, .045, .355, 1], easeInQuart: [.895, .03, .685, .22], easeOutQuart: [.165, .84, .44, 1], easeInOutQuart: [.77, 0, .175, 1], easeInQuint: [.755, .05, .855, .06], easeOutQuint: [.23, 1, .32, 1], easeInOutQuint: [.86, 0, .07, 1], easeInExpo: [.95, .05, .795, .035], easeOutExpo: [.19, 1, .22, 1], easeInOutExpo: [1, 0, 0, 1], easeInCirc: [.6, .04, .98, .335], easeOutCirc: [.075, .82, .165, 1], easeInOutCirc: [.785, .135, .15, .86], easeInBack: [.6, -.28, .735, .045], easeOutBack: [.175, .885, .32, 1.275], easeInOutBack: [.68, -.55, .265, 1.55] }, t.Svg.List = t.Class.extend({ constructor: function (e) { var i = this; this.svgElements = []; for (var n = 0; n < e.length; n++)this.svgElements.push(new t.Svg(e[n])); Object.keys(t.Svg.prototype).filter((function (e) { return -1 === ["constructor", "parent", "querySelector", "querySelectorAll", "replace", "append", "classes", "height", "width"].indexOf(e) })).forEach((function (e) { i[e] = function () { var n = Array.prototype.slice.call(arguments, 0); return i.svgElements.forEach((function (i) { t.Svg.prototype[e].apply(i, n) })), i } })) } }) }(this || global, e), function (e, t) { "use strict"; var i = { m: ["x", "y"], l: ["x", "y"], c: ["x1", "y1", "x2", "y2", "x", "y"], a: ["rx", "ry", "xAr", "lAf", "sf", "x", "y"] }, n = { accuracy: 3 }; function s(e, i, n, s, r, a) { var o = t.extend({ command: r ? e.toLowerCase() : e.toUpperCase() }, i, a ? { data: a } : {}); n.splice(s, 0, o) } function r(e, t) { e.forEach((function (n, s) { i[n.command.toLowerCase()].forEach((function (i, r) { t(n, i, s, r, e) })) })) } t.Svg.Path = t.Class.extend({ constructor: function (e, i) { this.pathElements = [], this.pos = 0, this.close = e, this.options = t.extend({}, n, i) }, position: function (e) { return void 0 !== e ? (this.pos = Math.max(0, Math.min(this.pathElements.length, e)), this) : this.pos }, remove: function (e) { return this.pathElements.splice(this.pos, e), this }, move: function (e, t, i, n) { return s("M", { x: +e, y: +t }, this.pathElements, this.pos++, i, n), this }, line: function (e, t, i, n) { return s("L", { x: +e, y: +t }, this.pathElements, this.pos++, i, n), this }, curve: function (e, t, i, n, r, a, o, l) { return s("C", { x1: +e, y1: +t, x2: +i, y2: +n, x: +r, y: +a }, this.pathElements, this.pos++, o, l), this }, arc: function (e, t, i, n, r, a, o, l, h) { return s("A", { rx: +e, ry: +t, xAr: +i, lAf: +n, sf: +r, x: +a, y: +o }, this.pathElements, this.pos++, l, h), this }, scale: function (e, t) { return r(this.pathElements, (function (i, n) { i[n] *= "x" === n[0] ? e : t })), this }, translate: function (e, t) { return r(this.pathElements, (function (i, n) { i[n] += "x" === n[0] ? e : t })), this }, transform: function (e) { return r(this.pathElements, (function (t, i, n, s, r) { var a = e(t, i, n, s, r); (a || 0 === a) && (t[i] = a) })), this }, parse: function (e) { var n = e.replace(/([A-Za-z])([0-9])/g, "$1 $2").replace(/([0-9])([A-Za-z])/g, "$1 $2").split(/[\s,]+/).reduce((function (e, t) { return t.match(/[A-Za-z]/) && e.push([]), e[e.length - 1].push(t), e }), []); "Z" === n[n.length - 1][0].toUpperCase() && n.pop(); var s = n.map((function (e) { var n = e.shift(), s = i[n.toLowerCase()]; return t.extend({ command: n }, s.reduce((function (t, i, n) { return t[i] = +e[n], t }), {})) })), r = [this.pos, 0]; return Array.prototype.push.apply(r, s), Array.prototype.splice.apply(this.pathElements, r), this.pos += s.length, this }, stringify: function () { var e = Math.pow(10, this.options.accuracy); return this.pathElements.reduce(function (t, n) { var s = i[n.command.toLowerCase()].map(function (t) { return this.options.accuracy ? Math.round(n[t] * e) / e : n[t] }.bind(this)); return t + n.command + s.join(",") }.bind(this), "") + (this.close ? "Z" : "") }, clone: function (e) { var i = new t.Svg.Path(e || this.close); return i.pos = this.pos, i.pathElements = this.pathElements.slice().map((function (e) { return t.extend({}, e) })), i.options = t.extend({}, this.options), i }, splitByCommand: function (e) { var i = [new t.Svg.Path]; return this.pathElements.forEach((function (n) { n.command === e.toUpperCase() && 0 !== i[i.length - 1].pathElements.length && i.push(new t.Svg.Path), i[i.length - 1].pathElements.push(n) })), i } }), t.Svg.Path.elementDescriptions = i, t.Svg.Path.join = function (e, i, n) { for (var s = new t.Svg.Path(i, n), r = 0; r < e.length; r++)for (var a = e[r], o = 0; o < a.pathElements.length; o++)s.pathElements.push(a.pathElements[o]); return s } }(this || global, e), function (e, t) { "use strict"; e.window, e.document; var i = { x: { pos: "x", len: "width", dir: "horizontal", rectStart: "x1", rectEnd: "x2", rectOffset: "y2" }, y: { pos: "y", len: "height", dir: "vertical", rectStart: "y2", rectEnd: "y1", rectOffset: "x1" } }; t.Axis = t.Class.extend({ constructor: function (e, t, n, s) { this.units = e, this.counterUnits = e === i.x ? i.y : i.x, this.chartRect = t, this.axisLength = t[e.rectEnd] - t[e.rectStart], this.gridOffset = t[e.rectOffset], this.ticks = n, this.options = s }, createGridAndLabels: function (e, i, n, s, r) { var a = s["axis" + this.units.pos.toUpperCase()], o = this.ticks.map(this.projectValue.bind(this)), l = this.ticks.map(a.labelInterpolationFnc); o.forEach(function (h, u) { var c, d = { x: 0, y: 0 }; c = o[u + 1] ? o[u + 1] - h : Math.max(this.axisLength - h, 30), t.isFalseyButZero(l[u]) && "" !== l[u] || ("x" === this.units.pos ? (h = this.chartRect.x1 + h, d.x = s.axisX.labelOffset.x, "start" === s.axisX.position ? d.y = this.chartRect.padding.top + s.axisX.labelOffset.y + (n ? 5 : 20) : d.y = this.chartRect.y1 + s.axisX.labelOffset.y + (n ? 5 : 20)) : (h = this.chartRect.y1 - h, d.y = s.axisY.labelOffset.y - (n ? c : 0), "start" === s.axisY.position ? d.x = n ? this.chartRect.padding.left + s.axisY.labelOffset.x : this.chartRect.x1 - 10 : d.x = this.chartRect.x2 + s.axisY.labelOffset.x + 10), a.showGrid && t.createGrid(h, u, this, this.gridOffset, this.chartRect[this.counterUnits.len](), e, [s.classNames.grid, s.classNames[this.units.dir]], r), a.showLabel && t.createLabel(h, c, u, l, this, a.offset, d, i, [s.classNames.label, s.classNames[this.units.dir], "start" === a.position ? s.classNames[a.position] : s.classNames.end], n, r)) }.bind(this)) }, projectValue: function (e, t, i) { throw new Error("Base axis can't be instantiated!") } }), t.Axis.units = i }(this || global, e), function (e, t) { "use strict"; e.window, e.document; t.AutoScaleAxis = t.Axis.extend({ constructor: function (e, i, n, s) { var r = s.highLow || t.getHighLow(i, s, e.pos); this.bounds = t.getBounds(n[e.rectEnd] - n[e.rectStart], r, s.scaleMinSpace || 20, s.onlyInteger), this.range = { min: this.bounds.min, max: this.bounds.max }, t.AutoScaleAxis.super.constructor.call(this, e, n, this.bounds.values, s) }, projectValue: function (e) { return this.axisLength * (+t.getMultiValue(e, this.units.pos) - this.bounds.min) / this.bounds.range } }) }(this || global, e), function (e, t) { "use strict"; e.window, e.document; t.FixedScaleAxis = t.Axis.extend({ constructor: function (e, i, n, s) { var r = s.highLow || t.getHighLow(i, s, e.pos); this.divisor = s.divisor || 1, this.ticks = s.ticks || t.times(this.divisor).map(function (e, t) { return r.low + (r.high - r.low) / this.divisor * t }.bind(this)), this.ticks.sort((function (e, t) { return e - t })), this.range = { min: r.low, max: r.high }, t.FixedScaleAxis.super.constructor.call(this, e, n, this.ticks, s), this.stepLength = this.axisLength / this.divisor }, projectValue: function (e) { return this.axisLength * (+t.getMultiValue(e, this.units.pos) - this.range.min) / (this.range.max - this.range.min) } }) }(this || global, e), function (e, t) { "use strict"; e.window, e.document; t.StepAxis = t.Axis.extend({ constructor: function (e, i, n, s) { t.StepAxis.super.constructor.call(this, e, n, s.ticks, s); var r = Math.max(1, s.ticks.length - (s.stretch ? 1 : 0)); this.stepLength = this.axisLength / r }, projectValue: function (e, t) { return this.stepLength * t } }) }(this || global, e), function (e, t) { "use strict"; e.window, e.document; var i = { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: t.noop, type: void 0 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: t.noop, type: void 0, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, showLine: !0, showPoint: !0, showArea: !1, areaBase: 0, lineSmooth: !0, showGridBackground: !1, low: void 0, high: void 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, fullWidth: !1, reverseData: !1, classNames: { chart: "ct-chart-line", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", line: "ct-line", point: "ct-point", area: "ct-area", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }; t.Line = t.Base.extend({ constructor: function (e, n, s, r) { t.Line.super.constructor.call(this, e, n, i, t.extend({}, i, s), r) }, createChart: function (e) { var n = t.normalizeData(this.data, e.reverseData, !0); this.svg = t.createSvg(this.container, e.width, e.height, e.classNames.chart); var s, r, a = this.svg.elem("g").addClass(e.classNames.gridGroup), o = this.svg.elem("g"), l = this.svg.elem("g").addClass(e.classNames.labelGroup), h = t.createChartRect(this.svg, e, i.padding); s = void 0 === e.axisX.type ? new t.StepAxis(t.Axis.units.x, n.normalized.series, h, t.extend({}, e.axisX, { ticks: n.normalized.labels, stretch: e.fullWidth })) : e.axisX.type.call(t, t.Axis.units.x, n.normalized.series, h, e.axisX), r = void 0 === e.axisY.type ? new t.AutoScaleAxis(t.Axis.units.y, n.normalized.series, h, t.extend({}, e.axisY, { high: t.isNumeric(e.high) ? e.high : e.axisY.high, low: t.isNumeric(e.low) ? e.low : e.axisY.low })) : e.axisY.type.call(t, t.Axis.units.y, n.normalized.series, h, e.axisY), s.createGridAndLabels(a, l, this.supportsForeignObject, e, this.eventEmitter), r.createGridAndLabels(a, l, this.supportsForeignObject, e, this.eventEmitter), e.showGridBackground && t.createGridBackground(a, h, e.classNames.gridBackground, this.eventEmitter), n.raw.series.forEach(function (i, a) { var l = o.elem("g"); l.attr({ "ct:series-name": i.name, "ct:meta": t.serialize(i.meta) }), l.addClass([e.classNames.series, i.className || e.classNames.series + "-" + t.alphaNumerate(a)].join(" ")); var u = [], c = []; n.normalized.series[a].forEach(function (e, o) { var l = { x: h.x1 + s.projectValue(e, o, n.normalized.series[a]), y: h.y1 - r.projectValue(e, o, n.normalized.series[a]) }; u.push(l.x, l.y), c.push({ value: e, valueIndex: o, meta: t.getMetaData(i, o) }) }.bind(this)); var d = { lineSmooth: t.getSeriesOption(i, e, "lineSmooth"), showPoint: t.getSeriesOption(i, e, "showPoint"), showLine: t.getSeriesOption(i, e, "showLine"), showArea: t.getSeriesOption(i, e, "showArea"), areaBase: t.getSeriesOption(i, e, "areaBase") }, p = ("function" == typeof d.lineSmooth ? d.lineSmooth : d.lineSmooth ? t.Interpolation.monotoneCubic() : t.Interpolation.none())(u, c); if (d.showPoint && p.pathElements.forEach(function (n) { var o = l.elem("line", { x1: n.x, y1: n.y, x2: n.x + .01, y2: n.y }, e.classNames.point).attr({ "ct:value": [n.data.value.x, n.data.value.y].filter(t.isNumeric).join(","), "ct:meta": t.serialize(n.data.meta) }); this.eventEmitter.emit("draw", { type: "point", value: n.data.value, index: n.data.valueIndex, meta: n.data.meta, series: i, seriesIndex: a, axisX: s, axisY: r, group: l, element: o, x: n.x, y: n.y }) }.bind(this)), d.showLine) { var f = l.elem("path", { d: p.stringify() }, e.classNames.line, !0); this.eventEmitter.emit("draw", { type: "line", values: n.normalized.series[a], path: p.clone(), chartRect: h, index: a, series: i, seriesIndex: a, seriesMeta: i.meta, axisX: s, axisY: r, group: l, element: f }) } if (d.showArea && r.range) { var m = Math.max(Math.min(d.areaBase, r.range.max), r.range.min), g = h.y1 - r.projectValue(m); p.splitByCommand("M").filter((function (e) { return e.pathElements.length > 1 })).map((function (e) { var t = e.pathElements[0], i = e.pathElements[e.pathElements.length - 1]; return e.clone(!0).position(0).remove(1).move(t.x, g).line(t.x, t.y).position(e.pathElements.length + 1).line(i.x, g) })).forEach(function (t) { var o = l.elem("path", { d: t.stringify() }, e.classNames.area, !0); this.eventEmitter.emit("draw", { type: "area", values: n.normalized.series[a], path: t.clone(), series: i, seriesIndex: a, axisX: s, axisY: r, chartRect: h, index: a, group: l, element: o }) }.bind(this)) } }.bind(this)), this.eventEmitter.emit("created", { bounds: r.bounds, chartRect: h, axisX: s, axisY: r, svg: this.svg, options: e }) } }) }(this || global, e), function (e, t) { "use strict"; e.window, e.document; var i = { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: t.noop, scaleMinSpace: 30, onlyInteger: !1 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: t.noop, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, high: void 0, low: void 0, referenceValue: 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, seriesBarDistance: 15, stackBars: !1, stackMode: "accumulate", horizontalBars: !1, distributeSeries: !1, reverseData: !1, showGridBackground: !1, classNames: { chart: "ct-chart-bar", horizontalBars: "ct-horizontal-bars", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", bar: "ct-bar", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }; t.Bar = t.Base.extend({ constructor: function (e, n, s, r) { t.Bar.super.constructor.call(this, e, n, i, t.extend({}, i, s), r) }, createChart: function (e) { var n, s; e.distributeSeries ? (n = t.normalizeData(this.data, e.reverseData, e.horizontalBars ? "x" : "y")).normalized.series = n.normalized.series.map((function (e) { return [e] })) : n = t.normalizeData(this.data, e.reverseData, e.horizontalBars ? "x" : "y"), this.svg = t.createSvg(this.container, e.width, e.height, e.classNames.chart + (e.horizontalBars ? " " + e.classNames.horizontalBars : "")); var r = this.svg.elem("g").addClass(e.classNames.gridGroup), a = this.svg.elem("g"), o = this.svg.elem("g").addClass(e.classNames.labelGroup); if (e.stackBars && 0 !== n.normalized.series.length) { var l = t.serialMap(n.normalized.series, (function () { return Array.prototype.slice.call(arguments).map((function (e) { return e })).reduce((function (e, t) { return { x: e.x + (t && t.x) || 0, y: e.y + (t && t.y) || 0 } }), { x: 0, y: 0 }) })); s = t.getHighLow([l], e, e.horizontalBars ? "x" : "y") } else s = t.getHighLow(n.normalized.series, e, e.horizontalBars ? "x" : "y"); s.high = +e.high || (0 === e.high ? 0 : s.high), s.low = +e.low || (0 === e.low ? 0 : s.low); var h, u, c, d, p, f = t.createChartRect(this.svg, e, i.padding); u = e.distributeSeries && e.stackBars ? n.normalized.labels.slice(0, 1) : n.normalized.labels, e.horizontalBars ? (h = d = void 0 === e.axisX.type ? new t.AutoScaleAxis(t.Axis.units.x, n.normalized.series, f, t.extend({}, e.axisX, { highLow: s, referenceValue: 0 })) : e.axisX.type.call(t, t.Axis.units.x, n.normalized.series, f, t.extend({}, e.axisX, { highLow: s, referenceValue: 0 })), c = p = void 0 === e.axisY.type ? new t.StepAxis(t.Axis.units.y, n.normalized.series, f, { ticks: u }) : e.axisY.type.call(t, t.Axis.units.y, n.normalized.series, f, e.axisY)) : (c = d = void 0 === e.axisX.type ? new t.StepAxis(t.Axis.units.x, n.normalized.series, f, { ticks: u }) : e.axisX.type.call(t, t.Axis.units.x, n.normalized.series, f, e.axisX), h = p = void 0 === e.axisY.type ? new t.AutoScaleAxis(t.Axis.units.y, n.normalized.series, f, t.extend({}, e.axisY, { highLow: s, referenceValue: 0 })) : e.axisY.type.call(t, t.Axis.units.y, n.normalized.series, f, t.extend({}, e.axisY, { highLow: s, referenceValue: 0 }))); var m = e.horizontalBars ? f.x1 + h.projectValue(0) : f.y1 - h.projectValue(0), g = []; c.createGridAndLabels(r, o, this.supportsForeignObject, e, this.eventEmitter), h.createGridAndLabels(r, o, this.supportsForeignObject, e, this.eventEmitter), e.showGridBackground && t.createGridBackground(r, f, e.classNames.gridBackground, this.eventEmitter), n.raw.series.forEach(function (i, s) { var r, o, l = s - (n.raw.series.length - 1) / 2; r = e.distributeSeries && !e.stackBars ? c.axisLength / n.normalized.series.length / 2 : e.distributeSeries && e.stackBars ? c.axisLength / 2 : c.axisLength / n.normalized.series[s].length / 2, (o = a.elem("g")).attr({ "ct:series-name": i.name, "ct:meta": t.serialize(i.meta) }), o.addClass([e.classNames.series, i.className || e.classNames.series + "-" + t.alphaNumerate(s)].join(" ")), n.normalized.series[s].forEach(function (a, u) { var v, x, y, b; if (b = e.distributeSeries && !e.stackBars ? s : e.distributeSeries && e.stackBars ? 0 : u, v = e.horizontalBars ? { x: f.x1 + h.projectValue(a && a.x ? a.x : 0, u, n.normalized.series[s]), y: f.y1 - c.projectValue(a && a.y ? a.y : 0, b, n.normalized.series[s]) } : { x: f.x1 + c.projectValue(a && a.x ? a.x : 0, b, n.normalized.series[s]), y: f.y1 - h.projectValue(a && a.y ? a.y : 0, u, n.normalized.series[s]) }, c instanceof t.StepAxis && (c.options.stretch || (v[c.units.pos] += r * (e.horizontalBars ? -1 : 1)), v[c.units.pos] += e.stackBars || e.distributeSeries ? 0 : l * e.seriesBarDistance * (e.horizontalBars ? -1 : 1)), y = g[u] || m, g[u] = y - (m - v[c.counterUnits.pos]), void 0 !== a) { var w = {}; w[c.units.pos + "1"] = v[c.units.pos], w[c.units.pos + "2"] = v[c.units.pos], !e.stackBars || "accumulate" !== e.stackMode && e.stackMode ? (w[c.counterUnits.pos + "1"] = m, w[c.counterUnits.pos + "2"] = v[c.counterUnits.pos]) : (w[c.counterUnits.pos + "1"] = y, w[c.counterUnits.pos + "2"] = g[u]), w.x1 = Math.min(Math.max(w.x1, f.x1), f.x2), w.x2 = Math.min(Math.max(w.x2, f.x1), f.x2), w.y1 = Math.min(Math.max(w.y1, f.y2), f.y1), w.y2 = Math.min(Math.max(w.y2, f.y2), f.y1); var E = t.getMetaData(i, u); x = o.elem("line", w, e.classNames.bar).attr({ "ct:value": [a.x, a.y].filter(t.isNumeric).join(","), "ct:meta": t.serialize(E) }), this.eventEmitter.emit("draw", t.extend({ type: "bar", value: a, index: u, meta: E, series: i, seriesIndex: s, axisX: d, axisY: p, chartRect: f, group: o, element: x }, w)) } }.bind(this)) }.bind(this)), this.eventEmitter.emit("created", { bounds: h.bounds, chartRect: f, axisX: d, axisY: p, svg: this.svg, options: e }) } }) }(this || global, e), function (e, t) { "use strict"; e.window, e.document; var i = { width: void 0, height: void 0, chartPadding: 5, classNames: { chartPie: "ct-chart-pie", chartDonut: "ct-chart-donut", series: "ct-series", slicePie: "ct-slice-pie", sliceDonut: "ct-slice-donut", sliceDonutSolid: "ct-slice-donut-solid", label: "ct-label" }, startAngle: 0, total: void 0, donut: !1, donutSolid: !1, donutWidth: 60, showLabel: !0, labelOffset: 0, labelPosition: "inside", labelInterpolationFnc: t.noop, labelDirection: "neutral", reverseData: !1, ignoreEmptyValues: !1 }; function n(e, t, i) { var n = t.x > e.x; return n && "explode" === i || !n && "implode" === i ? "start" : n && "implode" === i || !n && "explode" === i ? "end" : "middle" } t.Pie = t.Base.extend({ constructor: function (e, n, s, r) { t.Pie.super.constructor.call(this, e, n, i, t.extend({}, i, s), r) }, createChart: function (e) { var s, r, a, o, l, h = t.normalizeData(this.data), u = [], c = e.startAngle; this.svg = t.createSvg(this.container, e.width, e.height, e.donut ? e.classNames.chartDonut : e.classNames.chartPie), r = t.createChartRect(this.svg, e, i.padding), a = Math.min(r.width() / 2, r.height() / 2), l = e.total || h.normalized.series.reduce((function (e, t) { return e + t }), 0); var d = t.quantity(e.donutWidth); "%" === d.unit && (d.value *= a / 100), a -= e.donut && !e.donutSolid ? d.value / 2 : 0, o = "outside" === e.labelPosition || e.donut && !e.donutSolid ? a : "center" === e.labelPosition ? 0 : e.donutSolid ? a - d.value / 2 : a / 2, o += e.labelOffset; var p = { x: r.x1 + r.width() / 2, y: r.y2 + r.height() / 2 }, f = 1 === h.raw.series.filter((function (e) { return e.hasOwnProperty("value") ? 0 !== e.value : 0 !== e })).length; h.raw.series.forEach(function (e, t) { u[t] = this.svg.elem("g", null, null) }.bind(this)), e.showLabel && (s = this.svg.elem("g", null, null)), h.raw.series.forEach(function (i, r) { if (0 !== h.normalized.series[r] || !e.ignoreEmptyValues) { u[r].attr({ "ct:series-name": i.name }), u[r].addClass([e.classNames.series, i.className || e.classNames.series + "-" + t.alphaNumerate(r)].join(" ")); var m = l > 0 ? c + h.normalized.series[r] / l * 360 : 0, g = Math.max(0, c - (0 === r || f ? 0 : .2)); m - g >= 359.99 && (m = g + 359.99); var v, x, y, b = t.polarToCartesian(p.x, p.y, a, g), w = t.polarToCartesian(p.x, p.y, a, m), E = new t.Svg.Path(!e.donut || e.donutSolid).move(w.x, w.y).arc(a, a, 0, m - c > 180, 0, b.x, b.y); e.donut ? e.donutSolid && (y = a - d.value, v = t.polarToCartesian(p.x, p.y, y, c - (0 === r || f ? 0 : .2)), x = t.polarToCartesian(p.x, p.y, y, m), E.line(v.x, v.y), E.arc(y, y, 0, m - c > 180, 1, x.x, x.y)) : E.line(p.x, p.y); var S = e.classNames.slicePie; e.donut && (S = e.classNames.sliceDonut, e.donutSolid && (S = e.classNames.sliceDonutSolid)); var A = u[r].elem("path", { d: E.stringify() }, S); if (A.attr({ "ct:value": h.normalized.series[r], "ct:meta": t.serialize(i.meta) }), e.donut && !e.donutSolid && (A._node.style.strokeWidth = d.value + "px"), this.eventEmitter.emit("draw", { type: "slice", value: h.normalized.series[r], totalDataSum: l, index: r, meta: i.meta, series: i, group: u[r], element: A, path: E.clone(), center: p, radius: a, startAngle: c, endAngle: m }), e.showLabel) { var z, M; z = 1 === h.raw.series.length ? { x: p.x, y: p.y } : t.polarToCartesian(p.x, p.y, o, c + (m - c) / 2), M = h.normalized.labels && !t.isFalseyButZero(h.normalized.labels[r]) ? h.normalized.labels[r] : h.normalized.series[r]; var O = e.labelInterpolationFnc(M, r); if (O || 0 === O) { var C = s.elem("text", { dx: z.x, dy: z.y, "text-anchor": n(p, z, e.labelDirection) }, e.classNames.label).text("" + O); this.eventEmitter.emit("draw", { type: "label", index: r, group: s, element: C, text: "" + O, x: z.x, y: z.y }) } } c = m } }.bind(this)), this.eventEmitter.emit("created", { chartRect: r, svg: this.svg, options: e }) }, determineAnchorPosition: n }) }(this || global, e), e })); + +var i, l, selectedLine = null; + +/* Navigate to hash without browser history entry */ +var navigateToHash = function () { + if (window.history !== undefined && window.history.replaceState !== undefined) { + window.history.replaceState(undefined, undefined, this.getAttribute("href")); + } +}; + +var hashLinks = document.getElementsByClassName('navigatetohash'); +for (i = 0, l = hashLinks.length; i < l; i++) { + hashLinks[i].addEventListener('click', navigateToHash); +} + +/* Switch test method */ +var switchTestMethod = function () { + var method = this.getAttribute("value"); + console.log("Selected test method: " + method); + + var lines, i, l, coverageData, lineAnalysis, cells; + + lines = document.querySelectorAll('.lineAnalysis tr'); + + for (i = 1, l = lines.length; i < l; i++) { + coverageData = JSON.parse(lines[i].getAttribute('data-coverage').replace(/'/g, '"')); + lineAnalysis = coverageData[method]; + cells = lines[i].querySelectorAll('td'); + if (lineAnalysis === undefined) { + lineAnalysis = coverageData.AllTestMethods; + if (lineAnalysis.LVS !== 'gray') { + cells[0].setAttribute('class', 'red'); + cells[1].innerText = cells[1].textContent = '0'; + cells[4].setAttribute('class', 'lightred'); + } + } else { + cells[0].setAttribute('class', lineAnalysis.LVS); + cells[1].innerText = cells[1].textContent = lineAnalysis.VC; + cells[4].setAttribute('class', 'light' + lineAnalysis.LVS); + } + } +}; + +var testMethods = document.getElementsByClassName('switchtestmethod'); +for (i = 0, l = testMethods.length; i < l; i++) { + testMethods[i].addEventListener('change', switchTestMethod); +} + +/* Highlight test method by line */ +var toggleLine = function () { + if (selectedLine === this) { + selectedLine = null; + } else { + selectedLine = null; + unhighlightTestMethods(); + highlightTestMethods.call(this); + selectedLine = this; + } + +}; +var highlightTestMethods = function () { + if (selectedLine !== null) { + return; + } + + var lineAnalysis; + var coverageData = JSON.parse(this.getAttribute('data-coverage').replace(/'/g, '"')); + var testMethods = document.getElementsByClassName('testmethod'); + + for (i = 0, l = testMethods.length; i < l; i++) { + lineAnalysis = coverageData[testMethods[i].id]; + if (lineAnalysis === undefined) { + testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, ""); + } else { + testMethods[i].className += ' light' + lineAnalysis.LVS; + } + } +}; +var unhighlightTestMethods = function () { + if (selectedLine !== null) { + return; + } + + var testMethods = document.getElementsByClassName('testmethod'); + for (i = 0, l = testMethods.length; i < l; i++) { + testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, ""); + } +}; +var coverableLines = document.getElementsByClassName('coverableline'); +for (i = 0, l = coverableLines.length; i < l; i++) { + coverableLines[i].addEventListener('click', toggleLine); + coverableLines[i].addEventListener('mouseenter', highlightTestMethods); + coverableLines[i].addEventListener('mouseleave', unhighlightTestMethods); +} + +/* History charts */ +var renderChart = function (chart) { + // Remove current children (e.g. PNG placeholder) + while (chart.firstChild) { + chart.firstChild.remove(); + } + + var chartData = window[chart.getAttribute('data-data')]; + var options = { + axisY: { + type: undefined, + onlyInteger: true + }, + lineSmooth: false, + low: 0, + high: 100, + scaleMinSpace: 20, + onlyInteger: true, + fullWidth: true + }; + var lineChart = new Chartist.Line(chart, { + labels: [], + series: chartData.series + }, options); + + /* Zoom */ + var zoomButtonDiv = document.createElement("div"); + zoomButtonDiv.className = "toggleZoom"; + var zoomButtonLink = document.createElement("a"); + zoomButtonLink.setAttribute("href", ""); + var zoomButtonText = document.createElement("i"); + zoomButtonText.className = "icon-search-plus"; + + zoomButtonLink.appendChild(zoomButtonText); + zoomButtonDiv.appendChild(zoomButtonLink); + + chart.appendChild(zoomButtonDiv); + + zoomButtonDiv.addEventListener('click', function (event) { + event.preventDefault(); + + if (options.axisY.type === undefined) { + options.axisY.type = Chartist.AutoScaleAxis; + zoomButtonText.className = "icon-search-minus"; + } else { + options.axisY.type = undefined; + zoomButtonText.className = "icon-search-plus"; + } + + lineChart.update(null, options); + }); + + var tooltip = document.createElement("div"); + tooltip.className = "tooltip"; + + chart.appendChild(tooltip); + + /* Tooltips */ + var showToolTip = function () { + var index = this.getAttribute('ct:meta'); + + tooltip.innerHTML = chartData.tooltips[index]; + tooltip.style.display = 'block'; + }; + + var moveToolTip = function (event) { + var box = chart.getBoundingClientRect(); + var left = event.pageX - box.left - window.pageXOffset; + var top = event.pageY - box.top - window.pageYOffset; + + left = left + 20; + top = top - tooltip.offsetHeight / 2; + + if (left + tooltip.offsetWidth > box.width) { + left -= tooltip.offsetWidth + 40; + } + + if (top < 0) { + top = 0; + } + + if (top + tooltip.offsetHeight > box.height) { + top = box.height - tooltip.offsetHeight; + } + + tooltip.style.left = left + 'px'; + tooltip.style.top = top + 'px'; + }; + + var hideToolTip = function () { + tooltip.style.display = 'none'; + }; + chart.addEventListener('mousemove', moveToolTip); + + lineChart.on('created', function () { + var chartPoints = chart.getElementsByClassName('ct-point'); + for (i = 0, l = chartPoints.length; i < l; i++) { + chartPoints[i].addEventListener('mousemove', showToolTip); + chartPoints[i].addEventListener('mouseout', hideToolTip); + } + }); +}; + +var charts = document.getElementsByClassName('historychart'); +for (i = 0, l = charts.length; i < l; i++) { + renderChart(charts[i]); +} + +var assemblies = [ + { + "name": "ExchangeRateUpdater.Abstraction", + "classes": [ + { "name": "ExchangeRateUpdater.Abstraction.Model.Currency", "rp": "ExchangeRateUpdater.Abstraction_Currency.html", "cl": 18, "ucl": 0, "cal": 18, "tl": 48, "cb": 7, "tb": 8, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + { "name": "ExchangeRateUpdater.Abstraction.Model.ExchangeRate", "rp": "ExchangeRateUpdater.Abstraction_ExchangeRate.html", "cl": 16, "ucl": 0, "cal": 16, "tl": 55, "cb": 2, "tb": 2, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + ]}, + { + "name": "ExchangeRateUpdater.Api", + "classes": [ + { "name": "ExchangeRateUpdater.Api.Controllers.ExchangeRateController", "rp": "ExchangeRateUpdater.Api_ExchangeRateController.html", "cl": 13, "ucl": 0, "cal": 13, "tl": 31, "cb": 2, "tb": 2, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + { "name": "ExchangeRateUpdater.Api.Middleware.ExceptionHandlingMiddleware", "rp": "ExchangeRateUpdater.Api_ExceptionHandlingMiddleware.html", "cl": 12, "ucl": 18, "cal": 30, "tl": 70, "cb": 0, "tb": 4, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + { "name": "Microsoft.AspNetCore.OpenApi.Generated", "rp": "ExchangeRateUpdater.Api_Generated.html", "cl": 0, "ucl": 374, "cal": 374, "tl": 592, "cb": 0, "tb": 206, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + { "name": "Program", "rp": "ExchangeRateUpdater.Api_Program.html", "cl": 26, "ucl": 4, "cal": 30, "tl": 55, "cb": 2, "tb": 2, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + { "name": "System.Runtime.CompilerServices", "rp": "ExchangeRateUpdater.Api_CompilerServices.html", "cl": 0, "ucl": 3, "cal": 3, "tl": 23, "cb": 0, "tb": 0, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + ]}, + { + "name": "ExchangeRateUpdater.CbnApiClient", + "classes": [ + { "name": "ExchangeRateUpdater.CbnApiClient.Implementation.ExchangeRateCnbApiClient", "rp": "ExchangeRateUpdater.CbnApiClient_ExchangeRateCnbApiClient.html", "cl": 31, "ucl": 1, "cal": 32, "tl": 68, "cb": 8, "tb": 10, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + { "name": "ExchangeRateUpdater.CbnApiClient.Mapper.CnbExchangeRateMapperExtensions", "rp": "ExchangeRateUpdater.CbnApiClient_CnbExchangeRateMapperExtensions.html", "cl": 15, "ucl": 0, "cal": 15, "tl": 53, "cb": 2, "tb": 2, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + ]}, + { + "name": "ExchangeRateUpdater.DependencyInjection", + "classes": [ + { "name": "ExchangeRateUpdater.DependencyInjection.ExchangeRateCnbServicesExtension", "rp": "ExchangeRateUpdater.DependencyInjection_ExchangeRateCnbServicesExtension.html", "cl": 11, "ucl": 1, "cal": 12, "tl": 37, "cb": 0, "tb": 0, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + ]}, + { + "name": "ExchangeRateUpdater.Service", + "classes": [ + { "name": "ExchangeRateUpdater.Service.ExchangeRateProvider", "rp": "ExchangeRateUpdater.Service_ExchangeRateProvider.html", "cl": 25, "ucl": 3, "cal": 28, "tl": 59, "cb": 5, "tb": 8, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + { "name": "ExchangeRateUpdater.Service.ExchangeRateService", "rp": "ExchangeRateUpdater.Service_ExchangeRateService.html", "cl": 21, "ucl": 0, "cal": 21, "tl": 49, "cb": 4, "tb": 4, "cm": 0, "fcm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "mfch": [], "hc": [], "metrics": { } }, + ]}, +]; + +var metrics = [{ "name": "Crap Score", "abbreviation": "crp", "explanationUrl": "https://googletesting.blogspot.de/2011/02/this-code-is-crap.html" }, { "name": "Cyclomatic complexity", "abbreviation": "cc", "explanationUrl": "https://en.wikipedia.org/wiki/Cyclomatic_complexity" }, { "name": "Line coverage", "abbreviation": "cov", "explanationUrl": "https://en.wikipedia.org/wiki/Code_coverage" }, { "name": "Branch coverage", "abbreviation": "bcov", "explanationUrl": "https://en.wikipedia.org/wiki/Code_coverage" }]; + +var historicCoverageExecutionTimes = []; + +var riskHotspotMetrics = [ + { "name": "Crap Score", "explanationUrl": "https://googletesting.blogspot.de/2011/02/this-code-is-crap.html" }, + { "name": "Cyclomatic complexity", "explanationUrl": "https://en.wikipedia.org/wiki/Cyclomatic_complexity" }, +]; + +var riskHotspots = [ + { + "assembly": "ExchangeRateUpdater.Api", "class": "Microsoft.AspNetCore.OpenApi.Generated", "reportPath": "ExchangeRateUpdater.Api_Generated.html", "methodName": "TransformAsync(Microsoft.OpenApi.OpenApiOperation,Microsoft.AspNetCore.OpenApi.OpenApiOperationTransformerContext,System.Threading.CancellationToken)", "methodShortName": "TransformAsync(...)", "fileIndex": 0, "line": 345, + "metrics": [ + { "value": 8930, "exceeded": true }, + { "value": 94, "exceeded": true }, + ]}, + { + "assembly": "ExchangeRateUpdater.Api", "class": "Microsoft.AspNetCore.OpenApi.Generated", "reportPath": "ExchangeRateUpdater.Api_Generated.html", "methodName": "TransformAsync(Microsoft.OpenApi.OpenApiSchema,Microsoft.AspNetCore.OpenApi.OpenApiSchemaTransformerContext,System.Threading.CancellationToken)", "methodShortName": "TransformAsync(...)", "fileIndex": 0, "line": 511, + "metrics": [ + { "value": 1190, "exceeded": true }, + { "value": 34, "exceeded": true }, + ]}, + { + "assembly": "ExchangeRateUpdater.Api", "class": "Microsoft.AspNetCore.OpenApi.Generated", "reportPath": "ExchangeRateUpdater.Api_Generated.html", "methodName": "GetTypeDocId(System.Type,System.Boolean,System.Boolean)", "methodShortName": "GetTypeDocId(...)", "fileIndex": 0, "line": 238, + "metrics": [ + { "value": 812, "exceeded": true }, + { "value": 28, "exceeded": true }, + ]}, + { + "assembly": "ExchangeRateUpdater.Api", "class": "Microsoft.AspNetCore.OpenApi.Generated", "reportPath": "ExchangeRateUpdater.Api_Generated.html", "methodName": "CreateDocumentationId(System.Reflection.MethodInfo)", "methodShortName": "CreateDocumentationId(...)", "fileIndex": 0, "line": 168, + "metrics": [ + { "value": 342, "exceeded": true }, + { "value": 18, "exceeded": true }, + ]}, + { + "assembly": "ExchangeRateUpdater.Api", "class": "Microsoft.AspNetCore.OpenApi.Generated", "reportPath": "ExchangeRateUpdater.Api_Generated.html", "methodName": "CreateDocumentationId(System.Reflection.PropertyInfo)", "methodShortName": "CreateDocumentationId(...)", "fileIndex": 0, "line": 100, + "metrics": [ + { "value": 110, "exceeded": true }, + { "value": 10, "exceeded": false }, + ]}, + { + "assembly": "ExchangeRateUpdater.Api", "class": "Microsoft.AspNetCore.OpenApi.Generated", "reportPath": "ExchangeRateUpdater.Api_Generated.html", "methodName": "NormalizeDocId(System.String)", "methodShortName": "NormalizeDocId(...)", "fileIndex": 0, "line": 320, + "metrics": [ + { "value": 42, "exceeded": true }, + { "value": 6, "exceeded": false }, + ]}, + { + "assembly": "ExchangeRateUpdater.Api", "class": "Microsoft.AspNetCore.OpenApi.Generated", "reportPath": "ExchangeRateUpdater.Api_Generated.html", "methodName": "UnwrapOpenApiParameter(Microsoft.OpenApi.IOpenApiParameter)", "methodShortName": "UnwrapOpenApiParameter(...)", "fileIndex": 0, "line": 484, + "metrics": [ + { "value": 42, "exceeded": true }, + { "value": 6, "exceeded": false }, + ]}, +]; + +var branchCoverageAvailable = true; +var methodCoverageAvailable = false; +var applyMaximumGroupingLevel = false; +var maximumDecimalPlacesForCoverageQuotas = 1; + + +var translations = { +'top': 'Top:', +'all': 'All', +'assembly': 'Assembly', +'class': 'Class', +'method': 'Method', +'lineCoverage': 'Line coverage', +'noGrouping': 'No grouping', +'byAssembly': 'By assembly', +'byNamespace': 'By namespace, Level:', +'all': 'All', +'collapseAll': 'Collapse all', +'expandAll': 'Expand all', +'grouping': 'Grouping:', +'filter': 'Filter:', +'name': 'Name', +'covered': 'Covered', +'uncovered': 'Uncovered', +'coverable': 'Coverable', +'total': 'Total', +'coverage': 'Line coverage', +'branchCoverage': 'Branch coverage', +'methodCoverage': 'Method coverage', +'fullMethodCoverage': 'Full method coverage', +'percentage': 'Percentage', +'history': 'Coverage history', +'compareHistory': 'Compare with:', +'date': 'Date', +'allChanges': 'All changes', +'selectCoverageTypes': 'Select coverage types', +'selectCoverageTypesAndMetrics': 'Select coverage types & metrics', +'coverageTypes': 'Coverage types', +'metrics': 'Metrics', +'methodCoverageProVersion': 'Feature is only available for sponsors', +'lineCoverageIncreaseOnly': 'Line coverage: Increase only', +'lineCoverageDecreaseOnly': 'Line coverage: Decrease only', +'branchCoverageIncreaseOnly': 'Branch coverage: Increase only', +'branchCoverageDecreaseOnly': 'Branch coverage: Decrease only', +'methodCoverageIncreaseOnly': 'Method coverage: Increase only', +'methodCoverageDecreaseOnly': 'Method coverage: Decrease only', +'fullMethodCoverageIncreaseOnly': 'Full method coverage: Increase only', +'fullMethodCoverageDecreaseOnly': 'Full method coverage: Decrease only' +}; + + +(()=>{"use strict";var e,_={},p={};function n(e){var a=p[e];if(void 0!==a)return a.exports;var r=p[e]={exports:{}};return _[e](r,r.exports,n),r.exports}n.m=_,e=[],n.O=(a,r,u,l)=>{if(!r){var o=1/0;for(f=0;f=l)&&Object.keys(n.O).every(h=>n.O[h](r[t]))?r.splice(t--,1):(v=!1,l0&&e[f-1][2]>l;f--)e[f]=e[f-1];e[f]=[r,u,l]},n.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return n.d(a,{a}),a},n.d=(e,a)=>{for(var r in a)n.o(a,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:a[r]})},n.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),(()=>{var e={121:0};n.O.j=u=>0===e[u];var a=(u,l)=>{var t,c,[f,o,v]=l,s=0;if(f.some(d=>0!==e[d])){for(t in o)n.o(o,t)&&(n.m[t]=o[t]);if(v)var b=v(n)}for(u&&u(l);s{ve(935)},935:()=>{const te=globalThis;function Q(t){return(te.__Zone_symbol_prefix||"__zone_symbol__")+t}const Ee=Object.getOwnPropertyDescriptor,Le=Object.defineProperty,Ie=Object.getPrototypeOf,_t=Object.create,Et=Array.prototype.slice,Me="addEventListener",Ze="removeEventListener",Ae=Q(Me),je=Q(Ze),ae="true",le="false",Pe=Q("");function He(t,r){return Zone.current.wrap(t,r)}function xe(t,r,i,n,s){return Zone.current.scheduleMacroTask(t,r,i,n,s)}const H=Q,Ce=typeof window<"u",Te=Ce?window:void 0,$=Ce&&Te||globalThis;function Ve(t,r){for(let i=t.length-1;i>=0;i--)"function"==typeof t[i]&&(t[i]=He(t[i],r+"_"+i));return t}function We(t){return!t||!1!==t.writable&&!("function"==typeof t.get&&typeof t.set>"u")}const qe=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope,De=!("nw"in $)&&typeof $.process<"u"&&"[object process]"===$.process.toString(),Ge=!De&&!qe&&!(!Ce||!Te.HTMLElement),Xe=typeof $.process<"u"&&"[object process]"===$.process.toString()&&!qe&&!(!Ce||!Te.HTMLElement),Se={},pt=H("enable_beforeunload"),Ye=function(t){if(!(t=t||$.event))return;let r=Se[t.type];r||(r=Se[t.type]=H("ON_PROPERTY"+t.type));const i=this||t.target||$,n=i[r];let s;return Ge&&i===Te&&"error"===t.type?(s=n&&n.call(this,t.message,t.filename,t.lineno,t.colno,t.error),!0===s&&t.preventDefault()):(s=n&&n.apply(this,arguments),"beforeunload"===t.type&&$[pt]&&"string"==typeof s?t.returnValue=s:null!=s&&!s&&t.preventDefault()),s};function $e(t,r,i){let n=Ee(t,r);if(!n&&i&&Ee(i,r)&&(n={enumerable:!0,configurable:!0}),!n||!n.configurable)return;const s=H("on"+r+"patched");if(t.hasOwnProperty(s)&&t[s])return;delete n.writable,delete n.value;const f=n.get,T=n.set,g=r.slice(2);let m=Se[g];m||(m=Se[g]=H("ON_PROPERTY"+g)),n.set=function(C){let E=this;!E&&t===$&&(E=$),E&&("function"==typeof E[m]&&E.removeEventListener(g,Ye),T&&T.call(E,null),E[m]=C,"function"==typeof C&&E.addEventListener(g,Ye,!1))},n.get=function(){let C=this;if(!C&&t===$&&(C=$),!C)return null;const E=C[m];if(E)return E;if(f){let P=f.call(this);if(P)return n.set.call(this,P),"function"==typeof C.removeAttribute&&C.removeAttribute(r),P}return null},Le(t,r,n),t[s]=!0}function Ke(t,r,i){if(r)for(let n=0;nfunction(T,g){const m=i(T,g);return m.cbIdx>=0&&"function"==typeof g[m.cbIdx]?xe(m.name,g[m.cbIdx],m,s):f.apply(T,g)})}function fe(t,r){t[H("OriginalDelegate")]=r}let Je=!1,Be=!1;function kt(){if(Je)return Be;Je=!0;try{const t=Te.navigator.userAgent;(-1!==t.indexOf("MSIE ")||-1!==t.indexOf("Trident/")||-1!==t.indexOf("Edge/"))&&(Be=!0)}catch{}return Be}function Qe(t){return"function"==typeof t}function et(t){return"number"==typeof t}let ge=!1;if(typeof window<"u")try{const t=Object.defineProperty({},"passive",{get:function(){ge=!0}});window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch{ge=!1}const vt={useG:!0},ne={},tt={},nt=new RegExp("^"+Pe+"(\\w+)(true|false)$"),rt=H("propagationStopped");function ot(t,r){const i=(r?r(t):t)+le,n=(r?r(t):t)+ae,s=Pe+i,f=Pe+n;ne[t]={},ne[t][le]=s,ne[t][ae]=f}function bt(t,r,i,n){const s=n&&n.add||Me,f=n&&n.rm||Ze,T=n&&n.listeners||"eventListeners",g=n&&n.rmAll||"removeAllListeners",m=H(s),C="."+s+":",E="prependListener",P="."+E+":",A=function(k,h,x){if(k.isRemoved)return;const G=k.callback;let Y;"object"==typeof G&&G.handleEvent&&(k.callback=p=>G.handleEvent(p),k.originalDelegate=G);try{k.invoke(k,h,[x])}catch(p){Y=p}const B=k.options;return B&&"object"==typeof B&&B.once&&h[f].call(h,x.type,k.originalDelegate?k.originalDelegate:k.callback,B),Y};function V(k,h,x){if(!(h=h||t.event))return;const G=k||h.target||t,Y=G[ne[h.type][x?ae:le]];if(Y){const B=[];if(1===Y.length){const p=A(Y[0],G,h);p&&B.push(p)}else{const p=Y.slice();for(let W=0;W{throw W})}}}const z=function(k){return V(this,k,!1)},K=function(k){return V(this,k,!0)};function J(k,h){if(!k)return!1;let x=!0;h&&void 0!==h.useG&&(x=h.useG);const G=h&&h.vh;let Y=!0;h&&void 0!==h.chkDup&&(Y=h.chkDup);let B=!1;h&&void 0!==h.rt&&(B=h.rt);let p=k;for(;p&&!p.hasOwnProperty(s);)p=Ie(p);if(!p&&k[s]&&(p=k),!p||p[m])return!1;const W=h&&h.eventNameToString,L={},w=p[m]=p[s],b=p[H(f)]=p[f],S=p[H(T)]=p[T],ee=p[H(g)]=p[g];let q;h&&h.prepend&&(q=p[H(h.prepend)]=p[h.prepend]);const N=x?function(o){if(!L.isExisting)return w.call(L.target,L.eventName,L.capture?K:z,L.options)}:function(o){return w.call(L.target,L.eventName,o.invoke,L.options)},D=x?function(o){if(!o.isRemoved){const u=ne[o.eventName];let v;u&&(v=u[o.capture?ae:le]);const R=v&&o.target[v];if(R)for(let y=0;yse.zone.cancelTask(se);o.call(me,"abort",ce,{once:!0}),se.removeAbortListener=()=>me.removeEventListener("abort",ce)}return L.target=null,Re&&(Re.taskData=null),lt&&(L.options.once=!0),!ge&&"boolean"==typeof se.options||(se.options=ie),se.target=M,se.capture=Ue,se.eventName=Z,U&&(se.originalDelegate=F),I?ke.unshift(se):ke.push(se),y?M:void 0}};return p[s]=a(w,C,N,D,B),q&&(p[E]=a(q,P,function(o){return q.call(L.target,L.eventName,o.invoke,L.options)},D,B,!0)),p[f]=function(){const o=this||t;let u=arguments[0];h&&h.transferEventName&&(u=h.transferEventName(u));const v=arguments[2],R=!!v&&("boolean"==typeof v||v.capture),y=arguments[1];if(!y)return b.apply(this,arguments);if(G&&!G(b,y,o,arguments))return;const I=ne[u];let M;I&&(M=I[R?ae:le]);const Z=M&&o[M];if(Z)for(let F=0;Ffunction(s,f){s[rt]=!0,n&&n.apply(s,f)})}const Oe=H("zoneTask");function pe(t,r,i,n){let s=null,f=null;i+=n;const T={};function g(C){const E=C.data;E.args[0]=function(){return C.invoke.apply(this,arguments)};const P=s.apply(t,E.args);return et(P)?E.handleId=P:(E.handle=P,E.isRefreshable=Qe(P.refresh)),C}function m(C){const{handle:E,handleId:P}=C.data;return f.call(t,E??P)}s=ue(t,r+=n,C=>function(E,P){if(Qe(P[0])){const A={isRefreshable:!1,isPeriodic:"Interval"===n,delay:"Timeout"===n||"Interval"===n?P[1]||0:void 0,args:P},V=P[0];P[0]=function(){try{return V.apply(this,arguments)}finally{const{handle:x,handleId:G,isPeriodic:Y,isRefreshable:B}=A;!Y&&!B&&(G?delete T[G]:x&&(x[Oe]=null))}};const z=xe(r,P[0],A,g,m);if(!z)return z;const{handleId:K,handle:J,isRefreshable:X,isPeriodic:k}=z.data;if(K)T[K]=z;else if(J&&(J[Oe]=z,X&&!k)){const h=J.refresh;J.refresh=function(){const{zone:x,state:G}=z;return"notScheduled"===G?(z._state="scheduled",x._updateTaskCount(z,1)):"running"===G&&(z._state="scheduling"),h.call(this)}}return J??K??z}return C.apply(t,P)}),f=ue(t,i,C=>function(E,P){const A=P[0];let V;et(A)?(V=T[A],delete T[A]):(V=A?.[Oe],V?A[Oe]=null:V=A),V?.type?V.cancelFn&&V.zone.cancelTask(V):C.apply(t,P)})}function it(t,r,i){if(!i||0===i.length)return r;const n=i.filter(f=>f.target===t);if(!n||0===n.length)return r;const s=n[0].ignoreProperties;return r.filter(f=>-1===s.indexOf(f))}function ct(t,r,i,n){t&&Ke(t,it(t,r,i),n)}function Fe(t){return Object.getOwnPropertyNames(t).filter(r=>r.startsWith("on")&&r.length>2).map(r=>r.substring(2))}function It(t,r,i,n,s){const f=Zone.__symbol__(n);if(r[f])return;const T=r[f]=r[n];r[n]=function(g,m,C){return m&&m.prototype&&s.forEach(function(E){const P=`${i}.${n}::`+E,A=m.prototype;try{if(A.hasOwnProperty(E)){const V=t.ObjectGetOwnPropertyDescriptor(A,E);V&&V.value?(V.value=t.wrapWithCurrentZone(V.value,P),t._redefineProperty(m.prototype,E,V)):A[E]&&(A[E]=t.wrapWithCurrentZone(A[E],P))}else A[E]&&(A[E]=t.wrapWithCurrentZone(A[E],P))}catch{}}),T.call(r,g,m,C)},t.attachOriginToPatched(r[n],T)}const at=function be(){const t=globalThis,r=!0===t[Q("forceDuplicateZoneCheck")];if(t.Zone&&(r||"function"!=typeof t.Zone.__symbol__))throw new Error("Zone already loaded.");return t.Zone??=function ve(){const t=te.performance;function r(j){t&&t.mark&&t.mark(j)}function i(j,_){t&&t.measure&&t.measure(j,_)}r("Zone");let n=(()=>{var j;class _{static assertZonePatched(){if(te.Promise!==L.ZoneAwarePromise)throw new Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")}static get root(){let e=_.current;for(;e.parent;)e=e.parent;return e}static get current(){return b.zone}static get currentTask(){return S}static __load_patch(e,d,O=!1){if(L.hasOwnProperty(e)){const N=!0===te[Q("forceDuplicateZoneCheck")];if(!O&&N)throw Error("Already loaded patch: "+e)}else if(!te["__Zone_disable_"+e]){const N="Zone:"+e;r(N),L[e]=d(te,_,w),i(N,N)}}get parent(){return this._parent}get name(){return this._name}constructor(e,d){this._parent=e,this._name=d?d.name||"unnamed":"",this._properties=d&&d.properties||{},this._zoneDelegate=new f(this,this._parent&&this._parent._zoneDelegate,d)}get(e){const d=this.getZoneWith(e);if(d)return d._properties[e]}getZoneWith(e){let d=this;for(;d;){if(d._properties.hasOwnProperty(e))return d;d=d._parent}return null}fork(e){if(!e)throw new Error("ZoneSpec required!");return this._zoneDelegate.fork(this,e)}wrap(e,d){if("function"!=typeof e)throw new Error("Expecting function got: "+e);const O=this._zoneDelegate.intercept(this,e,d),N=this;return function(){return N.runGuarded(O,this,arguments,d)}}run(e,d,O,N){b={parent:b,zone:this};try{return this._zoneDelegate.invoke(this,e,d,O,N)}finally{b=b.parent}}runGuarded(e,d=null,O,N){b={parent:b,zone:this};try{try{return this._zoneDelegate.invoke(this,e,d,O,N)}catch(D){if(this._zoneDelegate.handleError(this,D))throw D}}finally{b=b.parent}}runTask(e,d,O){if(e.zone!=this)throw new Error("A task can only be run in the zone of creation! (Creation: "+(e.zone||J).name+"; Execution: "+this.name+")");const N=e,{type:D,data:{isPeriodic:_e=!1,isRefreshable:he=!1}={}}=e;if(e.state===X&&(D===W||D===p))return;const oe=e.state!=x;oe&&N._transitionTo(x,h);const ye=S;S=N,b={parent:b,zone:this};try{D==p&&e.data&&!_e&&!he&&(e.cancelFn=void 0);try{return this._zoneDelegate.invokeTask(this,N,d,O)}catch(l){if(this._zoneDelegate.handleError(this,l))throw l}}finally{const l=e.state;if(l!==X&&l!==Y)if(D==W||_e||he&&l===k)oe&&N._transitionTo(h,x,k);else{const a=N._zoneDelegates;this._updateTaskCount(N,-1),oe&&N._transitionTo(X,x,X),he&&(N._zoneDelegates=a)}b=b.parent,S=ye}}scheduleTask(e){if(e.zone&&e.zone!==this){let O=this;for(;O;){if(O===e.zone)throw Error(`can not reschedule task to ${this.name} which is descendants of the original zone ${e.zone.name}`);O=O.parent}}e._transitionTo(k,X);const d=[];e._zoneDelegates=d,e._zone=this;try{e=this._zoneDelegate.scheduleTask(this,e)}catch(O){throw e._transitionTo(Y,k,X),this._zoneDelegate.handleError(this,O),O}return e._zoneDelegates===d&&this._updateTaskCount(e,1),e.state==k&&e._transitionTo(h,k),e}scheduleMicroTask(e,d,O,N){return this.scheduleTask(new T(B,e,d,O,N,void 0))}scheduleMacroTask(e,d,O,N,D){return this.scheduleTask(new T(p,e,d,O,N,D))}scheduleEventTask(e,d,O,N,D){return this.scheduleTask(new T(W,e,d,O,N,D))}cancelTask(e){if(e.zone!=this)throw new Error("A task can only be cancelled in the zone of creation! (Creation: "+(e.zone||J).name+"; Execution: "+this.name+")");if(e.state===h||e.state===x){e._transitionTo(G,h,x);try{this._zoneDelegate.cancelTask(this,e)}catch(d){throw e._transitionTo(Y,G),this._zoneDelegate.handleError(this,d),d}return this._updateTaskCount(e,-1),e._transitionTo(X,G),e.runCount=-1,e}}_updateTaskCount(e,d){const O=e._zoneDelegates;-1==d&&(e._zoneDelegates=null);for(let N=0;Nthis.__symbol__=Q}return j(),_})();const s={name:"",onHasTask:(j,_,c,e)=>j.hasTask(c,e),onScheduleTask:(j,_,c,e)=>j.scheduleTask(c,e),onInvokeTask:(j,_,c,e,d,O)=>j.invokeTask(c,e,d,O),onCancelTask:(j,_,c,e)=>j.cancelTask(c,e)};class f{get zone(){return this._zone}constructor(_,c,e){this._taskCounts={microTask:0,macroTask:0,eventTask:0},this._zone=_,this._parentDelegate=c,this._forkZS=e&&(e&&e.onFork?e:c._forkZS),this._forkDlgt=e&&(e.onFork?c:c._forkDlgt),this._forkCurrZone=e&&(e.onFork?this._zone:c._forkCurrZone),this._interceptZS=e&&(e.onIntercept?e:c._interceptZS),this._interceptDlgt=e&&(e.onIntercept?c:c._interceptDlgt),this._interceptCurrZone=e&&(e.onIntercept?this._zone:c._interceptCurrZone),this._invokeZS=e&&(e.onInvoke?e:c._invokeZS),this._invokeDlgt=e&&(e.onInvoke?c:c._invokeDlgt),this._invokeCurrZone=e&&(e.onInvoke?this._zone:c._invokeCurrZone),this._handleErrorZS=e&&(e.onHandleError?e:c._handleErrorZS),this._handleErrorDlgt=e&&(e.onHandleError?c:c._handleErrorDlgt),this._handleErrorCurrZone=e&&(e.onHandleError?this._zone:c._handleErrorCurrZone),this._scheduleTaskZS=e&&(e.onScheduleTask?e:c._scheduleTaskZS),this._scheduleTaskDlgt=e&&(e.onScheduleTask?c:c._scheduleTaskDlgt),this._scheduleTaskCurrZone=e&&(e.onScheduleTask?this._zone:c._scheduleTaskCurrZone),this._invokeTaskZS=e&&(e.onInvokeTask?e:c._invokeTaskZS),this._invokeTaskDlgt=e&&(e.onInvokeTask?c:c._invokeTaskDlgt),this._invokeTaskCurrZone=e&&(e.onInvokeTask?this._zone:c._invokeTaskCurrZone),this._cancelTaskZS=e&&(e.onCancelTask?e:c._cancelTaskZS),this._cancelTaskDlgt=e&&(e.onCancelTask?c:c._cancelTaskDlgt),this._cancelTaskCurrZone=e&&(e.onCancelTask?this._zone:c._cancelTaskCurrZone),this._hasTaskZS=null,this._hasTaskDlgt=null,this._hasTaskDlgtOwner=null,this._hasTaskCurrZone=null;const d=e&&e.onHasTask;(d||c&&c._hasTaskZS)&&(this._hasTaskZS=d?e:s,this._hasTaskDlgt=c,this._hasTaskDlgtOwner=this,this._hasTaskCurrZone=this._zone,e.onScheduleTask||(this._scheduleTaskZS=s,this._scheduleTaskDlgt=c,this._scheduleTaskCurrZone=this._zone),e.onInvokeTask||(this._invokeTaskZS=s,this._invokeTaskDlgt=c,this._invokeTaskCurrZone=this._zone),e.onCancelTask||(this._cancelTaskZS=s,this._cancelTaskDlgt=c,this._cancelTaskCurrZone=this._zone))}fork(_,c){return this._forkZS?this._forkZS.onFork(this._forkDlgt,this.zone,_,c):new n(_,c)}intercept(_,c,e){return this._interceptZS?this._interceptZS.onIntercept(this._interceptDlgt,this._interceptCurrZone,_,c,e):c}invoke(_,c,e,d,O){return this._invokeZS?this._invokeZS.onInvoke(this._invokeDlgt,this._invokeCurrZone,_,c,e,d,O):c.apply(e,d)}handleError(_,c){return!this._handleErrorZS||this._handleErrorZS.onHandleError(this._handleErrorDlgt,this._handleErrorCurrZone,_,c)}scheduleTask(_,c){let e=c;if(this._scheduleTaskZS)this._hasTaskZS&&e._zoneDelegates.push(this._hasTaskDlgtOwner),e=this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt,this._scheduleTaskCurrZone,_,c),e||(e=c);else if(c.scheduleFn)c.scheduleFn(c);else{if(c.type!=B)throw new Error("Task is missing scheduleFn.");z(c)}return e}invokeTask(_,c,e,d){return this._invokeTaskZS?this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt,this._invokeTaskCurrZone,_,c,e,d):c.callback.apply(e,d)}cancelTask(_,c){let e;if(this._cancelTaskZS)e=this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt,this._cancelTaskCurrZone,_,c);else{if(!c.cancelFn)throw Error("Task is not cancelable");e=c.cancelFn(c)}return e}hasTask(_,c){try{this._hasTaskZS&&this._hasTaskZS.onHasTask(this._hasTaskDlgt,this._hasTaskCurrZone,_,c)}catch(e){this.handleError(_,e)}}_updateTaskCount(_,c){const e=this._taskCounts,d=e[_],O=e[_]=d+c;if(O<0)throw new Error("More tasks executed then were scheduled.");0!=d&&0!=O||this.hasTask(this._zone,{microTask:e.microTask>0,macroTask:e.macroTask>0,eventTask:e.eventTask>0,change:_})}}class T{constructor(_,c,e,d,O,N){if(this._zone=null,this.runCount=0,this._zoneDelegates=null,this._state="notScheduled",this.type=_,this.source=c,this.data=d,this.scheduleFn=O,this.cancelFn=N,!e)throw new Error("callback is not defined");this.callback=e;const D=this;this.invoke=_===W&&d&&d.useG?T.invokeTask:function(){return T.invokeTask.call(te,D,this,arguments)}}static invokeTask(_,c,e){_||(_=this),ee++;try{return _.runCount++,_.zone.runTask(_,c,e)}finally{1==ee&&K(),ee--}}get zone(){return this._zone}get state(){return this._state}cancelScheduleRequest(){this._transitionTo(X,k)}_transitionTo(_,c,e){if(this._state!==c&&this._state!==e)throw new Error(`${this.type} '${this.source}': can not transition to '${_}', expecting state '${c}'${e?" or '"+e+"'":""}, was '${this._state}'.`);this._state=_,_==X&&(this._zoneDelegates=null)}toString(){return this.data&&typeof this.data.handleId<"u"?this.data.handleId.toString():Object.prototype.toString.call(this)}toJSON(){return{type:this.type,state:this.state,source:this.source,zone:this.zone.name,runCount:this.runCount}}}const g=Q("setTimeout"),m=Q("Promise"),C=Q("then");let A,E=[],P=!1;function V(j){if(A||te[m]&&(A=te[m].resolve(0)),A){let _=A[C];_||(_=A.then),_.call(A,j)}else te[g](j,0)}function z(j){0===ee&&0===E.length&&V(K),j&&E.push(j)}function K(){if(!P){for(P=!0;E.length;){const j=E;E=[];for(let _=0;_b,onUnhandledError:q,microtaskDrainDone:q,scheduleMicroTask:z,showUncaughtError:()=>!n[Q("ignoreConsoleErrorUncaughtError")],patchEventTarget:()=>[],patchOnProperties:q,patchMethod:()=>q,bindArguments:()=>[],patchThen:()=>q,patchMacroTask:()=>q,patchEventPrototype:()=>q,isIEOrEdge:()=>!1,getGlobalObjects:()=>{},ObjectDefineProperty:()=>q,ObjectGetOwnPropertyDescriptor:()=>{},ObjectCreate:()=>{},ArraySlice:()=>[],patchClass:()=>q,wrapWithCurrentZone:()=>q,filterProperties:()=>[],attachOriginToPatched:()=>q,_redefineProperty:()=>q,patchCallbacks:()=>q,nativeScheduleMicroTask:V};let b={parent:null,zone:new n(null,null)},S=null,ee=0;function q(){}return i("Zone","Zone"),n}(),t.Zone}();(function Zt(t){(function Nt(t){t.__load_patch("ZoneAwarePromise",(r,i,n)=>{const s=Object.getOwnPropertyDescriptor,f=Object.defineProperty,g=n.symbol,m=[],C=!1!==r[g("DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION")],E=g("Promise"),P=g("then");n.onUnhandledError=l=>{if(n.showUncaughtError()){const a=l&&l.rejection;a?console.error("Unhandled Promise rejection:",a instanceof Error?a.message:a,"; Zone:",l.zone.name,"; Task:",l.task&&l.task.source,"; Value:",a,a instanceof Error?a.stack:void 0):console.error(l)}},n.microtaskDrainDone=()=>{for(;m.length;){const l=m.shift();try{l.zone.runGuarded(()=>{throw l.throwOriginal?l.rejection:l})}catch(a){z(a)}}};const V=g("unhandledPromiseRejectionHandler");function z(l){n.onUnhandledError(l);try{const a=i[V];"function"==typeof a&&a.call(this,l)}catch{}}function K(l){return l&&l.then}function J(l){return l}function X(l){return D.reject(l)}const k=g("state"),h=g("value"),x=g("finally"),G=g("parentPromiseValue"),Y=g("parentPromiseState"),p=null,W=!0,L=!1;function b(l,a){return o=>{try{j(l,a,o)}catch(u){j(l,!1,u)}}}const S=function(){let l=!1;return function(o){return function(){l||(l=!0,o.apply(null,arguments))}}},ee="Promise resolved with itself",q=g("currentTaskTrace");function j(l,a,o){const u=S();if(l===o)throw new TypeError(ee);if(l[k]===p){let v=null;try{("object"==typeof o||"function"==typeof o)&&(v=o&&o.then)}catch(R){return u(()=>{j(l,!1,R)})(),l}if(a!==L&&o instanceof D&&o.hasOwnProperty(k)&&o.hasOwnProperty(h)&&o[k]!==p)c(o),j(l,o[k],o[h]);else if(a!==L&&"function"==typeof v)try{v.call(o,u(b(l,a)),u(b(l,!1)))}catch(R){u(()=>{j(l,!1,R)})()}else{l[k]=a;const R=l[h];if(l[h]=o,l[x]===x&&a===W&&(l[k]=l[Y],l[h]=l[G]),a===L&&o instanceof Error){const y=i.currentTask&&i.currentTask.data&&i.currentTask.data.__creationTrace__;y&&f(o,q,{configurable:!0,enumerable:!1,writable:!0,value:y})}for(let y=0;y{try{const I=l[h],M=!!o&&x===o[x];M&&(o[G]=I,o[Y]=R);const Z=a.run(y,void 0,M&&y!==X&&y!==J?[]:[I]);j(o,!0,Z)}catch(I){j(o,!1,I)}},o)}const O=function(){},N=r.AggregateError;class D{static toString(){return"function ZoneAwarePromise() { [native code] }"}static resolve(a){return a instanceof D?a:j(new this(null),W,a)}static reject(a){return j(new this(null),L,a)}static withResolvers(){const a={};return a.promise=new D((o,u)=>{a.resolve=o,a.reject=u}),a}static any(a){if(!a||"function"!=typeof a[Symbol.iterator])return Promise.reject(new N([],"All promises were rejected"));const o=[];let u=0;try{for(let y of a)u++,o.push(D.resolve(y))}catch{return Promise.reject(new N([],"All promises were rejected"))}if(0===u)return Promise.reject(new N([],"All promises were rejected"));let v=!1;const R=[];return new D((y,I)=>{for(let M=0;M{v||(v=!0,y(Z))},Z=>{R.push(Z),u--,0===u&&(v=!0,I(new N(R,"All promises were rejected")))})})}static race(a){let o,u,v=new this((I,M)=>{o=I,u=M});function R(I){o(I)}function y(I){u(I)}for(let I of a)K(I)||(I=this.resolve(I)),I.then(R,y);return v}static all(a){return D.allWithCallback(a)}static allSettled(a){return(this&&this.prototype instanceof D?this:D).allWithCallback(a,{thenCallback:u=>({status:"fulfilled",value:u}),errorCallback:u=>({status:"rejected",reason:u})})}static allWithCallback(a,o){let u,v,R=new this((Z,F)=>{u=Z,v=F}),y=2,I=0;const M=[];for(let Z of a){K(Z)||(Z=this.resolve(Z));const F=I;try{Z.then(U=>{M[F]=o?o.thenCallback(U):U,y--,0===y&&u(M)},U=>{o?(M[F]=o.errorCallback(U),y--,0===y&&u(M)):v(U)})}catch(U){v(U)}y++,I++}return y-=2,0===y&&u(M),R}constructor(a){const o=this;if(!(o instanceof D))throw new Error("Must be an instanceof Promise.");o[k]=p,o[h]=[];try{const u=S();a&&a(u(b(o,W)),u(b(o,L)))}catch(u){j(o,!1,u)}}get[Symbol.toStringTag](){return"Promise"}get[Symbol.species](){return D}then(a,o){let u=this.constructor?.[Symbol.species];(!u||"function"!=typeof u)&&(u=this.constructor||D);const v=new u(O),R=i.current;return this[k]==p?this[h].push(R,v,a,o):e(this,R,v,a,o),v}catch(a){return this.then(null,a)}finally(a){let o=this.constructor?.[Symbol.species];(!o||"function"!=typeof o)&&(o=D);const u=new o(O);u[x]=x;const v=i.current;return this[k]==p?this[h].push(v,u,a,a):e(this,v,u,a,a),u}}D.resolve=D.resolve,D.reject=D.reject,D.race=D.race,D.all=D.all;const _e=r[E]=r.Promise;r.Promise=D;const he=g("thenPatched");function oe(l){const a=l.prototype,o=s(a,"then");if(o&&(!1===o.writable||!o.configurable))return;const u=a.then;a[P]=u,l.prototype.then=function(v,R){return new D((I,M)=>{u.call(this,I,M)}).then(v,R)},l[he]=!0}return n.patchThen=oe,_e&&(oe(_e),ue(r,"fetch",l=>function ye(l){return function(a,o){let u=l.apply(a,o);if(u instanceof D)return u;let v=u.constructor;return v[he]||oe(v),u}}(l))),Promise[i.__symbol__("uncaughtPromiseErrors")]=m,D})})(t),function Lt(t){t.__load_patch("toString",r=>{const i=Function.prototype.toString,n=H("OriginalDelegate"),s=H("Promise"),f=H("Error"),T=function(){if("function"==typeof this){const E=this[n];if(E)return"function"==typeof E?i.call(E):Object.prototype.toString.call(E);if(this===Promise){const P=r[s];if(P)return i.call(P)}if(this===Error){const P=r[f];if(P)return i.call(P)}}return i.call(this)};T[n]=i,Function.prototype.toString=T;const g=Object.prototype.toString;Object.prototype.toString=function(){return"function"==typeof Promise&&this instanceof Promise?"[object Promise]":g.call(this)}})}(t),function Mt(t){t.__load_patch("util",(r,i,n)=>{const s=Fe(r);n.patchOnProperties=Ke,n.patchMethod=ue,n.bindArguments=Ve,n.patchMacroTask=yt;const f=i.__symbol__("BLACK_LISTED_EVENTS"),T=i.__symbol__("UNPATCHED_EVENTS");r[T]&&(r[f]=r[T]),r[f]&&(i[f]=i[T]=r[f]),n.patchEventPrototype=Pt,n.patchEventTarget=bt,n.isIEOrEdge=kt,n.ObjectDefineProperty=Le,n.ObjectGetOwnPropertyDescriptor=Ee,n.ObjectCreate=_t,n.ArraySlice=Et,n.patchClass=we,n.wrapWithCurrentZone=He,n.filterProperties=it,n.attachOriginToPatched=fe,n._redefineProperty=Object.defineProperty,n.patchCallbacks=It,n.getGlobalObjects=()=>({globalSources:tt,zoneSymbolEventNames:ne,eventNames:s,isBrowser:Ge,isMix:Xe,isNode:De,TRUE_STR:ae,FALSE_STR:le,ZONE_SYMBOL_PREFIX:Pe,ADD_EVENT_LISTENER_STR:Me,REMOVE_EVENT_LISTENER_STR:Ze})})}(t)})(at),function Ot(t){t.__load_patch("legacy",r=>{const i=r[t.__symbol__("legacyPatch")];i&&i()}),t.__load_patch("timers",r=>{const n="clear";pe(r,"set",n,"Timeout"),pe(r,"set",n,"Interval"),pe(r,"set",n,"Immediate")}),t.__load_patch("requestAnimationFrame",r=>{pe(r,"request","cancel","AnimationFrame"),pe(r,"mozRequest","mozCancel","AnimationFrame"),pe(r,"webkitRequest","webkitCancel","AnimationFrame")}),t.__load_patch("blocking",(r,i)=>{const n=["alert","prompt","confirm"];for(let s=0;sfunction(C,E){return i.current.run(T,r,E,m)})}),t.__load_patch("EventTarget",(r,i,n)=>{(function Dt(t,r){r.patchEventPrototype(t,r)})(r,n),function Ct(t,r){if(Zone[r.symbol("patchEventTarget")])return;const{eventNames:i,zoneSymbolEventNames:n,TRUE_STR:s,FALSE_STR:f,ZONE_SYMBOL_PREFIX:T}=r.getGlobalObjects();for(let m=0;m{we("MutationObserver"),we("WebKitMutationObserver")}),t.__load_patch("IntersectionObserver",(r,i,n)=>{we("IntersectionObserver")}),t.__load_patch("FileReader",(r,i,n)=>{we("FileReader")}),t.__load_patch("on_property",(r,i,n)=>{!function St(t,r){if(De&&!Xe||Zone[t.symbol("patchEvents")])return;const i=r.__Zone_ignore_on_properties;let n=[];if(Ge){const s=window;n=n.concat(["Document","SVGElement","Element","HTMLElement","HTMLBodyElement","HTMLMediaElement","HTMLFrameSetElement","HTMLFrameElement","HTMLIFrameElement","HTMLMarqueeElement","Worker"]);const f=function mt(){try{const t=Te.navigator.userAgent;if(-1!==t.indexOf("MSIE ")||-1!==t.indexOf("Trident/"))return!0}catch{}return!1}()?[{target:s,ignoreProperties:["error"]}]:[];ct(s,Fe(s),i&&i.concat(f),Ie(s))}n=n.concat(["XMLHttpRequest","XMLHttpRequestEventTarget","IDBIndex","IDBRequest","IDBOpenDBRequest","IDBDatabase","IDBTransaction","IDBCursor","WebSocket"]);for(let s=0;s{!function Rt(t,r){const{isBrowser:i,isMix:n}=r.getGlobalObjects();(i||n)&&t.customElements&&"customElements"in t&&r.patchCallbacks(r,t.customElements,"customElements","define",["connectedCallback","disconnectedCallback","adoptedCallback","attributeChangedCallback","formAssociatedCallback","formDisabledCallback","formResetCallback","formStateRestoreCallback"])}(r,n)}),t.__load_patch("XHR",(r,i)=>{!function C(E){const P=E.XMLHttpRequest;if(!P)return;const A=P.prototype;let z=A[Ae],K=A[je];if(!z){const w=E.XMLHttpRequestEventTarget;if(w){const b=w.prototype;z=b[Ae],K=b[je]}}const J="readystatechange",X="scheduled";function k(w){const b=w.data,S=b.target;S[T]=!1,S[m]=!1;const ee=S[f];z||(z=S[Ae],K=S[je]),ee&&K.call(S,J,ee);const q=S[f]=()=>{if(S.readyState===S.DONE)if(!b.aborted&&S[T]&&w.state===X){const _=S[i.__symbol__("loadfalse")];if(0!==S.status&&_&&_.length>0){const c=w.invoke;w.invoke=function(){const e=S[i.__symbol__("loadfalse")];for(let d=0;dfunction(w,b){return w[s]=0==b[2],w[g]=b[1],G.apply(w,b)}),B=H("fetchTaskAborting"),p=H("fetchTaskScheduling"),W=ue(A,"send",()=>function(w,b){if(!0===i.current[p]||w[s])return W.apply(w,b);{const S={target:w,url:w[g],isPeriodic:!1,args:b,aborted:!1},ee=xe("XMLHttpRequest.send",h,S,k,x);w&&!0===w[m]&&!S.aborted&&ee.state===X&&ee.invoke()}}),L=ue(A,"abort",()=>function(w,b){const S=function V(w){return w[n]}(w);if(S&&"string"==typeof S.type){if(null==S.cancelFn||S.data&&S.data.aborted)return;S.zone.cancelTask(S)}else if(!0===i.current[B])return L.apply(w,b)})}(r);const n=H("xhrTask"),s=H("xhrSync"),f=H("xhrListener"),T=H("xhrScheduled"),g=H("xhrURL"),m=H("xhrErrorBeforeScheduled")}),t.__load_patch("geolocation",r=>{r.navigator&&r.navigator.geolocation&&function gt(t,r){const i=t.constructor.name;for(let n=0;n{const m=function(){return g.apply(this,Ve(arguments,i+"."+s))};return fe(m,g),m})(f)}}}(r.navigator.geolocation,["getCurrentPosition","watchPosition"])}),t.__load_patch("PromiseRejectionEvent",(r,i)=>{function n(s){return function(f){st(r,s).forEach(g=>{const m=r.PromiseRejectionEvent;if(m){const C=new m(s,{promise:f.promise,reason:f.rejection});g.invoke(C)}})}}r.PromiseRejectionEvent&&(i[H("unhandledPromiseRejectionHandler")]=n("unhandledrejection"),i[H("rejectionHandledHandler")]=n("rejectionhandled"))}),t.__load_patch("queueMicrotask",(r,i,n)=>{!function wt(t,r){r.patchMethod(t,"queueMicrotask",i=>function(n,s){Zone.current.scheduleMicroTask("queueMicrotask",s[0])})}(r,n)})}(at)}},te=>{te(te.s=50)}]); + +"use strict";(self.webpackChunkcoverage_app=self.webpackChunkcoverage_app||[]).push([[792],{653:()=>{let Yo;function sr(){return Yo}function un(e){const n=Yo;return Yo=e,n}const dI=Symbol("NotFound");function Vc(e){return e===dI||"\u0275NotFound"===e?.name}Error;let Je=null,ar=!1,Hc=1;const We=Symbol("SIGNAL");function z(e){const n=Je;return Je=e,n}const Qo={version:0,lastCleanEpoch:0,dirty:!1,producers:void 0,producersTail:void 0,consumers:void 0,consumersTail:void 0,recomputing:!1,consumerAllowSignalWrites:!1,consumerIsAlwaysLive:!1,kind:"unknown",producerMustRecompute:()=>!1,producerRecomputeValue:()=>{},consumerMarkedDirty:()=>{},consumerOnSignalRead:()=>{}};function Vs(e){if(ar)throw new Error("");if(null===Je)return;Je.consumerOnSignalRead(e);const n=Je.producersTail;if(void 0!==n&&n.producer===e)return;let t;const o=Je.recomputing;if(o&&(t=void 0!==n?n.nextProducer:Je.producers,void 0!==t&&t.producer===e))return Je.producersTail=t,void(t.lastReadVersion=e.version);const i=e.consumersTail;if(void 0!==i&&i.consumer===Je&&(!o||function mI(e,n){const t=n.producersTail;if(void 0!==t){let o=n.producers;do{if(o===e)return!0;if(o===t)break;o=o.nextProducer}while(void 0!==o)}return!1}(i,Je)))return;const r=Jo(Je),s={producer:e,consumer:Je,nextProducer:t,prevConsumer:i,lastReadVersion:e.version,nextConsumer:void 0};Je.producersTail=s,void 0!==n?n.nextProducer=s:Je.producers=s,r&&Gg(e,s)}function lr(e){if((!Jo(e)||e.dirty)&&(e.dirty||e.lastCleanEpoch!==Hc)){if(!e.producerMustRecompute(e)&&!Bs(e))return void Hs(e);e.producerRecomputeValue(e),Hs(e)}}function $g(e){if(void 0===e.consumers)return;const n=ar;ar=!0;try{for(let t=e.consumers;void 0!==t;t=t.nextConsumer){const o=t.consumer;o.dirty||hI(o)}}finally{ar=n}}function zg(){return!1!==Je?.consumerAllowSignalWrites}function hI(e){e.dirty=!0,$g(e),e.consumerMarkedDirty?.(e)}function Hs(e){e.dirty=!1,e.lastCleanEpoch=Hc}function Ko(e){return e&&function gI(e){e.producersTail=void 0,e.recomputing=!0}(e),z(e)}function cr(e,n){z(n),e&&function pI(e){e.recomputing=!1;const n=e.producersTail;let t=void 0!==n?n.nextProducer:e.producers;if(void 0!==t){if(Jo(e))do{t=Uc(t)}while(void 0!==t);void 0!==n?n.nextProducer=void 0:e.producers=void 0}}(e)}function Bs(e){for(let n=e.producers;void 0!==n;n=n.nextProducer){const t=n.producer,o=n.lastReadVersion;if(o!==t.version||(lr(t),o!==t.version))return!0}return!1}function ur(e){if(Jo(e)){let n=e.producers;for(;void 0!==n;)n=Uc(n)}e.producers=void 0,e.producersTail=void 0,e.consumers=void 0,e.consumersTail=void 0}function Gg(e,n){const t=e.consumersTail,o=Jo(e);if(void 0!==t?(n.nextConsumer=t.nextConsumer,t.nextConsumer=n):(n.nextConsumer=void 0,e.consumers=n),n.prevConsumer=t,e.consumersTail=n,!o)for(let i=e.producers;void 0!==i;i=i.nextProducer)Gg(i.producer,i)}function Uc(e){const n=e.producer,t=e.nextProducer,o=e.nextConsumer,i=e.prevConsumer;if(e.nextConsumer=void 0,e.prevConsumer=void 0,void 0!==o?o.prevConsumer=i:n.consumersTail=i,void 0!==i)i.nextConsumer=o;else if(n.consumers=o,!Jo(n)){let r=n.producers;for(;void 0!==r;)r=Uc(r)}return t}function Jo(e){return e.consumerIsAlwaysLive||void 0!==e.consumers}function zc(e,n){return Object.is(e,n)}const lo=Symbol("UNSET"),Xo=Symbol("COMPUTING"),Rn=Symbol("ERRORED"),vI={...Qo,value:lo,dirty:!0,error:null,equal:zc,kind:"computed",producerMustRecompute:e=>e.value===lo||e.value===Xo,producerRecomputeValue(e){if(e.value===Xo)throw new Error("");const n=e.value;e.value=Xo;const t=Ko(e);let o,i=!1;try{o=e.computation(),z(null),i=n!==lo&&n!==Rn&&o!==Rn&&e.equal(n,o)}catch(r){o=Rn,e.error=r}finally{cr(e,t)}i?e.value=n:(e.value=o,e.version++)}};let Wg=function yI(){throw new Error};function qg(e){Wg(e)}function bI(e,n){const t=Object.create(Yg);t.value=e,void 0!==n&&(t.equal=n);const o=()=>function DI(e){return Vs(e),e.value}(t);return o[We]=t,[o,s=>Gc(t,s),s=>function Zg(e,n){zg()||qg(e),Gc(e,n(e.value))}(t,s)]}function Gc(e,n){zg()||qg(e),e.equal(e.value,n)||(e.value=n,function wI(e){e.version++,function fI(){Hc++}(),$g(e)}(e))}const Yg={...Qo,equal:zc,value:void 0,kind:"signal"};function ke(e){return"function"==typeof e}function Qg(e){const t=e(o=>{Error.call(o),o.stack=(new Error).stack});return t.prototype=Object.create(Error.prototype),t.prototype.constructor=t,t}const Wc=Qg(e=>function(t){e(this),this.message=t?`${t.length} errors occurred during unsubscription:\n${t.map((o,i)=>`${i+1}) ${o.toString()}`).join("\n ")}`:"",this.name="UnsubscriptionError",this.errors=t});function Us(e,n){if(e){const t=e.indexOf(n);0<=t&&e.splice(t,1)}}class It{constructor(n){this.initialTeardown=n,this.closed=!1,this._parentage=null,this._finalizers=null}unsubscribe(){let n;if(!this.closed){this.closed=!0;const{_parentage:t}=this;if(t)if(this._parentage=null,Array.isArray(t))for(const r of t)r.remove(this);else t.remove(this);const{initialTeardown:o}=this;if(ke(o))try{o()}catch(r){n=r instanceof Wc?r.errors:[r]}const{_finalizers:i}=this;if(i){this._finalizers=null;for(const r of i)try{Xg(r)}catch(s){n=n??[],s instanceof Wc?n=[...n,...s.errors]:n.push(s)}}if(n)throw new Wc(n)}}add(n){var t;if(n&&n!==this)if(this.closed)Xg(n);else{if(n instanceof It){if(n.closed||n._hasParent(this))return;n._addParent(this)}(this._finalizers=null!==(t=this._finalizers)&&void 0!==t?t:[]).push(n)}}_hasParent(n){const{_parentage:t}=this;return t===n||Array.isArray(t)&&t.includes(n)}_addParent(n){const{_parentage:t}=this;this._parentage=Array.isArray(t)?(t.push(n),t):t?[t,n]:n}_removeParent(n){const{_parentage:t}=this;t===n?this._parentage=null:Array.isArray(t)&&Us(t,n)}remove(n){const{_finalizers:t}=this;t&&Us(t,n),n instanceof It&&n._removeParent(this)}}It.EMPTY=(()=>{const e=new It;return e.closed=!0,e})();const Kg=It.EMPTY;function Jg(e){return e instanceof It||e&&"closed"in e&&ke(e.remove)&&ke(e.add)&&ke(e.unsubscribe)}function Xg(e){ke(e)?e():e.unsubscribe()}const co={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1},$s={setTimeout(e,n,...t){const{delegate:o}=$s;return o?.setTimeout?o.setTimeout(e,n,...t):setTimeout(e,n,...t)},clearTimeout(e){const{delegate:n}=$s;return(n?.clearTimeout||clearTimeout)(e)},delegate:void 0};function ep(e){$s.setTimeout(()=>{const{onUnhandledError:n}=co;if(!n)throw e;n(e)})}function tp(){}const EI=qc("C",void 0,void 0);function qc(e,n,t){return{kind:e,value:n,error:t}}let uo=null;function zs(e){if(co.useDeprecatedSynchronousErrorHandling){const n=!uo;if(n&&(uo={errorThrown:!1,error:null}),e(),n){const{errorThrown:t,error:o}=uo;if(uo=null,t)throw o}}else e()}class Zc extends It{constructor(n){super(),this.isStopped=!1,n?(this.destination=n,Jg(n)&&n.add(this)):this.destination=OI}static create(n,t,o){return new Qc(n,t,o)}next(n){this.isStopped?Kc(function II(e){return qc("N",e,void 0)}(n),this):this._next(n)}error(n){this.isStopped?Kc(function MI(e){return qc("E",void 0,e)}(n),this):(this.isStopped=!0,this._error(n))}complete(){this.isStopped?Kc(EI,this):(this.isStopped=!0,this._complete())}unsubscribe(){this.closed||(this.isStopped=!0,super.unsubscribe(),this.destination=null)}_next(n){this.destination.next(n)}_error(n){try{this.destination.error(n)}finally{this.unsubscribe()}}_complete(){try{this.destination.complete()}finally{this.unsubscribe()}}}const SI=Function.prototype.bind;function Yc(e,n){return SI.call(e,n)}class AI{constructor(n){this.partialObserver=n}next(n){const{partialObserver:t}=this;if(t.next)try{t.next(n)}catch(o){Gs(o)}}error(n){const{partialObserver:t}=this;if(t.error)try{t.error(n)}catch(o){Gs(o)}else Gs(n)}complete(){const{partialObserver:n}=this;if(n.complete)try{n.complete()}catch(t){Gs(t)}}}class Qc extends Zc{constructor(n,t,o){let i;if(super(),ke(n)||!n)i={next:n??void 0,error:t??void 0,complete:o??void 0};else{let r;this&&co.useDeprecatedNextContext?(r=Object.create(n),r.unsubscribe=()=>this.unsubscribe(),i={next:n.next&&Yc(n.next,r),error:n.error&&Yc(n.error,r),complete:n.complete&&Yc(n.complete,r)}):i=n}this.destination=new AI(i)}}function Gs(e){co.useDeprecatedSynchronousErrorHandling?function TI(e){co.useDeprecatedSynchronousErrorHandling&&uo&&(uo.errorThrown=!0,uo.error=e)}(e):ep(e)}function Kc(e,n){const{onStoppedNotification:t}=co;t&&$s.setTimeout(()=>t(e,n))}const OI={closed:!0,next:tp,error:function NI(e){throw e},complete:tp},Jc="function"==typeof Symbol&&Symbol.observable||"@@observable";function Xc(e){return e}let ht=(()=>{class e{constructor(t){t&&(this._subscribe=t)}lift(t){const o=new e;return o.source=this,o.operator=t,o}subscribe(t,o,i){const r=function RI(e){return e&&e instanceof Zc||function xI(e){return e&&ke(e.next)&&ke(e.error)&&ke(e.complete)}(e)&&Jg(e)}(t)?t:new Qc(t,o,i);return zs(()=>{const{operator:s,source:a}=this;r.add(s?s.call(r,a):a?this._subscribe(r):this._trySubscribe(r))}),r}_trySubscribe(t){try{return this._subscribe(t)}catch(o){t.error(o)}}forEach(t,o){return new(o=op(o))((i,r)=>{const s=new Qc({next:a=>{try{t(a)}catch(l){r(l),s.unsubscribe()}},error:r,complete:i});this.subscribe(s)})}_subscribe(t){var o;return null===(o=this.source)||void 0===o?void 0:o.subscribe(t)}[Jc](){return this}pipe(...t){return function np(e){return 0===e.length?Xc:1===e.length?e[0]:function(t){return e.reduce((o,i)=>i(o),t)}}(t)(this)}toPromise(t){return new(t=op(t))((o,i)=>{let r;this.subscribe(s=>r=s,s=>i(s),()=>o(r))})}}return e.create=n=>new e(n),e})();function op(e){var n;return null!==(n=e??co.Promise)&&void 0!==n?n:Promise}const kI=Qg(e=>function(){e(this),this.name="ObjectUnsubscribedError",this.message="object unsubscribed"});let Xt=(()=>{class e extends ht{constructor(){super(),this.closed=!1,this.currentObservers=null,this.observers=[],this.isStopped=!1,this.hasError=!1,this.thrownError=null}lift(t){const o=new ip(this,this);return o.operator=t,o}_throwIfClosed(){if(this.closed)throw new kI}next(t){zs(()=>{if(this._throwIfClosed(),!this.isStopped){this.currentObservers||(this.currentObservers=Array.from(this.observers));for(const o of this.currentObservers)o.next(t)}})}error(t){zs(()=>{if(this._throwIfClosed(),!this.isStopped){this.hasError=this.isStopped=!0,this.thrownError=t;const{observers:o}=this;for(;o.length;)o.shift().error(t)}})}complete(){zs(()=>{if(this._throwIfClosed(),!this.isStopped){this.isStopped=!0;const{observers:t}=this;for(;t.length;)t.shift().complete()}})}unsubscribe(){this.isStopped=this.closed=!0,this.observers=this.currentObservers=null}get observed(){var t;return(null===(t=this.observers)||void 0===t?void 0:t.length)>0}_trySubscribe(t){return this._throwIfClosed(),super._trySubscribe(t)}_subscribe(t){return this._throwIfClosed(),this._checkFinalizedStatuses(t),this._innerSubscribe(t)}_innerSubscribe(t){const{hasError:o,isStopped:i,observers:r}=this;return o||i?Kg:(this.currentObservers=null,r.push(t),new It(()=>{this.currentObservers=null,Us(r,t)}))}_checkFinalizedStatuses(t){const{hasError:o,thrownError:i,isStopped:r}=this;o?t.error(i):r&&t.complete()}asObservable(){const t=new ht;return t.source=this,t}}return e.create=(n,t)=>new ip(n,t),e})();class ip extends Xt{constructor(n,t){super(),this.destination=n,this.source=t}next(n){var t,o;null===(o=null===(t=this.destination)||void 0===t?void 0:t.next)||void 0===o||o.call(t,n)}error(n){var t,o;null===(o=null===(t=this.destination)||void 0===t?void 0:t.error)||void 0===o||o.call(t,n)}complete(){var n,t;null===(t=null===(n=this.destination)||void 0===n?void 0:n.complete)||void 0===t||t.call(n)}_subscribe(n){var t,o;return null!==(o=null===(t=this.source)||void 0===t?void 0:t.subscribe(n))&&void 0!==o?o:Kg}}class FI extends Xt{constructor(n){super(),this._value=n}get value(){return this.getValue()}_subscribe(n){const t=super._subscribe(n);return!t.closed&&n.next(this._value),t}getValue(){const{hasError:n,thrownError:t,_value:o}=this;if(n)throw t;return this._throwIfClosed(),o}next(n){super.next(this._value=n)}}const sp="https://angular.dev/best-practices/security#preventing-cross-site-scripting-xss";class T extends Error{code;constructor(n,t){super(function en(e,n){return`${function LI(e){return`NG0${Math.abs(e)}`}(e)}${n?": "+n:""}`}(n,t)),this.code=n}}const Ie=globalThis;function se(e){for(let n in e)if(e[n]===se)return n;throw Error("")}function PI(e,n){for(const t in n)n.hasOwnProperty(t)&&!e.hasOwnProperty(t)&&(e[t]=n[t])}function gt(e){if("string"==typeof e)return e;if(Array.isArray(e))return`[${e.map(gt).join(", ")}]`;if(null==e)return""+e;const n=e.overriddenName||e.name;if(n)return`${n}`;const t=e.toString();if(null==t)return""+t;const o=t.indexOf("\n");return o>=0?t.slice(0,o):t}function tu(e,n){return e?n?`${e} ${n}`:e:n||""}const VI=se({__forward_ref__:se});function ge(e){return e.__forward_ref__=ge,e.toString=function(){return gt(this())},e}function Q(e){return Ws(e)?e():e}function Ws(e){return"function"==typeof e&&e.hasOwnProperty(VI)&&e.__forward_ref__===ge}function X(e){return{token:e.token,providedIn:e.providedIn||null,factory:e.factory,value:void 0}}function dn(e){return{providers:e.providers||[],imports:e.imports||[]}}function qs(e){return function zI(e,n){return e.hasOwnProperty(n)&&e[n]||null}(e,Ys)}function Zs(e){return e&&e.hasOwnProperty(nu)?e[nu]:null}const Ys=se({\u0275prov:se}),nu=se({\u0275inj:se});class R{_desc;ngMetadataName="InjectionToken";\u0275prov;constructor(n,t){this._desc=n,this.\u0275prov=void 0,"number"==typeof t?this.__NG_ELEMENT_ID__=t:void 0!==t&&(this.\u0275prov=X({token:this,providedIn:t.providedIn||"root",factory:t.factory}))}get multi(){return this}toString(){return`InjectionToken ${this._desc}`}}function iu(e){return e&&!!e.\u0275providers}const ru=se({\u0275cmp:se}),QI=se({\u0275dir:se}),KI=se({\u0275pipe:se}),ap=se({\u0275mod:se}),ho=se({\u0275fac:se}),hr=se({__NG_ELEMENT_ID__:se}),lp=se({__NG_ENV_ID__:se});function Z(e){return"string"==typeof e?e:null==e?"":String(e)}const su=se({ngErrorCode:se}),cp=se({ngErrorMessage:se}),gr=se({ngTokenPath:se});function au(e,n){return up("",-200,n)}function lu(e,n){throw new T(-201,!1)}function up(e,n,t){const o=new T(n,e);return o[su]=n,o[cp]=e,t&&(o[gr]=t),o}let cu;function dp(){return cu}function pt(e){const n=cu;return cu=e,n}function fp(e,n,t){const o=qs(e);return o&&"root"==o.providedIn?void 0===o.value?o.value=o.factory():o.value:8&t?null:void 0!==n?n:void lu()}const go={};class oT{injector;constructor(n){this.injector=n}retrieve(n,t){const o=pr(t)||0;try{return this.injector.get(n,8&o?null:go,o)}catch(i){if(Vc(i))return i;throw i}}}function iT(e,n=0){const t=sr();if(void 0===t)throw new T(-203,!1);if(null===t)return fp(e,void 0,n);{const o=function rT(e){return{optional:!!(8&e),host:!!(1&e),self:!!(2&e),skipSelf:!!(4&e)}}(n),i=t.retrieve(e,o);if(Vc(i)){if(o.optional)return null;throw i}return i}}function oe(e,n=0){return(dp()||iT)(Q(e),n)}function F(e,n){return oe(e,pr(n))}function pr(e){return typeof e>"u"||"number"==typeof e?e:0|(e.optional&&8)|(e.host&&1)|(e.self&&2)|(e.skipSelf&&4)}function du(e){const n=[];for(let t=0;tArray.isArray(t)?ei(t,n):n(t))}function gp(e,n,t){n>=e.length?e.push(t):e.splice(n,0,t)}function Ks(e,n){return n>=e.length-1?e.pop():e.splice(n,1)[0]}function Xs(e,n,t){let o=_r(e,n);return o>=0?e[1|o]=t:(o=~o,function mp(e,n,t,o){let i=e.length;if(i==n)e.push(t,o);else if(1===i)e.push(o,e[0]),e[0]=t;else{for(i--,e.push(e[i-1],e[i]);i>n;)e[i]=e[i-2],i--;e[n]=t,e[n+1]=o}}(e,o,n,t)),o}function fu(e,n){const t=_r(e,n);if(t>=0)return e[1|t]}function _r(e,n){return function lT(e,n,t){let o=0,i=e.length>>t;for(;i!==o;){const r=o+(i-o>>1),s=e[r<n?i=r:o=r+1}return~(i<{t.push(s)};return ei(n,s=>{const a=s;ta(a,r,[],o)&&(i||=[],i.push(a))}),void 0!==i&&yp(i,r),t}function yp(e,n){for(let t=0;t{n(r,o)})}}function ta(e,n,t,o){if(!(e=Q(e)))return!1;let i=null,r=Zs(e);const s=!r&&le(e);if(r||s){if(s&&!s.standalone)return!1;i=e}else{const l=e.ngModule;if(r=Zs(l),!r)return!1;i=l}const a=o.has(i);if(s){if(a)return!1;if(o.add(i),s.dependencies){const l="function"==typeof s.dependencies?s.dependencies():s.dependencies;for(const c of l)ta(c,n,t,o)}}else{if(!r)return!1;{if(null!=r.imports&&!a){let c;o.add(i);try{ei(r.imports,u=>{ta(u,n,t,o)&&(c||=[],c.push(u))})}finally{}void 0!==c&&yp(c,n)}if(!a){const c=po(i)||(()=>new i);n({provide:i,useFactory:c,deps:_e},i),n({provide:hu,useValue:i,multi:!0},i),n({provide:mo,useValue:()=>oe(i),multi:!0},i)}const l=r.providers;if(null!=l&&!a){const c=e;mu(l,u=>{n(u,c)})}}}return i!==e&&void 0!==e.providers}function mu(e,n){for(let t of e)iu(t)&&(t=t.\u0275providers),Array.isArray(t)?mu(t,n):n(t)}const dT=se({provide:String,useValue:se});function _u(e){return null!==e&&"object"==typeof e&&dT in e}function fn(e){return"function"==typeof e}const vu=new R(""),na={},wp={};let yu;function Cu(){return void 0===yu&&(yu=new ea),yu}class Lt{}class _o extends Lt{parent;source;scopes;records=new Map;_ngOnDestroyHooks=new Set;_onDestroyHooks=[];get destroyed(){return this._destroyed}_destroyed=!1;injectorDefTypes;constructor(n,t,o,i){super(),this.parent=t,this.source=o,this.scopes=i,Du(n,s=>this.processProvider(s)),this.records.set(_p,ti(void 0,this)),i.has("environment")&&this.records.set(Lt,ti(void 0,this));const r=this.records.get(vu);null!=r&&"string"==typeof r.value&&this.scopes.add(r.value),this.injectorDefTypes=new Set(this.get(hu,_e,{self:!0}))}retrieve(n,t){const o=pr(t)||0;try{return this.get(n,go,o)}catch(i){if(Vc(i))return i;throw i}}destroy(){yr(this),this._destroyed=!0;const n=z(null);try{for(const o of this._ngOnDestroyHooks)o.ngOnDestroy();const t=this._onDestroyHooks;this._onDestroyHooks=[];for(const o of t)o()}finally{this.records.clear(),this._ngOnDestroyHooks.clear(),this.injectorDefTypes.clear(),z(n)}}onDestroy(n){return yr(this),this._onDestroyHooks.push(n),()=>this.removeOnDestroy(n)}runInContext(n){yr(this);const t=un(this),o=pt(void 0);try{return n()}finally{un(t),pt(o)}}get(n,t=go,o){if(yr(this),n.hasOwnProperty(lp))return n[lp](this);const i=pr(o),s=un(this),a=pt(void 0);try{if(!(4&i)){let c=this.records.get(n);if(void 0===c){const u=function mT(e){return"function"==typeof e||"object"==typeof e&&"InjectionToken"===e.ngMetadataName}(n)&&qs(n);c=u&&this.injectableDefInScope(u)?ti(bu(n),na):null,this.records.set(n,c)}if(null!=c)return this.hydrate(n,c,i)}return(2&i?Cu():this.parent).get(n,t=8&i&&t===go?null:t)}catch(l){const c=function tT(e){return e[su]}(l);throw-200===c||-201===c?new T(c,null):l}finally{pt(a),un(s)}}resolveInjectorInitializers(){const n=z(null),t=un(this),o=pt(void 0);try{const r=this.get(mo,_e,{self:!0});for(const s of r)s()}finally{un(t),pt(o),z(n)}}toString(){const n=[],t=this.records;for(const o of t.keys())n.push(gt(o));return`R3Injector[${n.join(", ")}]`}processProvider(n){let t=fn(n=Q(n))?n:Q(n&&n.provide);const o=function hT(e){return _u(e)?ti(void 0,e.useValue):ti(Ep(e),na)}(n);if(!fn(n)&&!0===n.multi){let i=this.records.get(t);i||(i=ti(void 0,na,!0),i.factory=()=>du(i.multi),this.records.set(t,i)),t=n,i.multi.push(n)}this.records.set(t,o)}hydrate(n,t,o){const i=z(null);try{if(t.value===wp)throw au(gt(n));return t.value===na&&(t.value=wp,t.value=t.factory(void 0,o)),"object"==typeof t.value&&t.value&&function pT(e){return null!==e&&"object"==typeof e&&"function"==typeof e.ngOnDestroy}(t.value)&&this._ngOnDestroyHooks.add(t.value),t.value}finally{z(i)}}injectableDefInScope(n){if(!n.providedIn)return!1;const t=Q(n.providedIn);return"string"==typeof t?"any"===t||this.scopes.has(t):this.injectorDefTypes.has(t)}removeOnDestroy(n){const t=this._onDestroyHooks.indexOf(n);-1!==t&&this._onDestroyHooks.splice(t,1)}}function bu(e){const n=qs(e),t=null!==n?n.factory:po(e);if(null!==t)return t;if(e instanceof R)throw new T(204,!1);if(e instanceof Function)return function fT(e){if(e.length>0)throw new T(204,!1);const t=function GI(e){return(e?.[Ys]??null)||null}(e);return null!==t?()=>t.factory(e):()=>new e}(e);throw new T(204,!1)}function Ep(e,n,t){let o;if(fn(e)){const i=Q(e);return po(i)||bu(i)}if(_u(e))o=()=>Q(e.useValue);else if(function bp(e){return!(!e||!e.useFactory)}(e))o=()=>e.useFactory(...du(e.deps||[]));else if(function Cp(e){return!(!e||!e.useExisting)}(e))o=(i,r)=>oe(Q(e.useExisting),void 0!==r&&8&r?8:void 0);else{const i=Q(e&&(e.useClass||e.provide));if(!function gT(e){return!!e.deps}(e))return po(i)||bu(i);o=()=>new i(...du(e.deps))}return o}function yr(e){if(e.destroyed)throw new T(205,!1)}function ti(e,n,t=!1){return{factory:e,value:n,multi:t?[]:void 0}}function Du(e,n){for(const t of e)Array.isArray(t)?Du(t,n):t&&iu(t)?Du(t.\u0275providers,n):n(t)}function Mp(e,n){let t;e instanceof _o?(yr(e),t=e):t=new oT(e);const i=un(t),r=pt(void 0);try{return n()}finally{un(i),pt(r)}}function wu(){return void 0!==dp()||null!=sr()}const Y=11,H=27;function Me(e){return Array.isArray(e)&&"object"==typeof e[1]}function st(e){return Array.isArray(e)&&!0===e[1]}function Tp(e){return!!(4&e.flags)}function pn(e){return e.componentOffset>-1}function si(e){return!(1&~e.flags)}function At(e){return!!e.template}function Hn(e){return!!(512&e[2])}function mn(e){return!(256&~e[2])}function $e(e){for(;Array.isArray(e);)e=e[0];return e}function ai(e,n){return $e(n[e])}function Le(e,n){return $e(n[e.index])}function li(e,n){return e.data[n]}function at(e,n){const t=n[e];return Me(t)?t:t[0]}function Tu(e){return!(128&~e[2])}function tt(e,n){return null==n?null:e[n]}function Rp(e){e[17]=0}function kp(e){1024&e[2]||(e[2]|=1024,Tu(e)&&ci(e))}function sa(e){return!!(9216&e[2]||e[24]?.dirty)}function Su(e){e[10].changeDetectionScheduler?.notify(8),64&e[2]&&(e[2]|=1024),sa(e)&&ci(e)}function ci(e){e[10].changeDetectionScheduler?.notify(0);let n=_n(e);for(;null!==n&&!(8192&n[2])&&(n[2]|=8192,Tu(n));)n=_n(n)}function aa(e,n){if(mn(e))throw new T(911,!1);null===e[21]&&(e[21]=[]),e[21].push(n)}function _n(e){const n=e[3];return st(n)?n[3]:n}function Lp(e){return e[7]??=[]}function Pp(e){return e.cleanup??=[]}const G={lFrame:Jp(null),bindingsEnabled:!0,skipHydrationRootTNode:null};let Ou=!1;function xu(){return G.bindingsEnabled}function w(){return G.lFrame.lView}function K(){return G.lFrame.tView}function B(e){return G.lFrame.contextLView=e,e[8]}function j(e){return G.lFrame.contextLView=null,e}function q(){let e=Up();for(;null!==e&&64===e.type;)e=e.parent;return e}function Up(){return G.lFrame.currentTNode}function vn(e,n){const t=G.lFrame;t.currentTNode=e,t.isParent=n}function $p(){return G.lFrame.isParent}function qp(){return Ou}function la(e){const n=Ou;return Ou=e,n}function lt(){const e=G.lFrame;let n=e.bindingRootIndex;return-1===n&&(n=e.bindingRootIndex=e.tView.bindingStartIndex),n}function mt(){return G.lFrame.bindingIndex++}function Cn(e){const n=G.lFrame,t=n.bindingIndex;return n.bindingIndex=n.bindingIndex+e,t}function AT(e,n){const t=G.lFrame;t.bindingIndex=t.bindingRootIndex=e,Ru(n)}function Ru(e){G.lFrame.currentDirectiveIndex=e}function Fu(){return G.lFrame.currentQueryIndex}function ca(e){G.lFrame.currentQueryIndex=e}function OT(e){const n=e[1];return 2===n.type?n.declTNode:1===n.type?e[5]:null}function Qp(e,n,t){if(4&t){let i=n,r=e;for(;!(i=i.parent,null!==i||1&t||(i=OT(r),null===i||(r=r[14],10&i.type))););if(null===i)return!1;n=i,e=r}const o=G.lFrame=Kp();return o.currentTNode=n,o.lView=e,!0}function Lu(e){const n=Kp(),t=e[1];G.lFrame=n,n.currentTNode=t.firstChild,n.lView=e,n.tView=t,n.contextLView=e,n.bindingIndex=t.bindingStartIndex,n.inI18n=!1}function Kp(){const e=G.lFrame,n=null===e?null:e.child;return null===n?Jp(e):n}function Jp(e){const n={currentTNode:null,isParent:!0,lView:null,tView:null,selectedIndex:-1,contextLView:null,elementDepthCount:0,currentNamespace:null,currentDirectiveIndex:-1,bindingRootIndex:-1,bindingIndex:-1,currentQueryIndex:0,parent:e,child:null,inI18n:!1};return null!==e&&(e.child=n),n}function Xp(){const e=G.lFrame;return G.lFrame=e.parent,e.currentTNode=null,e.lView=null,e}const em=Xp;function Pu(){const e=Xp();e.isParent=!0,e.tView=null,e.selectedIndex=-1,e.contextLView=null,e.elementDepthCount=0,e.currentDirectiveIndex=-1,e.currentNamespace=null,e.bindingRootIndex=-1,e.bindingIndex=-1,e.currentQueryIndex=0}function qe(){return G.lFrame.selectedIndex}function Do(e){G.lFrame.selectedIndex=e}function on(){const e=G.lFrame;return li(e.tView,e.selectedIndex)}let nm=!0;function ua(){return nm}function wr(e){nm=e}function om(e,n=null,t=null,o){const i=im(e,n,t,o);return i.resolveInjectorInitializers(),i}function im(e,n=null,t=null,o,i=new Set){const r=[t||_e,uT(e)];return o=o||("object"==typeof e?void 0:gt(e)),new _o(r,n||Cu(),o||null,i)}class Vt{static THROW_IF_NOT_FOUND=go;static NULL=new ea;static create(n,t){if(Array.isArray(n))return om({name:""},t,n,"");{const o=n.name??"";return om({name:o},n.parent,n.providers,o)}}static \u0275prov=X({token:Vt,providedIn:"any",factory:()=>oe(_p)});static __NG_ELEMENT_ID__=-1}const Bn=new R("");let bn=(()=>class e{static __NG_ELEMENT_ID__=PT;static __NG_ENV_ID__=t=>t})();class rm extends bn{_lView;constructor(n){super(),this._lView=n}get destroyed(){return mn(this._lView)}onDestroy(n){const t=this._lView;return aa(t,n),()=>function Au(e,n){if(null===e[21])return;const t=e[21].indexOf(n);-1!==t&&e[21].splice(t,1)}(t,n)}}function PT(){return new rm(w())}class di{_console=console;handleError(n){this._console.error("ERROR",n)}}const Dn=new R("",{providedIn:"root",factory:()=>{const e=F(Lt);let n;return t=>{e.destroyed&&!n?setTimeout(()=>{throw t}):(n??=e.get(di),n.handleError(t))}}}),VT={provide:mo,useValue:()=>{F(di)},multi:!0};function wo(e,n){const[t,o,i]=bI(e,n?.equal),r=t;return r.set=o,r.update=i,r.asReadonly=Vu.bind(r),r}function Vu(){const e=this[We];if(void 0===e.readonlyFn){const n=()=>this();n[We]=e,e.readonlyFn=n}return e.readonlyFn}function am(e){return function sm(e){return"function"==typeof e&&void 0!==e[We]}(e)&&"function"==typeof e.set}let Hu=(()=>class e{view;node;constructor(t,o){this.view=t,this.node=o}static __NG_ELEMENT_ID__=BT})();function BT(){return new Hu(w(),q())}class fi{}const lm=new R("",{providedIn:"root",factory:()=>!1}),cm=new R(""),um=new R("");let Eo=(()=>{class e{taskId=0;pendingTasks=new Set;destroyed=!1;pendingTask=new FI(!1);get hasPendingTasks(){return!this.destroyed&&this.pendingTask.value}get hasPendingTasksObservable(){return this.destroyed?new ht(t=>{t.next(!1),t.complete()}):this.pendingTask}add(){!this.hasPendingTasks&&!this.destroyed&&this.pendingTask.next(!0);const t=this.taskId++;return this.pendingTasks.add(t),t}has(t){return this.pendingTasks.has(t)}remove(t){this.pendingTasks.delete(t),0===this.pendingTasks.size&&this.hasPendingTasks&&this.pendingTask.next(!1)}ngOnDestroy(){this.pendingTasks.clear(),this.hasPendingTasks&&this.pendingTask.next(!1),this.destroyed=!0,this.pendingTask.unsubscribe()}static \u0275prov=X({token:e,providedIn:"root",factory:()=>new e})}return e})();function Er(...e){}let fm=(()=>{class e{static \u0275prov=X({token:e,providedIn:"root",factory:()=>new jT})}return e})();class jT{dirtyEffectCount=0;queues=new Map;add(n){this.enqueue(n),this.schedule(n)}schedule(n){n.dirty&&this.dirtyEffectCount++}remove(n){const o=this.queues.get(n.zone);o.has(n)&&(o.delete(n),n.dirty&&this.dirtyEffectCount--)}enqueue(n){const t=n.zone;this.queues.has(t)||this.queues.set(t,new Set);const o=this.queues.get(t);o.has(n)||o.add(n)}flush(){for(;this.dirtyEffectCount>0;){let n=!1;for(const[t,o]of this.queues)n||=null===t?this.flushQueue(o):t.run(()=>this.flushQueue(o));n||(this.dirtyEffectCount=0)}}flushQueue(n){let t=!1;for(const o of n)o.dirty&&(this.dirtyEffectCount--,t=!0,o.run());return t}}let hm=null;function Mr(){return hm}class $T{}function Mo(e){return n=>{if(function E0(e){return ke(e?.lift)}(n))return n.lift(function(t){try{return e(t,this)}catch(o){this.error(o)}});throw new TypeError("Unable to lift unknown Observable type")}}function jn(e,n,t,o,i){return new M0(e,n,t,o,i)}class M0 extends Zc{constructor(n,t,o,i,r,s){super(n),this.onFinalize=r,this.shouldUnsubscribe=s,this._next=t?function(a){try{t(a)}catch(l){n.error(l)}}:super._next,this._error=i?function(a){try{i(a)}catch(l){n.error(l)}finally{this.unsubscribe()}}:super._error,this._complete=o?function(){try{o()}catch(a){n.error(a)}finally{this.unsubscribe()}}:super._complete}unsubscribe(){var n;if(!this.shouldUnsubscribe||this.shouldUnsubscribe()){const{closed:t}=this;super.unsubscribe(),!t&&(null===(n=this.onFinalize)||void 0===n||n.call(this))}}}function $u(e,n){return Mo((t,o)=>{let i=0;t.subscribe(jn(o,r=>{o.next(e.call(n,r,i++))}))})}function wn(e){return{toString:e}.toString()}class V0{previousValue;currentValue;firstChange;constructor(n,t,o){this.previousValue=n,this.currentValue=t,this.firstChange=o}isFirstChange(){return this.firstChange}}function Sm(e,n,t,o){null!==n?n.applyValueToInputSignal(n,o):e[t]=o}const En=(()=>{const e=()=>Am;return e.ngInherit=!0,e})();function Am(e){return e.type.prototype.ngOnChanges&&(e.setInput=B0),H0}function H0(){const e=Om(this),n=e?.current;if(n){const t=e.previous;if(t===tn)e.previous=n;else for(let o in n)t[o]=n[o];e.current=null,this.ngOnChanges(n)}}function B0(e,n,t,o,i){const r=this.declaredInputs[o],s=Om(e)||function j0(e,n){return e[Nm]=n}(e,{previous:tn,current:null}),a=s.current||(s.current={}),l=s.previous,c=l[r];a[r]=new V0(c&&c.currentValue,t,l===tn),Sm(e,n,i,t)}const Nm="__ngSimpleChanges__";function Om(e){return e[Nm]||null}const Io=[],fe=function(e,n=null,t){for(let o=0;o=o)break}else n[l]<0&&(e[17]+=65536),(a>14>16&&(3&e[2])===n&&(e[2]+=16384,km(a,r)):km(a,r)}class Or{factory;name;injectImpl;resolving=!1;canSeeViewProviders;multi;componentProviders;index;providerFactory;constructor(n,t,o,i){this.factory=n,this.name=i,this.canSeeViewProviders=t,this.injectImpl=o}}function Lm(e){return 3===e||4===e||6===e}function Pm(e){return 64===e.charCodeAt(0)}function vi(e,n){if(null!==n&&0!==n.length)if(null===e||0===e.length)e=n.slice();else{let t=-1;for(let o=0;on){s=r-1;break}}}for(;r>16}(e),o=n;for(;t>0;)o=o[14],t--;return o}let Yu=!0;function _a(e){const n=Yu;return Yu=e,n}let K0=0;const rn={};function va(e,n){const t=jm(e,n);if(-1!==t)return t;const o=n[1];o.firstCreatePass&&(e.injectorIndex=n.length,Qu(o.data,e),Qu(n,null),Qu(o.blueprint,null));const i=ya(e,n),r=e.injectorIndex;if(Zu(i)){const s=xr(i),a=Rr(i,n),l=a[1].data;for(let c=0;c<8;c++)n[r+c]=a[s+c]|l[s+c]}return n[r+8]=i,r}function Qu(e,n){e.push(0,0,0,0,0,0,0,0,n)}function jm(e,n){return-1===e.injectorIndex||e.parent&&e.parent.injectorIndex===e.injectorIndex||null===n[e.injectorIndex+8]?-1:e.injectorIndex}function ya(e,n){if(e.parent&&-1!==e.parent.injectorIndex)return e.parent.injectorIndex;let t=0,o=null,i=n;for(;null!==i;){if(o=Zm(i),null===o)return-1;if(t++,i=i[14],-1!==o.injectorIndex)return o.injectorIndex|t<<16}return-1}function Ku(e,n,t){!function J0(e,n,t){let o;"string"==typeof t?o=t.charCodeAt(0)||0:t.hasOwnProperty(hr)&&(o=t[hr]),null==o&&(o=t[hr]=K0++);const i=255&o;n.data[e+(i>>5)]|=1<=0?255&n:nS:n}(t);if("function"==typeof r){if(!Qp(n,e,o))return 1&o?Um(i,0,o):$m(n,t,o,i);try{let s;if(s=r(o),null!=s||8&o)return s;lu()}finally{em()}}else if("number"==typeof r){let s=null,a=jm(e,n),l=-1,c=1&o?n[15][5]:null;for((-1===a||4&o)&&(l=-1===a?ya(e,n):n[a+8],-1!==l&&qm(o,!1)?(s=n[1],a=xr(l),n=Rr(l,n)):a=-1);-1!==a;){const u=n[1];if(Wm(r,a,u.data)){const d=eS(a,n,t,s,o,c);if(d!==rn)return d}l=n[a+8],-1!==l&&qm(o,n[1].data[a+8]===c)&&Wm(r,a,n)?(s=u,a=xr(l),n=Rr(l,n)):a=-1}}return i}function eS(e,n,t,o,i,r){const s=n[1],a=s.data[e+8],u=Ca(a,s,t,null==o?pn(a)&&Yu:o!=s&&!!(3&a.type),1&i&&r===a);return null!==u?kr(n,s,u,a,i):rn}function Ca(e,n,t,o,i){const r=e.providerIndexes,s=n.data,a=1048575&r,l=e.directiveStart,u=r>>20,g=i?a+u:e.directiveEnd;for(let h=o?a:a+u;h=l&&p.type===t)return h}if(i){const h=s[l];if(h&&At(h)&&h.type===t)return l}return null}function kr(e,n,t,o,i){let r=e[t];const s=n.data;if(r instanceof Or){const a=r;if(a.resolving)throw function ne(e){return"function"==typeof e?e.name||e.toString():"object"==typeof e&&null!=e&&"function"==typeof e.type?e.type.name||e.type.toString():Z(e)}(s[t]),au();const l=_a(a.canSeeViewProviders);a.resolving=!0;const d=a.injectImpl?pt(a.injectImpl):null;Qp(e,o,0);try{r=e[t]=a.factory(void 0,i,s,e,o),n.firstCreatePass&&t>=o.directiveStart&&function G0(e,n,t){const{ngOnChanges:o,ngOnInit:i,ngDoCheck:r}=n.type.prototype;if(o){const s=Am(n);(t.preOrderHooks??=[]).push(e,s),(t.preOrderCheckHooks??=[]).push(e,s)}i&&(t.preOrderHooks??=[]).push(0-e,i),r&&((t.preOrderHooks??=[]).push(e,r),(t.preOrderCheckHooks??=[]).push(e,r))}(t,s[t],n)}finally{null!==d&&pt(d),_a(l),a.resolving=!1,em()}}return r}function Wm(e,n,t){return!!(t[n+(e>>5)]&1<{const n=e.prototype.constructor,t=n[ho]||Ju(n),o=Object.prototype;let i=Object.getPrototypeOf(e.prototype).constructor;for(;i&&i!==o;){const r=i[ho]||Ju(i);if(r&&r!==t)return r;i=Object.getPrototypeOf(i)}return r=>new r})}function Ju(e){return Ws(e)?()=>{const n=Ju(Q(e));return n&&n()}:po(e)}function Zm(e){const n=e[1],t=n.type;return 2===t?n.declTNode:1===t?e[5]:null}function dS(){return yi(q(),w())}function yi(e,n){return new Nt(Le(e,n))}let Nt=(()=>class e{nativeElement;constructor(t){this.nativeElement=t}static __NG_ELEMENT_ID__=dS})();function Xm(e){return e instanceof Nt?e.nativeElement:e}function fS(){return this._results[Symbol.iterator]()}class hS{_emitDistinctChangesOnly;dirty=!0;_onDirty=void 0;_results=[];_changesDetected=!1;_changes=void 0;length=0;first=void 0;last=void 0;get changes(){return this._changes??=new Xt}constructor(n=!1){this._emitDistinctChangesOnly=n}get(n){return this._results[n]}map(n){return this._results.map(n)}filter(n){return this._results.filter(n)}find(n){return this._results.find(n)}reduce(n,t){return this._results.reduce(n,t)}forEach(n){this._results.forEach(n)}some(n){return this._results.some(n)}toArray(){return this._results.slice()}toString(){return this._results.toString()}reset(n,t){this.dirty=!1;const o=function Ft(e){return e.flat(Number.POSITIVE_INFINITY)}(n);(this._changesDetected=!function aT(e,n,t){if(e.length!==n.length)return!1;for(let o=0;oBS}),BS="ng",y_=new R(""),C_=new R("",{providedIn:"platform",factory:()=>"unknown"}),b_=new R("",{providedIn:"root",factory:()=>$n().body?.querySelector("[ngCspNonce]")?.getAttribute("ngCspNonce")||null}),ZS=new R("",{providedIn:"root",factory:()=>!1});function Sa(e){return!(32&~e.flags)}function W_(e,n){const t=e.contentQueries;if(null!==t){const o=z(null);try{for(let i=0;ie,createScript:e=>e,createScriptURL:e=>e})}catch{}return Fa}()?.createHTML(e)||e}function K_(e){return function Td(){if(void 0===La&&(La=null,Ie.trustedTypes))try{La=Ie.trustedTypes.createPolicy("angular#unsafe-bypass",{createHTML:e=>e,createScript:e=>e,createScriptURL:e=>e})}catch{}return La}()?.createHTML(e)||e}class ev{changingThisBreaksApplicationSecurity;constructor(n){this.changingThisBreaksApplicationSecurity=n}toString(){return`SafeValue must use [property]=binding: ${this.changingThisBreaksApplicationSecurity} (see ${sp})`}}function Gn(e){return e instanceof ev?e.changingThisBreaksApplicationSecurity:e}function Br(e,n){const t=function O1(e){return e instanceof ev&&e.getTypeName()||null}(e);if(null!=t&&t!==n){if("ResourceURL"===t&&"URL"===n)return!0;throw new Error(`Required a safe ${n}, got a ${t} (see ${sp})`)}return t===n}class x1{inertDocumentHelper;constructor(n){this.inertDocumentHelper=n}getInertBodyElement(n){n=""+n;try{const t=(new window.DOMParser).parseFromString(Ei(n),"text/html").body;return null===t?this.inertDocumentHelper.getInertBodyElement(n):(t.firstChild?.remove(),t)}catch{return null}}}class R1{defaultDoc;inertDocument;constructor(n){this.defaultDoc=n,this.inertDocument=this.defaultDoc.implementation.createHTMLDocument("sanitization-inert")}getInertBodyElement(n){const t=this.inertDocument.createElement("template");return t.innerHTML=Ei(n),t}}const F1=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:\/?#]*(?:[\/?#]|$))/i;function Sd(e){return(e=String(e)).match(F1)?e:"unsafe:"+e}function In(e){const n={};for(const t of e.split(","))n[t]=!0;return n}function jr(...e){const n={};for(const t of e)for(const o in t)t.hasOwnProperty(o)&&(n[o]=!0);return n}const nv=In("area,br,col,hr,img,wbr"),ov=In("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),iv=In("rp,rt"),Ad=jr(nv,jr(ov,In("address,article,aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul")),jr(iv,In("a,abbr,acronym,audio,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video")),jr(iv,ov)),Nd=In("background,cite,href,itemtype,longdesc,poster,src,xlink:href"),rv=jr(Nd,In("abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,scope,scrolling,shape,size,sizes,span,srclang,srcset,start,summary,tabindex,target,title,translate,type,usemap,valign,value,vspace,width"),In("aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-checked,aria-colcount,aria-colindex,aria-colspan,aria-controls,aria-current,aria-describedby,aria-details,aria-disabled,aria-dropeffect,aria-errormessage,aria-expanded,aria-flowto,aria-grabbed,aria-haspopup,aria-hidden,aria-invalid,aria-keyshortcuts,aria-label,aria-labelledby,aria-level,aria-live,aria-modal,aria-multiline,aria-multiselectable,aria-orientation,aria-owns,aria-placeholder,aria-posinset,aria-pressed,aria-readonly,aria-relevant,aria-required,aria-roledescription,aria-rowcount,aria-rowindex,aria-rowspan,aria-selected,aria-setsize,aria-sort,aria-valuemax,aria-valuemin,aria-valuenow,aria-valuetext")),L1=In("script,style,template");class P1{sanitizedSomething=!1;buf=[];sanitizeChildren(n){let t=n.firstChild,o=!0,i=[];for(;t;)if(t.nodeType===Node.ELEMENT_NODE?o=this.startElement(t):t.nodeType===Node.TEXT_NODE?this.chars(t.nodeValue):this.sanitizedSomething=!0,o&&t.firstChild)i.push(t),t=B1(t);else for(;t;){t.nodeType===Node.ELEMENT_NODE&&this.endElement(t);let r=H1(t);if(r){t=r;break}t=i.pop()}return this.buf.join("")}startElement(n){const t=sv(n).toLowerCase();if(!Ad.hasOwnProperty(t))return this.sanitizedSomething=!0,!L1.hasOwnProperty(t);this.buf.push("<"),this.buf.push(t);const o=n.attributes;for(let i=0;i"),!0}endElement(n){const t=sv(n).toLowerCase();Ad.hasOwnProperty(t)&&!nv.hasOwnProperty(t)&&(this.buf.push(""))}chars(n){this.buf.push(lv(n))}}function H1(e){const n=e.nextSibling;if(n&&e!==n.previousSibling)throw av(n);return n}function B1(e){const n=e.firstChild;if(n&&function V1(e,n){return(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_CONTAINED_BY)!==Node.DOCUMENT_POSITION_CONTAINED_BY}(e,n))throw av(n);return n}function sv(e){const n=e.nodeName;return"string"==typeof n?n:"FORM"}function av(e){return new Error(`Failed to sanitize html because the element is clobbered: ${e.outerHTML}`)}const j1=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,U1=/([^\#-~ |!])/g;function lv(e){return e.replace(/&/g,"&").replace(j1,function(n){return"&#"+(1024*(n.charCodeAt(0)-55296)+(n.charCodeAt(1)-56320)+65536)+";"}).replace(U1,function(n){return"&#"+n.charCodeAt(0)+";"}).replace(//g,">")}let Pa;function Od(e){return"content"in e&&function z1(e){return e.nodeType===Node.ELEMENT_NODE&&"TEMPLATE"===e.nodeName}(e)?e.content:null}function Va(e,n,t){return e.createElement(n,t)}function So(e,n,t,o,i){e.insertBefore(n,t,o,i)}function dv(e,n,t){e.appendChild(n,t)}function fv(e,n,t,o,i){null!==o?So(e,n,t,o,i):dv(e,n,t)}function Ur(e,n,t,o){e.removeChild(null,n,t,o)}function gv(e,n,t){const{mergedAttrs:o,classes:i,styles:r}=t;null!==o&&function Y0(e,n,t){let o=0;for(;o-1){let r;for(;++ir?"":i[u+1].toLowerCase(),2&o&&c!==d){if(Wt(o))return!1;s=!0}}}}else{if(!s&&!Wt(o)&&!Wt(l))return!1;if(s&&Wt(l))continue;s=!1,o=l|1&o}}return Wt(o)||s}function Wt(e){return!(1&e)}function mA(e,n,t,o){if(null===n)return-1;let i=0;if(o||!t){let r=!1;for(;i-1)for(t++;t0?'="'+a+'"':"")+"]"}else 8&o?i+="."+s:4&o&&(i+=" "+s);else""!==i&&!Wt(s)&&(n+=wv(r,i),i=""),o=s,r=r||!Wt(o);t++}return""!==i&&(n+=wv(r,i)),n}const ce={};function Fd(e,n,t,o,i,r,s,a,l,c,u){const d=H+o,g=d+i,h=function EA(e,n){const t=[];for(let o=0;onull),s=o;if(n&&"object"==typeof n){const l=n;i=l.next?.bind(l),r=l.error?.bind(l),s=l.complete?.bind(l)}this.__isAsync&&(r=this.wrapInTimeout(r),i&&(i=this.wrapInTimeout(i)),s&&(s=this.wrapInTimeout(s)));const a=super.subscribe({next:i,error:r,complete:s});return n instanceof It&&n.add(a),a}wrapInTimeout(n){return t=>{const o=this.pendingTasks?.add();setTimeout(()=>{try{n(t)}finally{void 0!==o&&this.pendingTasks?.remove(o)}})}}};function Ov(e){let n,t;function o(){e=Er;try{void 0!==t&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(t),void 0!==n&&clearTimeout(n)}catch{}}return n=setTimeout(()=>{e(),o()}),"function"==typeof requestAnimationFrame&&(t=requestAnimationFrame(()=>{e(),o()})),()=>o()}function xv(e){return queueMicrotask(()=>e()),()=>{e=Er}}const jd="isAngularZone",za=jd+"_ID";let xA=0;class re{hasPendingMacrotasks=!1;hasPendingMicrotasks=!1;isStable=!0;onUnstable=new ve(!1);onMicrotaskEmpty=new ve(!1);onStable=new ve(!1);onError=new ve(!1);constructor(n){const{enableLongStackTrace:t=!1,shouldCoalesceEventChangeDetection:o=!1,shouldCoalesceRunChangeDetection:i=!1,scheduleInRootZone:r=Nv}=n;if(typeof Zone>"u")throw new T(908,!1);Zone.assertZonePatched();const s=this;s._nesting=0,s._outer=s._inner=Zone.current,Zone.TaskTrackingZoneSpec&&(s._inner=s._inner.fork(new Zone.TaskTrackingZoneSpec)),t&&Zone.longStackTraceZoneSpec&&(s._inner=s._inner.fork(Zone.longStackTraceZoneSpec)),s.shouldCoalesceEventChangeDetection=!i&&o,s.shouldCoalesceRunChangeDetection=i,s.callbackScheduled=!1,s.scheduleInRootZone=r,function FA(e){const n=()=>{!function kA(e){function n(){Ov(()=>{e.callbackScheduled=!1,$d(e),e.isCheckStableRunning=!0,Ud(e),e.isCheckStableRunning=!1})}e.isCheckStableRunning||e.callbackScheduled||(e.callbackScheduled=!0,e.scheduleInRootZone?Zone.root.run(()=>{n()}):e._outer.run(()=>{n()}),$d(e))}(e)},t=xA++;e._inner=e._inner.fork({name:"angular",properties:{[jd]:!0,[za]:t,[za+t]:!0},onInvokeTask:(o,i,r,s,a,l)=>{if(function LA(e){return Fv(e,"__ignore_ng_zone__")}(l))return o.invokeTask(r,s,a,l);try{return Rv(e),o.invokeTask(r,s,a,l)}finally{(e.shouldCoalesceEventChangeDetection&&"eventTask"===s.type||e.shouldCoalesceRunChangeDetection)&&n(),kv(e)}},onInvoke:(o,i,r,s,a,l,c)=>{try{return Rv(e),o.invoke(r,s,a,l,c)}finally{e.shouldCoalesceRunChangeDetection&&!e.callbackScheduled&&!function PA(e){return Fv(e,"__scheduler_tick__")}(l)&&n(),kv(e)}},onHasTask:(o,i,r,s)=>{o.hasTask(r,s),i===r&&("microTask"==s.change?(e._hasPendingMicrotasks=s.microTask,$d(e),Ud(e)):"macroTask"==s.change&&(e.hasPendingMacrotasks=s.macroTask))},onHandleError:(o,i,r,s)=>(o.handleError(r,s),e.runOutsideAngular(()=>e.onError.emit(s)),!1)})}(s)}static isInAngularZone(){return typeof Zone<"u"&&!0===Zone.current.get(jd)}static assertInAngularZone(){if(!re.isInAngularZone())throw new T(909,!1)}static assertNotInAngularZone(){if(re.isInAngularZone())throw new T(909,!1)}run(n,t,o){return this._inner.run(n,t,o)}runTask(n,t,o,i){const r=this._inner,s=r.scheduleEventTask("NgZoneEvent: "+i,n,RA,Er,Er);try{return r.runTask(s,t,o)}finally{r.cancelTask(s)}}runGuarded(n,t,o){return this._inner.runGuarded(n,t,o)}runOutsideAngular(n){return this._outer.run(n)}}const RA={};function Ud(e){if(0==e._nesting&&!e.hasPendingMicrotasks&&!e.isStable)try{e._nesting++,e.onMicrotaskEmpty.emit(null)}finally{if(e._nesting--,!e.hasPendingMicrotasks)try{e.runOutsideAngular(()=>e.onStable.emit(null))}finally{e.isStable=!0}}}function $d(e){e.hasPendingMicrotasks=!!(e._hasPendingMicrotasks||(e.shouldCoalesceEventChangeDetection||e.shouldCoalesceRunChangeDetection)&&!0===e.callbackScheduled)}function Rv(e){e._nesting++,e.isStable&&(e.isStable=!1,e.onUnstable.emit(null))}function kv(e){e._nesting--,Ud(e)}class zd{hasPendingMicrotasks=!1;hasPendingMacrotasks=!1;isStable=!0;onUnstable=new ve;onMicrotaskEmpty=new ve;onStable=new ve;onError=new ve;run(n,t,o){return n.apply(t,o)}runGuarded(n,t,o){return n.apply(t,o)}runOutsideAngular(n){return n()}runTask(n,t,o,i){return n.apply(t,o)}}function Fv(e,n){return!(!Array.isArray(e)||1!==e.length)&&!0===e[0]?.data?.[n]}let Lv=(()=>{class e{impl=null;execute(){this.impl?.execute()}static \u0275prov=X({token:e,providedIn:"root",factory:()=>new e})}return e})();const Pv=[0,1,2,3];let HA=(()=>{class e{ngZone=F(re);scheduler=F(fi);errorHandler=F(di,{optional:!0});sequences=new Set;deferredRegistrations=new Set;executing=!1;constructor(){F(Wr,{optional:!0})}execute(){const t=this.sequences.size>0;t&&fe(16),this.executing=!0;for(const o of Pv)for(const i of this.sequences)if(!i.erroredOrDestroyed&&i.hooks[o])try{i.pipelinedValue=this.ngZone.runOutsideAngular(()=>this.maybeTrace(()=>(0,i.hooks[o])(i.pipelinedValue),i.snapshot))}catch(r){i.erroredOrDestroyed=!0,this.errorHandler?.handleError(r)}this.executing=!1;for(const o of this.sequences)o.afterRun(),o.once&&(this.sequences.delete(o),o.destroy());for(const o of this.deferredRegistrations)this.sequences.add(o);this.deferredRegistrations.size>0&&this.scheduler.notify(7),this.deferredRegistrations.clear(),t&&fe(17)}register(t){const{view:o}=t;void 0!==o?((o[25]??=[]).push(t),ci(o),o[2]|=8192):this.executing?this.deferredRegistrations.add(t):this.addSequence(t)}addSequence(t){this.sequences.add(t),this.scheduler.notify(7)}unregister(t){this.executing&&this.sequences.has(t)?(t.erroredOrDestroyed=!0,t.pipelinedValue=void 0,t.once=!0):(this.sequences.delete(t),this.deferredRegistrations.delete(t))}maybeTrace(t,o){return o?o.run(Bd.AFTER_NEXT_RENDER,t):t()}static \u0275prov=X({token:e,providedIn:"root",factory:()=>new e})}return e})();class Vv{impl;hooks;view;once;snapshot;erroredOrDestroyed=!1;pipelinedValue=void 0;unregisterOnDestroy;constructor(n,t,o,i,r,s=null){this.impl=n,this.hooks=t,this.view=o,this.once=i,this.snapshot=s,this.unregisterOnDestroy=r?.onDestroy(()=>this.destroy())}afterRun(){this.erroredOrDestroyed=!1,this.pipelinedValue=void 0,this.snapshot?.dispose(),this.snapshot=null}destroy(){this.impl.unregister(this),this.unregisterOnDestroy?.();const n=this.view?.[25];n&&(this.view[25]=n.filter(t=>t!==this))}}function Gd(e,n){const t=n?.injector??F(Vt);return nt("NgAfterNextRender"),function Hv(e,n,t,o){const i=n.get(Lv);i.impl??=n.get(HA);const r=n.get(Wr,null,{optional:!0}),s=!0!==t?.manualCleanup?n.get(bn):null,a=n.get(Hu,null,{optional:!0}),l=new Vv(i.impl,function jA(e){return e instanceof Function?[void 0,void 0,e,void 0]:[e.earlyRead,e.write,e.mixedReadWrite,e.read]}(e),a?.view,o,s,r?.snapshot(null));return i.impl.register(l),l}(e,t,n,!0)}const Ga=new R("",{providedIn:"root",factory:()=>({queue:new Set,isScheduled:!1,scheduler:null})});function Bv(e,n,t){const o=e.get(Ga);if(Array.isArray(n))for(const i of n)o.queue.add(i),t?.detachedLeaveAnimationFns?.push(i);else o.queue.add(n),t?.detachedLeaveAnimationFns?.push(n);o.scheduler&&o.scheduler(e)}function jv(e,n,t,o){const i=e?.[26]?.enter;null!==n&&i&&i.has(t.index)&&function Wd(e,n){for(const[t,o]of n)Bv(e,o.animateFns)}(o,i)}function Si(e,n,t,o,i,r,s,a){if(null!=i){let l,c=!1;st(i)?l=i:Me(i)&&(c=!0,i=i[0]);const u=$e(i);0===e&&null!==o?(jv(a,o,r,t),null==s?dv(n,o,u):So(n,o,u,s||null,!0)):1===e&&null!==o?(jv(a,o,r,t),So(n,o,u,s||null,!0)):2===e?zv(a,r,t,d=>{Ur(n,u,c,d)}):3===e&&zv(a,r,t,()=>{n.destroyNode(u)}),null!=l&&function QA(e,n,t,o,i,r,s){const a=o[7];a!==$e(o)&&Si(n,e,t,r,a,i,s);for(let c=10;c=0?o[a]():o[-a].unsubscribe(),s+=2}else t[s].call(o[t[s+1]]);null!==o&&(n[7]=null);const i=n[21];if(null!==i){n[21]=null;for(let s=0;s{if(i.leave&&i.leave.has(n.index)){const s=i.leave.get(n.index),a=[];if(s){for(let l=0;l{e[26].running=void 0,Ao.delete(e),n(!0)}):n(!1)}(e,o)}else e&&Ao.delete(e),o(!1)},i)}function Yd(e,n,t){return function Gv(e,n,t){let o=n;for(;null!==o&&168&o.type;)o=(n=o).parent;if(null===o)return t[0];if(pn(o)){const{encapsulation:i}=e.data[o.directiveStart+o.componentOffset];if(i===Mn.None||i===Mn.Emulated)return null}return Le(o,t)}(e,n.parent,t)}let Zv=function qv(e,n,t){return 40&e.type?Le(e,t):null};function Kd(e,n,t,o){const i=Yd(e,o,n),r=n[Y],a=function Wv(e,n,t){return Zv(e,n,t)}(o.parent||n[5],o,n);if(null!=i)if(Array.isArray(t))for(let l=0;lH&&Mv(e,n,H,!1),fe(s?2:0,i,t),t(o,i)}finally{Do(r),fe(s?3:1,i,t)}}function Ya(e,n,t){(function nN(e,n,t){const o=t.directiveStart,i=t.directiveEnd;pn(t)&&function MA(e,n,t){const o=Le(n,e),i=function Ev(e){const n=e.tView;return null===n||n.incompleteFirstPass?e.tView=Fd(1,null,e.template,e.decls,e.vars,e.directiveDefs,e.pipeDefs,e.viewQuery,e.schemas,e.consts,e.id):n}(t),r=e[10].rendererFactory,s=Pd(e,ja(e,i,null,Ld(t),o,n,null,r.createRenderer(o,t),null,null,null));e[n.index]=s}(n,t,e.data[o+t.componentOffset]),e.firstCreatePass||va(t,n);const r=t.initialInputs;for(let s=o;snull;function Xd(e,n,t,o,i,r){Xa(e,n[1],n,t,o)?pn(e)&&function ey(e,n){const t=at(n,e);16&t[2]||(t[2]|=64)}(n,e.index):(3&e.type&&(t=function tN(e){return"class"===e?"className":"for"===e?"htmlFor":"formaction"===e?"formAction":"innerHtml"===e?"innerHTML":"readonly"===e?"readOnly":"tabindex"===e?"tabIndex":e}(t)),function ef(e,n,t,o,i,r){if(3&e.type){const s=Le(e,n);o=null!=r?r(o,e.value||"",t):o,i.setProperty(s,t,o)}}(e,n,t,o,i,r))}function iN(e,n){null!==e.hostBindings&&e.hostBindings(1,n)}function tf(e,n){const t=e.directiveRegistry;let o=null;if(t)for(let i=0;i{ci(e.lView)},consumerOnSignalRead(){this.lView[24]=this}},_N={...Qo,consumerIsAlwaysLive:!0,kind:"template",consumerMarkedDirty:e=>{let n=_n(e.lView);for(;n&&!ry(n[1]);)n=_n(n);n&&kp(n)},consumerOnSignalRead(){this.lView[24]=this}};function ry(e){return 2!==e.type}function sy(e){if(null===e[23])return;let n=!0;for(;n;){let t=!1;for(const o of e[23])o.dirty&&(t=!0,null===o.zone||Zone.current===o.zone?o.run():o.zone.run(()=>o.run()));n=t&&!!(8192&e[2])}}function tl(e,n=0){const o=e[10].rendererFactory;o.begin?.();try{!function yN(e,n){const t=qp();try{la(!0),of(e,n);let o=0;for(;sa(e);){if(100===o)throw new T(103,!1);o++,of(e,1)}}finally{la(t)}}(e,n)}finally{o.end?.()}}function ay(e,n,t,o){if(mn(n))return;const i=n[2];Lu(n);let a=!0,l=null,c=null;ry(e)?(c=function fN(e){return e[24]??function hN(e){const n=iy.pop()??Object.create(pN);return n.lView=e,n}(e)}(n),l=Ko(c)):null===function jc(){return Je}()?(a=!1,c=function mN(e){const n=e[24]??Object.create(_N);return n.lView=e,n}(n),l=Ko(c)):n[24]&&(ur(n[24]),n[24]=null);try{Rp(n),function Zp(e){return G.lFrame.bindingIndex=e}(e.bindingStartIndex),null!==t&&Jv(e,n,t,2,o);const u=!(3&~i);if(u){const h=e.preOrderCheckHooks;null!==h&&pa(n,h,null)}else{const h=e.preOrderHooks;null!==h&&ma(n,h,0,null),Wu(n,0)}if(function CN(e){for(let n=u_(e);null!==n;n=d_(n)){if(!(2&n[2]))continue;const t=n[9];for(let o=0;o0&&(t[i-1][4]=n),o0&&(e[t-1][4]=o[4]);const r=Ks(e,10+n);!function Uv(e,n){$v(e,n),n[0]=null,n[5]=null}(o[1],o);const s=r[18];null!==s&&s.detachView(r[1]),o[3]=null,o[4]=null,o[2]&=-129}return o}function hy(e,n){const t=e[9],o=n[3];(Me(o)||n[15]!==o[3][15])&&(e[2]|=2),null===t?e[9]=[n]:t.push(n)}class Qr{_lView;_cdRefInjectingView;_appRef=null;_attachedToViewContainer=!1;exhaustive;get rootNodes(){const n=this._lView,t=n[1];return Zr(t,n,t.firstChild,[])}constructor(n,t){this._lView=n,this._cdRefInjectingView=t}get context(){return this._lView[8]}set context(n){this._lView[8]=n}get destroyed(){return mn(this._lView)}destroy(){if(this._appRef)this._appRef.detachView(this);else if(this._attachedToViewContainer){const n=this._lView[3];if(st(n)){const t=n[8],o=t?t.indexOf(this):-1;o>-1&&(Yr(n,o),Ks(t,o))}this._attachedToViewContainer=!1}qr(this._lView[1],this._lView)}onDestroy(n){aa(this._lView,n)}markForCheck(){Oi(this._cdRefInjectingView||this._lView,4)}detach(){this._lView[2]&=-129}reattach(){Su(this._lView),this._lView[2]|=128}detectChanges(){this._lView[2]|=1024,tl(this._lView)}checkNoChanges(){}attachToViewContainerRef(){if(this._appRef)throw new T(902,!1);this._attachedToViewContainer=!0}detachFromAppRef(){this._appRef=null;const n=Hn(this._lView),t=this._lView[16];null!==t&&!n&&qd(t,this._lView),$v(this._lView[1],this._lView)}attachToAppRef(n){if(this._attachedToViewContainer)throw new T(902,!1);this._appRef=n;const t=Hn(this._lView),o=this._lView[16];null!==o&&!t&&hy(o,this._lView),Su(this._lView)}}let Tn=(()=>class e{_declarationLView;_declarationTContainer;elementRef;static __NG_ELEMENT_ID__=EN;constructor(t,o,i){this._declarationLView=t,this._declarationTContainer=o,this.elementRef=i}get ssrId(){return this._declarationTContainer.tView?.ssrId||null}createEmbeddedView(t,o){return this.createEmbeddedViewImpl(t,o)}createEmbeddedViewImpl(t,o,i){const r=Ni(this._declarationLView,this._declarationTContainer,t,{embeddedViewInjector:o,dehydratedView:i});return new Qr(r)}})();function EN(){return nl(q(),w())}function nl(e,n){return 4&e.type?new Tn(n,e,yi(e,n)):null}function xo(e,n,t,o,i){let r=e.data[n];if(null===r)r=function cf(e,n,t,o,i){const r=Up(),s=$p(),l=e.data[n]=function RN(e,n,t,o,i,r){let s=n?n.injectorIndex:-1,a=0;return function Hp(){return null!==G.skipHydrationRootTNode}()&&(a|=128),{type:t,index:o,insertBeforeIndex:null,injectorIndex:s,directiveStart:-1,directiveEnd:-1,directiveStylingLast:-1,componentOffset:-1,propertyBindings:null,flags:a,providerIndexes:0,value:i,attrs:r,mergedAttrs:null,localNames:null,initialInputs:null,inputs:null,hostDirectiveInputs:null,outputs:null,hostDirectiveOutputs:null,directiveToIndex:null,tView:null,next:null,prev:null,projectionNext:null,child:null,parent:n,projection:null,styles:null,stylesWithoutHost:null,residualStyles:void 0,classes:null,classesWithoutHost:null,residualClasses:void 0,classBindings:0,styleBindings:0}}(0,s?r:r&&r.parent,t,n,o,i);return function xN(e,n,t,o){null===e.firstChild&&(e.firstChild=n),null!==t&&(o?null==t.child&&null!==n.parent&&(t.child=n):null===t.next&&(t.next=n,n.prev=t))}(e,l,r,s),l}(e,n,t,o,i),function ST(){return G.lFrame.inI18n}()&&(r.flags|=32);else if(64&r.type){r.type=t,r.value=o,r.attrs=i;const s=function Dr(){const e=G.lFrame,n=e.currentTNode;return e.isParent?n:n.parent}();r.injectorIndex=null===s?-1:s.injectorIndex}return vn(r,!0),r}function xy(e,n){let t=0,o=e.firstChild;if(o){const i=e.data.r;for(;tclass e{destroyNode=null;static __NG_ELEMENT_ID__=()=>function _O(){const e=w(),t=at(q().index,e);return(Me(t)?t:e)[Y]}()})(),vO=(()=>{class e{static \u0275prov=X({token:e,providedIn:"root",factory:()=>null})}return e})();const vf={};class Fi{injector;parentInjector;constructor(n,t){this.injector=n,this.parentInjector=t}get(n,t,o){const i=this.injector.get(n,vf,o);return i!==vf||t===vf?i:this.parentInjector.get(n,t,o)}}function fl(e,n,t){let o=t?e.styles:null,i=t?e.classes:null,r=0;if(null!==n)for(let s=0;s0&&(t.directiveToIndex=new Map);for(let g=0;g0;){const t=e[--n];if("number"==typeof t&&t<0)return t}return 0})(s)!=a&&s.push(a),s.push(t,o,r)}}(e,n,o,zr(e,t,i.hostVars,ce),i)}function NO(e,n,t){if(t){if(n.exportAs)for(let o=0;o{const[t,o,i]=e[n],r={propName:t,templateName:n,isSignal:0!==(o&Ua.SignalBased)};return i&&(r.transform=i),r})}(this.componentDef.inputs),this.cachedInputs}get outputs(){return this.cachedOutputs??=function GO(e){return Object.keys(e).map(n=>({propName:e[n],templateName:n}))}(this.componentDef.outputs),this.cachedOutputs}constructor(n,t){super(),this.componentDef=n,this.ngModule=t,this.componentType=n.type,this.selector=function DA(e){return e.map(bA).join(",")}(n.selectors),this.ngContentSelectors=n.ngContentSelectors??[],this.isBoundToModule=!!t}create(n,t,o,i,r,s){fe(22);const a=z(null);try{const l=this.componentDef,c=function QO(e,n,t,o){const i=e?["ng-version","20.3.15"]:function wA(e){const n=[],t=[];let o=1,i=2;for(;o{if(1&t&&e)for(const o of e)o.create();if(2&t&&n)for(const o of n)o.update()}:null}(r,s),1,a,l,null,null,null,[i],null)}(o,l,s,r),u=function WO(e,n,t){let o=n instanceof Lt?n:n?.injector;return o&&null!==e.getStandaloneInjector&&(o=e.getStandaloneInjector(o)||o),o?new Fi(t,o):t}(l,i||this.ngModule,n),d=function qO(e){const n=e.get(mf,null);if(null===n)throw new T(407,!1);return{rendererFactory:n,sanitizer:e.get(vO,null),changeDetectionScheduler:e.get(fi,null),ngReflect:!1}}(u),g=d.rendererFactory.createRenderer(null,l),h=o?function JA(e,n,t,o){const r=o.get(ZS,!1)||t===Mn.ShadowDom,s=e.selectRootElement(n,r);return function XA(e){Xv(e)}(s),s}(g,o,l.encapsulation,u):function ZO(e,n){const t=function YO(e){return(e.selectors[0][0]||"div").toLowerCase()}(e);return Va(n,t,"svg"===t?"svg":"math"===t?"math":null)}(l,g),p=s?.some(Qy)||r?.some(N=>"function"!=typeof N&&N.bindings.some(Qy)),b=ja(null,c,null,512|Ld(l),null,null,d,g,u,null,null);b[H]=h,Lu(b);let I=null;try{const N=yf(H,b,2,"#host",()=>c.directiveRegistry,!0,0);gv(g,h,N),vt(h,b),Ya(c,b,N),Ed(c,N,b),Cf(c,N),void 0!==t&&function XO(e,n,t){const o=e.projection=[];for(let i=0;iclass e{static __NG_ELEMENT_ID__=ex})();function ex(){return Xy(q(),w())}const tx=ln,Ky=class extends tx{_lContainer;_hostTNode;_hostLView;constructor(n,t,o){super(),this._lContainer=n,this._hostTNode=t,this._hostLView=o}get element(){return yi(this._hostTNode,this._hostLView)}get injector(){return new Se(this._hostTNode,this._hostLView)}get parentInjector(){const n=ya(this._hostTNode,this._hostLView);if(Zu(n)){const t=Rr(n,this._hostLView),o=xr(n);return new Se(t[1].data[o+8],t)}return new Se(null,this._hostLView)}clear(){for(;this.length>0;)this.remove(this.length-1)}get(n){const t=Jy(this._lContainer);return null!==t&&t[n]||null}get length(){return this._lContainer.length-10}createEmbeddedView(n,t,o){let i,r;"number"==typeof o?i=o:null!=o&&(i=o.index,r=o.injector);const a=n.createEmbeddedViewImpl(t||{},r,null);return this.insertImpl(a,i,Oo(this._hostTNode,null)),a}createComponent(n,t,o,i,r,s,a){const l=n&&!function Nr(e){return"function"==typeof e}(n);let c;if(l)c=t;else{const I=t||{};c=I.index,o=I.injector,i=I.projectableNodes,r=I.environmentInjector||I.ngModuleRef,s=I.directives,a=I.bindings}const u=l?n:new Df(le(n)),d=o||this.parentInjector;if(!r&&null==u.ngModule){const N=(l?d:this.parentInjector).get(Lt,null);N&&(r=N)}le(u.componentType??{});const b=u.create(d,i,null,r,s,a);return this.insertImpl(b.hostView,c,Oo(this._hostTNode,null)),b}insert(n,t){return this.insertImpl(n,t,!0)}insertImpl(n,t,o){const i=n._lView;if(function DT(e){return st(e[3])}(i)){const a=this.indexOf(n);if(-1!==a)this.detach(a);else{const l=i[3],c=new Ky(l,l[5],l[3]);c.detach(c.indexOf(n))}}const r=this._adjustIndex(t),s=this._lContainer;return xi(s,i,r,o),n.attachToViewContainerRef(),gp(wf(s),r,n),n}move(n,t){return this.insert(n,t)}indexOf(n){const t=Jy(this._lContainer);return null!==t?t.indexOf(n):-1}remove(n){const t=this._adjustIndex(n,-1),o=Yr(this._lContainer,t);o&&(Ks(wf(this._lContainer),t),qr(o[1],o))}detach(n){const t=this._adjustIndex(n,-1),o=Yr(this._lContainer,t);return o&&null!=Ks(wf(this._lContainer),t)?new Qr(o):null}_adjustIndex(n,t=0){return n??this.length+t}};function Jy(e){return e[8]}function wf(e){return e[8]||(e[8]=[])}function Xy(e,n){let t;const o=n[e.index];return st(o)?t=o:(t=dy(o,n,null,e),n[e.index]=t,Pd(n,t)),eC(t,n,e,o),new Ky(t,e,n)}let eC=function nC(e,n,t,o){if(e[7])return;let i;i=8&t.type?$e(o):function nx(e,n){const t=e[Y],o=t.createComment(""),i=Le(n,e),r=t.parentNode(i);return So(t,r,o,t.nextSibling(i),!1),o}(n,t),e[7]=i};class Mf{queryList;matches=null;constructor(n){this.queryList=n}clone(){return new Mf(this.queryList)}setDirty(){this.queryList.setDirty()}}class If{queries;constructor(n=[]){this.queries=n}createEmbeddedView(n){const t=n.queries;if(null!==t){const o=null!==n.contentQueries?n.contentQueries[0]:t.length,i=[];for(let r=0;rn.trim())}(n):n}}class Tf{queries;constructor(n=[]){this.queries=n}elementStart(n,t){for(let o=0;o0)o.push(s[a/2]);else{const c=r[a+1],u=n[-l];for(let d=10;dt()),this.destroyCbs=null}onDestroy(n){this.destroyCbs.push(n)}}class gC extends yx{moduleType;constructor(n){super(),this.moduleType=n}create(n){return new kf(this.moduleType,n,[])}}class Dx extends Fo{injector;componentFactoryResolver=new Yy(this);instance=null;constructor(n){super();const t=new _o([...n.providers,{provide:Fo,useValue:this},{provide:ul,useValue:this.componentFactoryResolver}],n.parent||Cu(),n.debugName,new Set(["environment"]));this.injector=t,n.runEnvironmentInitializers&&t.resolveInjectorInitializers()}destroy(){this.injector.destroy()}onDestroy(n){this.injector.onDestroy(n)}}let wx=(()=>{class e{_injector;cachedInjectors=new Map;constructor(t){this._injector=t}getOrCreateStandaloneInjector(t){if(!t.standalone)return null;if(!this.cachedInjectors.has(t)){const o=pu(0,t.type),i=o.length>0?function pC(e,n,t=null){return new Dx({providers:e,parent:n,debugName:t,runEnvironmentInitializers:!0}).injector}([o],this._injector,`Standalone[${t.type.name}]`):null;this.cachedInjectors.set(t,i)}return this.cachedInjectors.get(t)}ngOnDestroy(){try{for(const t of this.cachedInjectors.values())null!==t&&t.destroy()}finally{this.cachedInjectors.clear()}}static \u0275prov=X({token:e,providedIn:"environment",factory:()=>new e(oe(Lt))})}return e})();function qt(e){return wn(()=>{const n=_C(e),t={...n,decls:e.decls,vars:e.vars,template:e.template,consts:e.consts||null,ngContentSelectors:e.ngContentSelectors,onPush:e.changeDetection===Da.OnPush,directiveDefs:null,pipeDefs:null,dependencies:n.standalone&&e.dependencies||null,getStandaloneInjector:n.standalone?i=>i.get(wx).getOrCreateStandaloneInjector(t):null,getExternalStyles:null,signals:e.signals??!1,data:e.data||{},encapsulation:e.encapsulation||Mn.Emulated,styles:e.styles||_e,_:null,schemas:e.schemas||null,tView:null,id:""};n.standalone&&nt("NgStandalone"),vC(t);const o=e.dependencies;return t.directiveDefs=ml(o,mC),t.pipeDefs=ml(o,Gt),t.id=function Tx(e){let n=0;const o=[e.selectors,e.ngContentSelectors,e.hostVars,e.hostAttrs,"function"==typeof e.consts?"":e.consts,e.vars,e.decls,e.encapsulation,e.standalone,e.signals,e.exportAs,JSON.stringify(e.inputs),JSON.stringify(e.outputs),Object.getOwnPropertyNames(e.type.prototype),!!e.contentQueries,!!e.viewQuery];for(const r of o.join("|"))n=Math.imul(31,n)+r.charCodeAt(0)|0;return n+=2147483648,"c"+n}(t),t})}function mC(e){return le(e)||rt(e)}function Qn(e){return wn(()=>({type:e.type,bootstrap:e.bootstrap||_e,declarations:e.declarations||_e,imports:e.imports||_e,exports:e.exports||_e,transitiveCompileScopes:null,schemas:e.schemas||null,id:e.id||null}))}function Ex(e,n){if(null==e)return tn;const t={};for(const o in e)if(e.hasOwnProperty(o)){const i=e[o];let r,s,a,l;Array.isArray(i)?(a=i[0],r=i[1],s=i[2]??r,l=i[3]||null):(r=i,s=i,a=Ua.None,l=null),t[r]=[o,a,l],n[r]=s}return t}function Mx(e){if(null==e)return tn;const n={};for(const t in e)e.hasOwnProperty(t)&&(n[e[t]]=t);return n}function W(e){return wn(()=>{const n=_C(e);return vC(n),n})}function yt(e){return{type:e.type,name:e.name,factory:null,pure:!1!==e.pure,standalone:e.standalone??!0,onDestroy:e.type.prototype.ngOnDestroy||null}}function _C(e){const n={};return{type:e.type,providersResolver:null,factory:null,hostBindings:e.hostBindings||null,hostVars:e.hostVars||0,hostAttrs:e.hostAttrs||null,contentQueries:e.contentQueries||null,declaredInputs:n,inputConfig:e.inputs||tn,exportAs:e.exportAs||null,standalone:e.standalone??!0,signals:!0===e.signals,selectors:e.selectors||_e,viewQuery:e.viewQuery||null,features:e.features||null,setInput:null,resolveHostDirectives:null,hostDirectives:null,inputs:Ex(e.inputs,n),outputs:Mx(e.outputs),debugInfo:null}}function vC(e){e.features?.forEach(n=>n(e))}function ml(e,n){return e?()=>{const t="function"==typeof e?e():e,o=[];for(const i of t){const r=n(i);null!==r&&o.push(r)}return o}:null}function ae(e){let n=function yC(e){return Object.getPrototypeOf(e.prototype).constructor}(e.type),t=!0;const o=[e];for(;n;){let i;if(At(e))i=n.\u0275cmp||n.\u0275dir;else{if(n.\u0275cmp)throw new T(903,!1);i=n.\u0275dir}if(i){if(t){o.push(i);const s=e;s.inputs=Ff(e.inputs),s.declaredInputs=Ff(e.declaredInputs),s.outputs=Ff(e.outputs);const a=i.hostBindings;a&&xx(e,a);const l=i.viewQuery,c=i.contentQueries;if(l&&Nx(e,l),c&&Ox(e,c),Sx(e,i),PI(e.outputs,i.outputs),At(i)&&i.data.animation){const u=e.data;u.animation=(u.animation||[]).concat(i.data.animation)}}const r=i.features;if(r)for(let s=0;s=0;o--){const i=e[o];i.hostVars=n+=i.hostVars,i.hostAttrs=vi(i.hostAttrs,t=vi(t,i.hostAttrs))}}(o)}function Sx(e,n){for(const t in n.inputs){if(!n.inputs.hasOwnProperty(t)||e.inputs.hasOwnProperty(t))continue;const o=n.inputs[t];void 0!==o&&(e.inputs[t]=o,e.declaredInputs[t]=n.declaredInputs[t])}}function Ff(e){return e===tn?{}:e===_e?[]:e}function Nx(e,n){const t=e.viewQuery;e.viewQuery=t?(o,i)=>{n(o,i),t(o,i)}:n}function Ox(e,n){const t=e.contentQueries;e.contentQueries=t?(o,i,r)=>{n(o,i,r),t(o,i,r)}:n}function xx(e,n){const t=e.hostBindings;e.hostBindings=t?(o,i)=>{n(o,i),t(o,i)}:n}function EC(e,n,t,o,i,r,s,a){if(t.firstCreatePass){e.mergedAttrs=vi(e.mergedAttrs,e.attrs);const u=e.tView=Fd(2,e,i,r,s,t.directiveRegistry,t.pipeRegistry,null,t.schemas,t.consts,null);null!==t.queries&&(t.queries.template(t,e),u.queries=t.queries.embeddedTView(e))}a&&(e.flags|=a),vn(e,!1);const l=IC(t,n,e,o);ua()&&Kd(t,n,l,e),vt(l,n);const c=dy(l,n,l,e);n[o+H]=c,Pd(n,c)}function Lo(e,n,t,o,i,r,s,a,l,c,u){const d=t+H;let g;if(n.firstCreatePass){if(g=xo(n,d,4,s||null,a||null),null!=c){const h=tt(n.consts,c);g.localNames=[];for(let p=0;p{class e{_ngZone;registry;_isZoneStable=!0;_callbacks=[];_taskTrackingZone=null;_destroyRef;constructor(t,o,i){this._ngZone=t,this.registry=o,wu()&&(this._destroyRef=F(bn,{optional:!0})??void 0),Gf||(function ZR(e){Gf=e}(i),i.addToWindow(o)),this._watchAngularEvents(),t.run(()=>{this._taskTrackingZone=typeof Zone>"u"?null:Zone.current.get("TaskTrackingZone")})}_watchAngularEvents(){const t=this._ngZone.onUnstable.subscribe({next:()=>{this._isZoneStable=!1}}),o=this._ngZone.runOutsideAngular(()=>this._ngZone.onStable.subscribe({next:()=>{re.assertNotInAngularZone(),queueMicrotask(()=>{this._isZoneStable=!0,this._runCallbacksIfReady()})}}));this._destroyRef?.onDestroy(()=>{t.unsubscribe(),o.unsubscribe()})}isStable(){return this._isZoneStable&&!this._ngZone.hasPendingMacrotasks}_runCallbacksIfReady(){if(this.isStable())queueMicrotask(()=>{for(;0!==this._callbacks.length;){let t=this._callbacks.pop();clearTimeout(t.timeoutId),t.doneCb()}});else{let t=this.getPendingTasks();this._callbacks=this._callbacks.filter(o=>!o.updateCb||!o.updateCb(t)||(clearTimeout(o.timeoutId),!1))}}getPendingTasks(){return this._taskTrackingZone?this._taskTrackingZone.macroTasks.map(t=>({source:t.source,creationLocation:t.creationLocation,data:t.data})):[]}addCallback(t,o,i){let r=-1;o&&o>0&&(r=setTimeout(()=>{this._callbacks=this._callbacks.filter(s=>s.timeoutId!==r),t()},o)),this._callbacks.push({doneCb:t,timeoutId:r,updateCb:i})}whenStable(t,o,i){if(i&&!this._taskTrackingZone)throw new Error('Task tracking zone is required when passing an update callback to whenStable(). Is "zone.js/plugins/task-tracking" loaded?');this.addCallback(t,o,i),this._runCallbacksIfReady()}registerApplication(t){this.registry.registerApplication(t,this)}unregisterApplication(t){this.registry.unregisterApplication(t)}findProviders(t,o,i){return[]}static \u0275fac=function(o){return new(o||e)(oe(re),oe(zf),oe(Ml))};static \u0275prov=X({token:e,factory:e.\u0275fac})}return e})(),zf=(()=>{class e{_applications=new Map;registerApplication(t,o){this._applications.set(t,o)}unregisterApplication(t){this._applications.delete(t)}unregisterAllApplications(){this._applications.clear()}getTestability(t){return this._applications.get(t)||null}getAllTestabilities(){return Array.from(this._applications.values())}getAllRootElements(){return Array.from(this._applications.keys())}findTestabilityInTree(t,o=!0){return Gf?.findTestabilityInTree(this,t,o)??null}static \u0275fac=function(o){return new(o||e)};static \u0275prov=X({token:e,factory:e.\u0275fac,providedIn:"platform"})}return e})();function Il(e){return!!e&&"function"==typeof e.then}function tb(e){return!!e&&"function"==typeof e.subscribe}const nb=new R("");let ob=(()=>{class e{resolve;reject;initialized=!1;done=!1;donePromise=new Promise((t,o)=>{this.resolve=t,this.reject=o});appInits=F(nb,{optional:!0})??[];injector=F(Vt);constructor(){}runInitializers(){if(this.initialized)return;const t=[];for(const i of this.appInits){const r=Mp(this.injector,i);if(Il(r))t.push(r);else if(tb(r)){const s=new Promise((a,l)=>{r.subscribe({complete:a,error:l})});t.push(s)}}const o=()=>{this.done=!0,this.resolve()};Promise.all(t).then(()=>{o()}).catch(i=>{this.reject(i)}),0===t.length&&o(),this.initialized=!0}static \u0275fac=function(o){return new(o||e)};static \u0275prov=X({token:e,factory:e.\u0275fac,providedIn:"root"})}return e})();const YR=new R("");function ib(e,n){return Array.isArray(n)?n.reduce(ib,e):{...e,...n}}let Jn=(()=>{class e{_runningTick=!1;_destroyed=!1;_destroyListeners=[];_views=[];internalErrorHandler=F(Dn);afterRenderManager=F(Lv);zonelessEnabled=F(lm);rootEffectScheduler=F(fm);dirtyFlags=0;tracingSnapshot=null;allTestViews=new Set;autoDetectTestViews=new Set;includeAllTestViews=!1;afterTick=new Xt;get allViews(){return[...(this.includeAllTestViews?this.allTestViews:this.autoDetectTestViews).keys(),...this._views]}get destroyed(){return this._destroyed}componentTypes=[];components=[];internalPendingTask=F(Eo);get isStable(){return this.internalPendingTask.hasPendingTasksObservable.pipe($u(t=>!t))}constructor(){F(Wr,{optional:!0})}whenStable(){let t;return new Promise(o=>{t=this.isStable.subscribe({next:i=>{i&&o()}})}).finally(()=>{t.unsubscribe()})}_injector=F(Lt);_rendererFactory=null;get injector(){return this._injector}bootstrap(t,o){return this.bootstrapImpl(t,o)}bootstrapImpl(t,o,i=Vt.NULL){return this._injector.get(re).run(()=>{fe(10);const s=t instanceof Vy;if(!this._injector.get(ob).done)throw new T(405,"");let l;l=s?t:this._injector.get(ul).resolveComponentFactory(t),this.componentTypes.push(l.componentType);const c=function KR(e){return e.isBoundToModule}(l)?void 0:this._injector.get(Fo),d=l.create(i,[],o||l.selector,c),g=d.location.nativeElement,h=d.injector.get(eb,null);return h?.registerApplication(g),d.onDestroy(()=>{this.detachView(d.hostView),Tl(this.components,d),h?.unregisterApplication(g)}),this._loadComponent(d),fe(11,d),d})}tick(){this.zonelessEnabled||(this.dirtyFlags|=1),this._tick()}_tick(){fe(12),null!==this.tracingSnapshot?this.tracingSnapshot.run(Bd.CHANGE_DETECTION,this.tickImpl):this.tickImpl()}tickImpl=()=>{if(this._runningTick)throw new T(101,!1);const t=z(null);try{this._runningTick=!0,this.synchronize()}finally{this._runningTick=!1,this.tracingSnapshot?.dispose(),this.tracingSnapshot=null,z(t),this.afterTick.next(),fe(13)}};synchronize(){null===this._rendererFactory&&!this._injector.destroyed&&(this._rendererFactory=this._injector.get(mf,null,{optional:!0}));let t=0;for(;0!==this.dirtyFlags&&t++<10;)fe(14),this.synchronizeOnce(),fe(15)}synchronizeOnce(){16&this.dirtyFlags&&(this.dirtyFlags&=-17,this.rootEffectScheduler.flush());let t=!1;if(7&this.dirtyFlags){const o=!!(1&this.dirtyFlags);this.dirtyFlags&=-8,this.dirtyFlags|=8;for(let{_lView:i}of this.allViews)(o||sa(i))&&(tl(i,o&&!this.zonelessEnabled?0:1),t=!0);if(this.dirtyFlags&=-5,this.syncDirtyFlagsWithViews(),23&this.dirtyFlags)return}t||(this._rendererFactory?.begin?.(),this._rendererFactory?.end?.()),8&this.dirtyFlags&&(this.dirtyFlags&=-9,this.afterRenderManager.execute()),this.syncDirtyFlagsWithViews()}syncDirtyFlagsWithViews(){this.allViews.some(({_lView:t})=>sa(t))?this.dirtyFlags|=2:this.dirtyFlags&=-8}attachView(t){const o=t;this._views.push(o),o.attachToAppRef(this)}detachView(t){const o=t;Tl(this._views,o),o.detachFromAppRef()}_loadComponent(t){this.attachView(t.hostView);try{this.tick()}catch(i){this.internalErrorHandler(i)}this.components.push(t),this._injector.get(YR,[]).forEach(i=>i(t))}ngOnDestroy(){if(!this._destroyed)try{this._destroyListeners.forEach(t=>t()),this._views.slice().forEach(t=>t.destroy())}finally{this._destroyed=!0,this._views=[],this._destroyListeners=[]}}onDestroy(t){return this._destroyListeners.push(t),()=>Tl(this._destroyListeners,t)}destroy(){if(this._destroyed)throw new T(406,!1);const t=this._injector;t.destroy&&!t.destroyed&&t.destroy()}get viewCount(){return this._views.length}static \u0275fac=function(o){return new(o||e)};static \u0275prov=X({token:e,factory:e.\u0275fac,providedIn:"root"})}return e})();function Tl(e,n){const t=e.indexOf(n);t>-1&&e.splice(t,1)}function ct(e,n,t,o){const i=w();return De(i,mt(),n)&&(K(),function rN(e,n,t,o,i,r){const s=Le(e,n);!function Qa(e,n,t,o,i,r,s){if(null==r)e.removeAttribute(n,i,t);else{const a=null==s?Z(r):s(r,o||"",i);e.setAttribute(n,i,a,t)}}(n[Y],s,r,e.value,t,o,i)}(on(),i,e,n,t,o)),ct}typeof document<"u"&&document;class Zk{destroy(n){}updateValue(n,t){}swap(n,t){const o=Math.min(n,t),i=Math.max(n,t),r=this.detach(i);if(i-o>1){const s=this.detach(o);this.attach(o,r),this.attach(i,s)}else this.attach(o,r)}move(n,t){this.attach(t,this.detach(n))}}function nh(e,n,t,o,i){return e===t&&Object.is(n,o)?1:Object.is(i(e,n),i(t,o))?-1:0}function oh(e,n,t,o){return!(void 0===n||!n.has(o)||(e.attach(t,n.get(o)),n.delete(o),0))}function _b(e,n,t,o,i){if(oh(e,n,o,t(o,i)))e.updateValue(o,i);else{const r=e.create(o,i);e.attach(o,r)}}function vb(e,n,t,o){const i=new Set;for(let r=n;r<=t;r++)i.add(o(r,e.at(r)));return i}class yb{kvMap=new Map;_vMap=void 0;has(n){return this.kvMap.has(n)}delete(n){if(!this.has(n))return!1;const t=this.kvMap.get(n);return void 0!==this._vMap&&this._vMap.has(t)?(this.kvMap.set(n,this._vMap.get(t)),this._vMap.delete(t)):this.kvMap.delete(n),!0}get(n){return this.kvMap.get(n)}set(n,t){if(this.kvMap.has(n)){let o=this.kvMap.get(n);void 0===this._vMap&&(this._vMap=new Map);const i=this._vMap;for(;i.has(o);)o=i.get(o);i.set(o,t)}else this.kvMap.set(n,t)}forEach(n){for(let[t,o]of this.kvMap)if(n(o,t),void 0!==this._vMap){const i=this._vMap;for(;i.has(o);)o=i.get(o),n(o,t)}}}function y(e,n,t,o,i,r,s,a){nt("NgControlFlow");const l=w(),c=K();return Lo(l,c,e,n,t,o,i,tt(c.consts,r),256,s,a),ih}function ih(e,n,t,o,i,r,s,a){nt("NgControlFlow");const l=w(),c=K();return Lo(l,c,e,n,t,o,i,tt(c.consts,r),512,s,a),ih}function C(e,n){nt("NgControlFlow");const t=w(),o=mt(),i=t[o]!==ce?t[o]:-1,r=-1!==i?Ll(t,H+i):void 0;if(De(t,o,e)){const a=z(null);try{if(void 0!==r&&rf(r,0),-1!==e){const l=H+e,c=Ll(t,l),u=rh(t[1],l),d=null;xi(c,Ni(t,u,n,{dehydratedView:d}),0,Oo(u,d))}}finally{z(a)}}else if(void 0!==r){const a=fy(r,0);void 0!==a&&(a[8]=n)}}class Qk{lContainer;$implicit;$index;constructor(n,t,o){this.lContainer=n,this.$implicit=t,this.$index=o}get $count(){return this.lContainer.length-10}}function Ye(e,n){return n}class Jk{hasEmptyBlock;trackByFn;liveCollection;constructor(n,t,o){this.hasEmptyBlock=n,this.trackByFn=t,this.liveCollection=o}}function Qe(e,n,t,o,i,r,s,a,l,c,u,d,g){nt("NgControlFlow");const h=w(),p=K(),b=void 0!==l,I=w(),N=a?s.bind(I[15][8]):s,E=new Jk(b,N);I[H+e]=E,Lo(h,p,e+1,n,t,o,i,tt(p.consts,r),256),b&&Lo(h,p,e+2,l,c,u,d,tt(p.consts,g),512)}class Xk extends Zk{lContainer;hostLView;templateTNode;operationsCounter=void 0;needsIndexUpdate=!1;constructor(n,t,o){super(),this.lContainer=n,this.hostLView=t,this.templateTNode=o}get length(){return this.lContainer.length-10}at(n){return this.getLView(n)[8].$implicit}attach(n,t){const o=t[6];this.needsIndexUpdate||=n!==this.length,xi(this.lContainer,t,n,Oo(this.templateTNode,o)),function eF(e,n){if(e.length<=10)return;const o=e[10+n],i=o?o[26]:void 0;o&&i&&i.detachedLeaveAnimationFns&&i.detachedLeaveAnimationFns.length>0&&(function UA(e,n){const t=e.get(Ga);if(n.detachedLeaveAnimationFns){for(const o of n.detachedLeaveAnimationFns)t.queue.delete(o);n.detachedLeaveAnimationFns=void 0}}(o[9],i),Ao.delete(o),i.detachedLeaveAnimationFns=void 0)}(this.lContainer,n)}detach(n){return this.needsIndexUpdate||=n!==this.length-1,function tF(e,n){if(e.length<=10)return;const o=e[10+n],i=o?o[26]:void 0;i&&i.leave&&i.leave.size>0&&(i.detachedLeaveAnimationFns=[])}(this.lContainer,n),function nF(e,n){return Yr(e,n)}(this.lContainer,n)}create(n,t){const i=Ni(this.hostLView,this.templateTNode,new Qk(this.lContainer,t,n),{dehydratedView:null});return this.operationsCounter?.recordCreate(),i}destroy(n){qr(n[1],n),this.operationsCounter?.recordDestroy()}updateValue(n,t){this.getLView(n)[8].$implicit=t}reset(){this.needsIndexUpdate=!1,this.operationsCounter?.reset()}updateIndexes(){if(this.needsIndexUpdate)for(let n=0;n{e.destroy(l)})}(l,e,r.trackByFn),l.updateIndexes(),r.hasEmptyBlock){const c=mt(),u=0===l.length;if(De(o,c,u)){const d=t+2,g=Ll(o,d);if(u){const h=rh(i,d),p=null;xi(g,Ni(o,h,void 0,{dehydratedView:p}),0,Oo(h,p))}else i.firstUpdatePass&&function al(e){const n=e[6]??[],o=e[3][Y],i=[];for(const r of n)void 0!==r.data.di?i.push(r):xy(r,o);e[6]=i}(g),rf(g,0)}}}finally{z(n)}}function Ll(e,n){return e[n]}function rh(e,n){return li(e,n)}function A(e,n,t){const o=w();return De(o,mt(),n)&&(K(),Xd(on(),o,e,n,o[Y],t)),A}function sh(e,n,t,o,i){Xa(n,e,t,i?"class":"style",o)}function v(e,n,t,o){const i=w(),r=i[1],s=e+H,a=r.firstCreatePass?yf(s,i,2,n,tf,xu(),t,o):r.data[s];if(function Ka(e,n,t,o,i){const r=H+t,s=n[1],a=i(s,n,e,o,t);n[r]=a,vn(e,!0);const l=2===e.type;return l?(gv(n[Y],a,e),(0===function ET(){return G.lFrame.elementDepthCount}()||si(e))&&vt(a,n),function MT(){G.lFrame.elementDepthCount++}()):vt(a,n),ua()&&(!l||!Sa(e))&&Kd(s,n,a,e),e}(a,i,e,n,ch),si(a)){const l=i[1];Ya(l,i,a),Ed(l,a,i)}return null!=o&&Ai(i,a),v}function _(){const e=K(),t=Ja(q());return e.firstCreatePass&&Cf(e,t),function Bp(e){return G.skipHydrationRootTNode===e}(t)&&function jp(){G.skipHydrationRootTNode=null}(),function Vp(){G.lFrame.elementDepthCount--}(),null!=t.classesWithoutHost&&function q0(e){return!!(8&e.flags)}(t)&&sh(e,t,w(),t.classesWithoutHost,!0),null!=t.stylesWithoutHost&&function Z0(e){return!!(16&e.flags)}(t)&&sh(e,t,w(),t.stylesWithoutHost,!1),_}function O(e,n,t,o){return v(e,n,t,o),_(),O}let ch=(e,n,t,o,i)=>(wr(!0),Va(n[Y],o,function LT(){return G.lFrame.currentNamespace}()));function ue(){return w()}const Hl="en-US";let Sb=Hl;function U(e,n,t){const o=w(),i=K(),r=q();return ph(i,o,o[Y],r,e,n,t),U}function ph(e,n,t,o,i,r,s){let a=!0,l=null;if((3&o.type||s)&&(l??=as(o,n,r),function qy(e,n,t,o,i,r,s,a){const l=si(e);let c=!1,u=null;if(!o&&l&&(u=function LO(e,n,t,o){const i=e.cleanup;if(null!=i)for(let r=0;rl?a[l]:null}"string"==typeof s&&(r+=2)}return null}(n,t,r,e.index)),null!==u)(u.__ngLastListenerFn__||u).__ngNextListenerFn__=s,u.__ngLastListenerFn__=s,c=!0;else{const d=Le(e,t),g=o?o(d):d,h=i.listen(g,r,a);(function FO(e){return e.startsWith("animation")||e.startsWith("transition")})(r)||Zy(o?b=>o($e(b[e.index])):e.index,n,t,r,a,h,!1)}return c}(o,e,n,s,t,i,r,l)&&(a=!1)),a){const c=o.outputs?.[i],u=o.hostDirectiveOutputs?.[i];if(u&&u.length)for(let d=0;d0;)n=n[14],e--;return n}(e,G.lFrame.contextLView))[8]}(e)}function Zb(e,n,t,o){!function aC(e,n,t,o){const i=K();if(i.firstCreatePass){const r=q();lC(i,new oC(n,t,o),r.index),function ux(e,n){const t=e.contentQueries||(e.contentQueries=[]);n!==(t.length?t[t.length-1]:-1)&&t.push(e.queries.length-1,n)}(i,e),!(2&~t)&&(i.staticContentQueries=!0)}return rC(i,w(),t)}(e,n,t,o)}function Ot(e,n,t){!function sC(e,n,t){const o=K();return o.firstCreatePass&&(lC(o,new oC(e,n,t),-1),!(2&~n)&&(o.staticViewQueries=!0)),rC(o,w(),n)}(e,n,t)}function wt(e){const n=w(),t=K(),o=Fu();ca(o+1);const i=Of(t,o);if(e.dirty&&function bT(e){return!(4&~e[2])}(n)===!(2&~i.metadata.flags)){if(null===i.matches)e.reset([]);else{const r=cC(n,o);e.reset(r,Xm),e.notifyOnChanges()}return!0}return!1}function Et(){return function Nf(e,n){return e[18].queries[n].queryList}(w(),Fu())}function $l(e,n){return e<<17|n<<2}function zo(e){return e>>17&32767}function mh(e){return 2|e}function Wi(e){return(131068&e)>>2}function _h(e,n){return-131069&e|n<<2}function vh(e){return 1|e}function Yb(e,n,t,o){const i=e[t+1],r=null===n;let s=o?zo(i):Wi(i),a=!1;for(;0!==s&&(!1===a||r);){const c=e[s+1];lL(e[s],n)&&(a=!0,e[s+1]=o?vh(c):mh(c)),s=o?zo(c):Wi(c)}a&&(e[t+1]=o?mh(i):vh(i))}function lL(e,n){return null===e||null==n||(Array.isArray(e)?e[1]:e)===n||!(!Array.isArray(e)||"string"!=typeof n)&&_r(e,n)>=0}const Be={textEnd:0,key:0,keyEnd:0,value:0,valueEnd:0};function Qb(e){return e.substring(Be.key,Be.keyEnd)}function Kb(e,n){const t=Be.textEnd;return t===n?-1:(n=Be.keyEnd=function fL(e,n,t){for(;n32;)n++;return n}(e,Be.key=n,t),qi(e,n,t))}function qi(e,n,t){for(;n=0;t=Kb(n,t))Xs(e,Qb(n),!0)}function nD(e,n,t,o){const i=w(),r=K(),s=Cn(2);r.firstUpdatePass&&rD(r,e,s,o),n!==ce&&De(i,s,n)&&aD(r,r.data[qe()],i,i[Y],e,i[s+1]=function ML(e,n){return null==e||""===e||("string"==typeof n?e+=n:"object"==typeof e&&(e=gt(Gn(e)))),e}(n,t),o,s)}function iD(e,n){return n>=e.expandoStartIndex}function rD(e,n,t,o){const i=e.data;if(null===i[t+1]){const r=i[qe()],s=iD(e,t);cD(r,o)&&null===n&&!s&&(n=!1),n=function vL(e,n,t,o){const i=function ku(e){const n=G.lFrame.currentDirectiveIndex;return-1===n?null:e[n]}(e);let r=o?n.residualClasses:n.residualStyles;if(null===i)0===(o?n.classBindings:n.styleBindings)&&(t=ys(t=yh(null,e,n,t,o),n.attrs,o),r=null);else{const s=n.directiveStylingLast;if(-1===s||e[s]!==i)if(t=yh(i,e,n,t,o),null===r){let l=function yL(e,n,t){const o=t?n.classBindings:n.styleBindings;if(0!==Wi(o))return e[zo(o)]}(e,n,o);void 0!==l&&Array.isArray(l)&&(l=yh(null,e,n,l[1],o),l=ys(l,n.attrs,o),function CL(e,n,t,o){e[zo(t?n.classBindings:n.styleBindings)]=o}(e,n,o,l))}else r=function bL(e,n,t){let o;const i=n.directiveEnd;for(let r=1+n.directiveStylingLast;r0)&&(c=!0)):u=t,i)if(0!==l){const g=zo(e[a+1]);e[o+1]=$l(g,a),0!==g&&(e[g+1]=_h(e[g+1],o)),e[a+1]=function iL(e,n){return 131071&e|n<<17}(e[a+1],o)}else e[o+1]=$l(a,0),0!==a&&(e[a+1]=_h(e[a+1],o)),a=o;else e[o+1]=$l(l,0),0===a?a=o:e[l+1]=_h(e[l+1],o),l=o;c&&(e[o+1]=mh(e[o+1])),Yb(e,u,o,!0),Yb(e,u,o,!1),function aL(e,n,t,o,i){const r=i?e.residualClasses:e.residualStyles;null!=r&&"string"==typeof n&&_r(r,n)>=0&&(t[o+1]=vh(t[o+1]))}(n,u,e,o,r),s=$l(a,l),r?n.classBindings=s:n.styleBindings=s}(i,r,n,t,s,o)}}function yh(e,n,t,o,i){let r=null;const s=t.directiveEnd;let a=t.directiveStylingLast;for(-1===a?a=t.directiveStart:a++;a0;){const l=e[i],c=Array.isArray(l),u=c?l[1]:l,d=null===u;let g=t[i+1];g===ce&&(g=d?_e:void 0);let h=d?fu(g,o):u===o?g:void 0;if(c&&!Gl(h)&&(h=fu(l,o)),Gl(h)&&(a=h,s))return a;const p=e[i+1];i=s?zo(p):Wi(p)}if(null!==n){let l=r?n.residualClasses:n.residualStyles;null!=l&&(a=fu(l,o))}return a}function Gl(e){return void 0!==e}function cD(e,n){return!!(e.flags&(n?8:16))}function D(e,n=""){const t=w(),o=K(),i=e+H,r=o.firstCreatePass?xo(o,i,1,n,null):o.data[i],s=uD(o,t,r,n,e);t[i]=s,ua()&&Kd(o,t,s,r),vn(r,!1)}let uD=(e,n,t,o,i)=>(wr(!0),function xd(e,n){return e.createText(n)}(n[Y],o));function fD(e,n,t,o=""){return De(e,mt(),t)?n+Z(t)+o:ce}function k(e){return P("",e),k}function P(e,n,t){const o=w(),i=fD(o,e,n,t);return i!==ce&&function Nn(e,n,t){const o=ai(n,e);!function uv(e,n,t){e.setValue(n,t)}(e[Y],o,t)}(o,qe(),i),P}function je(e,n,t){am(n)&&(n=n());const o=w();return De(o,mt(),n)&&(K(),Xd(on(),o,e,n,o[Y],t)),je}function ye(e,n){const t=am(e);return t&&e.set(n),t}function Ge(e,n){const t=w(),o=K(),i=q();return ph(o,t,t[Y],i,e,n),Ge}function On(e){return De(w(),mt(),e)?Z(e):ce}function Ut(e,n,t=""){return fD(w(),e,n,t)}function Ch(e,n,t,o,i){if(e=Q(e),Array.isArray(e))for(let r=0;r>20;if(fn(e)||!e.multi){const h=new Or(c,i,x,null),p=Dh(l,n,i?u:u+g,d);-1===p?(Ku(va(a,s),r,l),bh(r,e,n.length),n.push(l),a.directiveStart++,a.directiveEnd++,i&&(a.providerIndexes+=1048576),t.push(h),s.push(h)):(t[p]=h,s[p]=h)}else{const h=Dh(l,n,u+g,d),p=Dh(l,n,u,u+g),I=p>=0&&t[p];if(i&&!I||!i&&!(h>=0&&t[h])){Ku(va(a,s),r,l);const N=function jL(e,n,t,o,i){const s=new Or(e,t,x,null);return s.multi=[],s.index=n,s.componentProviders=0,ND(s,i,o&&!t),s}(i?BL:HL,t.length,i,o,c);!i&&I&&(t[p].providerFactory=N),bh(r,e,n.length,0),n.push(l),a.directiveStart++,a.directiveEnd++,i&&(a.providerIndexes+=1048576),t.push(N),s.push(N)}else bh(r,e,h>-1?h:p,ND(t[i?p:h],c,!i&&o));!i&&o&&I&&t[p].componentProviders++}}}function bh(e,n,t,o){const i=fn(n),r=function Dp(e){return!!e.useClass}(n);if(i||r){const l=(r?Q(n.useClass):n).prototype.ngOnDestroy;if(l){const c=e.destroyHooks||(e.destroyHooks=[]);if(!i&&n.multi){const u=c.indexOf(t);-1===u?c.push(t,[o,l]):c[u+1].push(o,l)}else c.push(t,l)}}}function ND(e,n,t){return t&&e.componentProviders++,e.multi.push(n)-1}function Dh(e,n,t,o){for(let i=t;i{t.providersResolver=(o,i)=>function VL(e,n,t){const o=K();if(o.firstCreatePass){const i=At(e);Ch(t,o.data,o.blueprint,i,!0),Ch(n,o.data,o.blueprint,i,!1)}}(o,i?i(e):e,n)}}function Zi(e,n,t,o){return function xD(e,n,t,o,i,r){const s=n+t;return De(e,s,i)?an(e,s+1,r?o.call(r,i):o(i)):Cs(e,s+1)}(w(),lt(),e,n,t,o)}function Eh(e,n,t,o,i){return function RD(e,n,t,o,i,r,s){const a=n+t;return ko(e,a,i,r)?an(e,a+2,s?o.call(s,i,r):o(i,r)):Cs(e,a+2)}(w(),lt(),e,n,t,o,i)}function Ne(e,n,t,o,i,r){return kD(w(),lt(),e,n,t,o,i,r)}function Cs(e,n){const t=e[n];return t===ce?void 0:t}function kD(e,n,t,o,i,r,s,a){const l=n+t;return function gl(e,n,t,o,i){const r=ko(e,n,t,o);return De(e,n+2,i)||r}(e,l,i,r,s)?an(e,l+3,a?o.call(a,i,r,s):o(i,r,s)):Cs(e,l+3)}let RP=(()=>{class e{zone=F(re);changeDetectionScheduler=F(fi);applicationRef=F(Jn);applicationErrorHandler=F(Dn);_onMicrotaskEmptySubscription;initialize(){this._onMicrotaskEmptySubscription||(this._onMicrotaskEmptySubscription=this.zone.onMicrotaskEmpty.subscribe({next:()=>{this.changeDetectionScheduler.runningTick||this.zone.run(()=>{try{this.applicationRef.dirtyFlags|=1,this.applicationRef._tick()}catch(t){this.applicationErrorHandler(t)}})}}))}ngOnDestroy(){this._onMicrotaskEmptySubscription?.unsubscribe()}static \u0275fac=function(o){return new(o||e)};static \u0275prov=X({token:e,factory:e.\u0275fac,providedIn:"root"})}return e})();function nw({ngZoneFactory:e,ignoreChangesOutsideZone:n,scheduleInRootZone:t}){return e??=()=>new re({...Ah(),scheduleInRootZone:t}),[{provide:re,useFactory:e},{provide:mo,multi:!0,useFactory:()=>{const o=F(RP,{optional:!0});return()=>o.initialize()}},{provide:mo,multi:!0,useFactory:()=>{const o=F(FP);return()=>{o.initialize()}}},!0===n?{provide:cm,useValue:!0}:[],{provide:um,useValue:t??Nv},{provide:Dn,useFactory:()=>{const o=F(re),i=F(Lt);let r;return s=>{o.runOutsideAngular(()=>{i.destroyed&&!r?setTimeout(()=>{throw s}):(r??=i.get(di),r.handleError(s))})}}}]}function Ah(e){return{enableLongStackTrace:!1,shouldCoalesceEventChangeDetection:e?.eventCoalescing??!1,shouldCoalesceRunChangeDetection:e?.runCoalescing??!1}}let FP=(()=>{class e{subscription=new It;initialized=!1;zone=F(re);pendingTasks=F(Eo);initialize(){if(this.initialized)return;this.initialized=!0;let t=null;!this.zone.isStable&&!this.zone.hasPendingMacrotasks&&!this.zone.hasPendingMicrotasks&&(t=this.pendingTasks.add()),this.zone.runOutsideAngular(()=>{this.subscription.add(this.zone.onStable.subscribe(()=>{re.assertNotInAngularZone(),queueMicrotask(()=>{null!==t&&!this.zone.hasPendingMacrotasks&&!this.zone.hasPendingMicrotasks&&(this.pendingTasks.remove(t),t=null)})}))}),this.subscription.add(this.zone.onUnstable.subscribe(()=>{re.assertInAngularZone(),t??=this.pendingTasks.add()}))}ngOnDestroy(){this.subscription.unsubscribe()}static \u0275fac=function(o){return new(o||e)};static \u0275prov=X({token:e,factory:e.\u0275fac,providedIn:"root"})}return e})(),rw=(()=>{class e{applicationErrorHandler=F(Dn);appRef=F(Jn);taskService=F(Eo);ngZone=F(re);zonelessEnabled=F(lm);tracing=F(Wr,{optional:!0});disableScheduling=F(cm,{optional:!0})??!1;zoneIsDefined=typeof Zone<"u"&&!!Zone.root.run;schedulerTickApplyArgs=[{data:{__scheduler_tick__:!0}}];subscriptions=new It;angularZoneId=this.zoneIsDefined?this.ngZone._inner?.get(za):null;scheduleInRootZone=!this.zonelessEnabled&&this.zoneIsDefined&&(F(um,{optional:!0})??!1);cancelScheduledCallback=null;useMicrotaskScheduler=!1;runningTick=!1;pendingRenderTaskId=null;constructor(){this.subscriptions.add(this.appRef.afterTick.subscribe(()=>{this.runningTick||this.cleanup()})),this.subscriptions.add(this.ngZone.onUnstable.subscribe(()=>{this.runningTick||this.cleanup()})),this.disableScheduling||=!this.zonelessEnabled&&(this.ngZone instanceof zd||!this.zoneIsDefined)}notify(t){if(!this.zonelessEnabled&&5===t)return;let o=!1;switch(t){case 0:this.appRef.dirtyFlags|=2;break;case 3:case 2:case 4:case 5:case 1:this.appRef.dirtyFlags|=4;break;case 6:case 13:this.appRef.dirtyFlags|=2,o=!0;break;case 12:this.appRef.dirtyFlags|=16,o=!0;break;case 11:o=!0;break;default:this.appRef.dirtyFlags|=8}if(this.appRef.tracingSnapshot=this.tracing?.snapshot(this.appRef.tracingSnapshot)??null,!this.shouldScheduleTick(o))return;const i=this.useMicrotaskScheduler?xv:Ov;this.pendingRenderTaskId=this.taskService.add(),this.cancelScheduledCallback=this.scheduleInRootZone?Zone.root.run(()=>i(()=>this.tick())):this.ngZone.runOutsideAngular(()=>i(()=>this.tick()))}shouldScheduleTick(t){return!(this.disableScheduling&&!t||this.appRef.destroyed||null!==this.pendingRenderTaskId||this.runningTick||this.appRef._runningTick||!this.zonelessEnabled&&this.zoneIsDefined&&Zone.current.get(za+this.angularZoneId))}tick(){if(this.runningTick||this.appRef.destroyed)return;if(0===this.appRef.dirtyFlags)return void this.cleanup();!this.zonelessEnabled&&7&this.appRef.dirtyFlags&&(this.appRef.dirtyFlags|=1);const t=this.taskService.add();try{this.ngZone.run(()=>{this.runningTick=!0,this.appRef._tick()},void 0,this.schedulerTickApplyArgs)}catch(o){this.taskService.remove(t),this.applicationErrorHandler(o)}finally{this.cleanup()}this.useMicrotaskScheduler=!0,xv(()=>{this.useMicrotaskScheduler=!1,this.taskService.remove(t)})}ngOnDestroy(){this.subscriptions.unsubscribe(),this.cleanup()}cleanup(){if(this.runningTick=!1,this.cancelScheduledCallback?.(),this.cancelScheduledCallback=null,null!==this.pendingRenderTaskId){const t=this.pendingRenderTaskId;this.pendingRenderTaskId=null,this.taskService.remove(t)}}static \u0275fac=function(o){return new(o||e)};static \u0275prov=X({token:e,factory:e.\u0275fac,providedIn:"root"})}return e})();const to=new R("",{providedIn:"root",factory:()=>F(to,{optional:!0,skipSelf:!0})||function LP(){return typeof $localize<"u"&&$localize.locale||Hl}()});new R("").__NG_ELEMENT_ID__=e=>{const n=q();if(null===n)throw new T(204,!1);if(2&n.type)return n.value;if(8&e)return null;throw new T(204,!1)};const Jl=new R(""),YP=new R("");function ws(e){return!e.moduleRef}let mw;function _w(){mw=QP}function QP(e,n){const t=e.injector.get(Jn);if(e._bootstrapComponents.length>0)e._bootstrapComponents.forEach(o=>t.bootstrap(o));else{if(!e.instance.ngDoBootstrap)throw new T(-403,!1);e.instance.ngDoBootstrap(t)}n.push(e)}let vw=(()=>{class e{_injector;_modules=[];_destroyListeners=[];_destroyed=!1;constructor(t){this._injector=t}bootstrapModuleFactory(t,o){const i=o?.scheduleInRootZone,s=o?.ignoreChangesOutsideZone,a=[nw({ngZoneFactory:()=>function VA(e="zone.js",n){return"noop"===e?new zd:"zone.js"===e?new re(n):e}(o?.ngZone,{...Ah({eventCoalescing:o?.ngZoneEventCoalescing,runCoalescing:o?.ngZoneRunCoalescing}),scheduleInRootZone:i}),ignoreChangesOutsideZone:s}),{provide:fi,useExisting:rw},VT],l=function bx(e,n,t){return new kf(e,n,t,!1)}(t.moduleType,this.injector,a);return _w(),function pw(e){const n=ws(e)?e.r3Injector:e.moduleRef.injector,t=n.get(re);return t.run(()=>{ws(e)?e.r3Injector.resolveInjectorInitializers():e.moduleRef.resolveInjectorInitializers();const o=n.get(Dn);let i;if(t.runOutsideAngular(()=>{i=t.onError.subscribe({next:o})}),ws(e)){const r=()=>n.destroy(),s=e.platformInjector.get(Jl);s.add(r),n.onDestroy(()=>{i.unsubscribe(),s.delete(r)})}else{const r=()=>e.moduleRef.destroy(),s=e.platformInjector.get(Jl);s.add(r),e.moduleRef.onDestroy(()=>{Tl(e.allPlatformModules,e.moduleRef),i.unsubscribe(),s.delete(r)})}return function KP(e,n,t){try{const o=t();return Il(o)?o.catch(i=>{throw n.runOutsideAngular(()=>e(i)),i}):o}catch(o){throw n.runOutsideAngular(()=>e(o)),o}}(o,t,()=>{const r=n.get(Eo),s=r.add(),a=n.get(ob);return a.runInitializers(),a.donePromise.then(()=>{if(function fF(e){"string"==typeof e&&(Sb=e.toLowerCase().replace(/_/g,"-"))}(n.get(to,Hl)||Hl),!n.get(YP,!0))return ws(e)?n.get(Jn):(e.allPlatformModules.push(e.moduleRef),e.moduleRef);if(ws(e)){const u=n.get(Jn);return void 0!==e.rootComponent&&u.bootstrap(e.rootComponent),u}return mw?.(e.moduleRef,e.allPlatformModules),e.moduleRef}).finally(()=>{r.remove(s)})})})}({moduleRef:l,allPlatformModules:this._modules,platformInjector:this.injector})}bootstrapModule(t,o=[]){const i=ib({},o);return _w(),function GP(e,n,t){const o=new gC(t);return Promise.resolve(o)}(0,0,t).then(r=>this.bootstrapModuleFactory(r,i))}onDestroy(t){this._destroyListeners.push(t)}get injector(){return this._injector}destroy(){if(this._destroyed)throw new T(404,!1);this._modules.slice().forEach(o=>o.destroy()),this._destroyListeners.forEach(o=>o());const t=this._injector.get(Jl,null);t&&(t.forEach(o=>o()),t.clear()),this._destroyed=!0}get destroyed(){return this._destroyed}static \u0275fac=function(o){return new(o||e)(oe(Vt))};static \u0275prov=X({token:e,factory:e.\u0275fac,providedIn:"platform"})}return e})(),Ki=null;function yw(e,n,t=[]){const o=`Platform: ${n}`,i=new R(o);return(r=[])=>{let s=Xl();if(!s){const a=[...t,...r,{provide:i,useValue:!0}];s=e?.(a)??function JP(e){if(Xl())throw new T(400,!1);(function QR(){!function CI(e){Wg=e}(()=>{throw new T(600,"")})})(),Ki=e;const n=e.get(vw);return function bw(e){const n=e.get(y_,null);Mp(e,()=>{n?.forEach(t=>t())})}(e),n}(function Cw(e=[],n){return Vt.create({name:n,providers:[{provide:vu,useValue:"platform"},{provide:Jl,useValue:new Set([()=>Ki=null])},...e]})}(a,o))}return function XP(){const n=Xl();if(!n)throw new T(-401,!1);return n}()}}function Xl(){return Ki?.get(vw)??null}let Es=(()=>class e{static __NG_ELEMENT_ID__=t2})();function t2(e){return function n2(e,n,t){if(pn(e)&&!t){const o=at(e.index,n);return new Qr(o,o)}return 175&e.type?new Qr(n[15],n):null}(q(),w(),!(16&~e))}class Iw{constructor(){}supports(n){return n instanceof Map||bf(n)}create(){return new a2}}class a2{_records=new Map;_mapHead=null;_appendAfter=null;_previousMapHead=null;_changesHead=null;_changesTail=null;_additionsHead=null;_additionsTail=null;_removalsHead=null;_removalsTail=null;get isDirty(){return null!==this._additionsHead||null!==this._changesHead||null!==this._removalsHead}forEachItem(n){let t;for(t=this._mapHead;null!==t;t=t._next)n(t)}forEachPreviousItem(n){let t;for(t=this._previousMapHead;null!==t;t=t._nextPrevious)n(t)}forEachChangedItem(n){let t;for(t=this._changesHead;null!==t;t=t._nextChanged)n(t)}forEachAddedItem(n){let t;for(t=this._additionsHead;null!==t;t=t._nextAdded)n(t)}forEachRemovedItem(n){let t;for(t=this._removalsHead;null!==t;t=t._nextRemoved)n(t)}diff(n){if(n){if(!(n instanceof Map||bf(n)))throw new T(900,!1)}else n=new Map;return this.check(n)?this:null}onDestroy(){}check(n){this._reset();let t=this._mapHead;if(this._appendAfter=null,this._forEach(n,(o,i)=>{if(t&&t.key===i)this._maybeAddToChanges(t,o),this._appendAfter=t,t=t._next;else{const r=this._getOrCreateRecordForKey(i,o);t=this._insertBeforeOrAppend(t,r)}}),t){t._prev&&(t._prev._next=null),this._removalsHead=t;for(let o=t;null!==o;o=o._nextRemoved)o===this._mapHead&&(this._mapHead=null),this._records.delete(o.key),o._nextRemoved=o._next,o.previousValue=o.currentValue,o.currentValue=null,o._prev=null,o._next=null}return this._changesTail&&(this._changesTail._nextChanged=null),this._additionsTail&&(this._additionsTail._nextAdded=null),this.isDirty}_insertBeforeOrAppend(n,t){if(n){const o=n._prev;return t._next=n,t._prev=o,n._prev=t,o&&(o._next=t),n===this._mapHead&&(this._mapHead=t),this._appendAfter=n,n}return this._appendAfter?(this._appendAfter._next=t,t._prev=this._appendAfter):this._mapHead=t,this._appendAfter=t,null}_getOrCreateRecordForKey(n,t){if(this._records.has(n)){const i=this._records.get(n);this._maybeAddToChanges(i,t);const r=i._prev,s=i._next;return r&&(r._next=s),s&&(s._prev=r),i._next=null,i._prev=null,i}const o=new l2(n);return this._records.set(n,o),o.currentValue=t,this._addToAdditions(o),o}_reset(){if(this.isDirty){let n;for(this._previousMapHead=this._mapHead,n=this._previousMapHead;null!==n;n=n._next)n._nextPrevious=n._next;for(n=this._changesHead;null!==n;n=n._nextChanged)n.previousValue=n.currentValue;for(n=this._additionsHead;null!=n;n=n._nextAdded)n.previousValue=n.currentValue;this._changesHead=this._changesTail=null,this._additionsHead=this._additionsTail=null,this._removalsHead=null}}_maybeAddToChanges(n,t){Object.is(t,n.currentValue)||(n.previousValue=n.currentValue,n.currentValue=t,this._addToChanges(n))}_addToAdditions(n){null===this._additionsHead?this._additionsHead=this._additionsTail=n:(this._additionsTail._nextAdded=n,this._additionsTail=n)}_addToChanges(n){null===this._changesHead?this._changesHead=this._changesTail=n:(this._changesTail._nextChanged=n,this._changesTail=n)}_forEach(n,t){n instanceof Map?n.forEach(t):Object.keys(n).forEach(o=>t(n[o],o))}}class l2{key;previousValue=null;currentValue=null;_nextPrevious=null;_next=null;_prev=null;_nextAdded=null;_nextRemoved=null;_nextChanged=null;constructor(n){this.key=n}}function Sw(){return new ec([new Iw])}let ec=(()=>{class e{static \u0275prov=X({token:e,providedIn:"root",factory:Sw});factories;constructor(t){this.factories=t}static create(t,o){if(o){const i=o.factories.slice();t=t.concat(i)}return new e(t)}static extend(t){return{provide:e,useFactory:()=>{const o=F(e,{optional:!0,skipSelf:!0});return e.create(t,o||Sw())}}}find(t){const o=this.factories.find(i=>i.supports(t));if(o)return o;throw new T(901,!1)}}return e})();const d2=yw(null,"core",[]);let f2=(()=>{class e{constructor(t){}static \u0275fac=function(o){return new(o||e)(oe(Jn))};static \u0275mod=Qn({type:e});static \u0275inj=dn({})}return e})();function Pe(e){return function U2(e){const n=z(null);try{return e()}finally{z(n)}}(e)}function Zt(e,n){return function _I(e,n){const t=Object.create(vI);t.computation=e,void 0!==n&&(t.equal=n);const o=()=>{if(lr(t),Vs(t),t.value===Rn)throw t.error;return t.value};return o[We]=t,o}(e,n?.equal)}Error,Error;const Zh=/\s+/,iE=[];let Xi=(()=>{class e{_ngEl;_renderer;initialClasses=iE;rawClass;stateMap=new Map;constructor(t,o){this._ngEl=t,this._renderer=o}set klass(t){this.initialClasses=null!=t?t.trim().split(Zh):iE}set ngClass(t){this.rawClass="string"==typeof t?t.trim().split(Zh):t}ngDoCheck(){for(const o of this.initialClasses)this._updateState(o,!0);const t=this.rawClass;if(Array.isArray(t)||t instanceof Set)for(const o of t)this._updateState(o,!0);else if(null!=t)for(const o of Object.keys(t))this._updateState(o,!!t[o]);this._applyStateDiff()}_updateState(t,o){const i=this.stateMap.get(t);void 0!==i?(i.enabled!==o&&(i.changed=!0,i.enabled=o),i.touched=!0):this.stateMap.set(t,{enabled:o,changed:!0,touched:!0})}_applyStateDiff(){for(const t of this.stateMap){const o=t[0],i=t[1];i.changed?(this._toggleClass(o,i.enabled),i.changed=!1):i.touched||(i.enabled&&this._toggleClass(o,!1),this.stateMap.delete(o)),i.touched=!1}}_toggleClass(t,o){(t=t.trim()).length>0&&t.split(Zh).forEach(i=>{o?this._renderer.addClass(this._ngEl.nativeElement,i):this._renderer.removeClass(this._ngEl.nativeElement,i)})}static \u0275fac=function(o){return new(o||e)(x(Nt),x(Sn))};static \u0275dir=W({type:e,selectors:[["","ngClass",""]],inputs:{klass:[0,"class","klass"],ngClass:"ngClass"}})}return e})(),cE=(()=>{class e{_ngEl;_differs;_renderer;_ngStyle=null;_differ=null;constructor(t,o,i){this._ngEl=t,this._differs=o,this._renderer=i}set ngStyle(t){this._ngStyle=t,!this._differ&&t&&(this._differ=this._differs.find(t).create())}ngDoCheck(){if(this._differ){const t=this._differ.diff(this._ngStyle);t&&this._applyChanges(t)}}_setStyle(t,o){const[i,r]=t.split("."),s=-1===i.indexOf("-")?void 0:qn.DashCase;null!=o?this._renderer.setStyle(this._ngEl.nativeElement,i,r?`${o}${r}`:o,s):this._renderer.removeStyle(this._ngEl.nativeElement,i,s)}_applyChanges(t){t.forEachRemovedItem(o=>this._setStyle(o.key,null)),t.forEachAddedItem(o=>this._setStyle(o.key,o.currentValue)),t.forEachChangedItem(o=>this._setStyle(o.key,o.currentValue))}static \u0275fac=function(o){return new(o||e)(x(Nt),x(ec),x(Sn))};static \u0275dir=W({type:e,selectors:[["","ngStyle",""]],inputs:{ngStyle:"ngStyle"}})}return e})(),uE=(()=>{class e{_viewContainerRef;_viewRef=null;ngTemplateOutletContext=null;ngTemplateOutlet=null;ngTemplateOutletInjector=null;constructor(t){this._viewContainerRef=t}ngOnChanges(t){if(this._shouldRecreateView(t)){const o=this._viewContainerRef;if(this._viewRef&&o.remove(o.indexOf(this._viewRef)),!this.ngTemplateOutlet)return void(this._viewRef=null);const i=this._createContextForwardProxy();this._viewRef=o.createEmbeddedView(this.ngTemplateOutlet,i,{injector:this.ngTemplateOutletInjector??void 0})}}_shouldRecreateView(t){return!!t.ngTemplateOutlet||!!t.ngTemplateOutletInjector}_createContextForwardProxy(){return new Proxy({},{set:(t,o,i)=>!!this.ngTemplateOutletContext&&Reflect.set(this.ngTemplateOutletContext,o,i),get:(t,o,i)=>{if(this.ngTemplateOutletContext)return Reflect.get(this.ngTemplateOutletContext,o,i)}})}static \u0275fac=function(o){return new(o||e)(x(ln))};static \u0275dir=W({type:e,selectors:[["","ngTemplateOutlet",""]],inputs:{ngTemplateOutletContext:"ngTemplateOutletContext",ngTemplateOutlet:"ngTemplateOutlet",ngTemplateOutletInjector:"ngTemplateOutletInjector"},features:[En]})}return e})();let fE=(()=>{class e{transform(t,o,i){if(null==t)return null;if("string"!=typeof t&&!Array.isArray(t))throw function Qt(e,n){return new T(2100,!1)}();return t.slice(o,i)}static \u0275fac=function(o){return new(o||e)};static \u0275pipe=yt({name:"slice",type:e,pure:!1})}return e})(),hE=(()=>{class e{static \u0275fac=function(o){return new(o||e)};static \u0275mod=Qn({type:e});static \u0275inj=dn({})}return e})();class gE{_doc;constructor(n){this._doc=n}manager}let Xh=(()=>{class e extends gE{constructor(t){super(t)}supports(t){return!0}addEventListener(t,o,i,r){return t.addEventListener(o,i,r),()=>this.removeEventListener(t,o,i,r)}removeEventListener(t,o,i,r){return t.removeEventListener(o,i,r)}static \u0275fac=function(o){return new(o||e)(oe(Bn))};static \u0275prov=X({token:e,factory:e.\u0275fac})}return e})();const eg=new R("");let pE=(()=>{class e{_zone;_plugins;_eventNameToPlugin=new Map;constructor(t,o){this._zone=o,t.forEach(s=>{s.manager=this});const i=t.filter(s=>!(s instanceof Xh));this._plugins=i.slice().reverse();const r=t.find(s=>s instanceof Xh);r&&this._plugins.push(r)}addEventListener(t,o,i,r){return this._findPluginFor(o).addEventListener(t,o,i,r)}getZone(){return this._zone}_findPluginFor(t){let o=this._eventNameToPlugin.get(t);if(o)return o;if(o=this._plugins.find(r=>r.supports(t)),!o)throw new T(5101,!1);return this._eventNameToPlugin.set(t,o),o}static \u0275fac=function(o){return new(o||e)(oe(eg),oe(re))};static \u0275prov=X({token:e,factory:e.\u0275fac})}return e})();const tg="ng-app-id";function mE(e){for(const n of e)n.remove()}function _E(e,n){const t=n.createElement("style");return t.textContent=e,t}function ng(e,n){const t=n.createElement("link");return t.setAttribute("rel","stylesheet"),t.setAttribute("href",e),t}let vE=(()=>{class e{doc;appId;nonce;inline=new Map;external=new Map;hosts=new Set;constructor(t,o,i,r={}){this.doc=t,this.appId=o,this.nonce=i,function vH(e,n,t,o){const i=e.head?.querySelectorAll(`style[${tg}="${n}"],link[${tg}="${n}"]`);if(i)for(const r of i)r.removeAttribute(tg),r instanceof HTMLLinkElement?o.set(r.href.slice(r.href.lastIndexOf("/")+1),{usage:0,elements:[r]}):r.textContent&&t.set(r.textContent,{usage:0,elements:[r]})}(t,o,this.inline,this.external),this.hosts.add(t.head)}addStyles(t,o){for(const i of t)this.addUsage(i,this.inline,_E);o?.forEach(i=>this.addUsage(i,this.external,ng))}removeStyles(t,o){for(const i of t)this.removeUsage(i,this.inline);o?.forEach(i=>this.removeUsage(i,this.external))}addUsage(t,o,i){const r=o.get(t);r?r.usage++:o.set(t,{usage:1,elements:[...this.hosts].map(s=>this.addElement(s,i(t,this.doc)))})}removeUsage(t,o){const i=o.get(t);i&&(i.usage--,i.usage<=0&&(mE(i.elements),o.delete(t)))}ngOnDestroy(){for(const[,{elements:t}]of[...this.inline,...this.external])mE(t);this.hosts.clear()}addHost(t){this.hosts.add(t);for(const[o,{elements:i}]of this.inline)i.push(this.addElement(t,_E(o,this.doc)));for(const[o,{elements:i}]of this.external)i.push(this.addElement(t,ng(o,this.doc)))}removeHost(t){this.hosts.delete(t)}addElement(t,o){return this.nonce&&o.setAttribute("nonce",this.nonce),t.appendChild(o)}static \u0275fac=function(o){return new(o||e)(oe(Bn),oe(Pr),oe(b_,8),oe(C_))};static \u0275prov=X({token:e,factory:e.\u0275fac})}return e})();const og={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/",math:"http://www.w3.org/1998/Math/MathML"},ig=/%COMP%/g,EH=new R("",{providedIn:"root",factory:()=>!0});function CE(e,n){return n.map(t=>t.replace(ig,e))}let bE=(()=>{class e{eventManager;sharedStylesHost;appId;removeStylesOnCompDestroy;doc;ngZone;nonce;tracingService;rendererByCompId=new Map;defaultRenderer;platformIsServer;constructor(t,o,i,r,s,a,l=null,c=null){this.eventManager=t,this.sharedStylesHost=o,this.appId=i,this.removeStylesOnCompDestroy=r,this.doc=s,this.ngZone=a,this.nonce=l,this.tracingService=c,this.platformIsServer=!1,this.defaultRenderer=new rg(t,s,a,this.platformIsServer,this.tracingService)}createRenderer(t,o){if(!t||!o)return this.defaultRenderer;const i=this.getOrCreateRenderer(t,o);return i instanceof wE?i.applyToHost(t):i instanceof sg&&i.applyStyles(),i}getOrCreateRenderer(t,o){const i=this.rendererByCompId;let r=i.get(o.id);if(!r){const s=this.doc,a=this.ngZone,l=this.eventManager,c=this.sharedStylesHost,u=this.removeStylesOnCompDestroy,d=this.platformIsServer,g=this.tracingService;switch(o.encapsulation){case Mn.Emulated:r=new wE(l,c,o,this.appId,u,s,a,d,g);break;case Mn.ShadowDom:return new SH(l,c,t,o,s,a,this.nonce,d,g);default:r=new sg(l,c,o,u,s,a,d,g)}i.set(o.id,r)}return r}ngOnDestroy(){this.rendererByCompId.clear()}componentReplaced(t){this.rendererByCompId.delete(t)}static \u0275fac=function(o){return new(o||e)(oe(pE),oe(vE),oe(Pr),oe(EH),oe(Bn),oe(re),oe(b_),oe(Wr,8))};static \u0275prov=X({token:e,factory:e.\u0275fac})}return e})();class rg{eventManager;doc;ngZone;platformIsServer;tracingService;data=Object.create(null);throwOnSyntheticProps=!0;constructor(n,t,o,i,r){this.eventManager=n,this.doc=t,this.ngZone=o,this.platformIsServer=i,this.tracingService=r}destroy(){}destroyNode=null;createElement(n,t){return t?this.doc.createElementNS(og[t]||t,n):this.doc.createElement(n)}createComment(n){return this.doc.createComment(n)}createText(n){return this.doc.createTextNode(n)}appendChild(n,t){(DE(n)?n.content:n).appendChild(t)}insertBefore(n,t,o){n&&(DE(n)?n.content:n).insertBefore(t,o)}removeChild(n,t){t.remove()}selectRootElement(n,t){let o="string"==typeof n?this.doc.querySelector(n):n;if(!o)throw new T(-5104,!1);return t||(o.textContent=""),o}parentNode(n){return n.parentNode}nextSibling(n){return n.nextSibling}setAttribute(n,t,o,i){if(i){t=i+":"+t;const r=og[i];r?n.setAttributeNS(r,t,o):n.setAttribute(t,o)}else n.setAttribute(t,o)}removeAttribute(n,t,o){if(o){const i=og[o];i?n.removeAttributeNS(i,t):n.removeAttribute(`${o}:${t}`)}else n.removeAttribute(t)}addClass(n,t){n.classList.add(t)}removeClass(n,t){n.classList.remove(t)}setStyle(n,t,o,i){i&(qn.DashCase|qn.Important)?n.style.setProperty(t,o,i&qn.Important?"important":""):n.style[t]=o}removeStyle(n,t,o){o&qn.DashCase?n.style.removeProperty(t):n.style[t]=""}setProperty(n,t,o){null!=n&&(n[t]=o)}setValue(n,t){n.nodeValue=t}listen(n,t,o,i){if("string"==typeof n&&!(n=Mr().getGlobalEventTarget(this.doc,n)))throw new T(5102,!1);let r=this.decoratePreventDefault(o);return this.tracingService?.wrapEventListener&&(r=this.tracingService.wrapEventListener(n,t,r)),this.eventManager.addEventListener(n,t,r,i)}decoratePreventDefault(n){return t=>{if("__ngUnwrap__"===t)return n;!1===n(t)&&t.preventDefault()}}}function DE(e){return"TEMPLATE"===e.tagName&&void 0!==e.content}class SH extends rg{sharedStylesHost;hostEl;shadowRoot;constructor(n,t,o,i,r,s,a,l,c){super(n,r,s,l,c),this.sharedStylesHost=t,this.hostEl=o,this.shadowRoot=o.attachShadow({mode:"open"}),this.sharedStylesHost.addHost(this.shadowRoot);let u=i.styles;u=CE(i.id,u);for(const g of u){const h=document.createElement("style");a&&h.setAttribute("nonce",a),h.textContent=g,this.shadowRoot.appendChild(h)}const d=i.getExternalStyles?.();if(d)for(const g of d){const h=ng(g,r);a&&h.setAttribute("nonce",a),this.shadowRoot.appendChild(h)}}nodeOrShadowRoot(n){return n===this.hostEl?this.shadowRoot:n}appendChild(n,t){return super.appendChild(this.nodeOrShadowRoot(n),t)}insertBefore(n,t,o){return super.insertBefore(this.nodeOrShadowRoot(n),t,o)}removeChild(n,t){return super.removeChild(null,t)}parentNode(n){return this.nodeOrShadowRoot(super.parentNode(this.nodeOrShadowRoot(n)))}destroy(){this.sharedStylesHost.removeHost(this.shadowRoot)}}class sg extends rg{sharedStylesHost;removeStylesOnCompDestroy;styles;styleUrls;constructor(n,t,o,i,r,s,a,l,c){super(n,r,s,a,l),this.sharedStylesHost=t,this.removeStylesOnCompDestroy=i;let u=o.styles;this.styles=c?CE(c,u):u,this.styleUrls=o.getExternalStyles?.(c)}applyStyles(){this.sharedStylesHost.addStyles(this.styles,this.styleUrls)}destroy(){this.removeStylesOnCompDestroy&&0===Ao.size&&this.sharedStylesHost.removeStyles(this.styles,this.styleUrls)}}class wE extends sg{contentAttr;hostAttr;constructor(n,t,o,i,r,s,a,l,c){const u=i+"-"+o.id;super(n,t,o,r,s,a,l,c,u),this.contentAttr=function MH(e){return"_ngcontent-%COMP%".replace(ig,e)}(u),this.hostAttr=function IH(e){return"_nghost-%COMP%".replace(ig,e)}(u)}applyToHost(n){this.applyStyles(),this.setAttribute(n,this.hostAttr,"")}createElement(n,t){const o=super.createElement(n,t);return super.setAttribute(o,this.contentAttr,""),o}}class ag extends $T{supportsDOMEvents=!0;static makeCurrent(){!function UT(e){hm??=e}(new ag)}onAndCancel(n,t,o,i){return n.addEventListener(t,o,i),()=>{n.removeEventListener(t,o,i)}}dispatchEvent(n,t){n.dispatchEvent(t)}remove(n){n.remove()}createElement(n,t){return(t=t||this.getDefaultDocument()).createElement(n)}createHtmlDocument(){return document.implementation.createHTMLDocument("fakeTitle")}getDefaultDocument(){return document}isElementNode(n){return n.nodeType===Node.ELEMENT_NODE}isShadowRoot(n){return n instanceof DocumentFragment}getGlobalEventTarget(n,t){return"window"===t?window:"document"===t?n:"body"===t?n.body:null}getBaseHref(n){const t=function AH(){return Ts=Ts||document.head.querySelector("base"),Ts?Ts.getAttribute("href"):null}();return null==t?null:function NH(e){return new URL(e,document.baseURI).pathname}(t)}resetBaseElement(){Ts=null}getUserAgent(){return window.navigator.userAgent}getCookie(n){return function WT(e,n){n=encodeURIComponent(n);for(const t of e.split(";")){const o=t.indexOf("="),[i,r]=-1==o?[t,""]:[t.slice(0,o),t.slice(o+1)];if(i.trim()===n)return decodeURIComponent(r)}return null}(document.cookie,n)}}let Ts=null,xH=(()=>{class e{build(){return new XMLHttpRequest}static \u0275fac=function(o){return new(o||e)};static \u0275prov=X({token:e,factory:e.\u0275fac})}return e})();const EE=["alt","control","meta","shift"],RH={"\b":"Backspace","\t":"Tab","\x7f":"Delete","\x1b":"Escape",Del:"Delete",Esc:"Escape",Left:"ArrowLeft",Right:"ArrowRight",Up:"ArrowUp",Down:"ArrowDown",Menu:"ContextMenu",Scroll:"ScrollLock",Win:"OS"},kH={alt:e=>e.altKey,control:e=>e.ctrlKey,meta:e=>e.metaKey,shift:e=>e.shiftKey};let FH=(()=>{class e extends gE{constructor(t){super(t)}supports(t){return null!=e.parseEventName(t)}addEventListener(t,o,i,r){const s=e.parseEventName(o),a=e.eventCallback(s.fullKey,i,this.manager.getZone());return this.manager.getZone().runOutsideAngular(()=>Mr().onAndCancel(t,s.domEventName,a,r))}static parseEventName(t){const o=t.toLowerCase().split("."),i=o.shift();if(0===o.length||"keydown"!==i&&"keyup"!==i)return null;const r=e._normalizeKey(o.pop());let s="",a=o.indexOf("code");if(a>-1&&(o.splice(a,1),s="code."),EE.forEach(c=>{const u=o.indexOf(c);u>-1&&(o.splice(u,1),s+=c+".")}),s+=r,0!=o.length||0===r.length)return null;const l={};return l.domEventName=i,l.fullKey=s,l}static matchEventFullKeyCode(t,o){let i=RH[t.key]||t.key,r="";return o.indexOf("code.")>-1&&(i=t.code,r="code."),!(null==i||!i)&&(i=i.toLowerCase()," "===i?i="space":"."===i&&(i="dot"),EE.forEach(s=>{s!==i&&(0,kH[s])(t)&&(r+=s+".")}),r+=i,r===o)}static eventCallback(t,o,i){return r=>{e.matchEventFullKeyCode(r,t)&&i.runGuarded(()=>o(r))}}static _normalizeKey(t){return"esc"===t?"escape":t}static \u0275fac=function(o){return new(o||e)(oe(Bn))};static \u0275prov=X({token:e,factory:e.\u0275fac})}return e})();const HH=yw(d2,"browser",[{provide:C_,useValue:"browser"},{provide:y_,useValue:function LH(){ag.makeCurrent()},multi:!0},{provide:Bn,useFactory:function VH(){return function HS(e){rd=e}(document),document}}]),TE=[{provide:Ml,useClass:class OH{addToWindow(n){Ie.getAngularTestability=(o,i=!0)=>{const r=n.findTestabilityInTree(o,i);if(null==r)throw new T(5103,!1);return r},Ie.getAllAngularTestabilities=()=>n.getAllTestabilities(),Ie.getAllAngularRootElements=()=>n.getAllRootElements(),Ie.frameworkStabilizers||(Ie.frameworkStabilizers=[]),Ie.frameworkStabilizers.push(o=>{const i=Ie.getAllAngularTestabilities();let r=i.length;const s=function(){r--,0==r&&o()};i.forEach(a=>{a.whenStable(s)})})}findTestabilityInTree(n,t,o){return null==t?null:n.getTestability(t)??(o?Mr().isShadowRoot(t)?this.findTestabilityInTree(n,t.host,!0):this.findTestabilityInTree(n,t.parentElement,!0):null)}}},{provide:eb,useClass:$f,deps:[re,zf,Ml]},{provide:$f,useClass:$f,deps:[re,zf,Ml]}],SE=[{provide:vu,useValue:"root"},{provide:di,useFactory:function PH(){return new di}},{provide:eg,useClass:Xh,multi:!0,deps:[Bn]},{provide:eg,useClass:FH,multi:!0,deps:[Bn]},bE,vE,pE,{provide:mf,useExisting:bE},{provide:class qT{},useClass:xH},[]];let BH=(()=>{class e{constructor(){}static \u0275fac=function(o){return new(o||e)};static \u0275mod=Qn({type:e});static \u0275inj=dn({providers:[...SE,...TE],imports:[hE,f2]})}return e})();function no(e){return this instanceof no?(this.v=e,this):new no(e)}function xE(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=function dg(e){var n="function"==typeof Symbol&&Symbol.iterator,t=n&&e[n],o=0;if(t)return t.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&o>=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(n?"Object is not iterable.":"Symbol.iterator is not defined.")}(e),t={},o("next"),o("throw"),o("return"),t[Symbol.asyncIterator]=function(){return this},t);function o(r){t[r]=e[r]&&function(s){return new Promise(function(a,l){!function i(r,s,a,l){Promise.resolve(l).then(function(c){r({value:c,done:a})},s)}(a,l,(s=e[r](s)).done,s.value)})}}}"function"==typeof SuppressedError&&SuppressedError;const RE=e=>e&&"number"==typeof e.length&&"function"!=typeof e;function kE(e){return ke(e?.then)}function FE(e){return ke(e[Jc])}function LE(e){return Symbol.asyncIterator&&ke(e?.[Symbol.asyncIterator])}function PE(e){return new TypeError(`You provided ${null!==e&&"object"==typeof e?"an invalid object":`'${e}'`} where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`)}const VE=function hB(){return"function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"}();function HE(e){return ke(e?.[VE])}function BE(e){return function OE(e,n,t){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var i,o=t.apply(e,n||[]),r=[];return i=Object.create(("function"==typeof AsyncIterator?AsyncIterator:Object).prototype),a("next"),a("throw"),a("return",function s(h){return function(p){return Promise.resolve(p).then(h,d)}}),i[Symbol.asyncIterator]=function(){return this},i;function a(h,p){o[h]&&(i[h]=function(b){return new Promise(function(I,N){r.push([h,b,I,N])>1||l(h,b)})},p&&(i[h]=p(i[h])))}function l(h,p){try{!function c(h){h.value instanceof no?Promise.resolve(h.value.v).then(u,d):g(r[0][2],h)}(o[h](p))}catch(b){g(r[0][3],b)}}function u(h){l("next",h)}function d(h){l("throw",h)}function g(h,p){h(p),r.shift(),r.length&&l(r[0][0],r[0][1])}}(this,arguments,function*(){const t=e.getReader();try{for(;;){const{value:o,done:i}=yield no(t.read());if(i)return yield no(void 0);yield yield no(o)}}finally{t.releaseLock()}})}function jE(e){return ke(e?.getReader)}function Ss(e){if(e instanceof ht)return e;if(null!=e){if(FE(e))return function gB(e){return new ht(n=>{const t=e[Jc]();if(ke(t.subscribe))return t.subscribe(n);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}(e);if(RE(e))return function pB(e){return new ht(n=>{for(let t=0;t{e.then(t=>{n.closed||(n.next(t),n.complete())},t=>n.error(t)).then(null,ep)})}(e);if(LE(e))return UE(e);if(HE(e))return function _B(e){return new ht(n=>{for(const t of e)if(n.next(t),n.closed)return;n.complete()})}(e);if(jE(e))return function vB(e){return UE(BE(e))}(e)}throw PE(e)}function UE(e){return new ht(n=>{(function yB(e,n){var t,o,i,r;return function AE(e,n,t,o){return new(t||(t=Promise))(function(r,s){function a(u){try{c(o.next(u))}catch(d){s(d)}}function l(u){try{c(o.throw(u))}catch(d){s(d)}}function c(u){u.done?r(u.value):function i(r){return r instanceof t?r:new t(function(s){s(r)})}(u.value).then(a,l)}c((o=o.apply(e,n||[])).next())})}(this,void 0,void 0,function*(){try{for(t=xE(e);!(o=yield t.next()).done;)if(n.next(o.value),n.closed)return}catch(s){i={error:s}}finally{try{o&&!o.done&&(r=t.return)&&(yield r.call(t))}finally{if(i)throw i.error}}n.complete()})})(e,n).catch(t=>n.error(t))})}function Wo(e,n,t,o=0,i=!1){const r=n.schedule(function(){t(),i?e.add(this.schedule(null,o)):this.unsubscribe()},o);if(e.add(r),!i)return r}function $E(e,n=0){return Mo((t,o)=>{t.subscribe(jn(o,i=>Wo(o,e,()=>o.next(i),n),()=>Wo(o,e,()=>o.complete(),n),i=>Wo(o,e,()=>o.error(i),n)))})}function zE(e,n=0){return Mo((t,o)=>{o.add(e.schedule(()=>t.subscribe(o),n))})}function GE(e,n){if(!e)throw new Error("Iterable cannot be null");return new ht(t=>{Wo(t,n,()=>{const o=e[Symbol.asyncIterator]();Wo(t,n,()=>{o.next().then(i=>{i.done?t.complete():t.next(i.value)})},0,!0)})})}const{isArray:TB}=Array,{getPrototypeOf:SB,prototype:AB,keys:NB}=Object;const{isArray:kB}=Array;function PB(e,n){return e.reduce((t,o,i)=>(t[o]=n[i],t),{})}function VB(...e){const n=function RB(e){return ke(function hg(e){return e[e.length-1]}(e))?e.pop():void 0}(e),{args:t,keys:o}=function OB(e){if(1===e.length){const n=e[0];if(TB(n))return{args:n,keys:null};if(function xB(e){return e&&"object"==typeof e&&SB(e)===AB}(n)){const t=NB(n);return{args:t.map(o=>n[o]),keys:t}}}return{args:e,keys:null}}(e),i=new ht(r=>{const{length:s}=t;if(!s)return void r.complete();const a=new Array(s);let l=s,c=s;for(let u=0;u{d||(d=!0,c--),a[u]=g},()=>l--,void 0,()=>{(!l||!d)&&(c||r.next(o?PB(o,a):a),r.complete())}))}});return n?i.pipe(function LB(e){return $u(n=>function FB(e,n){return kB(n)?e(...n):e(n)}(e,n))}(n)):i}let WE=(()=>{class e{_renderer;_elementRef;onChange=t=>{};onTouched=()=>{};constructor(t,o){this._renderer=t,this._elementRef=o}setProperty(t,o){this._renderer.setProperty(this._elementRef.nativeElement,t,o)}registerOnTouched(t){this.onTouched=t}registerOnChange(t){this.onChange=t}setDisabledState(t){this.setProperty("disabled",t)}static \u0275fac=function(o){return new(o||e)(x(Sn),x(Nt))};static \u0275dir=W({type:e})}return e})(),qo=(()=>{class e extends WE{static \u0275fac=(()=>{let t;return function(i){return(t||(t=ze(e)))(i||e)}})();static \u0275dir=W({type:e,features:[ae]})}return e})();const Kt=new R(""),HB={provide:Kt,useExisting:ge(()=>gg),multi:!0};let gg=(()=>{class e extends qo{writeValue(t){this.setProperty("checked",t)}static \u0275fac=(()=>{let t;return function(i){return(t||(t=ze(e)))(i||e)}})();static \u0275dir=W({type:e,selectors:[["input","type","checkbox","formControlName",""],["input","type","checkbox","formControl",""],["input","type","checkbox","ngModel",""]],hostBindings:function(o,i){1&o&&U("change",function(s){return i.onChange(s.target.checked)})("blur",function(){return i.onTouched()})},standalone:!1,features:[Ee([HB]),ae]})}return e})();const BB={provide:Kt,useExisting:ge(()=>As),multi:!0},UB=new R("");let As=(()=>{class e extends WE{_compositionMode;_composing=!1;constructor(t,o,i){super(t,o),this._compositionMode=i,null==this._compositionMode&&(this._compositionMode=!function jB(){const e=Mr()?Mr().getUserAgent():"";return/android (\d+)/.test(e.toLowerCase())}())}writeValue(t){this.setProperty("value",t??"")}_handleInput(t){(!this._compositionMode||this._compositionMode&&!this._composing)&&this.onChange(t)}_compositionStart(){this._composing=!0}_compositionEnd(t){this._composing=!1,this._compositionMode&&this.onChange(t)}static \u0275fac=function(o){return new(o||e)(x(Sn),x(Nt),x(UB,8))};static \u0275dir=W({type:e,selectors:[["input","formControlName","",3,"type","checkbox"],["textarea","formControlName",""],["input","formControl","",3,"type","checkbox"],["textarea","formControl",""],["input","ngModel","",3,"type","checkbox"],["textarea","ngModel",""],["","ngDefaultControl",""]],hostBindings:function(o,i){1&o&&U("input",function(s){return i._handleInput(s.target.value)})("blur",function(){return i.onTouched()})("compositionstart",function(){return i._compositionStart()})("compositionend",function(s){return i._compositionEnd(s.target.value)})},standalone:!1,features:[Ee([BB]),ae]})}return e})();const ot=new R(""),oo=new R("");function tM(e){return null!=e}function nM(e){return Il(e)?function IB(e,n){return n?function MB(e,n){if(null!=e){if(FE(e))return function CB(e,n){return Ss(e).pipe(zE(n),$E(n))}(e,n);if(RE(e))return function DB(e,n){return new ht(t=>{let o=0;return n.schedule(function(){o===e.length?t.complete():(t.next(e[o++]),t.closed||this.schedule())})})}(e,n);if(kE(e))return function bB(e,n){return Ss(e).pipe(zE(n),$E(n))}(e,n);if(LE(e))return GE(e,n);if(HE(e))return function wB(e,n){return new ht(t=>{let o;return Wo(t,n,()=>{o=e[VE](),Wo(t,n,()=>{let i,r;try{({value:i,done:r}=o.next())}catch(s){return void t.error(s)}r?t.complete():t.next(i)},0,!0)}),()=>ke(o?.return)&&o.return()})}(e,n);if(jE(e))return function EB(e,n){return GE(BE(e),n)}(e,n)}throw PE(e)}(e,n):Ss(e)}(e):e}function oM(e){let n={};return e.forEach(t=>{n=null!=t?{...n,...t}:n}),0===Object.keys(n).length?null:n}function iM(e,n){return n.map(t=>t(e))}function rM(e){return e.map(n=>function zB(e){return!e.validate}(n)?n:t=>n.validate(t))}function _g(e){return null!=e?function sM(e){if(!e)return null;const n=e.filter(tM);return 0==n.length?null:function(t){return oM(iM(t,n))}}(rM(e)):null}function vg(e){return null!=e?function aM(e){if(!e)return null;const n=e.filter(tM);return 0==n.length?null:function(t){return VB(iM(t,n).map(nM)).pipe($u(oM))}}(rM(e)):null}function lM(e,n){return null===e?[n]:Array.isArray(e)?[...e,n]:[e,n]}function yg(e){return e?Array.isArray(e)?e:[e]:[]}function _c(e,n){return Array.isArray(e)?e.includes(n):e===n}function dM(e,n){const t=yg(n);return yg(e).forEach(i=>{_c(t,i)||t.push(i)}),t}function fM(e,n){return yg(n).filter(t=>!_c(e,t))}class hM{get value(){return this.control?this.control.value:null}get valid(){return this.control?this.control.valid:null}get invalid(){return this.control?this.control.invalid:null}get pending(){return this.control?this.control.pending:null}get disabled(){return this.control?this.control.disabled:null}get enabled(){return this.control?this.control.enabled:null}get errors(){return this.control?this.control.errors:null}get pristine(){return this.control?this.control.pristine:null}get dirty(){return this.control?this.control.dirty:null}get touched(){return this.control?this.control.touched:null}get status(){return this.control?this.control.status:null}get untouched(){return this.control?this.control.untouched:null}get statusChanges(){return this.control?this.control.statusChanges:null}get valueChanges(){return this.control?this.control.valueChanges:null}get path(){return null}_composedValidatorFn;_composedAsyncValidatorFn;_rawValidators=[];_rawAsyncValidators=[];_setValidators(n){this._rawValidators=n||[],this._composedValidatorFn=_g(this._rawValidators)}_setAsyncValidators(n){this._rawAsyncValidators=n||[],this._composedAsyncValidatorFn=vg(this._rawAsyncValidators)}get validator(){return this._composedValidatorFn||null}get asyncValidator(){return this._composedAsyncValidatorFn||null}_onDestroyCallbacks=[];_registerOnDestroy(n){this._onDestroyCallbacks.push(n)}_invokeOnDestroyCallbacks(){this._onDestroyCallbacks.forEach(n=>n()),this._onDestroyCallbacks=[]}reset(n=void 0){this.control&&this.control.reset(n)}hasError(n,t){return!!this.control&&this.control.hasError(n,t)}getError(n,t){return this.control?this.control.getError(n,t):null}}class ft extends hM{name;get formDirective(){return null}get path(){return null}}class io extends hM{_parent=null;name=null;valueAccessor=null}class gM{_cd;constructor(n){this._cd=n}get isTouched(){return this._cd?.control?._touched?.(),!!this._cd?.control?.touched}get isUntouched(){return!!this._cd?.control?.untouched}get isPristine(){return this._cd?.control?._pristine?.(),!!this._cd?.control?.pristine}get isDirty(){return!!this._cd?.control?.dirty}get isValid(){return this._cd?.control?._status?.(),!!this._cd?.control?.valid}get isInvalid(){return!!this._cd?.control?.invalid}get isPending(){return!!this._cd?.control?.pending}get isSubmitted(){return this._cd?._submitted?.(),!!this._cd?.submitted}}let vc=(()=>{class e extends gM{constructor(t){super(t)}static \u0275fac=function(o){return new(o||e)(x(io,2))};static \u0275dir=W({type:e,selectors:[["","formControlName",""],["","ngModel",""],["","formControl",""]],hostVars:14,hostBindings:function(o,i){2&o&&An("ng-untouched",i.isUntouched)("ng-touched",i.isTouched)("ng-pristine",i.isPristine)("ng-dirty",i.isDirty)("ng-valid",i.isValid)("ng-invalid",i.isInvalid)("ng-pending",i.isPending)},standalone:!1,features:[ae]})}return e})();const Ns="VALID",Cc="INVALID",er="PENDING",Os="DISABLED";class tr{}class mM extends tr{value;source;constructor(n,t){super(),this.value=n,this.source=t}}class Dg extends tr{pristine;source;constructor(n,t){super(),this.pristine=n,this.source=t}}class wg extends tr{touched;source;constructor(n,t){super(),this.touched=n,this.source=t}}class bc extends tr{status;source;constructor(n,t){super(),this.status=n,this.source=t}}class Eg extends tr{source;constructor(n){super(),this.source=n}}function Dc(e){return null!=e&&!Array.isArray(e)&&"object"==typeof e}class Tg{_pendingDirty=!1;_hasOwnPendingAsyncValidator=null;_pendingTouched=!1;_onCollectionChange=()=>{};_updateOn;_parent=null;_asyncValidationSubscription;_composedValidatorFn;_composedAsyncValidatorFn;_rawValidators;_rawAsyncValidators;value;constructor(n,t){this._assignValidators(n),this._assignAsyncValidators(t)}get validator(){return this._composedValidatorFn}set validator(n){this._rawValidators=this._composedValidatorFn=n}get asyncValidator(){return this._composedAsyncValidatorFn}set asyncValidator(n){this._rawAsyncValidators=this._composedAsyncValidatorFn=n}get parent(){return this._parent}get status(){return Pe(this.statusReactive)}set status(n){Pe(()=>this.statusReactive.set(n))}_status=Zt(()=>this.statusReactive());statusReactive=wo(void 0);get valid(){return this.status===Ns}get invalid(){return this.status===Cc}get pending(){return this.status==er}get disabled(){return this.status===Os}get enabled(){return this.status!==Os}errors;get pristine(){return Pe(this.pristineReactive)}set pristine(n){Pe(()=>this.pristineReactive.set(n))}_pristine=Zt(()=>this.pristineReactive());pristineReactive=wo(!0);get dirty(){return!this.pristine}get touched(){return Pe(this.touchedReactive)}set touched(n){Pe(()=>this.touchedReactive.set(n))}_touched=Zt(()=>this.touchedReactive());touchedReactive=wo(!1);get untouched(){return!this.touched}_events=new Xt;events=this._events.asObservable();valueChanges;statusChanges;get updateOn(){return this._updateOn?this._updateOn:this.parent?this.parent.updateOn:"change"}setValidators(n){this._assignValidators(n)}setAsyncValidators(n){this._assignAsyncValidators(n)}addValidators(n){this.setValidators(dM(n,this._rawValidators))}addAsyncValidators(n){this.setAsyncValidators(dM(n,this._rawAsyncValidators))}removeValidators(n){this.setValidators(fM(n,this._rawValidators))}removeAsyncValidators(n){this.setAsyncValidators(fM(n,this._rawAsyncValidators))}hasValidator(n){return _c(this._rawValidators,n)}hasAsyncValidator(n){return _c(this._rawAsyncValidators,n)}clearValidators(){this.validator=null}clearAsyncValidators(){this.asyncValidator=null}markAsTouched(n={}){const t=!1===this.touched;this.touched=!0;const o=n.sourceControl??this;this._parent&&!n.onlySelf&&this._parent.markAsTouched({...n,sourceControl:o}),t&&!1!==n.emitEvent&&this._events.next(new wg(!0,o))}markAllAsDirty(n={}){this.markAsDirty({onlySelf:!0,emitEvent:n.emitEvent,sourceControl:this}),this._forEachChild(t=>t.markAllAsDirty(n))}markAllAsTouched(n={}){this.markAsTouched({onlySelf:!0,emitEvent:n.emitEvent,sourceControl:this}),this._forEachChild(t=>t.markAllAsTouched(n))}markAsUntouched(n={}){const t=!0===this.touched;this.touched=!1,this._pendingTouched=!1;const o=n.sourceControl??this;this._forEachChild(i=>{i.markAsUntouched({onlySelf:!0,emitEvent:n.emitEvent,sourceControl:o})}),this._parent&&!n.onlySelf&&this._parent._updateTouched(n,o),t&&!1!==n.emitEvent&&this._events.next(new wg(!1,o))}markAsDirty(n={}){const t=!0===this.pristine;this.pristine=!1;const o=n.sourceControl??this;this._parent&&!n.onlySelf&&this._parent.markAsDirty({...n,sourceControl:o}),t&&!1!==n.emitEvent&&this._events.next(new Dg(!1,o))}markAsPristine(n={}){const t=!1===this.pristine;this.pristine=!0,this._pendingDirty=!1;const o=n.sourceControl??this;this._forEachChild(i=>{i.markAsPristine({onlySelf:!0,emitEvent:n.emitEvent})}),this._parent&&!n.onlySelf&&this._parent._updatePristine(n,o),t&&!1!==n.emitEvent&&this._events.next(new Dg(!0,o))}markAsPending(n={}){this.status=er;const t=n.sourceControl??this;!1!==n.emitEvent&&(this._events.next(new bc(this.status,t)),this.statusChanges.emit(this.status)),this._parent&&!n.onlySelf&&this._parent.markAsPending({...n,sourceControl:t})}disable(n={}){const t=this._parentMarkedDirty(n.onlySelf);this.status=Os,this.errors=null,this._forEachChild(i=>{i.disable({...n,onlySelf:!0})}),this._updateValue();const o=n.sourceControl??this;!1!==n.emitEvent&&(this._events.next(new mM(this.value,o)),this._events.next(new bc(this.status,o)),this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._updateAncestors({...n,skipPristineCheck:t},this),this._onDisabledChange.forEach(i=>i(!0))}enable(n={}){const t=this._parentMarkedDirty(n.onlySelf);this.status=Ns,this._forEachChild(o=>{o.enable({...n,onlySelf:!0})}),this.updateValueAndValidity({onlySelf:!0,emitEvent:n.emitEvent}),this._updateAncestors({...n,skipPristineCheck:t},this),this._onDisabledChange.forEach(o=>o(!1))}_updateAncestors(n,t){this._parent&&!n.onlySelf&&(this._parent.updateValueAndValidity(n),n.skipPristineCheck||this._parent._updatePristine({},t),this._parent._updateTouched({},t))}setParent(n){this._parent=n}getRawValue(){return this.value}updateValueAndValidity(n={}){if(this._setInitialStatus(),this._updateValue(),this.enabled){const o=this._cancelExistingSubscription();this.errors=this._runValidator(),this.status=this._calculateStatus(),(this.status===Ns||this.status===er)&&this._runAsyncValidator(o,n.emitEvent)}const t=n.sourceControl??this;!1!==n.emitEvent&&(this._events.next(new mM(this.value,t)),this._events.next(new bc(this.status,t)),this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._parent&&!n.onlySelf&&this._parent.updateValueAndValidity({...n,sourceControl:t})}_updateTreeValidity(n={emitEvent:!0}){this._forEachChild(t=>t._updateTreeValidity(n)),this.updateValueAndValidity({onlySelf:!0,emitEvent:n.emitEvent})}_setInitialStatus(){this.status=this._allControlsDisabled()?Os:Ns}_runValidator(){return this.validator?this.validator(this):null}_runAsyncValidator(n,t){if(this.asyncValidator){this.status=er,this._hasOwnPendingAsyncValidator={emitEvent:!1!==t,shouldHaveEmitted:!1!==n};const o=nM(this.asyncValidator(this));this._asyncValidationSubscription=o.subscribe(i=>{this._hasOwnPendingAsyncValidator=null,this.setErrors(i,{emitEvent:t,shouldHaveEmitted:n})})}}_cancelExistingSubscription(){if(this._asyncValidationSubscription){this._asyncValidationSubscription.unsubscribe();const n=(this._hasOwnPendingAsyncValidator?.emitEvent||this._hasOwnPendingAsyncValidator?.shouldHaveEmitted)??!1;return this._hasOwnPendingAsyncValidator=null,n}return!1}setErrors(n,t={}){this.errors=n,this._updateControlsErrors(!1!==t.emitEvent,this,t.shouldHaveEmitted)}get(n){let t=n;return null==t||(Array.isArray(t)||(t=t.split(".")),0===t.length)?null:t.reduce((o,i)=>o&&o._find(i),this)}getError(n,t){const o=t?this.get(t):this;return o&&o.errors?o.errors[n]:null}hasError(n,t){return!!this.getError(n,t)}get root(){let n=this;for(;n._parent;)n=n._parent;return n}_updateControlsErrors(n,t,o){this.status=this._calculateStatus(),n&&this.statusChanges.emit(this.status),(n||o)&&this._events.next(new bc(this.status,t)),this._parent&&this._parent._updateControlsErrors(n,t,o)}_initObservables(){this.valueChanges=new ve,this.statusChanges=new ve}_calculateStatus(){return this._allControlsDisabled()?Os:this.errors?Cc:this._hasOwnPendingAsyncValidator||this._anyControlsHaveStatus(er)?er:this._anyControlsHaveStatus(Cc)?Cc:Ns}_anyControlsHaveStatus(n){return this._anyControls(t=>t.status===n)}_anyControlsDirty(){return this._anyControls(n=>n.dirty)}_anyControlsTouched(){return this._anyControls(n=>n.touched)}_updatePristine(n,t){const o=!this._anyControlsDirty(),i=this.pristine!==o;this.pristine=o,this._parent&&!n.onlySelf&&this._parent._updatePristine(n,t),i&&this._events.next(new Dg(this.pristine,t))}_updateTouched(n={},t){this.touched=this._anyControlsTouched(),this._events.next(new wg(this.touched,t)),this._parent&&!n.onlySelf&&this._parent._updateTouched(n,t)}_onDisabledChange=[];_registerOnCollectionChange(n){this._onCollectionChange=n}_setUpdateStrategy(n){Dc(n)&&null!=n.updateOn&&(this._updateOn=n.updateOn)}_parentMarkedDirty(n){return!n&&!(!this._parent||!this._parent.dirty)&&!this._parent._anyControlsDirty()}_find(n){return null}_assignValidators(n){this._rawValidators=Array.isArray(n)?n.slice():n,this._composedValidatorFn=function JB(e){return Array.isArray(e)?_g(e):e||null}(this._rawValidators)}_assignAsyncValidators(n){this._rawAsyncValidators=Array.isArray(n)?n.slice():n,this._composedAsyncValidatorFn=function XB(e){return Array.isArray(e)?vg(e):e||null}(this._rawAsyncValidators)}}const nr=new R("",{providedIn:"root",factory:()=>wc}),wc="always";function xs(e,n,t=wc){(function Ag(e,n){const t=function cM(e){return e._rawValidators}(e);null!==n.validator?e.setValidators(lM(t,n.validator)):"function"==typeof t&&e.setValidators([t]);const o=function uM(e){return e._rawAsyncValidators}(e);null!==n.asyncValidator?e.setAsyncValidators(lM(o,n.asyncValidator)):"function"==typeof o&&e.setAsyncValidators([o]);const i=()=>e.updateValueAndValidity();Ic(n._rawValidators,i),Ic(n._rawAsyncValidators,i)})(e,n),n.valueAccessor.writeValue(e.value),(e.disabled||"always"===t)&&n.valueAccessor.setDisabledState?.(e.disabled),function nj(e,n){n.valueAccessor.registerOnChange(t=>{e._pendingValue=t,e._pendingChange=!0,e._pendingDirty=!0,"change"===e.updateOn&&CM(e,n)})}(e,n),function ij(e,n){const t=(o,i)=>{n.valueAccessor.writeValue(o),i&&n.viewToModelUpdate(o)};e.registerOnChange(t),n._registerOnDestroy(()=>{e._unregisterOnChange(t)})}(e,n),function oj(e,n){n.valueAccessor.registerOnTouched(()=>{e._pendingTouched=!0,"blur"===e.updateOn&&e._pendingChange&&CM(e,n),"submit"!==e.updateOn&&e.markAsTouched()})}(e,n),function tj(e,n){if(n.valueAccessor.setDisabledState){const t=o=>{n.valueAccessor.setDisabledState(o)};e.registerOnDisabledChange(t),n._registerOnDestroy(()=>{e._unregisterOnDisabledChange(t)})}}(e,n)}function Ic(e,n){e.forEach(t=>{t.registerOnValidatorChange&&t.registerOnValidatorChange(n)})}function CM(e,n){e._pendingDirty&&e.markAsDirty(),e.setValue(e._pendingValue,{emitModelToViewChange:!1}),n.viewToModelUpdate(e._pendingValue),e._pendingChange=!1}function wM(e,n){const t=e.indexOf(n);t>-1&&e.splice(t,1)}function EM(e){return"object"==typeof e&&null!==e&&2===Object.keys(e).length&&"value"in e&&"disabled"in e}Promise.resolve();const MM=class extends Tg{defaultValue=null;_onChange=[];_pendingValue;_pendingChange=!1;constructor(n=null,t,o){super(function Mg(e){return(Dc(e)?e.validators:e)||null}(t),function Ig(e,n){return(Dc(n)?n.asyncValidators:e)||null}(o,t)),this._applyFormState(n),this._setUpdateStrategy(t),this._initObservables(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator}),Dc(t)&&(t.nonNullable||t.initialValueIsDefault)&&(this.defaultValue=EM(n)?n.value:n)}setValue(n,t={}){this.value=this._pendingValue=n,this._onChange.length&&!1!==t.emitModelToViewChange&&this._onChange.forEach(o=>o(this.value,!1!==t.emitViewToModelChange)),this.updateValueAndValidity(t)}patchValue(n,t={}){this.setValue(n,t)}reset(n=this.defaultValue,t={}){this._applyFormState(n),this.markAsPristine(t),this.markAsUntouched(t),this.setValue(this.value,t),this._pendingChange=!1,!1!==t?.emitEvent&&this._events.next(new Eg(this))}_updateValue(){}_anyControls(n){return!1}_allControlsDisabled(){return this.disabled}registerOnChange(n){this._onChange.push(n)}_unregisterOnChange(n){wM(this._onChange,n)}registerOnDisabledChange(n){this._onDisabledChange.push(n)}_unregisterOnDisabledChange(n){wM(this._onDisabledChange,n)}_forEachChild(n){}_syncPendingControls(){return!("submit"!==this.updateOn||(this._pendingDirty&&this.markAsDirty(),this._pendingTouched&&this.markAsTouched(),!this._pendingChange)||(this.setValue(this._pendingValue,{onlySelf:!0,emitModelToViewChange:!1}),0))}_applyFormState(n){EM(n)?(this.value=this._pendingValue=n.value,n.disabled?this.disable({onlySelf:!0,emitEvent:!1}):this.enable({onlySelf:!0,emitEvent:!1})):this.value=this._pendingValue=n}},gj={provide:io,useExisting:ge(()=>ks)},IM=Promise.resolve();let ks=(()=>{class e extends io{_changeDetectorRef;callSetDisabledState;control=new MM;static ngAcceptInputType_isDisabled;_registered=!1;viewModel;name="";isDisabled;model;options;update=new ve;constructor(t,o,i,r,s,a){super(),this._changeDetectorRef=s,this.callSetDisabledState=a,this._parent=t,this._setValidators(o),this._setAsyncValidators(i),this.valueAccessor=function xg(e,n){if(!n)return null;let t,o,i;return Array.isArray(n),n.forEach(r=>{r.constructor===As?t=r:function aj(e){return Object.getPrototypeOf(e.constructor)===qo}(r)?o=r:i=r}),i||o||t||null}(0,r)}ngOnChanges(t){if(this._checkForErrors(),!this._registered||"name"in t){if(this._registered&&(this._checkName(),this.formDirective)){const o=t.name.previousValue;this.formDirective.removeControl({name:o,path:this._getPath(o)})}this._setUpControl()}"isDisabled"in t&&this._updateDisabled(t),function Og(e,n){if(!e.hasOwnProperty("model"))return!1;const t=e.model;return!!t.isFirstChange()||!Object.is(n,t.currentValue)}(t,this.viewModel)&&(this._updateValue(this.model),this.viewModel=this.model)}ngOnDestroy(){this.formDirective&&this.formDirective.removeControl(this)}get path(){return this._getPath(this.name)}get formDirective(){return this._parent?this._parent.formDirective:null}viewToModelUpdate(t){this.viewModel=t,this.update.emit(t)}_setUpControl(){this._setUpdateStrategy(),this._isStandalone()?this._setUpStandalone():this.formDirective.addControl(this),this._registered=!0}_setUpdateStrategy(){this.options&&null!=this.options.updateOn&&(this.control._updateOn=this.options.updateOn)}_isStandalone(){return!this._parent||!(!this.options||!this.options.standalone)}_setUpStandalone(){xs(this.control,this,this.callSetDisabledState),this.control.updateValueAndValidity({emitEvent:!1})}_checkForErrors(){this._checkName()}_checkName(){this.options&&this.options.name&&(this.name=this.options.name),this._isStandalone()}_updateValue(t){IM.then(()=>{this.control.setValue(t,{emitViewToModelChange:!1}),this._changeDetectorRef?.markForCheck()})}_updateDisabled(t){const o=t.isDisabled.currentValue,i=0!==o&&function Lh(e){return"boolean"==typeof e?e:null!=e&&"false"!==e}(o);IM.then(()=>{i&&!this.control.disabled?this.control.disable():!i&&this.control.disabled&&this.control.enable(),this._changeDetectorRef?.markForCheck()})}_getPath(t){return this._parent?function Ec(e,n){return[...n.path,e]}(t,this._parent):[t]}static \u0275fac=function(o){return new(o||e)(x(ft,9),x(ot,10),x(oo,10),x(Kt,10),x(Es,8),x(nr,8))};static \u0275dir=W({type:e,selectors:[["","ngModel","",3,"formControlName","",3,"formControl",""]],inputs:{name:"name",isDisabled:[0,"disabled","isDisabled"],model:[0,"ngModel","model"],options:[0,"ngModelOptions","options"]},outputs:{update:"ngModelChange"},exportAs:["ngModel"],standalone:!1,features:[Ee([gj]),ae,En]})}return e})();const yj={provide:Kt,useExisting:ge(()=>Rg),multi:!0};let Rg=(()=>{class e extends qo{writeValue(t){this.setProperty("value",parseFloat(t))}registerOnChange(t){this.onChange=o=>{t(""==o?null:parseFloat(o))}}static \u0275fac=(()=>{let t;return function(i){return(t||(t=ze(e)))(i||e)}})();static \u0275dir=W({type:e,selectors:[["input","type","range","formControlName",""],["input","type","range","formControl",""],["input","type","range","ngModel",""]],hostBindings:function(o,i){1&o&&U("change",function(s){return i.onChange(s.target.value)})("input",function(s){return i.onChange(s.target.value)})("blur",function(){return i.onTouched()})},standalone:!1,features:[Ee([yj]),ae]})}return e})();const Mj={provide:Kt,useExisting:ge(()=>Ls),multi:!0};function RM(e,n){return null==e?`${n}`:(n&&"object"==typeof n&&(n="Object"),`${e}: ${n}`.slice(0,50))}let Ls=(()=>{class e extends qo{value;_optionMap=new Map;_idCounter=0;set compareWith(t){this._compareWith=t}_compareWith=Object.is;appRefInjector=F(Jn).injector;destroyRef=F(bn);cdr=F(Es);_queuedWrite=!1;_writeValueAfterRender(){this._queuedWrite||this.appRefInjector.destroyed||(this._queuedWrite=!0,Gd({write:()=>{this.destroyRef.destroyed||(this._queuedWrite=!1,this.writeValue(this.value))}},{injector:this.appRefInjector}))}writeValue(t){this.cdr.markForCheck(),this.value=t;const i=RM(this._getOptionId(t),t);this.setProperty("value",i)}registerOnChange(t){this.onChange=o=>{this.value=this._getOptionValue(o),t(this.value)}}_registerOption(){return(this._idCounter++).toString()}_getOptionId(t){for(const o of this._optionMap.keys())if(this._compareWith(this._optionMap.get(o),t))return o;return null}_getOptionValue(t){const o=function Ij(e){return e.split(":")[0]}(t);return this._optionMap.has(o)?this._optionMap.get(o):t}static \u0275fac=(()=>{let t;return function(i){return(t||(t=ze(e)))(i||e)}})();static \u0275dir=W({type:e,selectors:[["select","formControlName","",3,"multiple",""],["select","formControl","",3,"multiple",""],["select","ngModel","",3,"multiple",""]],hostBindings:function(o,i){1&o&&U("change",function(s){return i.onChange(s.target.value)})("blur",function(){return i.onTouched()})},inputs:{compareWith:"compareWith"},standalone:!1,features:[Ee([Mj]),ae]})}return e})(),kg=(()=>{class e{_element;_renderer;_select;id;constructor(t,o,i){this._element=t,this._renderer=o,this._select=i,this._select&&(this.id=this._select._registerOption())}set ngValue(t){null!=this._select&&(this._select._optionMap.set(this.id,t),this._setElementValue(RM(this.id,t)),this._select._writeValueAfterRender())}set value(t){this._setElementValue(t),this._select&&this._select._writeValueAfterRender()}_setElementValue(t){this._renderer.setProperty(this._element.nativeElement,"value",t)}ngOnDestroy(){this._select&&(this._select._optionMap.delete(this.id),this._select._writeValueAfterRender())}static \u0275fac=function(o){return new(o||e)(x(Nt),x(Sn),x(Ls,9))};static \u0275dir=W({type:e,selectors:[["option"]],inputs:{ngValue:"ngValue",value:"value"},standalone:!1})}return e})();const Tj={provide:Kt,useExisting:ge(()=>Fg),multi:!0};function kM(e,n){return null==e?`${n}`:("string"==typeof n&&(n=`'${n}'`),n&&"object"==typeof n&&(n="Object"),`${e}: ${n}`.slice(0,50))}let Fg=(()=>{class e extends qo{value;_optionMap=new Map;_idCounter=0;set compareWith(t){this._compareWith=t}_compareWith=Object.is;writeValue(t){let o;if(this.value=t,Array.isArray(t)){const i=t.map(r=>this._getOptionId(r));o=(r,s)=>{r._setSelected(i.indexOf(s.toString())>-1)}}else o=(i,r)=>{i._setSelected(!1)};this._optionMap.forEach(o)}registerOnChange(t){this.onChange=o=>{const i=[],r=o.selectedOptions;if(void 0!==r){const s=r;for(let a=0;a{let t;return function(i){return(t||(t=ze(e)))(i||e)}})();static \u0275dir=W({type:e,selectors:[["select","multiple","","formControlName",""],["select","multiple","","formControl",""],["select","multiple","","ngModel",""]],hostBindings:function(o,i){1&o&&U("change",function(s){return i.onChange(s.target)})("blur",function(){return i.onTouched()})},inputs:{compareWith:"compareWith"},standalone:!1,features:[Ee([Tj]),ae]})}return e})(),Lg=(()=>{class e{_element;_renderer;_select;id;_value;constructor(t,o,i){this._element=t,this._renderer=o,this._select=i,this._select&&(this.id=this._select._registerOption(this))}set ngValue(t){null!=this._select&&(this._value=t,this._setElementValue(kM(this.id,t)),this._select.writeValue(this._select.value))}set value(t){this._select?(this._value=t,this._setElementValue(kM(this.id,t)),this._select.writeValue(this._select.value)):this._setElementValue(t)}_setElementValue(t){this._renderer.setProperty(this._element.nativeElement,"value",t)}_setSelected(t){this._renderer.setProperty(this._element.nativeElement,"selected",t)}ngOnDestroy(){this._select&&(this._select._optionMap.delete(this.id),this._select.writeValue(this._select.value))}static \u0275fac=function(o){return new(o||e)(x(Nt),x(Sn),x(Fg,9))};static \u0275dir=W({type:e,selectors:[["option"]],inputs:{ngValue:"ngValue",value:"value"},standalone:!1})}return e})(),Pj=(()=>{class e{static \u0275fac=function(o){return new(o||e)};static \u0275mod=Qn({type:e});static \u0275inj=dn({})}return e})(),Hj=(()=>{class e{static withConfig(t){return{ngModule:e,providers:[{provide:nr,useValue:t.callSetDisabledState??wc}]}}static \u0275fac=function(o){return new(o||e)};static \u0275mod=Qn({type:e});static \u0275inj=dn({imports:[Pj]})}return e})();class Bj extends It{constructor(n,t){super()}schedule(n,t=0){return this}}const Rc={setInterval(e,n,...t){const{delegate:o}=Rc;return o?.setInterval?o.setInterval(e,n,...t):setInterval(e,n,...t)},clearInterval(e){const{delegate:n}=Rc;return(n?.clearInterval||clearInterval)(e)},delegate:void 0},zM={now:()=>(zM.delegate||Date).now(),delegate:void 0};class Ps{constructor(n,t=Ps.now){this.schedulerActionCtor=n,this.now=t}schedule(n,t=0,o){return new this.schedulerActionCtor(this,n).schedule(o,t)}}Ps.now=zM.now;const GM=new class Uj extends Ps{constructor(n,t=Ps.now){super(n,t),this.actions=[],this._active=!1}flush(n){const{actions:t}=this;if(this._active)return void t.push(n);let o;this._active=!0;do{if(o=n.execute(n.state,n.delay))break}while(n=t.shift());if(this._active=!1,o){for(;n=t.shift();)n.unsubscribe();throw o}}}(class jj extends Bj{constructor(n,t){super(n,t),this.scheduler=n,this.work=t,this.pending=!1}schedule(n,t=0){var o;if(this.closed)return this;this.state=n;const i=this.id,r=this.scheduler;return null!=i&&(this.id=this.recycleAsyncId(r,i,t)),this.pending=!0,this.delay=t,this.id=null!==(o=this.id)&&void 0!==o?o:this.requestAsyncId(r,this.id,t),this}requestAsyncId(n,t,o=0){return Rc.setInterval(n.flush.bind(n,this),o)}recycleAsyncId(n,t,o=0){if(null!=o&&this.delay===o&&!1===this.pending)return t;null!=t&&Rc.clearInterval(t)}execute(n,t){if(this.closed)return new Error("executing a cancelled action");this.pending=!1;const o=this._execute(n,t);if(o)return o;!1===this.pending&&null!=this.id&&(this.id=this.recycleAsyncId(this.scheduler,this.id,null))}_execute(n,t){let i,o=!1;try{this.work(n)}catch(r){o=!0,i=r||new Error("Scheduled action threw falsy error")}if(o)return this.unsubscribe(),i}unsubscribe(){if(!this.closed){const{id:n,scheduler:t}=this,{actions:o}=t;this.work=this.state=this.scheduler=null,this.pending=!1,Us(o,this),null!=n&&(this.id=this.recycleAsyncId(t,n,null)),this.delay=null,super.unsubscribe()}}}),$j=GM;function WM(e,n=GM,t){const o=function qj(e=0,n,t=$j){let o=-1;return null!=n&&(function Gj(e){return e&&ke(e.schedule)}(n)?t=n:o=n),new ht(i=>{let r=function Wj(e){return e instanceof Date&&!isNaN(e)}(e)?+e-t.now():e;r<0&&(r=0);let s=0;return t.schedule(function(){i.closed||(i.next(s++),0<=o?this.schedule(void 0,o):i.complete())},r)})}(e,n);return function zj(e,n){return Mo((t,o)=>{const{leading:i=!0,trailing:r=!1}=n??{};let s=!1,a=null,l=null,c=!1;const u=()=>{l?.unsubscribe(),l=null,r&&(h(),c&&o.complete())},d=()=>{l=null,c&&o.complete()},g=p=>l=Ss(e(p)).subscribe(jn(o,u,d)),h=()=>{if(s){s=!1;const p=a;a=null,o.next(p),!c&&g(p)}};t.subscribe(jn(o,p=>{s=!0,a=p,(!l||l.closed)&&(i?h():g(p))},()=>{c=!0,(!(r&&s&&l)||l.closed)&&o.complete()}))})}(()=>o,t)}function qM(e,n,t){const o=ke(e)||n||t?{next:e,error:n,complete:t}:e;return o?Mo((i,r)=>{var s;null===(s=o.subscribe)||void 0===s||s.call(o);let a=!0;i.subscribe(jn(r,l=>{var c;null===(c=o.next)||void 0===c||c.call(o,l),r.next(l)},()=>{var l;a=!1,null===(l=o.complete)||void 0===l||l.call(o),r.complete()},l=>{var c;a=!1,null===(c=o.error)||void 0===c||c.call(o,l),r.error(l)},()=>{var l,c;a&&(null===(l=o.unsubscribe)||void 0===l||l.call(o)),null===(c=o.finalize)||void 0===c||c.call(o)}))}):Xc}function ZM(e,n=Xc){return e=e??Zj,Mo((t,o)=>{let i,r=!0;t.subscribe(jn(o,s=>{const a=n(s);(r||!e(i,a))&&(r=!1,i=a,o.next(s))}))})}function Zj(e,n){return e===n}var Rt=typeof window<"u"?window:{screen:{},navigator:{}},or=(Rt.matchMedia||function(){return{matches:!1}}).bind(Rt),YM=!1,QM=function(){};Rt.addEventListener&&Rt.addEventListener("p",QM,{get passive(){return YM=!0}}),Rt.removeEventListener&&Rt.removeEventListener("p",QM,!1);var KM=YM,Vg="ontouchstart"in Rt,XM=(Vg||"TouchEvent"in Rt&&or("(any-pointer: coarse)"),Rt.navigator.userAgent||"");or("(pointer: coarse)").matches&&/iPad|Macintosh/.test(XM)&&Math.min(Rt.screen.width||0,Rt.screen.height||0);(or("(pointer: coarse)").matches||!or("(pointer: fine)").matches&&Vg)&&/Windows.*Firefox/.test(XM),or("(any-pointer: fine)").matches||or("(any-hover: hover)");const tU=(e,n,t)=>({tooltip:e,placement:n,content:t});function nU(e,n){}function oU(e,n){1&e&&_l(0,nU,0,0,"ng-template")}function iU(e,n){if(1&e&&_l(0,oU,1,0,null,1),2&e){const t=m();A("ngTemplateOutlet",t.template)("ngTemplateOutletContext",Ne(2,tU,t.tooltip,t.placement,t.content))}}function rU(e,n){if(1&e&&(v(0,"div",0),D(1),_()),2&e){const t=m();ct("title",t.tooltip)("data-tooltip-placement",t.placement),f(),P(" ",t.content," ")}}const sU=["tooltipTemplate"],aU=["leftOuterSelectionBar"],lU=["rightOuterSelectionBar"],cU=["fullBar"],uU=["selectionBar"],dU=["minHandle"],fU=["maxHandle"],hU=["floorLabel"],gU=["ceilLabel"],pU=["minHandleLabel"],mU=["maxHandleLabel"],_U=["combinedLabel"],vU=["ticksElement"],yU=e=>({"ngx-slider-selected":e});function CU(e,n){if(1&e&&O(0,"ngx-slider-tooltip-wrapper",28),2&e){const t=m().$implicit;A("template",m().tooltipTemplate)("tooltip",t.valueTooltip)("placement",t.valueTooltipPlacement)("content",t.value)}}function bU(e,n){1&e&&O(0,"span",29),2&e&&A("innerText",m().$implicit.legend)}function DU(e,n){1&e&&O(0,"span",30),2&e&&A("innerHTML",m().$implicit.legend,pv)}function wU(e,n){if(1&e&&(v(0,"span",26),O(1,"ngx-slider-tooltip-wrapper",27),y(2,CU,1,4,"ngx-slider-tooltip-wrapper",28),y(3,bU,1,1,"span",29),y(4,DU,1,1,"span",30),_()),2&e){const t=n.$implicit,o=m();A("ngClass",Zi(8,yU,t.selected))("ngStyle",t.style),f(),A("template",o.tooltipTemplate)("tooltip",t.tooltip)("placement",t.tooltipPlacement),f(),C(null!=t.value?2:-1),f(),C(null!=t.legend&&!1===o.allowUnsafeHtmlInSlider?3:-1),f(),C(null==t.legend||null!=o.allowUnsafeHtmlInSlider&&!o.allowUnsafeHtmlInSlider?-1:4)}}var cn=function(e){return e[e.Low=0]="Low",e[e.High=1]="High",e[e.Floor=2]="Floor",e[e.Ceil=3]="Ceil",e[e.TickValue=4]="TickValue",e}(cn||{});class kc{floor=0;ceil=null;step=1;minRange=null;maxRange=null;pushRange=!1;minLimit=null;maxLimit=null;translate=null;combineLabels=null;getLegend=null;getStepLegend=null;stepsArray=null;bindIndexForStepsArray=!1;draggableRange=!1;draggableRangeOnly=!1;showSelectionBar=!1;showSelectionBarEnd=!1;showSelectionBarFromValue=null;showOuterSelectionBars=!1;hidePointerLabels=!1;hideLimitLabels=!1;autoHideLimitLabels=!0;readOnly=!1;disabled=!1;showTicks=!1;showTicksValues=!1;tickStep=null;tickValueStep=null;ticksArray=null;ticksTooltip=null;ticksValuesTooltip=null;vertical=!1;getSelectionBarColor=null;getTickColor=null;getPointerColor=null;keyboardSupport=!0;scale=1;rotate=0;enforceStep=!0;enforceRange=!0;enforceStepsArray=!0;noSwitching=!1;onlyBindHandles=!1;rightToLeft=!1;reversedControls=!1;boundPointerLabels=!0;logScale=!1;customValueToPosition=null;customPositionToValue=null;precisionLimit=12;selectionBarGradient=null;ariaLabel="ngx-slider";ariaLabelledBy=null;ariaLabelHigh="ngx-slider-max";ariaLabelledByHigh=null;handleDimension=null;barDimension=null;animate=!0;animateOnMove=!1}const nI=new R("AllowUnsafeHtmlInSlider");var L=function(e){return e[e.Min=0]="Min",e[e.Max=1]="Max",e}(L||{});class EU{value;highValue;pointerType}class M{static isNullOrUndefined(n){return null==n}static areArraysEqual(n,t){if(n.length!==t.length)return!1;for(let o=0;oMath.abs(n-r.value));let i=0;for(let r=0;r{r.events.next(a)};return n.addEventListener(t,s,{passive:!0,capture:!1}),r.teardownCallback=()=>{n.removeEventListener(t,s,{passive:!0,capture:!1})},r.eventsSubscription=r.events.pipe(M.isNullOrUndefined(i)?qM(()=>{}):WM(i,void 0,{leading:!0,trailing:!0})).subscribe(a=>{o(a)}),r}detachEventListener(n){M.isNullOrUndefined(n.eventsSubscription)||(n.eventsSubscription.unsubscribe(),n.eventsSubscription=null),M.isNullOrUndefined(n.events)||(n.events.complete(),n.events=null),M.isNullOrUndefined(n.teardownCallback)||(n.teardownCallback(),n.teardownCallback=null)}attachEventListener(n,t,o,i){const r=new oI;return r.eventName=t,r.events=new Xt,r.teardownCallback=this.renderer.listen(n,t,a=>{r.events.next(a)}),r.eventsSubscription=r.events.pipe(M.isNullOrUndefined(i)?qM(()=>{}):WM(i,void 0,{leading:!0,trailing:!0})).subscribe(a=>{o(a)}),r}}let so=(()=>{class e{elemRef=F(Nt);renderer=F(Sn);changeDetectionRef=F(Es);_position=0;get position(){return this._position}_dimension=0;get dimension(){return this._dimension}_alwaysHide=!1;get alwaysHide(){return this._alwaysHide}_vertical=!1;get vertical(){return this._vertical}_scale=1;get scale(){return this._scale}_rotate=0;get rotate(){return this._rotate}opacity=1;visibility="visible";left="";bottom="";height="";width="";transform="";eventListenerHelper;eventListeners=[];constructor(){this.eventListenerHelper=new iI(this.renderer)}setAlwaysHide(t){this._alwaysHide=t,this.visibility=t?"hidden":"visible"}hide(){this.opacity=0}show(){this.alwaysHide||(this.opacity=1)}isVisible(){return!this.alwaysHide&&0!==this.opacity}setVertical(t){this._vertical=t,this._vertical?(this.left="",this.width=""):(this.bottom="",this.height="")}setScale(t){this._scale=t}setRotate(t){this._rotate=t,this.transform="rotate("+t+"deg)"}getRotate(){return this._rotate}setPosition(t){this._position!==t&&!this.isRefDestroyed()&&this.changeDetectionRef.markForCheck(),this._position=t,this._vertical?this.bottom=Math.round(t)+"px":this.left=Math.round(t)+"px"}calculateDimension(){const t=this.getBoundingClientRect();this._dimension=this.vertical?(t.bottom-t.top)*this.scale:(t.right-t.left)*this.scale}setDimension(t){this._dimension!==t&&!this.isRefDestroyed()&&this.changeDetectionRef.markForCheck(),this._dimension=t,this._vertical?this.height=Math.round(t)+"px":this.width=Math.round(t)+"px"}getBoundingClientRect(){return this.elemRef.nativeElement.getBoundingClientRect()}on(t,o,i){const r=this.eventListenerHelper.attachEventListener(this.elemRef.nativeElement,t,o,i);this.eventListeners.push(r)}onPassive(t,o,i){const r=this.eventListenerHelper.attachPassiveEventListener(this.elemRef.nativeElement,t,o,i);this.eventListeners.push(r)}off(t){let o,i;M.isNullOrUndefined(t)?(o=[],i=this.eventListeners):(o=this.eventListeners.filter(r=>r.eventName!==t),i=this.eventListeners.filter(r=>r.eventName===t));for(const r of i)this.eventListenerHelper.detachEventListener(r);this.eventListeners=o}isRefDestroyed(){return M.isNullOrUndefined(this.changeDetectionRef)||this.changeDetectionRef.destroyed}static \u0275fac=function(o){return new(o||e)};static \u0275dir=W({type:e,selectors:[["","ngxSliderElement",""]],hostVars:14,hostBindings:function(o,i){2&o&&zl("opacity",i.opacity)("visibility",i.visibility)("left",i.left)("bottom",i.bottom)("height",i.height)("width",i.width)("transform",i.transform)},standalone:!1})}return e})(),Hg=(()=>{class e extends so{active=!1;role="";tabindex="";ariaOrientation="";ariaLabel="";ariaLabelledBy="";ariaValueNow="";ariaValueText="";ariaValueMin="";ariaValueMax="";focus(){this.elemRef.nativeElement.focus()}focusIfNeeded(){document.activeElement!==this.elemRef.nativeElement&&this.elemRef.nativeElement.focus()}static \u0275fac=(()=>{let t;return function(i){return(t||(t=ze(e)))(i||e)}})();static \u0275dir=W({type:e,selectors:[["","ngxSliderHandle",""]],hostVars:11,hostBindings:function(o,i){2&o&&(ct("role",i.role)("tabindex",i.tabindex)("aria-orientation",i.ariaOrientation)("aria-label",i.ariaLabel)("aria-labelledby",i.ariaLabelledBy)("aria-valuenow",i.ariaValueNow)("aria-valuetext",i.ariaValueText)("aria-valuemin",i.ariaValueMin)("aria-valuemax",i.ariaValueMax),An("ngx-slider-active",i.active))},standalone:!1,features:[ae]})}return e})(),ir=(()=>{class e extends so{allowUnsafeHtmlInSlider=F(nI,{optional:!0});_value=null;get value(){return this._value}setValue(t){let o=!1;!this.alwaysHide&&(M.isNullOrUndefined(this.value)||this.value.length!==t.length||this.value.length>0&&0===this.dimension)&&(o=!0),this._value=t,!1===this.allowUnsafeHtmlInSlider?this.elemRef.nativeElement.innerText=t:this.elemRef.nativeElement.innerHTML=t,o&&this.calculateDimension()}static \u0275fac=(()=>{let t;return function(i){return(t||(t=ze(e)))(i||e)}})();static \u0275dir=W({type:e,selectors:[["","ngxSliderLabel",""]],standalone:!1,features:[ae]})}return e})(),MU=(()=>{class e{template;tooltip;placement;content;static \u0275fac=function(o){return new(o||e)};static \u0275cmp=qt({type:e,selectors:[["ngx-slider-tooltip-wrapper"]],inputs:{template:"template",tooltip:"tooltip",placement:"placement",content:"content"},standalone:!1,decls:2,vars:2,consts:[[1,"ngx-slider-inner-tooltip"],[4,"ngTemplateOutlet","ngTemplateOutletContext"]],template:function(o,i){1&o&&(y(0,iU,1,6),y(1,rU,2,3,"div",0)),2&o&&(C(i.template?0:-1),f(),C(i.template?-1:1))},dependencies:[uE],styles:[".ngx-slider-inner-tooltip[_ngcontent-%COMP%]{height:100%}"]})}return e})();class IU{selected=!1;style={};tooltip=null;tooltipPlacement=null;value=null;valueTooltip=null;valueTooltipPlacement=null;legend=null}class rI{active=!1;value=0;difference=0;position=0;lowLimit=0;highLimit=0}class Fc{value;highValue;static compare(n,t){return!(M.isNullOrUndefined(n)&&M.isNullOrUndefined(t)||M.isNullOrUndefined(n)!==M.isNullOrUndefined(t))&&n.value===t.value&&n.highValue===t.highValue}}class sI extends Fc{forceChange;static compare(n,t){return!(M.isNullOrUndefined(n)&&M.isNullOrUndefined(t)||M.isNullOrUndefined(n)!==M.isNullOrUndefined(t))&&n.value===t.value&&n.highValue===t.highValue&&n.forceChange===t.forceChange}}const TU={provide:Kt,useExisting:ge(()=>aI),multi:!0};let aI=(()=>{class e{renderer=F(Sn);elementRef=F(Nt);changeDetectionRef=F(Es);zone=F(re);allowUnsafeHtmlInSlider=F(nI,{optional:!0});sliderElementNgxSliderClass=!0;value=null;valueChange=new ve;highValue=null;highValueChange=new ve;options=new kc;userChangeStart=new ve;userChange=new ve;userChangeEnd=new ve;manualRefreshSubscription;set manualRefresh(t){this.unsubscribeManualRefresh(),this.manualRefreshSubscription=t.subscribe(()=>{setTimeout(()=>this.calculateViewDimensionsAndDetectChanges())})}triggerFocusSubscription;set triggerFocus(t){this.unsubscribeTriggerFocus(),this.triggerFocusSubscription=t.subscribe(o=>{this.focusPointer(o)})}cancelUserChangeSubscription;set cancelUserChange(t){this.unsubscribeCancelUserChange(),this.cancelUserChangeSubscription=t.subscribe(()=>{this.moving&&(this.positionTrackingHandle(this.preStartHandleValue),this.forceEnd(!0))})}get range(){return!M.isNullOrUndefined(this.value)&&!M.isNullOrUndefined(this.highValue)}initHasRun=!1;inputModelChangeSubject=new Xt;inputModelChangeSubscription=null;outputModelChangeSubject=new Xt;outputModelChangeSubscription=null;viewLowValue=null;viewHighValue=null;viewOptions=new kc;handleHalfDimension=0;maxHandlePosition=0;currentTrackingPointer=null;currentFocusPointer=null;firstKeyDown=!1;touchId=null;dragging=new rI;preStartHandleValue=null;leftOuterSelectionBarElement;rightOuterSelectionBarElement;fullBarElement;selectionBarElement;minHandleElement;maxHandleElement;floorLabelElement;ceilLabelElement;minHandleLabelElement;maxHandleLabelElement;combinedLabelElement;ticksElement;tooltipTemplate;sliderElementVerticalClass=!1;sliderElementAnimateClass=!1;sliderElementWithLegendClass=!1;sliderElementDisabledAttr=null;sliderElementAriaLabel="ngx-slider";barStyle={};minPointerStyle={};maxPointerStyle={};fullBarTransparentClass=!1;selectionBarDraggableClass=!1;ticksUnderValuesClass=!1;get showTicks(){return this.viewOptions.showTicks}intermediateTicks=!1;ticks=[];eventListenerHelper=null;onMoveEventListener=null;onEndEventListener=null;moving=!1;resizeObserver=null;onTouchedCallback=null;onChangeCallback=null;constructor(){this.eventListenerHelper=new iI(this.renderer)}ngOnInit(){this.viewOptions=new kc,Object.assign(this.viewOptions,this.options),this.updateDisabledState(),this.updateVerticalState(),this.updateAriaLabel()}ngAfterViewInit(){this.applyOptions(),this.subscribeInputModelChangeSubject(),this.subscribeOutputModelChangeSubject(),this.renormaliseModelValues(),this.viewLowValue=this.modelValueToViewValue(this.value),this.viewHighValue=this.range?this.modelValueToViewValue(this.highValue):null,this.updateVerticalState(),this.manageElementsStyle(),this.updateDisabledState(),this.calculateViewDimensions(),this.addAccessibility(),this.updateCeilLabel(),this.updateFloorLabel(),this.initHandles(),this.manageEventsBindings(),this.updateAriaLabel(),this.subscribeResizeObserver(),this.initHasRun=!0,this.isRefDestroyed()||this.changeDetectionRef.detectChanges()}ngOnChanges(t){!M.isNullOrUndefined(t.options)&&JSON.stringify(t.options.previousValue)!==JSON.stringify(t.options.currentValue)&&this.onChangeOptions(),(!M.isNullOrUndefined(t.value)||!M.isNullOrUndefined(t.highValue))&&this.inputModelChangeSubject.next({value:this.value,highValue:this.highValue,controlAccessorChange:!1,forceChange:!1,internalChange:!1})}ngOnDestroy(){this.unbindEvents(),this.unsubscribeResizeObserver(),this.unsubscribeInputModelChangeSubject(),this.unsubscribeOutputModelChangeSubject(),this.unsubscribeManualRefresh(),this.unsubscribeTriggerFocus()}writeValue(t){t instanceof Array?(this.value=t[0],this.highValue=t[1]):this.value=t,this.inputModelChangeSubject.next({value:this.value,highValue:this.highValue,forceChange:!1,internalChange:!1,controlAccessorChange:!0})}registerOnChange(t){this.onChangeCallback=t}registerOnTouched(t){this.onTouchedCallback=t}setDisabledState(t){this.viewOptions.disabled=t,this.updateDisabledState(),this.initHasRun&&this.manageEventsBindings()}setAriaLabel(t){this.viewOptions.ariaLabel=t,this.updateAriaLabel()}onResize(t){this.calculateViewDimensionsAndDetectChanges()}subscribeInputModelChangeSubject(){this.inputModelChangeSubscription=this.inputModelChangeSubject.pipe(ZM(sI.compare),function Yj(e,n){return Mo((t,o)=>{let i=0;t.subscribe(jn(o,r=>e.call(n,r,i++)&&o.next(r)))})}(t=>!t.forceChange&&!t.internalChange)).subscribe(t=>this.applyInputModelChange(t))}subscribeOutputModelChangeSubject(){this.outputModelChangeSubscription=this.outputModelChangeSubject.pipe(ZM(sI.compare)).subscribe(t=>this.publishOutputModelChange(t))}subscribeResizeObserver(){ro.isResizeObserverAvailable()&&(this.resizeObserver=new ResizeObserver(()=>this.calculateViewDimensionsAndDetectChanges()),this.resizeObserver.observe(this.elementRef.nativeElement))}unsubscribeResizeObserver(){ro.isResizeObserverAvailable()&&null!==this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null)}unsubscribeOnMove(){M.isNullOrUndefined(this.onMoveEventListener)||(this.eventListenerHelper.detachEventListener(this.onMoveEventListener),this.onMoveEventListener=null)}unsubscribeOnEnd(){M.isNullOrUndefined(this.onEndEventListener)||(this.eventListenerHelper.detachEventListener(this.onEndEventListener),this.onEndEventListener=null)}unsubscribeInputModelChangeSubject(){M.isNullOrUndefined(this.inputModelChangeSubscription)||(this.inputModelChangeSubscription.unsubscribe(),this.inputModelChangeSubscription=null)}unsubscribeOutputModelChangeSubject(){M.isNullOrUndefined(this.outputModelChangeSubscription)||(this.outputModelChangeSubscription.unsubscribe(),this.outputModelChangeSubscription=null)}unsubscribeManualRefresh(){M.isNullOrUndefined(this.manualRefreshSubscription)||(this.manualRefreshSubscription.unsubscribe(),this.manualRefreshSubscription=null)}unsubscribeTriggerFocus(){M.isNullOrUndefined(this.triggerFocusSubscription)||(this.triggerFocusSubscription.unsubscribe(),this.triggerFocusSubscription=null)}unsubscribeCancelUserChange(){M.isNullOrUndefined(this.cancelUserChangeSubscription)||(this.cancelUserChangeSubscription.unsubscribe(),this.cancelUserChangeSubscription=null)}getPointerElement(t){return t===L.Min?this.minHandleElement:t===L.Max?this.maxHandleElement:null}getCurrentTrackingValue(){return this.currentTrackingPointer===L.Min?this.viewLowValue:this.currentTrackingPointer===L.Max?this.viewHighValue:null}modelValueToViewValue(t){return M.isNullOrUndefined(t)?NaN:M.isNullOrUndefined(this.viewOptions.stepsArray)||this.viewOptions.bindIndexForStepsArray?+t:M.findStepIndex(+t,this.viewOptions.stepsArray)}viewValueToModelValue(t){return M.isNullOrUndefined(this.viewOptions.stepsArray)||this.viewOptions.bindIndexForStepsArray?t:this.getStepValue(t)}getStepValue(t){const o=this.viewOptions.stepsArray[t];return M.isNullOrUndefined(o)?NaN:o.value}applyViewChange(){this.value=this.viewValueToModelValue(this.viewLowValue),this.range&&(this.highValue=this.viewValueToModelValue(this.viewHighValue)),this.outputModelChangeSubject.next({value:this.value,highValue:this.highValue,controlAccessorChange:!1,userEventInitiated:!0,forceChange:!1}),this.inputModelChangeSubject.next({value:this.value,highValue:this.highValue,controlAccessorChange:!1,forceChange:!1,internalChange:!0})}applyInputModelChange(t){const o=this.normaliseModelValues(t),i=!Fc.compare(t,o);i&&(this.value=o.value,this.highValue=o.highValue),this.viewLowValue=this.modelValueToViewValue(o.value),this.viewHighValue=this.range?this.modelValueToViewValue(o.highValue):null,this.updateLowHandle(this.valueToPosition(this.viewLowValue)),this.range&&this.updateHighHandle(this.valueToPosition(this.viewHighValue)),this.updateSelectionBar(),this.updateTicksScale(),this.updateAriaAttributes(),this.range&&this.updateCombinedLabel(),this.outputModelChangeSubject.next({value:o.value,highValue:o.highValue,controlAccessorChange:t.controlAccessorChange,forceChange:i,userEventInitiated:!1})}publishOutputModelChange(t){const o=()=>{this.valueChange.emit(t.value),this.range&&this.highValueChange.emit(t.highValue),!t.controlAccessorChange&&(M.isNullOrUndefined(this.onChangeCallback)||this.onChangeCallback(this.range?[t.value,t.highValue]:t.value),M.isNullOrUndefined(this.onTouchedCallback)||this.onTouchedCallback(this.range?[t.value,t.highValue]:t.value))};t.userEventInitiated?(o(),this.userChange.emit(this.getChangeContext())):setTimeout(()=>{o()})}normaliseModelValues(t){const o=new Fc;if(o.value=t.value,o.highValue=t.highValue,!M.isNullOrUndefined(this.viewOptions.stepsArray)){if(this.viewOptions.enforceStepsArray){const i=M.findStepIndex(o.value,this.viewOptions.stepsArray);if(o.value=this.viewOptions.stepsArray[i].value,this.range){const r=M.findStepIndex(o.highValue,this.viewOptions.stepsArray);o.highValue=this.viewOptions.stepsArray[r].value}}return o}if(this.viewOptions.enforceStep&&(o.value=this.roundStep(o.value),this.range&&(o.highValue=this.roundStep(o.highValue))),this.viewOptions.enforceRange&&(o.value=Re.clampToRange(o.value,this.viewOptions.floor,this.viewOptions.ceil),this.range&&(o.highValue=Re.clampToRange(o.highValue,this.viewOptions.floor,this.viewOptions.ceil)),this.range&&t.value>t.highValue))if(this.viewOptions.noSwitching)o.value=o.highValue;else{const i=t.value;o.value=t.highValue,o.highValue=i}return o}renormaliseModelValues(){const t={value:this.value,highValue:this.highValue},o=this.normaliseModelValues(t);Fc.compare(o,t)||(this.value=o.value,this.highValue=o.highValue,this.outputModelChangeSubject.next({value:this.value,highValue:this.highValue,controlAccessorChange:!1,forceChange:!0,userEventInitiated:!1}))}onChangeOptions(){if(!this.initHasRun)return;const t=this.getOptionsInfluencingEventBindings(this.viewOptions);this.applyOptions();const o=this.getOptionsInfluencingEventBindings(this.viewOptions),i=!M.areArraysEqual(t,o);this.renormaliseModelValues(),this.viewLowValue=this.modelValueToViewValue(this.value),this.viewHighValue=this.range?this.modelValueToViewValue(this.highValue):null,this.resetSlider(i)}applyOptions(){if(this.viewOptions=new kc,Object.assign(this.viewOptions,this.options),this.viewOptions.draggableRange=this.range&&this.viewOptions.draggableRange,this.viewOptions.draggableRangeOnly=this.range&&this.viewOptions.draggableRangeOnly,this.viewOptions.draggableRangeOnly&&(this.viewOptions.draggableRange=!0),this.viewOptions.showTicks=this.viewOptions.showTicks||this.viewOptions.showTicksValues||!M.isNullOrUndefined(this.viewOptions.ticksArray),this.viewOptions.showTicks&&(!M.isNullOrUndefined(this.viewOptions.tickStep)||!M.isNullOrUndefined(this.viewOptions.ticksArray))&&(this.intermediateTicks=!0),this.viewOptions.showSelectionBar=this.viewOptions.showSelectionBar||this.viewOptions.showSelectionBarEnd||!M.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue),M.isNullOrUndefined(this.viewOptions.stepsArray)?this.applyFloorCeilOptions():this.applyStepsArrayOptions(),M.isNullOrUndefined(this.viewOptions.combineLabels)&&(this.viewOptions.combineLabels=(t,o)=>t+" - "+o),this.viewOptions.logScale&&0===this.viewOptions.floor)throw Error("Can't use floor=0 with logarithmic scale")}applyStepsArrayOptions(){this.viewOptions.floor=0,this.viewOptions.ceil=this.viewOptions.stepsArray.length-1,this.viewOptions.step=1,M.isNullOrUndefined(this.viewOptions.translate)&&(this.viewOptions.translate=t=>String(this.viewOptions.bindIndexForStepsArray?this.getStepValue(t):t))}applyFloorCeilOptions(){if(M.isNullOrUndefined(this.viewOptions.step)?this.viewOptions.step=1:(this.viewOptions.step=+this.viewOptions.step,this.viewOptions.step<=0&&(this.viewOptions.step=1)),M.isNullOrUndefined(this.viewOptions.ceil)||M.isNullOrUndefined(this.viewOptions.floor))throw Error("floor and ceil options must be supplied");this.viewOptions.ceil=+this.viewOptions.ceil,this.viewOptions.floor=+this.viewOptions.floor,M.isNullOrUndefined(this.viewOptions.translate)&&(this.viewOptions.translate=t=>String(t))}resetSlider(t=!0){this.manageElementsStyle(),this.addAccessibility(),this.updateCeilLabel(),this.updateFloorLabel(),t&&(this.unbindEvents(),this.manageEventsBindings()),this.updateDisabledState(),this.updateAriaLabel(),this.calculateViewDimensions(),this.refocusPointerIfNeeded()}focusPointer(t){t!==L.Min&&t!==L.Max&&(t=L.Min),t===L.Min?this.minHandleElement.focus():this.range&&t===L.Max&&this.maxHandleElement.focus()}refocusPointerIfNeeded(){M.isNullOrUndefined(this.currentFocusPointer)||this.getPointerElement(this.currentFocusPointer).focusIfNeeded()}manageElementsStyle(){this.updateScale(),this.floorLabelElement.setAlwaysHide(this.viewOptions.showTicksValues||this.viewOptions.hideLimitLabels),this.ceilLabelElement.setAlwaysHide(this.viewOptions.showTicksValues||this.viewOptions.hideLimitLabels);const t=this.viewOptions.showTicksValues&&!this.intermediateTicks;this.minHandleLabelElement.setAlwaysHide(t||this.viewOptions.hidePointerLabels),this.maxHandleLabelElement.setAlwaysHide(t||!this.range||this.viewOptions.hidePointerLabels),this.combinedLabelElement.setAlwaysHide(t||!this.range||this.viewOptions.hidePointerLabels),this.selectionBarElement.setAlwaysHide(!this.range&&!this.viewOptions.showSelectionBar),this.leftOuterSelectionBarElement.setAlwaysHide(!this.range||!this.viewOptions.showOuterSelectionBars),this.rightOuterSelectionBarElement.setAlwaysHide(!this.range||!this.viewOptions.showOuterSelectionBars),this.fullBarTransparentClass=this.range&&this.viewOptions.showOuterSelectionBars,this.selectionBarDraggableClass=this.viewOptions.draggableRange&&!this.viewOptions.onlyBindHandles,this.ticksUnderValuesClass=this.intermediateTicks&&this.options.showTicksValues,this.sliderElementVerticalClass!==this.viewOptions.vertical&&(this.updateVerticalState(),setTimeout(()=>{this.resetSlider()})),this.sliderElementAnimateClass!==this.viewOptions.animate&&setTimeout(()=>{this.sliderElementAnimateClass=this.viewOptions.animate}),this.updateRotate()}manageEventsBindings(){this.viewOptions.disabled||this.viewOptions.readOnly?this.unbindEvents():this.bindEvents()}updateDisabledState(){this.sliderElementDisabledAttr=this.viewOptions.disabled?"disabled":null}updateAriaLabel(){this.sliderElementAriaLabel=this.viewOptions.ariaLabel||"nxg-slider"}updateVerticalState(){this.sliderElementVerticalClass=this.viewOptions.vertical;for(const t of this.getAllSliderElements())M.isNullOrUndefined(t)||t.setVertical(this.viewOptions.vertical)}updateScale(){for(const t of this.getAllSliderElements())t.setScale(this.viewOptions.scale)}updateRotate(){for(const t of this.getAllSliderElements())t.setRotate(this.viewOptions.rotate)}getAllSliderElements(){return[this.leftOuterSelectionBarElement,this.rightOuterSelectionBarElement,this.fullBarElement,this.selectionBarElement,this.minHandleElement,this.maxHandleElement,this.floorLabelElement,this.ceilLabelElement,this.minHandleLabelElement,this.maxHandleLabelElement,this.combinedLabelElement,this.ticksElement]}initHandles(){this.updateLowHandle(this.valueToPosition(this.viewLowValue)),this.range&&this.updateHighHandle(this.valueToPosition(this.viewHighValue)),this.updateSelectionBar(),this.range&&this.updateCombinedLabel(),this.updateTicksScale()}addAccessibility(){this.updateAriaAttributes(),this.minHandleElement.role="slider",this.minHandleElement.tabindex=!this.viewOptions.keyboardSupport||this.viewOptions.readOnly||this.viewOptions.disabled?"":"0",this.minHandleElement.ariaOrientation=this.viewOptions.vertical||0!==this.viewOptions.rotate?"vertical":"horizontal",M.isNullOrUndefined(this.viewOptions.ariaLabel)?M.isNullOrUndefined(this.viewOptions.ariaLabelledBy)||(this.minHandleElement.ariaLabelledBy=this.viewOptions.ariaLabelledBy):this.minHandleElement.ariaLabel=this.viewOptions.ariaLabel,this.range&&(this.maxHandleElement.role="slider",this.maxHandleElement.tabindex=!this.viewOptions.keyboardSupport||this.viewOptions.readOnly||this.viewOptions.disabled?"":"0",this.maxHandleElement.ariaOrientation=this.viewOptions.vertical||0!==this.viewOptions.rotate?"vertical":"horizontal",M.isNullOrUndefined(this.viewOptions.ariaLabelHigh)?M.isNullOrUndefined(this.viewOptions.ariaLabelledByHigh)||(this.maxHandleElement.ariaLabelledBy=this.viewOptions.ariaLabelledByHigh):this.maxHandleElement.ariaLabel=this.viewOptions.ariaLabelHigh)}updateAriaAttributes(){this.minHandleElement.ariaValueNow=(+this.value).toString(),this.minHandleElement.ariaValueText=this.viewOptions.translate(+this.value,cn.Low),this.minHandleElement.ariaValueMin=this.viewOptions.floor.toString(),this.minHandleElement.ariaValueMax=this.viewOptions.ceil.toString(),this.range&&(this.maxHandleElement.ariaValueNow=(+this.highValue).toString(),this.maxHandleElement.ariaValueText=this.viewOptions.translate(+this.highValue,cn.High),this.maxHandleElement.ariaValueMin=this.viewOptions.floor.toString(),this.maxHandleElement.ariaValueMax=this.viewOptions.ceil.toString())}calculateViewDimensions(){M.isNullOrUndefined(this.viewOptions.handleDimension)?this.minHandleElement.calculateDimension():this.minHandleElement.setDimension(this.viewOptions.handleDimension);const t=this.minHandleElement.dimension;this.handleHalfDimension=t/2,M.isNullOrUndefined(this.viewOptions.barDimension)?this.fullBarElement.calculateDimension():this.fullBarElement.setDimension(this.viewOptions.barDimension),this.maxHandlePosition=this.fullBarElement.dimension-t,this.initHasRun&&(this.updateFloorLabel(),this.updateCeilLabel(),this.initHandles())}calculateViewDimensionsAndDetectChanges(){this.calculateViewDimensions(),this.isRefDestroyed()||this.changeDetectionRef.detectChanges()}isRefDestroyed(){return this.changeDetectionRef.destroyed}updateTicksScale(){if(!this.viewOptions.showTicks&&this.sliderElementWithLegendClass)return void setTimeout(()=>{this.sliderElementWithLegendClass=!1});const t=M.isNullOrUndefined(this.viewOptions.ticksArray)?this.getTicksArray():this.viewOptions.ticksArray,o=this.viewOptions.vertical?"translateY":"translateX";this.viewOptions.rightToLeft&&t.reverse();const i=M.isNullOrUndefined(this.viewOptions.tickValueStep)?M.isNullOrUndefined(this.viewOptions.tickStep)?this.viewOptions.step:this.viewOptions.tickStep:this.viewOptions.tickValueStep;let r=!1;const s=t.map(a=>{let l=this.valueToPosition(a);this.viewOptions.vertical&&(l=this.maxHandlePosition-l);const c=o+"("+Math.round(l)+"px)",u=new IU;u.selected=this.isTickSelected(a),u.style={"-webkit-transform":c,"-moz-transform":c,"-o-transform":c,"-ms-transform":c,transform:c},u.selected&&!M.isNullOrUndefined(this.viewOptions.getSelectionBarColor)&&(u.style["background-color"]=this.getSelectionBarColor()),!u.selected&&!M.isNullOrUndefined(this.viewOptions.getTickColor)&&(u.style["background-color"]=this.getTickColor(a)),M.isNullOrUndefined(this.viewOptions.ticksTooltip)||(u.tooltip=this.viewOptions.ticksTooltip(a),u.tooltipPlacement=this.viewOptions.vertical?"right":"top"),this.viewOptions.showTicksValues&&!M.isNullOrUndefined(i)&&Re.isModuloWithinPrecisionLimit(a,i,this.viewOptions.precisionLimit)&&(u.value=this.getDisplayValue(a,cn.TickValue),M.isNullOrUndefined(this.viewOptions.ticksValuesTooltip)||(u.valueTooltip=this.viewOptions.ticksValuesTooltip(a),u.valueTooltipPlacement=this.viewOptions.vertical?"right":"top"));let d=null;if(M.isNullOrUndefined(this.viewOptions.stepsArray))M.isNullOrUndefined(this.viewOptions.getLegend)||(d=this.viewOptions.getLegend(a));else{const g=this.viewOptions.stepsArray[a];M.isNullOrUndefined(this.viewOptions.getStepLegend)?M.isNullOrUndefined(g)||(d=g.legend):d=this.viewOptions.getStepLegend(g)}return M.isNullOrUndefined(d)||(u.legend=d,r=!0),u});if(this.sliderElementWithLegendClass!==r&&setTimeout(()=>{this.sliderElementWithLegendClass=r}),M.isNullOrUndefined(this.ticks)||this.ticks.length!==s.length)this.ticks=s,this.isRefDestroyed()||this.changeDetectionRef.detectChanges();else for(let a=0;a=this.viewLowValue)return!0}else if(this.viewOptions.showSelectionBar&&t<=this.viewLowValue)return!0}else{const o=this.viewOptions.showSelectionBarFromValue;if(this.viewLowValue>o&&t>=o&&t<=this.viewLowValue)return!0;if(this.viewLowValue=this.viewLowValue)return!0}return!!(this.range&&t>=this.viewLowValue&&t<=this.viewHighValue)}updateFloorLabel(){this.floorLabelElement.alwaysHide||(this.floorLabelElement.setValue(this.getDisplayValue(this.viewOptions.floor,cn.Floor)),this.floorLabelElement.calculateDimension(),this.floorLabelElement.setPosition(this.viewOptions.rightToLeft?this.fullBarElement.dimension-this.floorLabelElement.dimension:0))}updateCeilLabel(){this.ceilLabelElement.alwaysHide||(this.ceilLabelElement.setValue(this.getDisplayValue(this.viewOptions.ceil,cn.Ceil)),this.ceilLabelElement.calculateDimension(),this.ceilLabelElement.setPosition(this.viewOptions.rightToLeft?0:this.fullBarElement.dimension-this.ceilLabelElement.dimension))}updateHandles(t,o){t===L.Min?this.updateLowHandle(o):t===L.Max&&this.updateHighHandle(o),this.updateSelectionBar(),this.updateTicksScale(),this.range&&this.updateCombinedLabel()}getHandleLabelPos(t,o){const i=t===L.Min?this.minHandleLabelElement.dimension:this.maxHandleLabelElement.dimension,r=o-i/2+this.handleHalfDimension,s=this.fullBarElement.dimension-i;return this.viewOptions.boundPointerLabels?this.viewOptions.rightToLeft&&t===L.Min||!this.viewOptions.rightToLeft&&t===L.Max?Math.min(r,s):Math.min(Math.max(r,0),s):r}updateLowHandle(t){this.minHandleElement.setPosition(t),this.minHandleLabelElement.setValue(this.getDisplayValue(this.viewLowValue,cn.Low)),this.minHandleLabelElement.setPosition(this.getHandleLabelPos(L.Min,t)),M.isNullOrUndefined(this.viewOptions.getPointerColor)||(this.minPointerStyle={backgroundColor:this.getPointerColor(L.Min)}),this.viewOptions.autoHideLimitLabels&&this.updateFloorAndCeilLabelsVisibility()}updateHighHandle(t){this.maxHandleElement.setPosition(t),this.maxHandleLabelElement.setValue(this.getDisplayValue(this.viewHighValue,cn.High)),this.maxHandleLabelElement.setPosition(this.getHandleLabelPos(L.Max,t)),M.isNullOrUndefined(this.viewOptions.getPointerColor)||(this.maxPointerStyle={backgroundColor:this.getPointerColor(L.Max)}),this.viewOptions.autoHideLimitLabels&&this.updateFloorAndCeilLabelsVisibility()}updateFloorAndCeilLabelsVisibility(){if(this.viewOptions.hidePointerLabels)return;let t=!1,o=!1;const i=this.isLabelBelowFloorLabel(this.minHandleLabelElement),r=this.isLabelAboveCeilLabel(this.minHandleLabelElement),s=this.isLabelAboveCeilLabel(this.maxHandleLabelElement),a=this.isLabelBelowFloorLabel(this.combinedLabelElement),l=this.isLabelAboveCeilLabel(this.combinedLabelElement);if(i?(t=!0,this.floorLabelElement.hide()):(t=!1,this.floorLabelElement.show()),r?(o=!0,this.ceilLabelElement.hide()):(o=!1,this.ceilLabelElement.show()),this.range){const c=this.combinedLabelElement.isVisible()?l:s,u=this.combinedLabelElement.isVisible()?a:i;c?this.ceilLabelElement.hide():o||this.ceilLabelElement.show(),u?this.floorLabelElement.hide():t||this.floorLabelElement.show()}}isLabelBelowFloorLabel(t){const o=t.position,r=this.floorLabelElement.position;return this.viewOptions.rightToLeft?o+t.dimension>=r-2:o<=r+this.floorLabelElement.dimension+2}isLabelAboveCeilLabel(t){const o=t.position,r=this.ceilLabelElement.position;return this.viewOptions.rightToLeft?o<=r+this.ceilLabelElement.dimension+2:o+t.dimension>=r-2}updateSelectionBar(){let t=0,o=0;const i=this.viewOptions.rightToLeft?!this.viewOptions.showSelectionBarEnd:this.viewOptions.showSelectionBarEnd,r=this.viewOptions.rightToLeft?this.maxHandleElement.position+this.handleHalfDimension:this.minHandleElement.position+this.handleHalfDimension;if(this.range)o=Math.abs(this.maxHandleElement.position-this.minHandleElement.position),t=r;else if(M.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue))i?(o=Math.ceil(Math.abs(this.maxHandlePosition-this.minHandleElement.position)+this.handleHalfDimension),t=Math.floor(this.minHandleElement.position+this.handleHalfDimension)):(o=this.minHandleElement.position+this.handleHalfDimension,t=0);else{const s=this.viewOptions.showSelectionBarFromValue,a=this.valueToPosition(s);(this.viewOptions.rightToLeft?this.viewLowValue<=s:this.viewLowValue>s)?(o=this.minHandleElement.position-a,t=a+this.handleHalfDimension):(o=a-this.minHandleElement.position,t=this.minHandleElement.position+this.handleHalfDimension)}if(this.selectionBarElement.setDimension(o),this.selectionBarElement.setPosition(t),this.range&&this.viewOptions.showOuterSelectionBars&&(this.viewOptions.rightToLeft?(this.rightOuterSelectionBarElement.setDimension(t),this.rightOuterSelectionBarElement.setPosition(0),this.fullBarElement.calculateDimension(),this.leftOuterSelectionBarElement.setDimension(this.fullBarElement.dimension-(t+o)),this.leftOuterSelectionBarElement.setPosition(t+o)):(this.leftOuterSelectionBarElement.setDimension(t),this.leftOuterSelectionBarElement.setPosition(0),this.fullBarElement.calculateDimension(),this.rightOuterSelectionBarElement.setDimension(this.fullBarElement.dimension-(t+o)),this.rightOuterSelectionBarElement.setPosition(t+o))),M.isNullOrUndefined(this.viewOptions.getSelectionBarColor)){if(!M.isNullOrUndefined(this.viewOptions.selectionBarGradient)){const s=M.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue)?0:this.valueToPosition(this.viewOptions.showSelectionBarFromValue),a=s-t>0&&!i||s-t<=0&&i;this.barStyle={backgroundImage:"linear-gradient(to "+(this.viewOptions.vertical?a?"bottom":"top":a?"left":"right")+", "+this.viewOptions.selectionBarGradient.from+" 0%,"+this.viewOptions.selectionBarGradient.to+" 100%)"},this.viewOptions.vertical?(this.barStyle.backgroundPosition="center "+(s+o+t+(a?-this.handleHalfDimension:0))+"px",this.barStyle.backgroundSize="100% "+(this.fullBarElement.dimension-this.handleHalfDimension)+"px"):(this.barStyle.backgroundPosition=s-t+(a?this.handleHalfDimension:0)+"px center",this.barStyle.backgroundSize=this.fullBarElement.dimension-this.handleHalfDimension+"px 100%")}}else{const s=this.getSelectionBarColor();this.barStyle={backgroundColor:s}}}getSelectionBarColor(){return this.range?this.viewOptions.getSelectionBarColor(this.value,this.highValue):this.viewOptions.getSelectionBarColor(this.value)}getPointerColor(t){return this.viewOptions.getPointerColor(t===L.Max?this.highValue:this.value,t)}getTickColor(t){return this.viewOptions.getTickColor(t)}updateCombinedLabel(){let t=null;if(t=this.viewOptions.rightToLeft?this.minHandleLabelElement.position-this.minHandleLabelElement.dimension-10<=this.maxHandleLabelElement.position:this.minHandleLabelElement.position+this.minHandleLabelElement.dimension+10>=this.maxHandleLabelElement.position,t){const o=this.getDisplayValue(this.viewLowValue,cn.Low),i=this.getDisplayValue(this.viewHighValue,cn.High),r=this.viewOptions.rightToLeft?this.viewOptions.combineLabels(i,o):this.viewOptions.combineLabels(o,i);this.combinedLabelElement.setValue(r);const s=this.viewOptions.boundPointerLabels?Math.min(Math.max(this.selectionBarElement.position+this.selectionBarElement.dimension/2-this.combinedLabelElement.dimension/2,0),this.fullBarElement.dimension-this.combinedLabelElement.dimension):this.selectionBarElement.position+this.selectionBarElement.dimension/2-this.combinedLabelElement.dimension/2;this.combinedLabelElement.setPosition(s),this.minHandleLabelElement.hide(),this.maxHandleLabelElement.hide(),this.combinedLabelElement.show()}else this.updateHighHandle(this.valueToPosition(this.viewHighValue)),this.updateLowHandle(this.valueToPosition(this.viewLowValue)),this.maxHandleLabelElement.show(),this.minHandleLabelElement.show(),this.combinedLabelElement.hide();this.viewOptions.autoHideLimitLabels&&this.updateFloorAndCeilLabelsVisibility()}getDisplayValue(t,o){return!M.isNullOrUndefined(this.viewOptions.stepsArray)&&!this.viewOptions.bindIndexForStepsArray&&(t=this.getStepValue(t)),this.viewOptions.translate(t,o)}roundStep(t,o){const i=M.isNullOrUndefined(o)?this.viewOptions.step:o;let r=Re.roundToPrecisionLimit((t-this.viewOptions.floor)/i,this.viewOptions.precisionLimit);return r=Math.round(r)*i,Re.roundToPrecisionLimit(this.viewOptions.floor+r,this.viewOptions.precisionLimit)}valueToPosition(t){let o=M.linearValueToPosition;M.isNullOrUndefined(this.viewOptions.customValueToPosition)?this.viewOptions.logScale&&(o=M.logValueToPosition):o=this.viewOptions.customValueToPosition;let i=o(t=Re.clampToRange(t,this.viewOptions.floor,this.viewOptions.ceil),this.viewOptions.floor,this.viewOptions.ceil);return M.isNullOrUndefined(i)&&(i=0),this.viewOptions.rightToLeft&&(i=1-i),i*this.maxHandlePosition}positionToValue(t){let o=t/this.maxHandlePosition;this.viewOptions.rightToLeft&&(o=1-o);let i=M.linearPositionToValue;M.isNullOrUndefined(this.viewOptions.customPositionToValue)?this.viewOptions.logScale&&(i=M.logPositionToValue):i=this.viewOptions.customPositionToValue;const r=i(o,this.viewOptions.floor,this.viewOptions.ceil);return M.isNullOrUndefined(r)?0:r}getEventXY(t,o){if(t instanceof MouseEvent)return this.viewOptions.vertical||0!==this.viewOptions.rotate?t.clientY:t.clientX;let i=0;const r=t.touches;if(!M.isNullOrUndefined(o))for(let s=0;sr?L.Max:this.viewOptions.rightToLeft?o>this.minHandleElement.position?L.Min:L.Max:othis.onBarStart(null,t,o,!0,!0,!0)),this.viewOptions.draggableRangeOnly?(this.minHandleElement.on("mousedown",o=>this.onBarStart(L.Min,t,o,!0,!0)),this.maxHandleElement.on("mousedown",o=>this.onBarStart(L.Max,t,o,!0,!0))):(this.minHandleElement.on("mousedown",o=>this.onStart(L.Min,o,!0,!0)),this.range&&this.maxHandleElement.on("mousedown",o=>this.onStart(L.Max,o,!0,!0)),this.viewOptions.onlyBindHandles||(this.fullBarElement.on("mousedown",o=>this.onStart(null,o,!0,!0,!0)),this.ticksElement.on("mousedown",o=>this.onStart(null,o,!0,!0,!0,!0)))),this.viewOptions.onlyBindHandles||this.selectionBarElement.onPassive("touchstart",o=>this.onBarStart(null,t,o,!0,!0,!0)),this.viewOptions.draggableRangeOnly?(this.minHandleElement.onPassive("touchstart",o=>this.onBarStart(L.Min,t,o,!0,!0)),this.maxHandleElement.onPassive("touchstart",o=>this.onBarStart(L.Max,t,o,!0,!0))):(this.minHandleElement.onPassive("touchstart",o=>this.onStart(L.Min,o,!0,!0)),this.range&&this.maxHandleElement.onPassive("touchstart",o=>this.onStart(L.Max,o,!0,!0)),this.viewOptions.onlyBindHandles||(this.fullBarElement.onPassive("touchstart",o=>this.onStart(null,o,!0,!0,!0)),this.ticksElement.onPassive("touchstart",o=>this.onStart(null,o,!1,!1,!0,!0)))),this.viewOptions.keyboardSupport&&(this.minHandleElement.on("focus",()=>this.onPointerFocus(L.Min)),this.range&&this.maxHandleElement.on("focus",()=>this.onPointerFocus(L.Max)))}getOptionsInfluencingEventBindings(t){return[t.disabled,t.readOnly,t.draggableRange,t.draggableRangeOnly,t.onlyBindHandles,t.keyboardSupport]}unbindEvents(){this.unsubscribeOnMove(),this.unsubscribeOnEnd();for(const t of this.getAllSliderElements())M.isNullOrUndefined(t)||t.off()}onBarStart(t,o,i,r,s,a,l){o?this.onDragStart(t,i,r,s):this.onStart(t,i,r,s,a,l)}onStart(t,o,i,r,s,a){o.stopPropagation(),!ro.isTouchEvent(o)&&!KM&&o.preventDefault(),this.moving=!1,this.calculateViewDimensions(),M.isNullOrUndefined(t)&&(t=this.getNearestHandle(o)),this.currentTrackingPointer=t;const l=this.getPointerElement(t);if(l.active=!0,this.preStartHandleValue=this.getCurrentTrackingValue(),this.viewOptions.keyboardSupport&&l.focus(),i){this.unsubscribeOnMove();const c=u=>this.dragging.active?this.onDragMove(u):this.onMove(u);this.onMoveEventListener=ro.isTouchEvent(o)?this.eventListenerHelper.attachPassiveEventListener(document,"touchmove",c):this.eventListenerHelper.attachEventListener(document,"mousemove",c)}if(r){this.unsubscribeOnEnd();const c=u=>this.onEnd(u);this.onEndEventListener=ro.isTouchEvent(o)?this.eventListenerHelper.attachPassiveEventListener(document,"touchend",c):this.eventListenerHelper.attachEventListener(document,"mouseup",c)}this.userChangeStart.emit(this.getChangeContext()),ro.isTouchEvent(o)&&!M.isNullOrUndefined(o.changedTouches)&&M.isNullOrUndefined(this.touchId)&&(this.touchId=o.changedTouches[0].identifier),s&&this.onMove(o,!0),a&&this.onEnd(o)}onMove(t,o){let i=null;if(ro.isTouchEvent(t)){const c=t.changedTouches;for(let u=0;u=this.maxHandlePosition?s=this.viewOptions.rightToLeft?this.viewOptions.floor:this.viewOptions.ceil:(s=this.positionToValue(r),s=o&&!M.isNullOrUndefined(this.viewOptions.tickStep)?this.roundStep(s,this.viewOptions.tickStep):this.roundStep(s)),this.positionTrackingHandle(s)}forceEnd(t=!1){this.moving=!1,this.viewOptions.animate&&(this.sliderElementAnimateClass=!0),t&&(this.sliderElementAnimateClass=!1,setTimeout(()=>{this.sliderElementAnimateClass=this.viewOptions.animate})),this.touchId=null,this.viewOptions.keyboardSupport||(this.minHandleElement.active=!1,this.maxHandleElement.active=!1,this.currentTrackingPointer=null),this.dragging.active=!1,this.unsubscribeOnMove(),this.unsubscribeOnEnd(),this.userChangeEnd.emit(this.getChangeContext())}onEnd(t){ro.isTouchEvent(t)&&t.changedTouches[0].identifier!==this.touchId||this.forceEnd()}onPointerFocus(t){const o=this.getPointerElement(t);o.on("blur",()=>this.onPointerBlur(o)),o.on("keydown",i=>this.onKeyboardEvent(i)),o.on("keyup",()=>this.onKeyUp()),o.active=!0,this.currentTrackingPointer=t,this.currentFocusPointer=t,this.firstKeyDown=!0}onKeyUp(){this.firstKeyDown=!0,this.userChangeEnd.emit(this.getChangeContext())}onPointerBlur(t){t.off("blur"),t.off("keydown"),t.off("keyup"),t.active=!1,M.isNullOrUndefined(this.touchId)&&(this.currentTrackingPointer=null,this.currentFocusPointer=null)}getKeyActions(t){const o=this.viewOptions.ceil-this.viewOptions.floor;let i=t+this.viewOptions.step,r=t-this.viewOptions.step,s=t+o/10,a=t-o/10;this.viewOptions.reversedControls&&(i=t-this.viewOptions.step,r=t+this.viewOptions.step,s=t-o/10,a=t+o/10);const l={UP:i,DOWN:r,LEFT:r,RIGHT:i,PAGEUP:s,PAGEDOWN:a,HOME:this.viewOptions.reversedControls?this.viewOptions.ceil:this.viewOptions.floor,END:this.viewOptions.reversedControls?this.viewOptions.floor:this.viewOptions.ceil};return this.viewOptions.rightToLeft&&(l.LEFT=i,l.RIGHT=r,(this.viewOptions.vertical||0!==this.viewOptions.rotate)&&(l.UP=r,l.DOWN=i)),l}onKeyboardEvent(t){const o=this.getCurrentTrackingValue(),i=M.isNullOrUndefined(t.keyCode)?t.which:t.keyCode,l=this.getKeyActions(o)[{38:"UP",40:"DOWN",37:"LEFT",39:"RIGHT",33:"PAGEUP",34:"PAGEDOWN",36:"HOME",35:"END"}[i]];if(M.isNullOrUndefined(l)||M.isNullOrUndefined(this.currentTrackingPointer))return;t.preventDefault(),this.firstKeyDown&&(this.firstKeyDown=!1,this.userChangeStart.emit(this.getChangeContext()));const c=Re.clampToRange(l,this.viewOptions.floor,this.viewOptions.ceil),u=this.roundStep(c);if(this.viewOptions.draggableRangeOnly){const d=this.viewHighValue-this.viewLowValue;let g,h;this.currentTrackingPointer===L.Min?(g=u,h=u+d,h>this.viewOptions.ceil&&(h=this.viewOptions.ceil,g=h-d)):this.currentTrackingPointer===L.Max&&(h=u,g=u-d,g=this.maxHandlePosition-i;let u,d;if(o<=r){if(0===s.position)return;u=this.getMinValue(o,!0,!1),d=this.getMaxValue(o,!0,!1)}else if(c){if(a.position===this.maxHandlePosition)return;d=this.getMaxValue(o,!0,!0),u=this.getMinValue(o,!0,!0)}else u=this.getMinValue(o,!1,!1),d=this.getMaxValue(o,!1,!1);this.positionTrackingBar(u,d)}positionTrackingBar(t,o){!M.isNullOrUndefined(this.viewOptions.minLimit)&&tthis.viewOptions.maxLimit&&(t=Re.roundToPrecisionLimit((o=this.viewOptions.maxLimit)-this.dragging.difference,this.viewOptions.precisionLimit)),this.viewLowValue=t,this.viewHighValue=o,this.applyViewChange(),this.updateHandles(L.Min,this.valueToPosition(t)),this.updateHandles(L.Max,this.valueToPosition(o))}positionTrackingHandle(t){t=this.applyMinMaxLimit(t),this.range&&(this.viewOptions.pushRange?t=this.applyPushRange(t):(this.viewOptions.noSwitching&&(this.currentTrackingPointer===L.Min&&t>this.viewHighValue?t=this.applyMinMaxRange(this.viewHighValue):this.currentTrackingPointer===L.Max&&tthis.viewHighValue?(this.viewLowValue=this.viewHighValue,this.applyViewChange(),this.updateHandles(L.Min,this.maxHandleElement.position),this.updateAriaAttributes(),this.currentTrackingPointer=L.Max,this.minHandleElement.active=!1,this.maxHandleElement.active=!0,this.viewOptions.keyboardSupport&&this.maxHandleElement.focus()):this.currentTrackingPointer===L.Max&&tthis.viewOptions.maxLimit?this.viewOptions.maxLimit:t}applyMinMaxRange(t){const i=Math.abs(t-(this.currentTrackingPointer===L.Min?this.viewHighValue:this.viewLowValue));if(!M.isNullOrUndefined(this.viewOptions.minRange)&&ithis.viewOptions.maxRange){if(this.currentTrackingPointer===L.Min)return Re.roundToPrecisionLimit(this.viewHighValue-this.viewOptions.maxRange,this.viewOptions.precisionLimit);if(this.currentTrackingPointer===L.Max)return Re.roundToPrecisionLimit(this.viewLowValue+this.viewOptions.maxRange,this.viewOptions.precisionLimit)}return t}applyPushRange(t){const o=this.currentTrackingPointer===L.Min?this.viewHighValue-t:t-this.viewLowValue,i=M.isNullOrUndefined(this.viewOptions.minRange)?this.viewOptions.step:this.viewOptions.minRange,r=this.viewOptions.maxRange;return or&&(this.currentTrackingPointer===L.Min?(this.viewHighValue=Re.roundToPrecisionLimit(t+r,this.viewOptions.precisionLimit),this.applyViewChange(),this.updateHandles(L.Max,this.valueToPosition(this.viewHighValue))):this.currentTrackingPointer===L.Max&&(this.viewLowValue=Re.roundToPrecisionLimit(t-r,this.viewOptions.precisionLimit),this.applyViewChange(),this.updateHandles(L.Min,this.valueToPosition(this.viewLowValue))),this.updateAriaAttributes()),t}getChangeContext(){const t=new EU;return t.pointerType=this.currentTrackingPointer,t.value=+this.value,this.range&&(t.highValue=+this.highValue),t}static \u0275fac=function(o){return new(o||e)};static \u0275cmp=qt({type:e,selectors:[["ngx-slider"]],contentQueries:function(o,i,r){if(1&o&&Zb(r,sU,5),2&o){let s;wt(s=Et())&&(i.tooltipTemplate=s.first)}},viewQuery:function(o,i){if(1&o&&(Ot(aU,5,so),Ot(lU,5,so),Ot(cU,5,so),Ot(uU,5,so),Ot(dU,5,Hg),Ot(fU,5,Hg),Ot(hU,5,ir),Ot(gU,5,ir),Ot(pU,5,ir),Ot(mU,5,ir),Ot(_U,5,ir),Ot(vU,5,so)),2&o){let r;wt(r=Et())&&(i.leftOuterSelectionBarElement=r.first),wt(r=Et())&&(i.rightOuterSelectionBarElement=r.first),wt(r=Et())&&(i.fullBarElement=r.first),wt(r=Et())&&(i.selectionBarElement=r.first),wt(r=Et())&&(i.minHandleElement=r.first),wt(r=Et())&&(i.maxHandleElement=r.first),wt(r=Et())&&(i.floorLabelElement=r.first),wt(r=Et())&&(i.ceilLabelElement=r.first),wt(r=Et())&&(i.minHandleLabelElement=r.first),wt(r=Et())&&(i.maxHandleLabelElement=r.first),wt(r=Et())&&(i.combinedLabelElement=r.first),wt(r=Et())&&(i.ticksElement=r.first)}},hostVars:10,hostBindings:function(o,i){1&o&&U("resize",function(s){return i.onResize(s)},Ba),2&o&&(ct("disabled",i.sliderElementDisabledAttr)("aria-label",i.sliderElementAriaLabel),An("ngx-slider",i.sliderElementNgxSliderClass)("vertical",i.sliderElementVerticalClass)("animate",i.sliderElementAnimateClass)("with-legend",i.sliderElementWithLegendClass))},inputs:{value:"value",highValue:"highValue",options:"options",manualRefresh:"manualRefresh",triggerFocus:"triggerFocus",cancelUserChange:"cancelUserChange"},outputs:{valueChange:"valueChange",highValueChange:"highValueChange",userChangeStart:"userChangeStart",userChange:"userChange",userChangeEnd:"userChangeEnd"},standalone:!1,features:[Ee([TU]),En],decls:30,vars:12,consts:[["leftOuterSelectionBar",""],["rightOuterSelectionBar",""],["fullBar",""],["selectionBar",""],["minHandle",""],["maxHandle",""],["floorLabel",""],["ceilLabel",""],["minHandleLabel",""],["maxHandleLabel",""],["combinedLabel",""],["ticksElement",""],["ngxSliderElement","",1,"ngx-slider-span","ngx-slider-bar-wrapper","ngx-slider-left-out-selection"],[1,"ngx-slider-span","ngx-slider-bar"],["ngxSliderElement","",1,"ngx-slider-span","ngx-slider-bar-wrapper","ngx-slider-right-out-selection"],["ngxSliderElement","",1,"ngx-slider-span","ngx-slider-bar-wrapper","ngx-slider-full-bar"],["ngxSliderElement","",1,"ngx-slider-span","ngx-slider-bar-wrapper","ngx-slider-selection-bar"],[1,"ngx-slider-span","ngx-slider-bar","ngx-slider-selection",3,"ngStyle"],["ngxSliderHandle","",1,"ngx-slider-span","ngx-slider-pointer","ngx-slider-pointer-min",3,"ngStyle"],["ngxSliderHandle","",1,"ngx-slider-span","ngx-slider-pointer","ngx-slider-pointer-max",3,"ngStyle"],["ngxSliderLabel","",1,"ngx-slider-span","ngx-slider-bubble","ngx-slider-limit","ngx-slider-floor"],["ngxSliderLabel","",1,"ngx-slider-span","ngx-slider-bubble","ngx-slider-limit","ngx-slider-ceil"],["ngxSliderLabel","",1,"ngx-slider-span","ngx-slider-bubble","ngx-slider-model-value"],["ngxSliderLabel","",1,"ngx-slider-span","ngx-slider-bubble","ngx-slider-model-high"],["ngxSliderLabel","",1,"ngx-slider-span","ngx-slider-bubble","ngx-slider-combined"],["ngxSliderElement","",1,"ngx-slider-ticks",3,"hidden"],[1,"ngx-slider-tick",3,"ngClass","ngStyle"],[3,"template","tooltip","placement"],[1,"ngx-slider-span","ngx-slider-tick-value",3,"template","tooltip","placement","content"],[1,"ngx-slider-span","ngx-slider-tick-legend",3,"innerText"],[1,"ngx-slider-span","ngx-slider-tick-legend",3,"innerHTML"]],template:function(o,i){1&o&&(v(0,"span",12,0),O(2,"span",13),_(),v(3,"span",14,1),O(5,"span",13),_(),v(6,"span",15,2),O(8,"span",13),_(),v(9,"span",16,3),O(11,"span",17),_(),O(12,"span",18,4)(14,"span",19,5)(16,"span",20,6)(18,"span",21,7)(20,"span",22,8)(22,"span",23,9)(24,"span",24,10),v(26,"span",25,11),Qe(28,wU,5,10,"span",26,Ye),_()),2&o&&(f(6),An("ngx-slider-transparent",i.fullBarTransparentClass),f(3),An("ngx-slider-draggable",i.selectionBarDraggableClass),f(2),A("ngStyle",i.barStyle),f(),A("ngStyle",i.minPointerStyle),f(2),zl("display",i.range?"inherit":"none"),A("ngStyle",i.maxPointerStyle),f(12),An("ngx-slider-ticks-values-under",i.ticksUnderValuesClass),A("hidden",!i.showTicks),f(2),Ke(i.ticks))},dependencies:[Xi,cE,so,Hg,ir,MU],styles:['.ngx-slider{display:inline-block;position:relative;height:4px;width:100%;margin:35px 0 15px;vertical-align:middle;-webkit-user-select:none;user-select:none;touch-action:pan-y} .ngx-slider.with-legend{margin-bottom:40px} .ngx-slider[disabled]{cursor:not-allowed} .ngx-slider[disabled] .ngx-slider-pointer{cursor:not-allowed;background-color:#d8e0f3} .ngx-slider[disabled] .ngx-slider-draggable{cursor:not-allowed} .ngx-slider[disabled] .ngx-slider-selection{background:#8b91a2} .ngx-slider[disabled] .ngx-slider-tick{cursor:not-allowed} .ngx-slider[disabled] .ngx-slider-tick.ngx-slider-selected{background:#8b91a2} .ngx-slider .ngx-slider-span{white-space:nowrap;position:absolute;display:inline-block} .ngx-slider .ngx-slider-base{width:100%;height:100%;padding:0} .ngx-slider .ngx-slider-bar-wrapper{left:0;box-sizing:border-box;margin-top:-16px;padding-top:16px;width:100%;height:32px;z-index:1} .ngx-slider .ngx-slider-draggable{cursor:move} .ngx-slider .ngx-slider-bar{left:0;width:100%;height:4px;z-index:1;background:#d8e0f3;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px} .ngx-slider .ngx-slider-bar-wrapper.ngx-slider-transparent .ngx-slider-bar{background:transparent} .ngx-slider .ngx-slider-bar-wrapper.ngx-slider-left-out-selection .ngx-slider-bar{background:#df002d} .ngx-slider .ngx-slider-bar-wrapper.ngx-slider-right-out-selection .ngx-slider-bar{background:#03a688} .ngx-slider .ngx-slider-selection{z-index:2;background:#0db9f0;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px} .ngx-slider .ngx-slider-pointer{cursor:pointer;width:32px;height:32px;top:-14px;background-color:#0db9f0;z-index:3;-webkit-border-radius:16px;-moz-border-radius:16px;border-radius:16px} .ngx-slider .ngx-slider-pointer:after{content:"";width:8px;height:8px;position:absolute;top:12px;left:12px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;background:#fff} .ngx-slider .ngx-slider-pointer:hover:after{background-color:#fff} .ngx-slider .ngx-slider-pointer.ngx-slider-active{z-index:4} .ngx-slider .ngx-slider-pointer.ngx-slider-active:after{background-color:#451aff} .ngx-slider .ngx-slider-bubble{cursor:default;bottom:16px;padding:1px 3px;color:#55637d;font-size:16px} .ngx-slider .ngx-slider-bubble.ngx-slider-limit{color:#55637d} .ngx-slider .ngx-slider-ticks{box-sizing:border-box;width:100%;height:0;position:absolute;left:0;top:-3px;margin:0;z-index:1;list-style:none} .ngx-slider .ngx-slider-ticks-values-under .ngx-slider-tick-value{top:auto;bottom:-36px} .ngx-slider .ngx-slider-tick{text-align:center;cursor:pointer;width:10px;height:10px;background:#d8e0f3;border-radius:50%;position:absolute;top:0;left:0;margin-left:11px} .ngx-slider .ngx-slider-tick.ngx-slider-selected{background:#0db9f0} .ngx-slider .ngx-slider-tick-value{position:absolute;top:-34px;transform:translate(-50%)} .ngx-slider .ngx-slider-tick-legend{position:absolute;top:24px;transform:translate(-50%);max-width:50px;white-space:normal} .ngx-slider.vertical{position:relative;width:4px;height:100%;margin:0 20px;padding:0;vertical-align:baseline;touch-action:pan-x} .ngx-slider.vertical .ngx-slider-base{width:100%;height:100%;padding:0} .ngx-slider.vertical .ngx-slider-bar-wrapper{top:auto;left:0;margin:0 0 0 -16px;padding:0 0 0 16px;height:100%;width:32px} .ngx-slider.vertical .ngx-slider-bar{bottom:0;left:auto;width:4px;height:100%} .ngx-slider.vertical .ngx-slider-pointer{left:-14px!important;top:auto;bottom:0} .ngx-slider.vertical .ngx-slider-bubble{left:16px!important;bottom:0} .ngx-slider.vertical .ngx-slider-ticks{height:100%;width:0;left:-3px;top:0;z-index:1} .ngx-slider.vertical .ngx-slider-tick{vertical-align:middle;margin-left:auto;margin-top:11px} .ngx-slider.vertical .ngx-slider-tick-value{left:24px;top:auto;transform:translateY(-28%)} .ngx-slider.vertical .ngx-slider-tick-legend{top:auto;right:24px;transform:translateY(-28%);max-width:none;white-space:nowrap} .ngx-slider.vertical .ngx-slider-ticks-values-under .ngx-slider-tick-value{bottom:auto;left:auto;right:24px} .ngx-slider *{transition:none} .ngx-slider.animate .ngx-slider-bar-wrapper{transition:all linear .3s} .ngx-slider.animate .ngx-slider-selection{transition:background-color linear .3s} .ngx-slider.animate .ngx-slider-pointer{transition:all linear .3s} .ngx-slider.animate .ngx-slider-pointer:after{transition:all linear .3s} .ngx-slider.animate .ngx-slider-bubble{transition:all linear .3s} .ngx-slider.animate .ngx-slider-bubble.ngx-slider-limit{transition:opacity linear .3s} .ngx-slider.animate .ngx-slider-bubble.ngx-slider-combined{transition:opacity linear .3s} .ngx-slider.animate .ngx-slider-tick{transition:background-color linear .3s}']})}return e})(),SU=(()=>{class e{static \u0275fac=function(o){return new(o||e)};static \u0275mod=Qn({type:e});static \u0275inj=dn({imports:[hE]})}return e})();class lI{constructor(){this.riskHotspotsSettings=null,this.coverageInfoSettings=null}}class AU{constructor(){this.showLineCoverage=!0,this.showBranchCoverage=!0,this.showMethodCoverage=!0,this.showFullMethodCoverage=!0,this.visibleMetrics=[],this.groupingMaximum=0,this.grouping=0,this.historyComparisionDate="",this.historyComparisionType="",this.filter="",this.lineCoverageMin=0,this.lineCoverageMax=100,this.branchCoverageMin=0,this.branchCoverageMax=100,this.methodCoverageMin=0,this.methodCoverageMax=100,this.methodFullCoverageMin=0,this.methodFullCoverageMax=100,this.sortBy="name",this.sortOrder="asc",this.collapseStates=[]}}class NU{constructor(n){this.et="",this.et=n.et,this.cl=n.cl,this.ucl=n.ucl,this.cal=n.cal,this.tl=n.tl,this.lcq=n.lcq,this.cb=n.cb,this.tb=n.tb,this.bcq=n.bcq,this.cm=n.cm,this.fcm=n.fcm,this.tm=n.tm,this.mcq=n.mcq,this.mfcq=n.mfcq}get coverageRatioText(){return 0===this.tl?"-":this.cl+"/"+this.cal}get branchCoverageRatioText(){return 0===this.tb?"-":this.cb+"/"+this.tb}get methodCoverageRatioText(){return 0===this.tm?"-":this.cm+"/"+this.tm}get methodFullCoverageRatioText(){return 0===this.tm?"-":this.fcm+"/"+this.tm}}class kt{static roundNumber(n){return Math.floor(n*Math.pow(10,kt.maximumDecimalPlacesForCoverageQuotas))/Math.pow(10,kt.maximumDecimalPlacesForCoverageQuotas)}static getNthOrLastIndexOf(n,t,o){let i=0,r=-1,s=-1;for(;i{this.historicCoverages.push(new NU(o))}),this.metrics=n.metrics}get coverage(){return 0===this.coverableLines?NaN:kt.roundNumber(100*this.coveredLines/this.coverableLines)}visible(n){if(""!==n.filter&&-1===this.name.toLowerCase().indexOf(n.filter.toLowerCase()))return!1;let t=this.coverage,o=t;if(t=Number.isNaN(t)?0:t,o=Number.isNaN(o)?100:o,n.lineCoverageMin>t||n.lineCoverageMaxi||n.branchCoverageMaxs||n.methodCoverageMaxl||n.methodFullCoverageMax=this.currentHistoricCoverage.lcq)return!1}else if("branchCoverageIncreaseOnly"===n.historyComparisionType){let u=this.branchCoverage;if(isNaN(u)||u<=this.currentHistoricCoverage.bcq)return!1}else if("branchCoverageDecreaseOnly"===n.historyComparisionType){let u=this.branchCoverage;if(isNaN(u)||u>=this.currentHistoricCoverage.bcq)return!1}else if("methodCoverageIncreaseOnly"===n.historyComparisionType){let u=this.methodCoverage;if(isNaN(u)||u<=this.currentHistoricCoverage.mcq)return!1}else if("methodCoverageDecreaseOnly"===n.historyComparisionType){let u=this.methodCoverage;if(isNaN(u)||u>=this.currentHistoricCoverage.mcq)return!1}else if("fullMethodCoverageIncreaseOnly"===n.historyComparisionType){let u=this.methodFullCoverage;if(isNaN(u)||u<=this.currentHistoricCoverage.mfcq)return!1}else if("fullMethodCoverageDecreaseOnly"===n.historyComparisionType){let u=this.methodFullCoverage;if(isNaN(u)||u>=this.currentHistoricCoverage.mfcq)return!1}return!0}updateCurrentHistoricCoverage(n){if(this.currentHistoricCoverage=null,""!==n)for(let t=0;t-1&&null===t}visible(n){if(""!==n.filter&&this.name.toLowerCase().indexOf(n.filter.toLowerCase())>-1)return!0;for(let t=0;t{var e;class n{get nativeWindow(){return function OU(){return window}()}static#e=e=()=>(this.\u0275fac=function(i){return new(i||n)},this.\u0275prov=X({token:n,factory:n.\u0275fac}))}return e(),n})(),xU=(()=>{var e;class n{constructor(){this.translations={}}static#e=e=()=>(this.\u0275fac=function(i){return new(i||n)},this.\u0275cmp=qt({type:n,selectors:[["pro-button"]],inputs:{translations:"translations"},standalone:!1,decls:3,vars:2,consts:[["href","https://reportgenerator.io/pro","target","_blank",1,"pro-button","pro-button-tiny",3,"title"]],template:function(i,r){1&i&&(D(0,"\xa0"),v(1,"a",0),D(2,"PRO"),_()),2&i&&(f(),A("title",On(r.translations.methodCoverageProVersion)))},encapsulation:2}))}return e(),n})();function RU(e,n){if(1&e){const t=ue();v(0,"div",3)(1,"label")(2,"input",4),Ge("ngModelChange",function(i){B(t);const r=m();return ye(r.showBranchCoverage,i)||(r.showBranchCoverage=i),j(i)}),U("change",function(){B(t);const i=m();return j(i.showBranchCoverageChange.emit(i.showBranchCoverage))}),_(),D(3),_()()}if(2&e){const t=m();f(2),je("ngModel",t.showBranchCoverage),f(),P(" ",t.translations.branchCoverage)}}function kU(e,n){1&e&&O(0,"pro-button",6),2&e&&A("translations",m().translations)}function FU(e,n){1&e&&O(0,"pro-button",6),2&e&&A("translations",m().translations)}function LU(e,n){1&e&&O(0,"pro-button",6),2&e&&A("translations",m(2).translations)}function PU(e,n){1&e&&(v(0,"a",8),O(1,"i",9),_()),2&e&&A("href",m().$implicit.explanationUrl,Wn)}function VU(e,n){if(1&e){const t=ue();v(0,"div",3)(1,"label")(2,"input",7),U("change",function(){const i=B(t).$implicit;return j(m(2).toggleMetric(i))}),_(),D(3),_(),D(4,"\xa0"),y(5,PU,2,1,"a",8),_()}if(2&e){const t=n.$implicit,o=m(2);f(2),A("checked",o.isMetricSelected(t))("disabled",!o.methodCoverageAvailable),f(),P(" ",t.name),f(2),C(t.explanationUrl?5:-1)}}function HU(e,n){if(1&e&&(O(0,"br")(1,"br"),v(2,"b"),D(3),_(),y(4,LU,1,1,"pro-button",6),Qe(5,VU,6,4,"div",3,Ye)),2&e){const t=m();f(3),k(t.translations.metrics),f(),C(t.methodCoverageAvailable?-1:4),f(),Ke(t.metrics)}}let BU=(()=>{var e;class n{constructor(){this.visible=!1,this.visibleChange=new ve,this.translations={},this.branchCoverageAvailable=!1,this.methodCoverageAvailable=!1,this.metrics=[],this.showLineCoverage=!1,this.showLineCoverageChange=new ve,this.showBranchCoverage=!1,this.showBranchCoverageChange=new ve,this.showMethodCoverage=!1,this.showMethodCoverageChange=new ve,this.showMethodFullCoverage=!1,this.showMethodFullCoverageChange=new ve,this.visibleMetrics=[],this.visibleMetricsChange=new ve}isMetricSelected(o){return void 0!==this.visibleMetrics.find(i=>i.name===o.name)}toggleMetric(o){let i=this.visibleMetrics.find(r=>r.name===o.name);i?this.visibleMetrics.splice(this.visibleMetrics.indexOf(i),1):this.visibleMetrics.push(o),this.visibleMetrics=[...this.visibleMetrics],this.visibleMetricsChange.emit(this.visibleMetrics)}close(){this.visible=!1,this.visibleChange.emit(this.visible)}cancelEvent(o){o.stopPropagation()}static#e=e=()=>(this.\u0275fac=function(i){return new(i||n)},this.\u0275cmp=qt({type:n,selectors:[["popup"]],inputs:{visible:"visible",translations:"translations",branchCoverageAvailable:"branchCoverageAvailable",methodCoverageAvailable:"methodCoverageAvailable",metrics:"metrics",showLineCoverage:"showLineCoverage",showBranchCoverage:"showBranchCoverage",showMethodCoverage:"showMethodCoverage",showMethodFullCoverage:"showMethodFullCoverage",visibleMetrics:"visibleMetrics"},outputs:{visibleChange:"visibleChange",showLineCoverageChange:"showLineCoverageChange",showBranchCoverageChange:"showBranchCoverageChange",showMethodCoverageChange:"showMethodCoverageChange",showMethodFullCoverageChange:"showMethodFullCoverageChange",visibleMetricsChange:"visibleMetricsChange"},standalone:!1,decls:22,vars:13,consts:[[1,"popup-container",3,"click"],[1,"popup",3,"click"],[1,"close",3,"click"],[1,"mt-1"],["type","checkbox",3,"ngModelChange","change","ngModel"],["type","checkbox",3,"ngModelChange","change","ngModel","disabled"],[3,"translations"],["type","checkbox",3,"change","checked","disabled"],["target","_blank",3,"href"],[1,"icon-info-circled"]],template:function(i,r){1&i&&(v(0,"div",0),U("click",function(){return r.close()}),v(1,"div",1),U("click",function(a){return r.cancelEvent(a)}),v(2,"div",2),U("click",function(){return r.close()}),D(3,"X"),_(),v(4,"b"),D(5),_(),v(6,"div",3)(7,"label")(8,"input",4),Ge("ngModelChange",function(a){return ye(r.showLineCoverage,a)||(r.showLineCoverage=a),a}),U("change",function(){return r.showLineCoverageChange.emit(r.showLineCoverage)}),_(),D(9),_()(),y(10,RU,4,2,"div",3),v(11,"div",3)(12,"label")(13,"input",5),Ge("ngModelChange",function(a){return ye(r.showMethodCoverage,a)||(r.showMethodCoverage=a),a}),U("change",function(){return r.showMethodCoverageChange.emit(r.showMethodCoverage)}),_(),D(14),_(),y(15,kU,1,1,"pro-button",6),_(),v(16,"div",3)(17,"label")(18,"input",5),Ge("ngModelChange",function(a){return ye(r.showMethodFullCoverage,a)||(r.showMethodFullCoverage=a),a}),U("change",function(){return r.showMethodFullCoverageChange.emit(r.showMethodFullCoverage)}),_(),D(19),_(),y(20,FU,1,1,"pro-button",6),_(),y(21,HU,7,2),_()()),2&i&&(f(5),k(r.translations.coverageTypes),f(3),je("ngModel",r.showLineCoverage),f(),P(" ",r.translations.coverage),f(),C(r.branchCoverageAvailable?10:-1),f(3),je("ngModel",r.showMethodCoverage),A("disabled",!r.methodCoverageAvailable),f(),P(" ",r.translations.methodCoverage),f(),C(r.methodCoverageAvailable?-1:15),f(3),je("ngModel",r.showMethodFullCoverage),A("disabled",!r.methodCoverageAvailable),f(),P(" ",r.translations.fullMethodCoverage),f(),C(r.methodCoverageAvailable?-1:20),f(),C(r.metrics.length>0?21:-1))},dependencies:[gg,vc,ks,xU],encapsulation:2}))}return e(),n})();function jU(e,n){1&e&&O(0,"td",1)}function UU(e,n){1&e&&O(0,"td"),2&e&&jt(Ut("green ",m().greenClass))}function $U(e,n){1&e&&O(0,"td"),2&e&&jt(Ut("red ",m().redClass))}let uI=(()=>{var e;class n{constructor(){this.grayVisible=!0,this.greenVisible=!1,this.redVisible=!1,this.greenClass="",this.redClass="",this._percentage=NaN}get percentage(){return this._percentage}set percentage(o){this._percentage=o,this.grayVisible=isNaN(o),this.greenVisible=!isNaN(o)&&Math.round(o)>0,this.redVisible=!isNaN(o)&&100-Math.round(o)>0,this.greenClass="covered"+Math.round(o),this.redClass="covered"+(100-Math.round(o))}static#e=e=()=>(this.\u0275fac=function(i){return new(i||n)},this.\u0275cmp=qt({type:n,selectors:[["coverage-bar"]],inputs:{percentage:"percentage"},standalone:!1,decls:4,vars:3,consts:[[1,"coverage"],[1,"gray","covered100"],[3,"class"]],template:function(i,r){1&i&&(v(0,"table",0),y(1,jU,1,0,"td",1),y(2,UU,1,3,"td",2),y(3,$U,1,3,"td",2),_()),2&i&&(f(),C(r.grayVisible?1:-1),f(),C(r.greenVisible?2:-1),f(),C(r.redVisible?3:-1))},encapsulation:2,changeDetection:0}))}return e(),n})();const zU=["codeelement-row",""],GU=(e,n)=>({"icon-plus":e,"icon-minus":n});function WU(e,n){if(1&e&&(v(0,"th",2),D(1),_()),2&e){const t=m();f(),k(t.element.coveredLines)}}function qU(e,n){if(1&e&&(v(0,"th",2),D(1),_()),2&e){const t=m();f(),k(t.element.uncoveredLines)}}function ZU(e,n){if(1&e&&(v(0,"th",2),D(1),_()),2&e){const t=m();f(),k(t.element.coverableLines)}}function YU(e,n){if(1&e&&(v(0,"th",2),D(1),_()),2&e){const t=m();f(),k(t.element.totalLines)}}function QU(e,n){if(1&e&&(v(0,"th",3),D(1),_()),2&e){const t=m();A("title",t.element.coverageRatioText),f(),k(t.element.coveragePercentage)}}function KU(e,n){if(1&e&&(v(0,"th",2),O(1,"coverage-bar",4),_()),2&e){const t=m();f(),A("percentage",t.element.coverage)}}function JU(e,n){if(1&e&&(v(0,"th",2),D(1),_()),2&e){const t=m();f(),k(t.element.coveredBranches)}}function XU(e,n){if(1&e&&(v(0,"th",2),D(1),_()),2&e){const t=m();f(),k(t.element.totalBranches)}}function e3(e,n){if(1&e&&(v(0,"th",3),D(1),_()),2&e){const t=m();A("title",t.element.branchCoverageRatioText),f(),k(t.element.branchCoveragePercentage)}}function t3(e,n){if(1&e&&(v(0,"th",2),O(1,"coverage-bar",4),_()),2&e){const t=m();f(),A("percentage",t.element.branchCoverage)}}function n3(e,n){if(1&e&&(v(0,"th",2),D(1),_()),2&e){const t=m();f(),k(t.element.coveredMethods)}}function o3(e,n){if(1&e&&(v(0,"th",2),D(1),_()),2&e){const t=m();f(),k(t.element.totalMethods)}}function i3(e,n){if(1&e&&(v(0,"th",3),D(1),_()),2&e){const t=m();A("title",t.element.methodCoverageRatioText),f(),k(t.element.methodCoveragePercentage)}}function r3(e,n){if(1&e&&(v(0,"th",2),O(1,"coverage-bar",4),_()),2&e){const t=m();f(),A("percentage",t.element.methodCoverage)}}function s3(e,n){if(1&e&&(v(0,"th",2),D(1),_()),2&e){const t=m();f(),k(t.element.fullyCoveredMethods)}}function a3(e,n){if(1&e&&(v(0,"th",2),D(1),_()),2&e){const t=m();f(),k(t.element.totalMethods)}}function l3(e,n){if(1&e&&(v(0,"th",3),D(1),_()),2&e){const t=m();A("title",t.element.methodFullCoverageRatioText),f(),k(t.element.methodFullCoveragePercentage)}}function c3(e,n){if(1&e&&(v(0,"th",2),O(1,"coverage-bar",4),_()),2&e){const t=m();f(),A("percentage",t.element.methodFullCoverage)}}function u3(e,n){1&e&&O(0,"th",2)}let d3=(()=>{var e;class n{constructor(){this.collapsed=!1,this.lineCoverageAvailable=!1,this.branchCoverageAvailable=!1,this.methodCoverageAvailable=!1,this.methodFullCoverageAvailable=!1,this.visibleMetrics=[]}static#e=e=()=>(this.\u0275fac=function(i){return new(i||n)},this.\u0275cmp=qt({type:n,selectors:[["","codeelement-row",""]],inputs:{element:"element",collapsed:"collapsed",lineCoverageAvailable:"lineCoverageAvailable",branchCoverageAvailable:"branchCoverageAvailable",methodCoverageAvailable:"methodCoverageAvailable",methodFullCoverageAvailable:"methodFullCoverageAvailable",visibleMetrics:"visibleMetrics"},standalone:!1,attrs:zU,decls:24,vars:23,consts:[["href","#",3,"click"],[3,"ngClass"],[1,"right"],[1,"right",3,"title"],[3,"percentage"]],template:function(i,r){1&i&&(v(0,"th")(1,"a",0),U("click",function(a){return r.element.toggleCollapse(a)}),O(2,"i",1),D(3),_()(),y(4,WU,2,1,"th",2),y(5,qU,2,1,"th",2),y(6,ZU,2,1,"th",2),y(7,YU,2,1,"th",2),y(8,QU,2,2,"th",3),y(9,KU,2,1,"th",2),y(10,JU,2,1,"th",2),y(11,XU,2,1,"th",2),y(12,e3,2,2,"th",3),y(13,t3,2,1,"th",2),y(14,n3,2,1,"th",2),y(15,o3,2,1,"th",2),y(16,i3,2,2,"th",3),y(17,r3,2,1,"th",2),y(18,s3,2,1,"th",2),y(19,a3,2,1,"th",2),y(20,l3,2,2,"th",3),y(21,c3,2,1,"th",2),Qe(22,u3,1,0,"th",2,Ye)),2&i&&(f(2),A("ngClass",Eh(20,GU,r.element.collapsed,!r.element.collapsed)),f(),P("\n",r.element.name),f(),C(r.lineCoverageAvailable?4:-1),f(),C(r.lineCoverageAvailable?5:-1),f(),C(r.lineCoverageAvailable?6:-1),f(),C(r.lineCoverageAvailable?7:-1),f(),C(r.lineCoverageAvailable?8:-1),f(),C(r.lineCoverageAvailable?9:-1),f(),C(r.branchCoverageAvailable?10:-1),f(),C(r.branchCoverageAvailable?11:-1),f(),C(r.branchCoverageAvailable?12:-1),f(),C(r.branchCoverageAvailable?13:-1),f(),C(r.methodCoverageAvailable?14:-1),f(),C(r.methodCoverageAvailable?15:-1),f(),C(r.methodCoverageAvailable?16:-1),f(),C(r.methodCoverageAvailable?17:-1),f(),C(r.methodFullCoverageAvailable?18:-1),f(),C(r.methodFullCoverageAvailable?19:-1),f(),C(r.methodFullCoverageAvailable?20:-1),f(),C(r.methodFullCoverageAvailable?21:-1),f(),Ke(r.visibleMetrics))},dependencies:[Xi,uI],encapsulation:2,changeDetection:0}))}return e(),n})();const f3=["coverage-history-chart",""];let h3=(()=>{var e;class n{constructor(){this.path=null,this._historicCoverages=[]}get historicCoverages(){return this._historicCoverages}set historicCoverages(o){if(this._historicCoverages=o,o.length>1){let i="";for(let r=0;r(this.\u0275fac=function(i){return new(i||n)},this.\u0275cmp=qt({type:n,selectors:[["","coverage-history-chart",""]],inputs:{historicCoverages:"historicCoverages"},standalone:!1,attrs:f3,decls:3,vars:1,consts:[["width","30","height","18",1,"ct-chart-line"],[1,"ct-series","ct-series-a"],[1,"ct-line"]],template:function(i,r){1&i&&(function tm(){G.lFrame.currentNamespace="svg"}(),v(0,"svg",0)(1,"g",1),O(2,"path",2),_()()),2&i&&(f(2),ct("d",r.path))},encapsulation:2,changeDetection:0}))}return e(),n})();const g3=["class-row",""],Lc=e=>({historiccoverageoffset:e});function p3(e,n){if(1&e&&(v(0,"a",0),D(1),_()),2&e){const t=m();A("href",t.clazz.reportPath,Wn),f(),k(t.clazz.name)}}function m3(e,n){1&e&&D(0),2&e&&P(" ",m().clazz.name," ")}function _3(e,n){if(1&e&&(v(0,"div"),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);jt(Ut("currenthistory ",t.getClassName(t.clazz.coveredLines,t.clazz.currentHistoricCoverage.cl))),f(),P(" ",t.clazz.coveredLines," "),f(),A("title",t.clazz.currentHistoricCoverage.et),f(),P(" ",t.clazz.currentHistoricCoverage.cl," ")}}function v3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.coveredLines," ")}function y3(e,n){if(1&e&&(v(0,"td",1),y(1,_3,4,6),y(2,v3,1,1),_()),2&e){const t=m();f(),C(null!==t.clazz.currentHistoricCoverage?1:-1),f(),C(null===t.clazz.currentHistoricCoverage?2:-1)}}function C3(e,n){if(1&e&&(v(0,"div"),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);jt(Ut("currenthistory ",t.getClassName(t.clazz.currentHistoricCoverage.ucl,t.clazz.uncoveredLines))),f(),P(" ",t.clazz.uncoveredLines," "),f(),A("title",t.clazz.currentHistoricCoverage.et),f(),P(" ",t.clazz.currentHistoricCoverage.ucl," ")}}function b3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.uncoveredLines," ")}function D3(e,n){if(1&e&&(v(0,"td",1),y(1,C3,4,6),y(2,b3,1,1),_()),2&e){const t=m();f(),C(null!==t.clazz.currentHistoricCoverage?1:-1),f(),C(null===t.clazz.currentHistoricCoverage?2:-1)}}function w3(e,n){if(1&e&&(v(0,"div",4),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);f(),k(t.clazz.coverableLines),f(),A("title",t.clazz.currentHistoricCoverage.et),f(),k(t.clazz.currentHistoricCoverage.cal)}}function E3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.coverableLines," ")}function M3(e,n){if(1&e&&(v(0,"td",1),y(1,w3,4,3),y(2,E3,1,1),_()),2&e){const t=m();f(),C(null!==t.clazz.currentHistoricCoverage?1:-1),f(),C(null===t.clazz.currentHistoricCoverage?2:-1)}}function I3(e,n){if(1&e&&(v(0,"div",4),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);f(),k(t.clazz.totalLines),f(),A("title",t.clazz.currentHistoricCoverage.et),f(),k(t.clazz.currentHistoricCoverage.tl)}}function T3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.totalLines," ")}function S3(e,n){if(1&e&&(v(0,"td",1),y(1,I3,4,3),y(2,T3,1,1),_()),2&e){const t=m();f(),C(null!==t.clazz.currentHistoricCoverage?1:-1),f(),C(null===t.clazz.currentHistoricCoverage?2:-1)}}function A3(e,n){if(1&e&&O(0,"div",5),2&e){const t=m(2);A("title",On(t.translations.history+": "+t.translations.coverage))("historicCoverages",t.clazz.lineCoverageHistory)("ngClass",Zi(4,Lc,null!==t.clazz.currentHistoricCoverage))}}function N3(e,n){if(1&e&&(v(0,"div"),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);jt(Ut("currenthistory ",t.getClassName(t.clazz.coverage,t.clazz.currentHistoricCoverage.lcq))),f(),P(" ",t.clazz.coveragePercentage," "),f(),A("title",t.clazz.currentHistoricCoverage.et+": "+t.clazz.currentHistoricCoverage.coverageRatioText),f(),P("",t.clazz.currentHistoricCoverage.lcq,"%")}}function O3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.coveragePercentage," ")}function x3(e,n){if(1&e&&(v(0,"td",2),y(1,A3,1,6,"div",5),y(2,N3,4,6),y(3,O3,1,1),_()),2&e){const t=m();A("title",t.clazz.coverageRatioText),f(),C(t.clazz.lineCoverageHistory.length>1?1:-1),f(),C(null!==t.clazz.currentHistoricCoverage?2:-1),f(),C(null===t.clazz.currentHistoricCoverage?3:-1)}}function R3(e,n){if(1&e&&(v(0,"td",1),O(1,"coverage-bar",6),_()),2&e){const t=m();f(),A("percentage",t.clazz.coverage)}}function k3(e,n){if(1&e&&(v(0,"div"),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);jt(Ut("currenthistory ",t.getClassName(t.clazz.coveredBranches,t.clazz.currentHistoricCoverage.cb))),f(),P(" ",t.clazz.coveredBranches," "),f(),A("title",t.clazz.currentHistoricCoverage.et),f(),P(" ",t.clazz.currentHistoricCoverage.cb," ")}}function F3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.coveredBranches," ")}function L3(e,n){if(1&e&&(v(0,"td",1),y(1,k3,4,6),y(2,F3,1,1),_()),2&e){const t=m();f(),C(null!==t.clazz.currentHistoricCoverage?1:-1),f(),C(null===t.clazz.currentHistoricCoverage?2:-1)}}function P3(e,n){if(1&e&&(v(0,"div",4),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);f(),k(t.clazz.totalBranches),f(),A("title",t.clazz.currentHistoricCoverage.et),f(),k(t.clazz.currentHistoricCoverage.tb)}}function V3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.totalBranches," ")}function H3(e,n){if(1&e&&(v(0,"td",1),y(1,P3,4,3),y(2,V3,1,1),_()),2&e){const t=m();f(),C(null!==t.clazz.currentHistoricCoverage?1:-1),f(),C(null===t.clazz.currentHistoricCoverage?2:-1)}}function B3(e,n){if(1&e&&O(0,"div",7),2&e){const t=m(2);A("title",On(t.translations.history+": "+t.translations.branchCoverage))("historicCoverages",t.clazz.branchCoverageHistory)("ngClass",Zi(4,Lc,null!==t.clazz.currentHistoricCoverage))}}function j3(e,n){if(1&e&&(v(0,"div"),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);jt(Ut("currenthistory ",t.getClassName(t.clazz.branchCoverage,t.clazz.currentHistoricCoverage.bcq))),f(),P(" ",t.clazz.branchCoveragePercentage," "),f(),A("title",t.clazz.currentHistoricCoverage.et+": "+t.clazz.currentHistoricCoverage.branchCoverageRatioText),f(),P("",t.clazz.currentHistoricCoverage.bcq,"%")}}function U3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.branchCoveragePercentage," ")}function $3(e,n){if(1&e&&(v(0,"td",2),y(1,B3,1,6,"div",7),y(2,j3,4,6),y(3,U3,1,1),_()),2&e){const t=m();A("title",t.clazz.branchCoverageRatioText),f(),C(t.clazz.branchCoverageHistory.length>1?1:-1),f(),C(null!==t.clazz.currentHistoricCoverage?2:-1),f(),C(null===t.clazz.currentHistoricCoverage?3:-1)}}function z3(e,n){if(1&e&&(v(0,"td",1),O(1,"coverage-bar",6),_()),2&e){const t=m();f(),A("percentage",t.clazz.branchCoverage)}}function G3(e,n){if(1&e&&(v(0,"div"),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);jt(Ut("currenthistory ",t.getClassName(t.clazz.coveredMethods,t.clazz.currentHistoricCoverage.cm))),f(),P(" ",t.clazz.coveredMethods," "),f(),A("title",t.clazz.currentHistoricCoverage.et),f(),P(" ",t.clazz.currentHistoricCoverage.cm," ")}}function W3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.coveredMethods," ")}function q3(e,n){if(1&e&&(v(0,"td",1),y(1,G3,4,6),y(2,W3,1,1),_()),2&e){const t=m();f(),C(null!==t.clazz.currentHistoricCoverage?1:-1),f(),C(null===t.clazz.currentHistoricCoverage?2:-1)}}function Z3(e,n){if(1&e&&(v(0,"div",4),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);f(),k(t.clazz.totalMethods),f(),A("title",t.clazz.currentHistoricCoverage.et),f(),k(t.clazz.currentHistoricCoverage.tm)}}function Y3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.totalMethods," ")}function Q3(e,n){if(1&e&&(v(0,"td",1),y(1,Z3,4,3),y(2,Y3,1,1),_()),2&e){const t=m();f(),C(null!==t.clazz.currentHistoricCoverage?1:-1),f(),C(null===t.clazz.currentHistoricCoverage?2:-1)}}function K3(e,n){if(1&e&&O(0,"div",8),2&e){const t=m(2);A("title",On(t.translations.history+": "+t.translations.methodCoverage))("historicCoverages",t.clazz.methodCoverageHistory)("ngClass",Zi(4,Lc,null!==t.clazz.currentHistoricCoverage))}}function J3(e,n){if(1&e&&(v(0,"div"),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);jt(Ut("currenthistory ",t.getClassName(t.clazz.methodCoverage,t.clazz.currentHistoricCoverage.mcq))),f(),P(" ",t.clazz.methodCoveragePercentage," "),f(),A("title",t.clazz.currentHistoricCoverage.et+": "+t.clazz.currentHistoricCoverage.methodCoverageRatioText),f(),P("",t.clazz.currentHistoricCoverage.mcq,"%")}}function X3(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.methodCoveragePercentage," ")}function e$(e,n){if(1&e&&(v(0,"td",2),y(1,K3,1,6,"div",8),y(2,J3,4,6),y(3,X3,1,1),_()),2&e){const t=m();A("title",t.clazz.methodCoverageRatioText),f(),C(t.clazz.methodCoverageHistory.length>1?1:-1),f(),C(null!==t.clazz.currentHistoricCoverage?2:-1),f(),C(null===t.clazz.currentHistoricCoverage?3:-1)}}function t$(e,n){if(1&e&&(v(0,"td",1),O(1,"coverage-bar",6),_()),2&e){const t=m();f(),A("percentage",t.clazz.methodCoverage)}}function n$(e,n){if(1&e&&(v(0,"div"),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);jt(Ut("currenthistory ",t.getClassName(t.clazz.fullyCoveredMethods,t.clazz.currentHistoricCoverage.fcm))),f(),P(" ",t.clazz.fullyCoveredMethods," "),f(),A("title",t.clazz.currentHistoricCoverage.et),f(),P(" ",t.clazz.currentHistoricCoverage.fcm," ")}}function o$(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.fullyCoveredMethods," ")}function i$(e,n){if(1&e&&(v(0,"td",1),y(1,n$,4,6),y(2,o$,1,1),_()),2&e){const t=m();f(),C(null!==t.clazz.currentHistoricCoverage?1:-1),f(),C(null===t.clazz.currentHistoricCoverage?2:-1)}}function r$(e,n){if(1&e&&(v(0,"div",4),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);f(),k(t.clazz.totalMethods),f(),A("title",t.clazz.currentHistoricCoverage.et),f(),k(t.clazz.currentHistoricCoverage.tm)}}function s$(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.totalMethods," ")}function a$(e,n){if(1&e&&(v(0,"td",1),y(1,r$,4,3),y(2,s$,1,1),_()),2&e){const t=m();f(),C(null!==t.clazz.currentHistoricCoverage?1:-1),f(),C(null===t.clazz.currentHistoricCoverage?2:-1)}}function l$(e,n){if(1&e&&O(0,"div",9),2&e){const t=m(2);A("title",On(t.translations.history+": "+t.translations.fullMethodCoverage))("historicCoverages",t.clazz.methodFullCoverageHistory)("ngClass",Zi(4,Lc,null!==t.clazz.currentHistoricCoverage))}}function c$(e,n){if(1&e&&(v(0,"div"),D(1),_(),v(2,"div",3),D(3),_()),2&e){const t=m(2);jt(Ut("currenthistory ",t.getClassName(t.clazz.methodFullCoverage,t.clazz.currentHistoricCoverage.mfcq))),f(),P(" ",t.clazz.methodFullCoveragePercentage," "),f(),A("title",t.clazz.currentHistoricCoverage.et+": "+t.clazz.currentHistoricCoverage.methodFullCoverageRatioText),f(),P("",t.clazz.currentHistoricCoverage.mfcq,"%")}}function u$(e,n){1&e&&D(0),2&e&&P(" ",m(2).clazz.methodFullCoveragePercentage," ")}function d$(e,n){if(1&e&&(v(0,"td",2),y(1,l$,1,6,"div",9),y(2,c$,4,6),y(3,u$,1,1),_()),2&e){const t=m();A("title",t.clazz.methodFullCoverageRatioText),f(),C(t.clazz.methodFullCoverageHistory.length>1?1:-1),f(),C(null!==t.clazz.currentHistoricCoverage?2:-1),f(),C(null===t.clazz.currentHistoricCoverage?3:-1)}}function f$(e,n){if(1&e&&(v(0,"td",1),O(1,"coverage-bar",6),_()),2&e){const t=m();f(),A("percentage",t.clazz.methodFullCoverage)}}function h$(e,n){if(1&e&&(v(0,"td",1),D(1),_()),2&e){const t=n.$implicit,o=m();f(),k(o.clazz.metrics[t.abbreviation])}}let g$=(()=>{var e;class n{constructor(){this.translations={},this.lineCoverageAvailable=!1,this.branchCoverageAvailable=!1,this.methodCoverageAvailable=!1,this.methodFullCoverageAvailable=!1,this.visibleMetrics=[],this.historyComparisionDate=""}getClassName(o,i){return o>i?"lightgreen":o(this.\u0275fac=function(i){return new(i||n)},this.\u0275cmp=qt({type:n,selectors:[["","class-row",""]],inputs:{clazz:"clazz",translations:"translations",lineCoverageAvailable:"lineCoverageAvailable",branchCoverageAvailable:"branchCoverageAvailable",methodCoverageAvailable:"methodCoverageAvailable",methodFullCoverageAvailable:"methodFullCoverageAvailable",visibleMetrics:"visibleMetrics",historyComparisionDate:"historyComparisionDate"},standalone:!1,attrs:g3,decls:23,vars:20,consts:[[3,"href"],[1,"right"],[1,"right",3,"title"],[3,"title"],[1,"currenthistory"],["coverage-history-chart","",1,"tinylinecoveragechart","ct-chart",3,"historicCoverages","ngClass","title"],[3,"percentage"],["coverage-history-chart","",1,"tinybranchcoveragechart","ct-chart",3,"historicCoverages","ngClass","title"],["coverage-history-chart","",1,"tinymethodcoveragechart","ct-chart",3,"historicCoverages","ngClass","title"],["coverage-history-chart","",1,"tinyfullmethodcoveragechart","ct-chart",3,"historicCoverages","ngClass","title"]],template:function(i,r){1&i&&(v(0,"td"),y(1,p3,2,2,"a",0),y(2,m3,1,1),_(),y(3,y3,3,2,"td",1),y(4,D3,3,2,"td",1),y(5,M3,3,2,"td",1),y(6,S3,3,2,"td",1),y(7,x3,4,4,"td",2),y(8,R3,2,1,"td",1),y(9,L3,3,2,"td",1),y(10,H3,3,2,"td",1),y(11,$3,4,4,"td",2),y(12,z3,2,1,"td",1),y(13,q3,3,2,"td",1),y(14,Q3,3,2,"td",1),y(15,e$,4,4,"td",2),y(16,t$,2,1,"td",1),y(17,i$,3,2,"td",1),y(18,a$,3,2,"td",1),y(19,d$,4,4,"td",2),y(20,f$,2,1,"td",1),Qe(21,h$,2,1,"td",1,Ye)),2&i&&(f(),C(""!==r.clazz.reportPath?1:-1),f(),C(""===r.clazz.reportPath?2:-1),f(),C(r.lineCoverageAvailable?3:-1),f(),C(r.lineCoverageAvailable?4:-1),f(),C(r.lineCoverageAvailable?5:-1),f(),C(r.lineCoverageAvailable?6:-1),f(),C(r.lineCoverageAvailable?7:-1),f(),C(r.lineCoverageAvailable?8:-1),f(),C(r.branchCoverageAvailable?9:-1),f(),C(r.branchCoverageAvailable?10:-1),f(),C(r.branchCoverageAvailable?11:-1),f(),C(r.branchCoverageAvailable?12:-1),f(),C(r.methodCoverageAvailable?13:-1),f(),C(r.methodCoverageAvailable?14:-1),f(),C(r.methodCoverageAvailable?15:-1),f(),C(r.methodCoverageAvailable?16:-1),f(),C(r.methodFullCoverageAvailable?17:-1),f(),C(r.methodFullCoverageAvailable?18:-1),f(),C(r.methodFullCoverageAvailable?19:-1),f(),C(r.methodFullCoverageAvailable?20:-1),f(),Ke(r.visibleMetrics))},dependencies:[Xi,h3,uI],encapsulation:2,changeDetection:0}))}return e(),n})();const it=(e,n,t)=>({"icon-up-dir_active":e,"icon-down-dir_active":n,"icon-up-down-dir":t});function p$(e,n){if(1&e){const t=ue();v(0,"popup",27),Ge("visibleChange",function(i){B(t);const r=m(2);return ye(r.popupVisible,i)||(r.popupVisible=i),j(i)})("showLineCoverageChange",function(i){B(t);const r=m(2);return ye(r.settings.showLineCoverage,i)||(r.settings.showLineCoverage=i),j(i)})("showBranchCoverageChange",function(i){B(t);const r=m(2);return ye(r.settings.showBranchCoverage,i)||(r.settings.showBranchCoverage=i),j(i)})("showMethodCoverageChange",function(i){B(t);const r=m(2);return ye(r.settings.showMethodCoverage,i)||(r.settings.showMethodCoverage=i),j(i)})("showMethodFullCoverageChange",function(i){B(t);const r=m(2);return ye(r.settings.showFullMethodCoverage,i)||(r.settings.showFullMethodCoverage=i),j(i)})("visibleMetricsChange",function(i){B(t);const r=m(2);return ye(r.settings.visibleMetrics,i)||(r.settings.visibleMetrics=i),j(i)}),_()}if(2&e){const t=m(2);je("visible",t.popupVisible),A("translations",t.translations)("branchCoverageAvailable",t.branchCoverageAvailable)("methodCoverageAvailable",t.methodCoverageAvailable)("metrics",t.metrics),je("showLineCoverage",t.settings.showLineCoverage)("showBranchCoverage",t.settings.showBranchCoverage)("showMethodCoverage",t.settings.showMethodCoverage)("showMethodFullCoverage",t.settings.showFullMethodCoverage)("visibleMetrics",t.settings.visibleMetrics)}}function m$(e,n){1&e&&D(0),2&e&&P(" ",m(2).translations.noGrouping," ")}function _$(e,n){1&e&&D(0),2&e&&P(" ",m(2).translations.byAssembly," ")}function v$(e,n){if(1&e&&D(0),2&e){const t=m(2);P(" ",t.translations.byNamespace+" "+t.settings.grouping," ")}}function y$(e,n){if(1&e&&(v(0,"option",30),D(1),_()),2&e){const t=n.$implicit;A("value",t),f(),k(t)}}function C$(e,n){1&e&&O(0,"br")}function b$(e,n){if(1&e&&(v(0,"option",34),D(1),_()),2&e){const t=m(4);f(),P(" ",t.translations.branchCoverageIncreaseOnly," ")}}function D$(e,n){if(1&e&&(v(0,"option",35),D(1),_()),2&e){const t=m(4);f(),P(" ",t.translations.branchCoverageDecreaseOnly," ")}}function w$(e,n){if(1&e&&(v(0,"option",36),D(1),_()),2&e){const t=m(4);f(),P(" ",t.translations.methodCoverageIncreaseOnly," ")}}function E$(e,n){if(1&e&&(v(0,"option",37),D(1),_()),2&e){const t=m(4);f(),P(" ",t.translations.methodCoverageDecreaseOnly," ")}}function M$(e,n){if(1&e&&(v(0,"option",38),D(1),_()),2&e){const t=m(4);f(),P(" ",t.translations.fullMethodCoverageIncreaseOnly," ")}}function I$(e,n){if(1&e&&(v(0,"option",39),D(1),_()),2&e){const t=m(4);f(),P(" ",t.translations.fullMethodCoverageDecreaseOnly," ")}}function T$(e,n){if(1&e){const t=ue();v(0,"div")(1,"select",28),Ge("ngModelChange",function(i){B(t);const r=m(3);return ye(r.settings.historyComparisionType,i)||(r.settings.historyComparisionType=i),j(i)}),v(2,"option",29),D(3),_(),v(4,"option",31),D(5),_(),v(6,"option",32),D(7),_(),v(8,"option",33),D(9),_(),y(10,b$,2,1,"option",34),y(11,D$,2,1,"option",35),y(12,w$,2,1,"option",36),y(13,E$,2,1,"option",37),y(14,M$,2,1,"option",38),y(15,I$,2,1,"option",39),_()()}if(2&e){const t=m(3);f(),je("ngModel",t.settings.historyComparisionType),f(2),k(t.translations.filter),f(2),k(t.translations.allChanges),f(2),k(t.translations.lineCoverageIncreaseOnly),f(2),k(t.translations.lineCoverageDecreaseOnly),f(),C(t.branchCoverageAvailable?10:-1),f(),C(t.branchCoverageAvailable?11:-1),f(),C(t.methodCoverageAvailable?12:-1),f(),C(t.methodCoverageAvailable?13:-1),f(),C(t.methodCoverageAvailable?14:-1),f(),C(t.methodCoverageAvailable?15:-1)}}function S$(e,n){if(1&e){const t=ue();v(0,"div"),D(1),v(2,"select",28),Ge("ngModelChange",function(i){B(t);const r=m(2);return ye(r.settings.historyComparisionDate,i)||(r.settings.historyComparisionDate=i),j(i)}),U("ngModelChange",function(){return B(t),j(m(2).updateCurrentHistoricCoverage())}),v(3,"option",29),D(4),_(),Qe(5,y$,2,2,"option",30,Ye),_()(),y(7,C$,1,0,"br"),y(8,T$,16,11,"div")}if(2&e){const t=m(2);f(),P(" ",t.translations.compareHistory," "),f(),je("ngModel",t.settings.historyComparisionDate),f(2),k(t.translations.date),f(),Ke(t.historicCoverageExecutionTimes),f(2),C(""!==t.settings.historyComparisionDate?7:-1),f(),C(""!==t.settings.historyComparisionDate?8:-1)}}function A$(e,n){1&e&&O(0,"col",12)}function N$(e,n){1&e&&O(0,"col",13)}function O$(e,n){1&e&&O(0,"col",14)}function x$(e,n){1&e&&O(0,"col",15)}function R$(e,n){1&e&&O(0,"col",16)}function k$(e,n){1&e&&O(0,"col",17)}function F$(e,n){1&e&&O(0,"col",12)}function L$(e,n){1&e&&O(0,"col",15)}function P$(e,n){1&e&&O(0,"col",16)}function V$(e,n){1&e&&O(0,"col",17)}function H$(e,n){1&e&&O(0,"col",12)}function B$(e,n){1&e&&O(0,"col",15)}function j$(e,n){1&e&&O(0,"col",16)}function U$(e,n){1&e&&O(0,"col",17)}function $$(e,n){1&e&&O(0,"col",12)}function z$(e,n){1&e&&O(0,"col",15)}function G$(e,n){1&e&&O(0,"col",16)}function W$(e,n){1&e&&O(0,"col",17)}function q$(e,n){1&e&&O(0,"col",17)}function Z$(e,n){if(1&e&&(v(0,"th",19),D(1),_()),2&e){const t=m(2);f(),k(t.translations.coverage)}}function Y$(e,n){if(1&e&&(v(0,"th",20),D(1),_()),2&e){const t=m(2);f(),k(t.translations.branchCoverage)}}function Q$(e,n){if(1&e&&(v(0,"th",20),D(1),_()),2&e){const t=m(2);f(),k(t.translations.methodCoverage)}}function K$(e,n){if(1&e&&(v(0,"th",20),D(1),_()),2&e){const t=m(2);f(),k(t.translations.fullMethodCoverage)}}function J$(e,n){if(1&e&&(v(0,"th",21),D(1),_()),2&e){const t=m(2);ct("colspan",t.settings.visibleMetrics.length),f(),k(t.translations.metrics)}}function X$(e,n){if(1&e){const t=ue();v(0,"td",19)(1,"ngx-slider",40),Ge("valueChange",function(i){B(t);const r=m(2);return ye(r.settings.lineCoverageMin,i)||(r.settings.lineCoverageMin=i),j(i)})("highValueChange",function(i){B(t);const r=m(2);return ye(r.settings.lineCoverageMax,i)||(r.settings.lineCoverageMax=i),j(i)}),_()()}if(2&e){const t=m(2);f(),je("value",t.settings.lineCoverageMin)("highValue",t.settings.lineCoverageMax),A("options",t.sliderOptions)}}function e8(e,n){if(1&e){const t=ue();v(0,"td",20)(1,"ngx-slider",40),Ge("valueChange",function(i){B(t);const r=m(2);return ye(r.settings.branchCoverageMin,i)||(r.settings.branchCoverageMin=i),j(i)})("highValueChange",function(i){B(t);const r=m(2);return ye(r.settings.branchCoverageMax,i)||(r.settings.branchCoverageMax=i),j(i)}),_()()}if(2&e){const t=m(2);f(),je("value",t.settings.branchCoverageMin)("highValue",t.settings.branchCoverageMax),A("options",t.sliderOptions)}}function t8(e,n){if(1&e){const t=ue();v(0,"td",20)(1,"ngx-slider",40),Ge("valueChange",function(i){B(t);const r=m(2);return ye(r.settings.methodCoverageMin,i)||(r.settings.methodCoverageMin=i),j(i)})("highValueChange",function(i){B(t);const r=m(2);return ye(r.settings.methodCoverageMax,i)||(r.settings.methodCoverageMax=i),j(i)}),_()()}if(2&e){const t=m(2);f(),je("value",t.settings.methodCoverageMin)("highValue",t.settings.methodCoverageMax),A("options",t.sliderOptions)}}function n8(e,n){if(1&e){const t=ue();v(0,"td",20)(1,"ngx-slider",40),Ge("valueChange",function(i){B(t);const r=m(2);return ye(r.settings.methodFullCoverageMin,i)||(r.settings.methodFullCoverageMin=i),j(i)})("highValueChange",function(i){B(t);const r=m(2);return ye(r.settings.methodFullCoverageMax,i)||(r.settings.methodFullCoverageMax=i),j(i)}),_()()}if(2&e){const t=m(2);f(),je("value",t.settings.methodFullCoverageMin)("highValue",t.settings.methodFullCoverageMax),A("options",t.sliderOptions)}}function o8(e,n){1&e&&O(0,"td",21),2&e&&ct("colspan",m(2).settings.visibleMetrics.length)}function i8(e,n){if(1&e){const t=ue();v(0,"th",25)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("covered",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"covered"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"covered"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"covered"!==t.settings.sortBy)),f(),k(t.translations.covered)}}function r8(e,n){if(1&e){const t=ue();v(0,"th",25)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("uncovered",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"uncovered"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"uncovered"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"uncovered"!==t.settings.sortBy)),f(),k(t.translations.uncovered)}}function s8(e,n){if(1&e){const t=ue();v(0,"th",25)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("coverable",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"coverable"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"coverable"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"coverable"!==t.settings.sortBy)),f(),k(t.translations.coverable)}}function a8(e,n){if(1&e){const t=ue();v(0,"th",25)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("total",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"total"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"total"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"total"!==t.settings.sortBy)),f(),k(t.translations.total)}}function l8(e,n){if(1&e){const t=ue();v(0,"th",26)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("coverage",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"coverage"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"coverage"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"coverage"!==t.settings.sortBy)),f(),k(t.translations.percentage)}}function c8(e,n){if(1&e){const t=ue();v(0,"th",25)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("covered_branches",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"covered_branches"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"covered_branches"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"covered_branches"!==t.settings.sortBy)),f(),k(t.translations.covered)}}function u8(e,n){if(1&e){const t=ue();v(0,"th",25)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("total_branches",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"total_branches"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"total_branches"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"total_branches"!==t.settings.sortBy)),f(),k(t.translations.total)}}function d8(e,n){if(1&e){const t=ue();v(0,"th",26)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("branchcoverage",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"branchcoverage"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"branchcoverage"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"branchcoverage"!==t.settings.sortBy)),f(),k(t.translations.percentage)}}function f8(e,n){if(1&e){const t=ue();v(0,"th",25)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("covered_methods",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"covered_methods"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"covered_methods"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"covered_methods"!==t.settings.sortBy)),f(),k(t.translations.covered)}}function h8(e,n){if(1&e){const t=ue();v(0,"th",25)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("total_methods",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"total_methods"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"total_methods"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"total_methods"!==t.settings.sortBy)),f(),k(t.translations.total)}}function g8(e,n){if(1&e){const t=ue();v(0,"th",26)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("methodcoverage",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"methodcoverage"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"methodcoverage"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"methodcoverage"!==t.settings.sortBy)),f(),k(t.translations.percentage)}}function p8(e,n){if(1&e){const t=ue();v(0,"th",25)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("fullycovered_methods",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"fullycovered_methods"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"fullycovered_methods"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"fullycovered_methods"!==t.settings.sortBy)),f(),k(t.translations.covered)}}function m8(e,n){if(1&e){const t=ue();v(0,"th",25)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("total_methods",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"total_methods"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"total_methods"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"total_methods"!==t.settings.sortBy)),f(),k(t.translations.total)}}function _8(e,n){if(1&e){const t=ue();v(0,"th",26)(1,"a",2),U("click",function(i){return B(t),j(m(2).updateSorting("methodfullcoverage",i))}),O(2,"i",24),D(3),_()()}if(2&e){const t=m(2);f(2),A("ngClass",Ne(2,it,"methodfullcoverage"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"methodfullcoverage"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"methodfullcoverage"!==t.settings.sortBy)),f(),k(t.translations.percentage)}}function v8(e,n){if(1&e){const t=ue();v(0,"th")(1,"a",2),U("click",function(i){const r=B(t).$implicit;return j(m(2).updateSorting(r.abbreviation,i))}),O(2,"i",24),D(3),_(),v(4,"a",41),O(5,"i",42),_()()}if(2&e){const t=n.$implicit,o=m(2);f(2),A("ngClass",Ne(4,it,o.settings.sortBy===t.abbreviation&&"asc"===o.settings.sortOrder,o.settings.sortBy===t.abbreviation&&"desc"===o.settings.sortOrder,o.settings.sortBy!==t.abbreviation)),f(),k(t.name),f(),A("href",On(t.explanationUrl),Wn)}}function y8(e,n){if(1&e&&O(0,"tr",43),2&e){const t=m().$implicit,o=m(2);A("element",t)("collapsed",t.collapsed)("lineCoverageAvailable",o.settings.showLineCoverage)("branchCoverageAvailable",o.branchCoverageAvailable&&o.settings.showBranchCoverage)("methodCoverageAvailable",o.methodCoverageAvailable&&o.settings.showMethodCoverage)("methodFullCoverageAvailable",o.methodCoverageAvailable&&o.settings.showFullMethodCoverage)("visibleMetrics",o.settings.visibleMetrics)}}function C8(e,n){if(1&e&&O(0,"tr",44),2&e){const t=m().$implicit,o=m(3);A("clazz",t)("translations",o.translations)("lineCoverageAvailable",o.settings.showLineCoverage)("branchCoverageAvailable",o.branchCoverageAvailable&&o.settings.showBranchCoverage)("methodCoverageAvailable",o.methodCoverageAvailable&&o.settings.showMethodCoverage)("methodFullCoverageAvailable",o.methodCoverageAvailable&&o.settings.showFullMethodCoverage)("visibleMetrics",o.settings.visibleMetrics)("historyComparisionDate",o.settings.historyComparisionDate)}}function b8(e,n){if(1&e&&y(0,C8,1,8,"tr",44),2&e){const t=n.$implicit,o=m().$implicit,i=m(2);C(!o.collapsed&&t.visible(i.settings)?0:-1)}}function D8(e,n){if(1&e&&O(0,"tr",46),2&e){const t=m().$implicit,o=m(5);A("clazz",t)("translations",o.translations)("lineCoverageAvailable",o.settings.showLineCoverage)("branchCoverageAvailable",o.branchCoverageAvailable&&o.settings.showBranchCoverage)("methodCoverageAvailable",o.methodCoverageAvailable&&o.settings.showMethodCoverage)("methodFullCoverageAvailable",o.methodCoverageAvailable&&o.settings.showFullMethodCoverage)("visibleMetrics",o.settings.visibleMetrics)("historyComparisionDate",o.settings.historyComparisionDate)}}function w8(e,n){if(1&e&&y(0,D8,1,8,"tr",46),2&e){const t=n.$implicit,o=m(2).$implicit,i=m(3);C(!o.collapsed&&t.visible(i.settings)?0:-1)}}function E8(e,n){if(1&e&&(O(0,"tr",45),Qe(1,w8,1,1,null,null,Ye)),2&e){const t=m().$implicit,o=m(3);A("element",t)("collapsed",t.collapsed)("lineCoverageAvailable",o.settings.showLineCoverage)("branchCoverageAvailable",o.branchCoverageAvailable&&o.settings.showBranchCoverage)("methodCoverageAvailable",o.methodCoverageAvailable&&o.settings.showMethodCoverage)("methodFullCoverageAvailable",o.methodCoverageAvailable&&o.settings.showFullMethodCoverage)("visibleMetrics",o.settings.visibleMetrics),f(),Ke(t.classes)}}function M8(e,n){if(1&e&&y(0,E8,3,7),2&e){const t=n.$implicit,o=m().$implicit,i=m(2);C(!o.collapsed&&t.visible(i.settings)?0:-1)}}function I8(e,n){if(1&e&&(y(0,y8,1,7,"tr",43),Qe(1,b8,1,1,null,null,Ye),Qe(3,M8,1,1,null,null,Ye)),2&e){const t=n.$implicit,o=m(2);C(t.visible(o.settings)?0:-1),f(),Ke(t.classes),f(2),Ke(t.subElements)}}function T8(e,n){if(1&e){const t=ue();v(0,"div"),y(1,p$,1,10,"popup",0),v(2,"div",1)(3,"div")(4,"a",2),U("click",function(i){return B(t),j(m().collapseAll(i))}),D(5),_(),D(6," | "),v(7,"a",2),U("click",function(i){return B(t),j(m().expandAll(i))}),D(8),_()(),v(9,"div",3)(10,"span",4),y(11,m$,1,1),y(12,_$,1,1),y(13,v$,1,1),_(),O(14,"br"),D(15),v(16,"input",5),Ge("ngModelChange",function(i){B(t);const r=m();return ye(r.settings.grouping,i)||(r.settings.grouping=i),j(i)}),U("ngModelChange",function(){return B(t),j(m().updateCoverageInfo())}),_()(),v(17,"div",3),y(18,S$,9,5),_(),v(19,"div",6)(20,"button",7),U("click",function(){return B(t),j(m().popupVisible=!0)}),O(21,"i",8),D(22),_()()(),v(23,"div",9)(24,"table",10)(25,"colgroup"),O(26,"col",11),y(27,A$,1,0,"col",12),y(28,N$,1,0,"col",13),y(29,O$,1,0,"col",14),y(30,x$,1,0,"col",15),y(31,R$,1,0,"col",16),y(32,k$,1,0,"col",17),y(33,F$,1,0,"col",12),y(34,L$,1,0,"col",15),y(35,P$,1,0,"col",16),y(36,V$,1,0,"col",17),y(37,H$,1,0,"col",12),y(38,B$,1,0,"col",15),y(39,j$,1,0,"col",16),y(40,U$,1,0,"col",17),y(41,$$,1,0,"col",12),y(42,z$,1,0,"col",15),y(43,G$,1,0,"col",16),y(44,W$,1,0,"col",17),Qe(45,q$,1,0,"col",17,Ye),_(),v(47,"thead")(48,"tr",18),O(49,"th"),y(50,Z$,2,1,"th",19),y(51,Y$,2,1,"th",20),y(52,Q$,2,1,"th",20),y(53,K$,2,1,"th",20),y(54,J$,2,2,"th",21),_(),v(55,"tr",22)(56,"td")(57,"input",23),Ge("ngModelChange",function(i){B(t);const r=m();return ye(r.settings.filter,i)||(r.settings.filter=i),j(i)}),_()(),y(58,X$,2,3,"td",19),y(59,e8,2,3,"td",20),y(60,t8,2,3,"td",20),y(61,n8,2,3,"td",20),y(62,o8,1,1,"td",21),_(),v(63,"tr")(64,"th")(65,"a",2),U("click",function(i){return B(t),j(m().updateSorting("name",i))}),O(66,"i",24),D(67),_()(),y(68,i8,4,6,"th",25),y(69,r8,4,6,"th",25),y(70,s8,4,6,"th",25),y(71,a8,4,6,"th",25),y(72,l8,4,6,"th",26),y(73,c8,4,6,"th",25),y(74,u8,4,6,"th",25),y(75,d8,4,6,"th",26),y(76,f8,4,6,"th",25),y(77,h8,4,6,"th",25),y(78,g8,4,6,"th",26),y(79,p8,4,6,"th",25),y(80,m8,4,6,"th",25),y(81,_8,4,6,"th",26),Qe(82,v8,6,8,"th",null,Ye),_()(),v(84,"tbody"),Qe(85,I8,5,1,null,null,Ye),_()()()()}if(2&e){const t=m();f(),C(t.popupVisible?1:-1),f(4),k(t.translations.collapseAll),f(3),k(t.translations.expandAll),f(3),C(-1===t.settings.grouping?11:-1),f(),C(0===t.settings.grouping?12:-1),f(),C(t.settings.grouping>0?13:-1),f(2),P(" ",t.translations.grouping," "),f(),A("max",t.settings.groupingMaximum),je("ngModel",t.settings.grouping),f(2),C(t.historicCoverageExecutionTimes.length>0?18:-1),f(4),k(t.metrics.length>0?t.translations.selectCoverageTypesAndMetrics:t.translations.selectCoverageTypes),f(5),C(t.settings.showLineCoverage?27:-1),f(),C(t.settings.showLineCoverage?28:-1),f(),C(t.settings.showLineCoverage?29:-1),f(),C(t.settings.showLineCoverage?30:-1),f(),C(t.settings.showLineCoverage?31:-1),f(),C(t.settings.showLineCoverage?32:-1),f(),C(t.branchCoverageAvailable&&t.settings.showBranchCoverage?33:-1),f(),C(t.branchCoverageAvailable&&t.settings.showBranchCoverage?34:-1),f(),C(t.branchCoverageAvailable&&t.settings.showBranchCoverage?35:-1),f(),C(t.branchCoverageAvailable&&t.settings.showBranchCoverage?36:-1),f(),C(t.methodCoverageAvailable&&t.settings.showMethodCoverage?37:-1),f(),C(t.methodCoverageAvailable&&t.settings.showMethodCoverage?38:-1),f(),C(t.methodCoverageAvailable&&t.settings.showMethodCoverage?39:-1),f(),C(t.methodCoverageAvailable&&t.settings.showMethodCoverage?40:-1),f(),C(t.methodCoverageAvailable&&t.settings.showFullMethodCoverage?41:-1),f(),C(t.methodCoverageAvailable&&t.settings.showFullMethodCoverage?42:-1),f(),C(t.methodCoverageAvailable&&t.settings.showFullMethodCoverage?43:-1),f(),C(t.methodCoverageAvailable&&t.settings.showFullMethodCoverage?44:-1),f(),Ke(t.settings.visibleMetrics),f(5),C(t.settings.showLineCoverage?50:-1),f(),C(t.branchCoverageAvailable&&t.settings.showBranchCoverage?51:-1),f(),C(t.methodCoverageAvailable&&t.settings.showMethodCoverage?52:-1),f(),C(t.methodCoverageAvailable&&t.settings.showFullMethodCoverage?53:-1),f(),C(t.settings.visibleMetrics.length>0?54:-1),f(3),A("placeholder",On(t.translations.filter)),je("ngModel",t.settings.filter),f(),C(t.settings.showLineCoverage?58:-1),f(),C(t.branchCoverageAvailable&&t.settings.showBranchCoverage?59:-1),f(),C(t.methodCoverageAvailable&&t.settings.showMethodCoverage?60:-1),f(),C(t.methodCoverageAvailable&&t.settings.showFullMethodCoverage?61:-1),f(),C(t.settings.visibleMetrics.length>0?62:-1),f(4),A("ngClass",Ne(58,it,"name"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"name"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"name"!==t.settings.sortBy)),f(),k(t.translations.name),f(),C(t.settings.showLineCoverage?68:-1),f(),C(t.settings.showLineCoverage?69:-1),f(),C(t.settings.showLineCoverage?70:-1),f(),C(t.settings.showLineCoverage?71:-1),f(),C(t.settings.showLineCoverage?72:-1),f(),C(t.branchCoverageAvailable&&t.settings.showBranchCoverage?73:-1),f(),C(t.branchCoverageAvailable&&t.settings.showBranchCoverage?74:-1),f(),C(t.branchCoverageAvailable&&t.settings.showBranchCoverage?75:-1),f(),C(t.methodCoverageAvailable&&t.settings.showMethodCoverage?76:-1),f(),C(t.methodCoverageAvailable&&t.settings.showMethodCoverage?77:-1),f(),C(t.methodCoverageAvailable&&t.settings.showMethodCoverage?78:-1),f(),C(t.methodCoverageAvailable&&t.settings.showFullMethodCoverage?79:-1),f(),C(t.methodCoverageAvailable&&t.settings.showFullMethodCoverage?80:-1),f(),C(t.methodCoverageAvailable&&t.settings.showFullMethodCoverage?81:-1),f(),Ke(t.settings.visibleMetrics),f(3),Ke(t.codeElements)}}let S8=(()=>{var e;class n{constructor(o){this.queryString="",this.historicCoverageExecutionTimes=[],this.branchCoverageAvailable=!1,this.methodCoverageAvailable=!1,this.metrics=[],this.codeElements=[],this.translations={},this.popupVisible=!1,this.settings=new AU,this.sliderOptions={floor:0,ceil:100,step:1,ticksArray:[0,10,20,30,40,50,60,70,80,90,100],showTicks:!0},this.window=o.nativeWindow}ngOnInit(){this.historicCoverageExecutionTimes=this.window.historicCoverageExecutionTimes,this.branchCoverageAvailable=this.window.branchCoverageAvailable,this.methodCoverageAvailable=this.window.methodCoverageAvailable,this.metrics=this.window.metrics,this.translations=this.window.translations,kt.maximumDecimalPlacesForCoverageQuotas=this.window.maximumDecimalPlacesForCoverageQuotas;let o=!1;if(void 0!==this.window.history&&void 0!==this.window.history.replaceState&&null!==this.window.history.state&&null!=this.window.history.state.coverageInfoSettings)console.log("Coverage info: Restoring from history",this.window.history.state.coverageInfoSettings),o=!0,this.settings=JSON.parse(JSON.stringify(this.window.history.state.coverageInfoSettings));else{let r=0,s=this.window.assemblies;for(let a=0;a-1&&(this.queryString=window.location.href.substring(i)),this.updateCoverageInfo(),o&&this.restoreCollapseState()}onBeforeUnload(){if(this.saveCollapseState(),void 0!==this.window.history&&void 0!==this.window.history.replaceState){console.log("Coverage info: Updating history",this.settings);let o=new lI;null!==window.history.state&&(o=JSON.parse(JSON.stringify(this.window.history.state))),o.coverageInfoSettings=JSON.parse(JSON.stringify(this.settings)),window.history.replaceState(o,"")}}updateCoverageInfo(){let o=(new Date).getTime(),i=this.window.assemblies,r=[],s=0;if(0===this.settings.grouping)for(let c=0;c{for(let r=0;r{for(let s=0;so&&(r[s].collapsed=this.settings.collapseStates[o]),o++,i(r[s].subElements)};i(this.codeElements)}static#e=e=()=>(this.\u0275fac=function(i){return new(i||n)(x(jg))},this.\u0275cmp=qt({type:n,selectors:[["coverage-info"]],hostBindings:function(i,r){1&i&&U("beforeunload",function(){return r.onBeforeUnload()},Ba)},standalone:!1,decls:1,vars:1,consts:[[3,"visible","translations","branchCoverageAvailable","methodCoverageAvailable","metrics","showLineCoverage","showBranchCoverage","showMethodCoverage","showMethodFullCoverage","visibleMetrics"],[1,"customizebox"],["href","#",3,"click"],[1,"col-center"],[1,"slider-label"],["type","range","step","1","min","-1",3,"ngModelChange","max","ngModel"],[1,"col-right","right"],["type","button",3,"click"],[1,"icon-cog"],[1,"table-responsive"],[1,"overview","table-fixed","stripped"],[1,"column-min-200"],[1,"column90"],[1,"column105"],[1,"column100"],[1,"column70"],[1,"column98"],[1,"column112"],[1,"header"],["colspan","6",1,"center"],["colspan","4",1,"center"],[1,"center"],[1,"filterbar"],["type","search",3,"ngModelChange","ngModel","placeholder"],[3,"ngClass"],[1,"right"],["colspan","2",1,"center"],[3,"visibleChange","showLineCoverageChange","showBranchCoverageChange","showMethodCoverageChange","showMethodFullCoverageChange","visibleMetricsChange","visible","translations","branchCoverageAvailable","methodCoverageAvailable","metrics","showLineCoverage","showBranchCoverage","showMethodCoverage","showMethodFullCoverage","visibleMetrics"],[3,"ngModelChange","ngModel"],["value",""],[3,"value"],["value","allChanges"],["value","lineCoverageIncreaseOnly"],["value","lineCoverageDecreaseOnly"],["value","branchCoverageIncreaseOnly"],["value","branchCoverageDecreaseOnly"],["value","methodCoverageIncreaseOnly"],["value","methodCoverageDecreaseOnly"],["value","fullMethodCoverageIncreaseOnly"],["value","fullMethodCoverageDecreaseOnly"],[3,"valueChange","highValueChange","value","highValue","options"],["target","_blank",3,"href"],[1,"icon-info-circled"],["codeelement-row","",3,"element","collapsed","lineCoverageAvailable","branchCoverageAvailable","methodCoverageAvailable","methodFullCoverageAvailable","visibleMetrics"],["class-row","",3,"clazz","translations","lineCoverageAvailable","branchCoverageAvailable","methodCoverageAvailable","methodFullCoverageAvailable","visibleMetrics","historyComparisionDate"],["codeelement-row","",1,"namespace",3,"element","collapsed","lineCoverageAvailable","branchCoverageAvailable","methodCoverageAvailable","methodFullCoverageAvailable","visibleMetrics"],["class-row","",1,"namespace",3,"clazz","translations","lineCoverageAvailable","branchCoverageAvailable","methodCoverageAvailable","methodFullCoverageAvailable","visibleMetrics","historyComparisionDate"]],template:function(i,r){1&i&&y(0,T8,87,62,"div"),2&i&&C(r.codeElements.length>0?0:-1)},dependencies:[Xi,kg,Lg,As,Rg,Ls,vc,ks,aI,BU,d3,g$],encapsulation:2}))}return e(),n})();class A8{constructor(){this.assembly="",this.numberOfRiskHotspots=10,this.filter="",this.sortBy="",this.sortOrder="asc"}}const Pc=(e,n,t)=>({"icon-up-dir_active":e,"icon-down-dir_active":n,"icon-up-down-dir":t}),N8=(e,n)=>({lightred:e,lightgreen:n});function O8(e,n){if(1&e&&(v(0,"option",3),D(1),_()),2&e){const t=n.$implicit;A("value",t),f(),k(t)}}function x8(e,n){if(1&e&&(v(0,"span"),D(1),_()),2&e){const t=m(2);f(),k(t.translations.top)}}function R8(e,n){1&e&&(v(0,"option",16),D(1,"20"),_())}function k8(e,n){1&e&&(v(0,"option",17),D(1,"50"),_())}function F8(e,n){1&e&&(v(0,"option",18),D(1,"100"),_())}function L8(e,n){if(1&e&&(v(0,"option",3),D(1),_()),2&e){const t=m(3);A("value",t.totalNumberOfRiskHotspots),f(),k(t.translations.all)}}function P8(e,n){if(1&e){const t=ue();v(0,"select",14),Ge("ngModelChange",function(i){B(t);const r=m(2);return ye(r.settings.numberOfRiskHotspots,i)||(r.settings.numberOfRiskHotspots=i),j(i)}),v(1,"option",15),D(2,"10"),_(),y(3,R8,2,0,"option",16),y(4,k8,2,0,"option",17),y(5,F8,2,0,"option",18),y(6,L8,2,2,"option",3),_()}if(2&e){const t=m(2);je("ngModel",t.settings.numberOfRiskHotspots),f(3),C(t.totalNumberOfRiskHotspots>10?3:-1),f(),C(t.totalNumberOfRiskHotspots>20?4:-1),f(),C(t.totalNumberOfRiskHotspots>50?5:-1),f(),C(t.totalNumberOfRiskHotspots>100?6:-1)}}function V8(e,n){1&e&&O(0,"col",11)}function H8(e,n){if(1&e){const t=ue();v(0,"th")(1,"a",12),U("click",function(i){const r=B(t).$index;return j(m(2).updateSorting(""+r,i))}),O(2,"i",13),D(3),_(),v(4,"a",19),O(5,"i",20),_()()}if(2&e){const t=n.$implicit,o=n.$index,i=m(2);f(2),A("ngClass",Ne(4,Pc,i.settings.sortBy===""+o&&"asc"===i.settings.sortOrder,i.settings.sortBy===""+o&&"desc"===i.settings.sortOrder,i.settings.sortBy!==""+o)),f(),k(t.name),f(),A("href",On(t.explanationUrl),Wn)}}function B8(e,n){if(1&e&&(v(0,"td",23),D(1),_()),2&e){const t=n.$implicit;A("ngClass",Eh(2,N8,t.exceeded,!t.exceeded)),f(),k(t.value)}}function j8(e,n){if(1&e&&(v(0,"tr")(1,"td"),D(2),_(),v(3,"td")(4,"a",21),D(5),_()(),v(6,"td",22)(7,"a",21),D(8),_()(),Qe(9,B8,2,5,"td",23,Ye),_()),2&e){const t=n.$implicit,o=m(2);f(2),k(t.assembly),f(2),A("href",t.reportPath+o.queryString,Wn),f(),k(t.class),f(),A("title",t.methodName),f(),A("href",t.reportPath+o.queryString+"#file"+t.fileIndex+"_line"+t.line,Wn),f(),P(" ",t.methodShortName," "),f(),Ke(t.metrics)}}function U8(e,n){if(1&e){const t=ue();v(0,"div")(1,"div",0)(2,"div")(3,"select",1),Ge("ngModelChange",function(i){B(t);const r=m();return ye(r.settings.assembly,i)||(r.settings.assembly=i),j(i)}),U("ngModelChange",function(){return B(t),j(m().updateRiskHotpots())}),v(4,"option",2),D(5),_(),Qe(6,O8,2,2,"option",3,Ye),_()(),v(8,"div",4),y(9,x8,2,1,"span"),y(10,P8,7,5,"select",5),_(),O(11,"div",4),v(12,"div",6)(13,"span"),D(14),_(),v(15,"input",7),Ge("ngModelChange",function(i){B(t);const r=m();return ye(r.settings.filter,i)||(r.settings.filter=i),j(i)}),U("ngModelChange",function(){return B(t),j(m().updateRiskHotpots())}),_()()(),v(16,"div",8)(17,"table",9)(18,"colgroup"),O(19,"col",10)(20,"col",10)(21,"col",10),Qe(22,V8,1,0,"col",11,Ye),_(),v(24,"thead")(25,"tr")(26,"th")(27,"a",12),U("click",function(i){return B(t),j(m().updateSorting("assembly",i))}),O(28,"i",13),D(29),_()(),v(30,"th")(31,"a",12),U("click",function(i){return B(t),j(m().updateSorting("class",i))}),O(32,"i",13),D(33),_()(),v(34,"th")(35,"a",12),U("click",function(i){return B(t),j(m().updateSorting("method",i))}),O(36,"i",13),D(37),_()(),Qe(38,H8,6,8,"th",null,Ye),_()(),v(40,"tbody"),Qe(41,j8,11,6,"tr",null,Ye),function PD(e,n){const t=K();let o;const i=e+H;t.firstCreatePass?(o=function JL(e,n){if(n)for(let t=n.length-1;t>=0;t--){const o=n[t];if(e===o.name)return o}}(n,t.pipeRegistry),t.data[i]=o,o.onDestroy&&(t.destroyHooks??=[]).push(i,o.onDestroy)):o=t.data[i];const r=o.factory||(o.factory=po(o.type)),a=pt(x);try{const l=_a(!1),c=r();return _a(l),function Iu(e,n,t,o){t>=e.data.length&&(e.data[t]=null,e.blueprint[t]=null),n[t]=o}(t,w(),i,c),c}finally{pt(a)}}(43,"slice"),_()()()()}if(2&e){const t=m();f(3),je("ngModel",t.settings.assembly),f(2),k(t.translations.assembly),f(),Ke(t.assemblies),f(3),C(t.totalNumberOfRiskHotspots>10?9:-1),f(),C(t.totalNumberOfRiskHotspots>10?10:-1),f(4),P("",t.translations.filter," "),f(),je("ngModel",t.settings.filter),f(7),Ke(t.riskHotspotMetrics),f(6),A("ngClass",Ne(16,Pc,"assembly"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"assembly"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"assembly"!==t.settings.sortBy)),f(),k(t.translations.assembly),f(3),A("ngClass",Ne(20,Pc,"class"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"class"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"class"!==t.settings.sortBy)),f(),k(t.translations.class),f(3),A("ngClass",Ne(24,Pc,"method"===t.settings.sortBy&&"asc"===t.settings.sortOrder,"method"===t.settings.sortBy&&"desc"===t.settings.sortOrder,"method"!==t.settings.sortBy)),f(),k(t.translations.method),f(),Ke(t.riskHotspotMetrics),f(3),Ke(function VD(e,n,t,o,i){const r=e+H,s=w(),a=function bo(e,n){return e[n]}(s,r);return function bs(e,n){return e[1].data[n].pure}(s,r)?kD(s,lt(),n,a.transform,t,o,i,a):a.transform(t,o,i)}(43,12,t.riskHotspots,0,t.settings.numberOfRiskHotspots))}}let $8=(()=>{var e;class n{constructor(o){this.queryString="",this.riskHotspotMetrics=[],this.riskHotspots=[],this.totalNumberOfRiskHotspots=0,this.assemblies=[],this.translations={},this.settings=new A8,this.window=o.nativeWindow}ngOnInit(){this.riskHotspotMetrics=this.window.riskHotspotMetrics,this.translations=this.window.translations,void 0!==this.window.history&&void 0!==this.window.history.replaceState&&null!==this.window.history.state&&null!=this.window.history.state.riskHotspotsSettings&&(console.log("Risk hotspots: Restoring from history",this.window.history.state.riskHotspotsSettings),this.settings=JSON.parse(JSON.stringify(this.window.history.state.riskHotspotsSettings)));const o=window.location.href.indexOf("?");o>-1&&(this.queryString=window.location.href.substring(o)),this.updateRiskHotpots()}onDonBeforeUnlodad(){if(void 0!==this.window.history&&void 0!==this.window.history.replaceState){console.log("Risk hotspots: Updating history",this.settings);let o=new lI;null!==window.history.state&&(o=JSON.parse(JSON.stringify(this.window.history.state))),o.riskHotspotsSettings=JSON.parse(JSON.stringify(this.settings)),window.history.replaceState(o,"")}}updateRiskHotpots(){const o=this.window.riskHotspots;if(this.totalNumberOfRiskHotspots=o.length,0===this.assemblies.length){let a=[];for(let l=0;l(this.\u0275fac=function(i){return new(i||n)(x(jg))},this.\u0275cmp=qt({type:n,selectors:[["risk-hotspots"]],hostBindings:function(i,r){1&i&&U("beforeunload",function(){return r.onDonBeforeUnlodad()},Ba)},standalone:!1,decls:1,vars:1,consts:[[1,"customizebox"],["name","assembly",3,"ngModelChange","ngModel"],["value",""],[3,"value"],[1,"col-center"],[3,"ngModel"],[1,"col-right"],["type","search",3,"ngModelChange","ngModel"],[1,"table-responsive"],[1,"overview","table-fixed","stripped"],[1,"column-min-200"],[1,"column105"],["href","#",3,"click"],[3,"ngClass"],[3,"ngModelChange","ngModel"],["value","10"],["value","20"],["value","50"],["value","100"],["target","_blank",3,"href"],[1,"icon-info-circled"],[3,"href"],[3,"title"],[1,"right",3,"ngClass"]],template:function(i,r){1&i&&y(0,U8,44,28,"div"),2&i&&C(r.totalNumberOfRiskHotspots>0?0:-1)},dependencies:[Xi,kg,Lg,As,Ls,vc,ks,fE],encapsulation:2}))}return e(),n})(),z8=(()=>{var e;class n{static#e=e=()=>(this.\u0275fac=function(i){return new(i||n)},this.\u0275mod=Qn({type:n,bootstrap:[$8,S8]}),this.\u0275inj=dn({providers:[jg],imports:[BH,Hj,SU]}))}return e(),n})();HH().bootstrapModule(z8).catch(e=>console.error(e))}},Yo=>{Yo(Yo.s=653)}]); \ No newline at end of file diff --git a/jobs/Backend/coveragereport/report.css b/jobs/Backend/coveragereport/report.css new file mode 100644 index 0000000000..fed1a219a3 --- /dev/null +++ b/jobs/Backend/coveragereport/report.css @@ -0,0 +1,838 @@ +:root { + color-scheme: light; + --green: #0aad0a; + --lightgreen: #dcf4dc; +} + +html { font-family: sans-serif; margin: 0; padding: 0; font-size: 0.9em; background-color: #d6d6d6; height: 100%; } +body { margin: 0; padding: 0; height: 100%; color: #000; } +h1 { font-family: 'Century Gothic', sans-serif; font-size: 1.2em; font-weight: normal; color: #fff; background-color: #6f6f6f; padding: 10px; margin: 20px -20px 20px -20px; } +h1:first-of-type { margin-top: 0; } +h2 { font-size: 1.0em; font-weight: bold; margin: 10px 0 15px 0; padding: 0; } +h3 { font-size: 1.0em; font-weight: bold; margin: 0 0 10px 0; padding: 0; display: inline-block; } +input, select, button { border: 1px solid #767676; border-radius: 0; } +button { background-color: #ddd; cursor: pointer; } +a { color: #c00; text-decoration: none; } +a:hover { color: #000; text-decoration: none; } +h1 a.back { color: #fff; background-color: #949494; display: inline-block; margin: -12px 5px -10px -10px; padding: 10px; border-right: 1px solid #fff; } +h1 a.back:hover { background-color: #ccc; } +h1 a.button { color: #000; background-color: #bebebe; margin: -5px 0 0 10px; padding: 5px 8px 5px 8px; border: 1px solid #fff; font-size: 0.9em; border-radius: 3px; float:right; } +h1 a.button:hover { background-color: #ccc; } +h1 a.button i { position: relative; top: 1px; } + +.container { margin: auto; max-width: 1650px; width: 90%; background-color: #fff; display: flex; box-shadow: 0 0 60px #7d7d7d; min-height: 100%; } +.containerleft { padding: 0 20px 20px 20px; flex: 1; min-width: 1%; } +.containerright { width: 340px; min-width: 340px; background-color: #e5e5e5; height: 100%; } +.containerrightfixed { position: fixed; padding: 0 20px 20px 20px; border-left: 1px solid #6f6f6f; width: 300px; overflow-y: auto; height: 100%; top: 0; bottom: 0; } +.containerrightfixed h1 { background-color: #c00; } +.containerrightfixed label, .containerright a { white-space: nowrap; overflow: hidden; display: inline-block; width: 100%; max-width: 300px; text-overflow: ellipsis; } +.containerright a { margin-bottom: 3px; } + +@media screen and (max-width:1200px){ + .container { box-shadow: none; width: 100%; } + .containerright { display: none; } +} + +.popup-container { position: fixed; left: 0; right: 0; top: 0; bottom: 0; background-color: rgb(0, 0, 0, 0.6); z-index: 100; } +.popup { position: absolute; top: 50%; right: 50%; transform: translate(50%,-50%); background-color: #fff; padding: 25px; border-radius: 15px; min-width: 300px; } +.popup .close { text-align: right; color: #979797; font-size: 25px;position: relative; left: 10px; bottom: 10px; cursor: pointer; } + +.footer { font-size: 0.7em; text-align: center; margin-top: 35px; } + +.card-group { display: flex; flex-wrap: wrap; margin-top: -15px; margin-left: -15px; } +.card-group + .card-group { margin-top: 0; } +.card-group .card { margin-top: 15px; margin-left: 15px; display: flex; flex-direction: column; background-color: #e4e4e4; background: radial-gradient(circle, #fefefe 0%, #f6f6f6 100%); border: 1px solid #c1c1c1; padding: 15px; color: #6f6f6f; max-width: 100% } +.card-group .card .card-header { font-size: 1.5rem; font-family: 'Century Gothic', sans-serif; margin-bottom: 15px; flex-grow: 1; } +.card-group .card .card-body { display: flex; flex-direction: row; gap: 15px; flex-grow: 1; } +.card-group .card .card-body div.table { display: flex; flex-direction: column; } +.card-group .card .large { font-size: 5rem; line-height: 5rem; font-weight: bold; align-self: flex-end; border-left-width: 4px; padding-left: 10px; } +.card-group .card table { align-self: flex-end; border-collapse: collapse; } +.card-group .card table tr { border-bottom: 1px solid #c1c1c1; } +.card-group .card table tr:hover { background-color: #c1c1c1; } +.card-group .card table tr:last-child { border-bottom: none; } +.card-group .card table th, .card-group .card table td { padding: 2px; } +.card-group td.limit-width { max-width: 200px; text-overflow: ellipsis; overflow: hidden; } +.card-group td.overflow-wrap { overflow-wrap: anywhere; } + +.pro-button { color: #fff; background-color: #20A0D2; background-image: linear-gradient(50deg, #1c7ed6 0%, #23b8cf 100%); padding: 10px; border-radius: 3px; font-weight: bold; display: inline-block; } +.pro-button:hover { color: #fff; background-color: #1C8EB7; background-image: linear-gradient(50deg, #1A6FBA 0%, #1EA1B5 100%); } +.pro-button-tiny { border-radius: 10px; padding: 3px 8px; } + +th { text-align: left; } +.table-fixed { table-layout: fixed; } +.table-responsive { overflow-x: auto; } +.table-responsive::-webkit-scrollbar { height: 20px; } +.table-responsive::-webkit-scrollbar-thumb { background-color: #6f6f6f; border-radius: 20px; border: 5px solid #fff; } +.overview { border: 1px solid #c1c1c1; border-collapse: collapse; width: 100%; word-wrap: break-word; } +.overview th { border: 1px solid #c1c1c1; border-collapse: collapse; padding: 2px 4px 2px 4px; background-color: #ddd; } +.overview tr.namespace th { background-color: #dcdcdc; } +.overview thead th { background-color: #d1d1d1; } +.overview th a { color: #000; } +.overview tr.namespace a { margin-left: 15px; display: block; } +.overview td { border: 1px solid #c1c1c1; border-collapse: collapse; padding: 2px 5px 2px 5px; } +.overview tr.filterbar td { height: 60px; } +.overview tr.header th { background-color: #d1d1d1; } +.overview tr.header th:nth-child(2n+1) { background-color: #ddd; } +.overview tr.header th:first-child { border-left: 1px solid #fff; border-top: 1px solid #fff; background-color: #fff; } +.overview tbody tr:hover>td { background-color: #b0b0b0; } + +div.currenthistory { margin: -2px -5px 0 -5px; padding: 2px 5px 2px 5px; height: 16px; } +.coverage { border-collapse: collapse; font-size: 5px; height: 10px; } +.coverage td { padding: 0; border: none; } +.stripped tr:nth-child(2n+1) { background-color: #F3F3F3; } + +.customizebox { font-size: 0.75em; margin-bottom: 7px; display: grid; grid-template-columns: 1fr; grid-template-rows: auto auto auto auto; grid-column-gap: 10px; grid-row-gap: 10px; } +.customizebox>div { align-self: end; } +.customizebox div.col-right input { width: 150px; } + +@media screen and (min-width: 1000px) { + .customizebox { grid-template-columns: repeat(4, 1fr); grid-template-rows: 1fr; } + .customizebox div.col-center { justify-self: center; } + .customizebox div.col-right { justify-self: end; } +} +.slider-label { position: relative; left: 85px; } + +.percentagebar { + padding-left: 3px; +} +a.percentagebar { + padding-left: 6px; +} +.percentagebarundefined { + border-left: 2px solid #fff; +} +.percentagebar0 { + border-left: 2px solid #c10909; +} +.percentagebar10 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 90%, var(--green) 90%, var(--green) 100%) 1; +} +.percentagebar20 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 80%, var(--green) 80%, var(--green) 100%) 1; +} +.percentagebar30 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 70%, var(--green) 70%, var(--green) 100%) 1; +} +.percentagebar40 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 60%, var(--green) 60%, var(--green) 100%) 1; +} +.percentagebar50 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 50%, var(--green) 50%, var(--green) 100%) 1; +} +.percentagebar60 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 40%, var(--green) 40%, var(--green) 100%) 1; +} +.percentagebar70 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 30%, var(--green) 30%, var(--green) 100%) 1; +} +.percentagebar80 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 20%, var(--green) 20%, var(--green) 100%) 1; +} +.percentagebar90 { + border-left: 2px solid; + border-image: linear-gradient(to bottom, #c10909 10%, var(--green) 10%, var(--green) 100%) 1; +} +.percentagebar100 { + border-left: 2px solid var(--green); +} + +.mt-1 { margin-top: 4px; } +.hidden, .ng-hide { display: none; } +.right { text-align: right; } +.center { text-align: center; } +.rightmargin { padding-right: 8px; } +.leftmargin { padding-left: 5px; } +.green { background-color: var(--green); } +.lightgreen { background-color: var(--lightgreen); } +.red { background-color: #c10909; } +.lightred { background-color: #f7dede; } +.orange { background-color: #FFA500; } +.lightorange { background-color: #FFEFD5; } +.gray { background-color: #dcdcdc; } +.lightgray { color: #888888; } +.lightgraybg { background-color: #dadada; } + +code { font-family: Consolas, monospace; font-size: 0.9em; } + +.toggleZoom { text-align:right; } + +.historychart svg { max-width: 100%; } +.ct-chart { position: relative; } +.ct-chart .ct-line { stroke-width: 2px !important; } +.ct-chart .ct-point { stroke-width: 6px !important; transition: stroke-width .2s; } +.ct-chart .ct-point:hover { stroke-width: 10px !important; } +.ct-chart .ct-series.ct-series-a .ct-line, .ct-chart .ct-series.ct-series-a .ct-point { stroke: #c00 !important;} +.ct-chart .ct-series.ct-series-b .ct-line, .ct-chart .ct-series.ct-series-b .ct-point { stroke: #1c2298 !important;} +.ct-chart .ct-series.ct-series-c .ct-line, .ct-chart .ct-series.ct-series-c .ct-point { stroke: #0aad0a !important;} +.ct-chart .ct-series.ct-series-d .ct-line, .ct-chart .ct-series.ct-series-d .ct-point { stroke: #FF6A00 !important;} + +.tinylinecoveragechart, .tinybranchcoveragechart, .tinymethodcoveragechart, .tinyfullmethodcoveragechart { background-color: #fff; margin-left: -3px; float: left; border: 1px solid #c1c1c1; width: 30px; height: 18px; } +.historiccoverageoffset { margin-top: 7px; } + +.tinylinecoveragechart .ct-line, .tinybranchcoveragechart .ct-line, .tinymethodcoveragechart .ct-line, .tinyfullmethodcoveragechart .ct-line { stroke-width: 1px !important; } +.tinybranchcoveragechart .ct-series.ct-series-a .ct-line { stroke: #1c2298 !important; } +.tinymethodcoveragechart .ct-series.ct-series-a .ct-line { stroke: #0aad0a !important; } +.tinyfullmethodcoveragechart .ct-series.ct-series-a .ct-line { stroke: #FF6A00 !important; } + +.linecoverage { background-color: #c00; width: 10px; height: 8px; border: 1px solid #000; display: inline-block; } +.branchcoverage { background-color: #1c2298; width: 10px; height: 8px; border: 1px solid #000; display: inline-block; } +.codeelementcoverage { background-color: #0aad0a; width: 10px; height: 8px; border: 1px solid #000; display: inline-block; } +.fullcodeelementcoverage { background-color: #FF6A00; width: 10px; height: 8px; border: 1px solid #000; display: inline-block; } + +.tooltip { position: absolute; display: none; padding: 5px; background: #F4C63D; color: #453D3F; pointer-events: none; z-index: 1; min-width: 250px; } + +.column-min-200 { min-width: 200px; } +.column70 { width: 70px; } +.column90 { width: 90px; } +.column98 { width: 98px; } +.column100 { width: 100px; } +.column105 { width: 105px; } +.column112 { width: 112px; } + +.cardpercentagebar { border-left-style: solid; } +.cardpercentagebar0 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 0%, var(--green) 0%) 1; } +.cardpercentagebar1 { border-image: linear-gradient(to bottom, #c10909 1%, #c10909 1%, var(--green) 1%) 1; } +.cardpercentagebar2 { border-image: linear-gradient(to bottom, #c10909 2%, #c10909 2%, var(--green) 2%) 1; } +.cardpercentagebar3 { border-image: linear-gradient(to bottom, #c10909 3%, #c10909 3%, var(--green) 3%) 1; } +.cardpercentagebar4 { border-image: linear-gradient(to bottom, #c10909 4%, #c10909 4%, var(--green) 4%) 1; } +.cardpercentagebar5 { border-image: linear-gradient(to bottom, #c10909 5%, #c10909 5%, var(--green) 5%) 1; } +.cardpercentagebar6 { border-image: linear-gradient(to bottom, #c10909 6%, #c10909 6%, var(--green) 6%) 1; } +.cardpercentagebar7 { border-image: linear-gradient(to bottom, #c10909 7%, #c10909 7%, var(--green) 7%) 1; } +.cardpercentagebar8 { border-image: linear-gradient(to bottom, #c10909 8%, #c10909 8%, var(--green) 8%) 1; } +.cardpercentagebar9 { border-image: linear-gradient(to bottom, #c10909 9%, #c10909 9%, var(--green) 9%) 1; } +.cardpercentagebar10 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 10%, var(--green) 10%) 1; } +.cardpercentagebar11 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 11%, var(--green) 11%) 1; } +.cardpercentagebar12 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 12%, var(--green) 12%) 1; } +.cardpercentagebar13 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 13%, var(--green) 13%) 1; } +.cardpercentagebar14 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 14%, var(--green) 14%) 1; } +.cardpercentagebar15 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 15%, var(--green) 15%) 1; } +.cardpercentagebar16 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 16%, var(--green) 16%) 1; } +.cardpercentagebar17 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 17%, var(--green) 17%) 1; } +.cardpercentagebar18 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 18%, var(--green) 18%) 1; } +.cardpercentagebar19 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 19%, var(--green) 19%) 1; } +.cardpercentagebar20 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 20%, var(--green) 20%) 1; } +.cardpercentagebar21 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 21%, var(--green) 21%) 1; } +.cardpercentagebar22 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 22%, var(--green) 22%) 1; } +.cardpercentagebar23 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 23%, var(--green) 23%) 1; } +.cardpercentagebar24 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 24%, var(--green) 24%) 1; } +.cardpercentagebar25 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 25%, var(--green) 25%) 1; } +.cardpercentagebar26 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 26%, var(--green) 26%) 1; } +.cardpercentagebar27 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 27%, var(--green) 27%) 1; } +.cardpercentagebar28 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 28%, var(--green) 28%) 1; } +.cardpercentagebar29 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 29%, var(--green) 29%) 1; } +.cardpercentagebar30 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 30%, var(--green) 30%) 1; } +.cardpercentagebar31 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 31%, var(--green) 31%) 1; } +.cardpercentagebar32 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 32%, var(--green) 32%) 1; } +.cardpercentagebar33 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 33%, var(--green) 33%) 1; } +.cardpercentagebar34 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 34%, var(--green) 34%) 1; } +.cardpercentagebar35 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 35%, var(--green) 35%) 1; } +.cardpercentagebar36 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 36%, var(--green) 36%) 1; } +.cardpercentagebar37 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 37%, var(--green) 37%) 1; } +.cardpercentagebar38 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 38%, var(--green) 38%) 1; } +.cardpercentagebar39 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 39%, var(--green) 39%) 1; } +.cardpercentagebar40 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 40%, var(--green) 40%) 1; } +.cardpercentagebar41 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 41%, var(--green) 41%) 1; } +.cardpercentagebar42 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 42%, var(--green) 42%) 1; } +.cardpercentagebar43 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 43%, var(--green) 43%) 1; } +.cardpercentagebar44 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 44%, var(--green) 44%) 1; } +.cardpercentagebar45 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 45%, var(--green) 45%) 1; } +.cardpercentagebar46 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 46%, var(--green) 46%) 1; } +.cardpercentagebar47 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 47%, var(--green) 47%) 1; } +.cardpercentagebar48 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 48%, var(--green) 48%) 1; } +.cardpercentagebar49 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 49%, var(--green) 49%) 1; } +.cardpercentagebar50 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 50%, var(--green) 50%) 1; } +.cardpercentagebar51 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 51%, var(--green) 51%) 1; } +.cardpercentagebar52 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 52%, var(--green) 52%) 1; } +.cardpercentagebar53 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 53%, var(--green) 53%) 1; } +.cardpercentagebar54 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 54%, var(--green) 54%) 1; } +.cardpercentagebar55 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 55%, var(--green) 55%) 1; } +.cardpercentagebar56 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 56%, var(--green) 56%) 1; } +.cardpercentagebar57 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 57%, var(--green) 57%) 1; } +.cardpercentagebar58 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 58%, var(--green) 58%) 1; } +.cardpercentagebar59 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 59%, var(--green) 59%) 1; } +.cardpercentagebar60 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 60%, var(--green) 60%) 1; } +.cardpercentagebar61 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 61%, var(--green) 61%) 1; } +.cardpercentagebar62 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 62%, var(--green) 62%) 1; } +.cardpercentagebar63 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 63%, var(--green) 63%) 1; } +.cardpercentagebar64 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 64%, var(--green) 64%) 1; } +.cardpercentagebar65 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 65%, var(--green) 65%) 1; } +.cardpercentagebar66 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 66%, var(--green) 66%) 1; } +.cardpercentagebar67 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 67%, var(--green) 67%) 1; } +.cardpercentagebar68 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 68%, var(--green) 68%) 1; } +.cardpercentagebar69 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 69%, var(--green) 69%) 1; } +.cardpercentagebar70 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 70%, var(--green) 70%) 1; } +.cardpercentagebar71 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 71%, var(--green) 71%) 1; } +.cardpercentagebar72 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 72%, var(--green) 72%) 1; } +.cardpercentagebar73 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 73%, var(--green) 73%) 1; } +.cardpercentagebar74 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 74%, var(--green) 74%) 1; } +.cardpercentagebar75 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 75%, var(--green) 75%) 1; } +.cardpercentagebar76 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 76%, var(--green) 76%) 1; } +.cardpercentagebar77 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 77%, var(--green) 77%) 1; } +.cardpercentagebar78 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 78%, var(--green) 78%) 1; } +.cardpercentagebar79 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 79%, var(--green) 79%) 1; } +.cardpercentagebar80 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 80%, var(--green) 80%) 1; } +.cardpercentagebar81 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 81%, var(--green) 81%) 1; } +.cardpercentagebar82 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 82%, var(--green) 82%) 1; } +.cardpercentagebar83 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 83%, var(--green) 83%) 1; } +.cardpercentagebar84 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 84%, var(--green) 84%) 1; } +.cardpercentagebar85 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 85%, var(--green) 85%) 1; } +.cardpercentagebar86 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 86%, var(--green) 86%) 1; } +.cardpercentagebar87 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 87%, var(--green) 87%) 1; } +.cardpercentagebar88 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 88%, var(--green) 88%) 1; } +.cardpercentagebar89 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 89%, var(--green) 89%) 1; } +.cardpercentagebar90 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 90%, var(--green) 90%) 1; } +.cardpercentagebar91 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 91%, var(--green) 91%) 1; } +.cardpercentagebar92 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 92%, var(--green) 92%) 1; } +.cardpercentagebar93 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 93%, var(--green) 93%) 1; } +.cardpercentagebar94 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 94%, var(--green) 94%) 1; } +.cardpercentagebar95 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 95%, var(--green) 95%) 1; } +.cardpercentagebar96 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 96%, var(--green) 96%) 1; } +.cardpercentagebar97 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 97%, var(--green) 97%) 1; } +.cardpercentagebar98 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 98%, var(--green) 98%) 1; } +.cardpercentagebar99 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 99%, var(--green) 99%) 1; } +.cardpercentagebar100 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 100%, var(--green) 100%) 1; } + +.covered0 { width: 0px; } +.covered1 { width: 1px; } +.covered2 { width: 2px; } +.covered3 { width: 3px; } +.covered4 { width: 4px; } +.covered5 { width: 5px; } +.covered6 { width: 6px; } +.covered7 { width: 7px; } +.covered8 { width: 8px; } +.covered9 { width: 9px; } +.covered10 { width: 10px; } +.covered11 { width: 11px; } +.covered12 { width: 12px; } +.covered13 { width: 13px; } +.covered14 { width: 14px; } +.covered15 { width: 15px; } +.covered16 { width: 16px; } +.covered17 { width: 17px; } +.covered18 { width: 18px; } +.covered19 { width: 19px; } +.covered20 { width: 20px; } +.covered21 { width: 21px; } +.covered22 { width: 22px; } +.covered23 { width: 23px; } +.covered24 { width: 24px; } +.covered25 { width: 25px; } +.covered26 { width: 26px; } +.covered27 { width: 27px; } +.covered28 { width: 28px; } +.covered29 { width: 29px; } +.covered30 { width: 30px; } +.covered31 { width: 31px; } +.covered32 { width: 32px; } +.covered33 { width: 33px; } +.covered34 { width: 34px; } +.covered35 { width: 35px; } +.covered36 { width: 36px; } +.covered37 { width: 37px; } +.covered38 { width: 38px; } +.covered39 { width: 39px; } +.covered40 { width: 40px; } +.covered41 { width: 41px; } +.covered42 { width: 42px; } +.covered43 { width: 43px; } +.covered44 { width: 44px; } +.covered45 { width: 45px; } +.covered46 { width: 46px; } +.covered47 { width: 47px; } +.covered48 { width: 48px; } +.covered49 { width: 49px; } +.covered50 { width: 50px; } +.covered51 { width: 51px; } +.covered52 { width: 52px; } +.covered53 { width: 53px; } +.covered54 { width: 54px; } +.covered55 { width: 55px; } +.covered56 { width: 56px; } +.covered57 { width: 57px; } +.covered58 { width: 58px; } +.covered59 { width: 59px; } +.covered60 { width: 60px; } +.covered61 { width: 61px; } +.covered62 { width: 62px; } +.covered63 { width: 63px; } +.covered64 { width: 64px; } +.covered65 { width: 65px; } +.covered66 { width: 66px; } +.covered67 { width: 67px; } +.covered68 { width: 68px; } +.covered69 { width: 69px; } +.covered70 { width: 70px; } +.covered71 { width: 71px; } +.covered72 { width: 72px; } +.covered73 { width: 73px; } +.covered74 { width: 74px; } +.covered75 { width: 75px; } +.covered76 { width: 76px; } +.covered77 { width: 77px; } +.covered78 { width: 78px; } +.covered79 { width: 79px; } +.covered80 { width: 80px; } +.covered81 { width: 81px; } +.covered82 { width: 82px; } +.covered83 { width: 83px; } +.covered84 { width: 84px; } +.covered85 { width: 85px; } +.covered86 { width: 86px; } +.covered87 { width: 87px; } +.covered88 { width: 88px; } +.covered89 { width: 89px; } +.covered90 { width: 90px; } +.covered91 { width: 91px; } +.covered92 { width: 92px; } +.covered93 { width: 93px; } +.covered94 { width: 94px; } +.covered95 { width: 95px; } +.covered96 { width: 96px; } +.covered97 { width: 97px; } +.covered98 { width: 98px; } +.covered99 { width: 99px; } +.covered100 { width: 100px; } + + @media print { + html, body { background-color: #fff; } + .container { max-width: 100%; width: 100%; padding: 0; } + .overview colgroup col:first-child { width: 300px; } +} + +.icon-up-down-dir { + background-image: url(icon_up-down-dir.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0gMTQwOCw3NDIgcSAwLDI2IC0xOSw0NSAtMTksMTkgLTQ1LDE5IEggNDQ4IHEgLTI2LDAgLTQ1LC0xOSAtMTksLTE5IC0xOSwtNDUgMCwtMjYgMTksLTQ1IEwgODUxLDI0OSBxIDE5LC0xOSA0NSwtMTkgMjYsMCA0NSwxOSBsIDQ0OCw0NDggcSAxOSwxOSAxOSw0NSB6IiAvPjxwYXRoIGQ9Im0gMTQwOCwxMDUwIHEgMCwyNiAtMTksNDUgbCAtNDQ4LDQ0OCBxIC0xOSwxOSAtNDUsMTkgLTI2LDAgLTQ1LC0xOSBMIDQwMywxMDk1IHEgLTE5LC0xOSAtMTksLTQ1IDAsLTI2IDE5LC00NSAxOSwtMTkgNDUsLTE5IGggODk2IHEgMjYsMCA0NSwxOSAxOSwxOSAxOSw0NSB6IiAvPjwvc3ZnPg==); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; + position: relative; + top: 3px; +} +.icon-up-dir_active { + background-image: url(icon_up-dir.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiNjMDAiIGQ9Ik0xNDA4IDEyMTZxMCAyNi0xOSA0NXQtNDUgMTloLTg5NnEtMjYgMC00NS0xOXQtMTktNDUgMTktNDVsNDQ4LTQ0OHExOS0xOSA0NS0xOXQ0NSAxOWw0NDggNDQ4cTE5IDE5IDE5IDQ1eiIvPjwvc3ZnPg==); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; + position: relative; + top: 3px; +} +.icon-down-dir_active { + background-image: url(icon_up-dir_active.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiNjMDAiIGQ9Ik0xNDA4IDcwNHEwIDI2LTE5IDQ1bC00NDggNDQ4cS0xOSAxOS00NSAxOXQtNDUtMTlsLTQ0OC00NDhxLTE5LTE5LTE5LTQ1dDE5LTQ1IDQ1LTE5aDg5NnEyNiAwIDQ1IDE5dDE5IDQ1eiIvPjwvc3ZnPg==); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; + position: relative; + top: 3px; +} +.icon-info-circled { + background-image: url(icon_info-circled.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxjaXJjbGUgY3g9Ijg5NiIgY3k9Ijg5NiIgcj0iNzUwIiBmaWxsPSIjZmZmIiAvPjxwYXRoIGZpbGw9IiMyOEE1RkYiIGQ9Ik0xMTUyIDEzNzZ2LTE2MHEwLTE0LTktMjN0LTIzLTloLTk2di01MTJxMC0xNC05LTIzdC0yMy05aC0zMjBxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloOTZ2MzIwaC05NnEtMTQgMC0yMyA5dC05IDIzdjE2MHEwIDE0IDkgMjN0MjMgOWg0NDhxMTQgMCAyMy05dDktMjN6bS0xMjgtODk2di0xNjBxMC0xNC05LTIzdC0yMy05aC0xOTJxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloMTkycTE0IDAgMjMtOXQ5LTIzem02NDAgNDE2cTAgMjA5LTEwMyAzODUuNXQtMjc5LjUgMjc5LjUtMzg1LjUgMTAzLTM4NS41LTEwMy0yNzkuNS0yNzkuNS0xMDMtMzg1LjUgMTAzLTM4NS41IDI3OS41LTI3OS41IDM4NS41LTEwMyAzODUuNSAxMDMgMjc5LjUgMjc5LjUgMTAzIDM4NS41eiIvPjwvc3ZnPg==); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; +} +.icon-plus { + background-image: url(icon_plus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNjAwIDczNnYxOTJxMCA0MC0yOCA2OHQtNjggMjhoLTQxNnY0MTZxMCA0MC0yOCA2OHQtNjggMjhoLTE5MnEtNDAgMC02OC0yOHQtMjgtNjh2LTQxNmgtNDE2cS00MCAwLTY4LTI4dC0yOC02OHYtMTkycTAtNDAgMjgtNjh0NjgtMjhoNDE2di00MTZxMC00MCAyOC02OHQ2OC0yOGgxOTJxNDAgMCA2OCAyOHQyOCA2OHY0MTZoNDE2cTQwIDAgNjggMjh0MjggNjh6Ii8+PC9zdmc+); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; + position: relative; + top: 3px; +} +.icon-minus { + background-image: url(icon_minus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiNjMDAiIGQ9Ik0xNjAwIDczNnYxOTJxMCA0MC0yOCA2OHQtNjggMjhoLTEyMTZxLTQwIDAtNjgtMjh0LTI4LTY4di0xOTJxMC00MCAyOC02OHQ2OC0yOGgxMjE2cTQwIDAgNjggMjh0MjggNjh6Ii8+PC9zdmc+); + background-repeat: no-repeat; + background-size: contain; + padding-left: 15px; + height: 0.9em; + display: inline-block; + position: relative; + top: 3px; +} +.icon-wrench { + background-image: url(icon_wrench.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik00NDggMTQ3MnEwLTI2LTE5LTQ1dC00NS0xOS00NSAxOS0xOSA0NSAxOSA0NSA0NSAxOSA0NS0xOSAxOS00NXptNjQ0LTQyMGwtNjgyIDY4MnEtMzcgMzctOTAgMzctNTIgMC05MS0zN2wtMTA2LTEwOHEtMzgtMzYtMzgtOTAgMC01MyAzOC05MWw2ODEtNjgxcTM5IDk4IDExNC41IDE3My41dDE3My41IDExNC41em02MzQtNDM1cTAgMzktMjMgMTA2LTQ3IDEzNC0xNjQuNSAyMTcuNXQtMjU4LjUgODMuNXEtMTg1IDAtMzE2LjUtMTMxLjV0LTEzMS41LTMxNi41IDEzMS41LTMxNi41IDMxNi41LTEzMS41cTU4IDAgMTIxLjUgMTYuNXQxMDcuNSA0Ni41cTE2IDExIDE2IDI4dC0xNiAyOGwtMjkzIDE2OXYyMjRsMTkzIDEwN3E1LTMgNzktNDguNXQxMzUuNS04MSA3MC41LTM1LjVxMTUgMCAyMy41IDEwdDguNSAyNXoiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-cog { + background-image: url(icon_cog.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNNDQ0Ljc4OCAyOTEuMWw0Mi42MTYgMjQuNTk5YzQuODY3IDIuODA5IDcuMTI2IDguNjE4IDUuNDU5IDEzLjk4NS0xMS4wNyAzNS42NDItMjkuOTcgNjcuODQyLTU0LjY4OSA5NC41ODZhMTIuMDE2IDEyLjAxNiAwIDAgMS0xNC44MzIgMi4yNTRsLTQyLjU4NC0yNC41OTVhMTkxLjU3NyAxOTEuNTc3IDAgMCAxLTYwLjc1OSAzNS4xM3Y0OS4xODJhMTIuMDEgMTIuMDEgMCAwIDEtOS4zNzcgMTEuNzE4Yy0zNC45NTYgNy44NS03Mi40OTkgOC4yNTYtMTA5LjIxOS4wMDctNS40OS0xLjIzMy05LjQwMy02LjA5Ni05LjQwMy0xMS43MjN2LTQ5LjE4NGExOTEuNTU1IDE5MS41NTUgMCAwIDEtNjAuNzU5LTM1LjEzbC00Mi41ODQgMjQuNTk1YTEyLjAxNiAxMi4wMTYgMCAwIDEtMTQuODMyLTIuMjU0Yy0yNC43MTgtMjYuNzQ0LTQzLjYxOS01OC45NDQtNTQuNjg5LTk0LjU4Ni0xLjY2Ny01LjM2Ni41OTItMTEuMTc1IDUuNDU5LTEzLjk4NUw2Ny4yMTIgMjkxLjFhMTkzLjQ4IDE5My40OCAwIDAgMSAwLTcwLjE5OWwtNDIuNjE2LTI0LjU5OWMtNC44NjctMi44MDktNy4xMjYtOC42MTgtNS40NTktMTMuOTg1IDExLjA3LTM1LjY0MiAyOS45Ny02Ny44NDIgNTQuNjg5LTk0LjU4NmExMi4wMTYgMTIuMDE2IDAgMCAxIDE0LjgzMi0yLjI1NGw0Mi41ODQgMjQuNTk1YTE5MS41NzcgMTkxLjU3NyAwIDAgMSA2MC43NTktMzUuMTNWMjUuNzU5YTEyLjAxIDEyLjAxIDAgMCAxIDkuMzc3LTExLjcxOGMzNC45NTYtNy44NSA3Mi40OTktOC4yNTYgMTA5LjIxOS0uMDA3IDUuNDkgMS4yMzMgOS40MDMgNi4wOTYgOS40MDMgMTEuNzIzdjQ5LjE4NGExOTEuNTU1IDE5MS41NTUgMCAwIDEgNjAuNzU5IDM1LjEzbDQyLjU4NC0yNC41OTVhMTIuMDE2IDEyLjAxNiAwIDAgMSAxNC44MzIgMi4yNTRjMjQuNzE4IDI2Ljc0NCA0My42MTkgNTguOTQ0IDU0LjY4OSA5NC41ODYgMS42NjcgNS4zNjYtLjU5MiAxMS4xNzUtNS40NTkgMTMuOTg1TDQ0NC43ODggMjIwLjlhMTkzLjQ4NSAxOTMuNDg1IDAgMCAxIDAgNzAuMnpNMzM2IDI1NmMwLTQ0LjExMi0zNS44ODgtODAtODAtODBzLTgwIDM1Ljg4OC04MCA4MCAzNS44ODggODAgODAgODAgODAtMzUuODg4IDgwLTgweiIvPjwvc3ZnPg==); + background-repeat: no-repeat; + background-size: contain; + padding-left: 16px; + height: 0.8em; + display: inline-block; +} +.icon-fork { + background-image: url(icon_fork.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHN0eWxlPSJmaWxsOiNmZmYiIC8+PHBhdGggZD0iTTY3MiAxNDcycTAtNDAtMjgtNjh0LTY4LTI4LTY4IDI4LTI4IDY4IDI4IDY4IDY4IDI4IDY4LTI4IDI4LTY4em0wLTExNTJxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTY0MCAxMjhxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTk2IDBxMCA1Mi0yNiA5Ni41dC03MCA2OS41cS0yIDI4Ny0yMjYgNDE0LTY3IDM4LTIwMyA4MS0xMjggNDAtMTY5LjUgNzF0LTQxLjUgMTAwdjI2cTQ0IDI1IDcwIDY5LjV0MjYgOTYuNXEwIDgwLTU2IDEzNnQtMTM2IDU2LTEzNi01Ni01Ni0xMzZxMC01MiAyNi05Ni41dDcwLTY5LjV2LTgyMHEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnEwIDUyLTI2IDk2LjV0LTcwIDY5LjV2NDk3cTU0LTI2IDE1NC01NyA1NS0xNyA4Ny41LTI5LjV0NzAuNS0zMSA1OS0zOS41IDQwLjUtNTEgMjgtNjkuNSA4LjUtOTEuNXEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnoiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-cube { + background-image: url(icon_cube.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik04OTYgMTYyOWw2NDAtMzQ5di02MzZsLTY0MCAyMzN2NzUyem0tNjQtODY1bDY5OC0yNTQtNjk4LTI1NC02OTggMjU0em04MzItMjUydjc2OHEwIDM1LTE4IDY1dC00OSA0N2wtNzA0IDM4NHEtMjggMTYtNjEgMTZ0LTYxLTE2bC03MDQtMzg0cS0zMS0xNy00OS00N3QtMTgtNjV2LTc2OHEwLTQwIDIzLTczdDYxLTQ3bDcwNC0yNTZxMjItOCA0NC04dDQ0IDhsNzA0IDI1NnEzOCAxNCA2MSA0N3QyMyA3M3oiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-search-plus { + background-image: url(icon_search-plus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiM2ZjZmNmYiIGQ9Ik0xMDg4IDgwMHY2NHEwIDEzLTkuNSAyMi41dC0yMi41IDkuNWgtMjI0djIyNHEwIDEzLTkuNSAyMi41dC0yMi41IDkuNWgtNjRxLTEzIDAtMjIuNS05LjV0LTkuNS0yMi41di0yMjRoLTIyNHEtMTMgMC0yMi41LTkuNXQtOS41LTIyLjV2LTY0cTAtMTMgOS41LTIyLjV0MjIuNS05LjVoMjI0di0yMjRxMC0xMyA5LjUtMjIuNXQyMi41LTkuNWg2NHExMyAwIDIyLjUgOS41dDkuNSAyMi41djIyNGgyMjRxMTMgMCAyMi41IDkuNXQ5LjUgMjIuNXptMTI4IDMycTAtMTg1LTEzMS41LTMxNi41dC0zMTYuNS0xMzEuNS0zMTYuNSAxMzEuNS0xMzEuNSAzMTYuNSAxMzEuNSAzMTYuNSAzMTYuNSAxMzEuNSAzMTYuNS0xMzEuNSAxMzEuNS0zMTYuNXptNTEyIDgzMnEwIDUzLTM3LjUgOTAuNXQtOTAuNSAzNy41cS01NCAwLTkwLTM4bC0zNDMtMzQycS0xNzkgMTI0LTM5OSAxMjQtMTQzIDAtMjczLjUtNTUuNXQtMjI1LTE1MC0xNTAtMjI1LTU1LjUtMjczLjUgNTUuNS0yNzMuNSAxNTAtMjI1IDIyNS0xNTAgMjczLjUtNTUuNSAyNzMuNSA1NS41IDIyNSAxNTAgMTUwIDIyNSA1NS41IDI3My41cTAgMjIwLTEyNCAzOTlsMzQzIDM0M3EzNyAzNyAzNyA5MHoiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-search-minus { + background-image: url(icon_search-minus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiM2ZjZmNmYiIGQ9Ik0xMDg4IDgwMHY2NHEwIDEzLTkuNSAyMi41dC0yMi41IDkuNWgtNTc2cS0xMyAwLTIyLjUtOS41dC05LjUtMjIuNXYtNjRxMC0xMyA5LjUtMjIuNXQyMi41LTkuNWg1NzZxMTMgMCAyMi41IDkuNXQ5LjUgMjIuNXptMTI4IDMycTAtMTg1LTEzMS41LTMxNi41dC0zMTYuNS0xMzEuNS0zMTYuNSAxMzEuNS0xMzEuNSAzMTYuNSAxMzEuNSAzMTYuNSAzMTYuNSAxMzEuNSAzMTYuNS0xMzEuNSAxMzEuNS0zMTYuNXptNTEyIDgzMnEwIDUzLTM3LjUgOTAuNXQtOTAuNSAzNy41cS01NCAwLTkwLTM4bC0zNDMtMzQycS0xNzkgMTI0LTM5OSAxMjQtMTQzIDAtMjczLjUtNTUuNXQtMjI1LTE1MC0xNTAtMjI1LTU1LjUtMjczLjUgNTUuNS0yNzMuNSAxNTAtMjI1IDIyNS0xNTAgMjczLjUtNTUuNSAyNzMuNSA1NS41IDIyNSAxNTAgMTUwIDIyNSA1NS41IDI3My41cTAgMjIwLTEyNCAzOTlsMzQzIDM0M3EzNyAzNyAzNyA5MHoiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-star { + background-image: url(icon_star.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNzI4IDY0N3EwIDIyLTI2IDQ4bC0zNjMgMzU0IDg2IDUwMHExIDcgMSAyMCAwIDIxLTEwLjUgMzUuNXQtMzAuNSAxNC41cS0xOSAwLTQwLTEybC00NDktMjM2LTQ0OSAyMzZxLTIyIDEyLTQwIDEyLTIxIDAtMzEuNS0xNC41dC0xMC41LTM1LjVxMC02IDItMjBsODYtNTAwLTM2NC0zNTRxLTI1LTI3LTI1LTQ4IDAtMzcgNTYtNDZsNTAyLTczIDIyNS00NTVxMTktNDEgNDktNDF0NDkgNDFsMjI1IDQ1NSA1MDIgNzNxNTYgOSA1NiA0NnoiIGZpbGw9IiMwMDAiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} +.icon-sponsor { + background-image: url(icon_sponsor.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik04OTYgMTY2NHEtMjYgMC00NC0xOGwtNjI0LTYwMnEtMTAtOC0yNy41LTI2dC01NS41LTY1LjUtNjgtOTcuNS01My41LTEyMS0yMy41LTEzOHEwLTIyMCAxMjctMzQ0dDM1MS0xMjRxNjIgMCAxMjYuNSAyMS41dDEyMCA1OCA5NS41IDY4LjUgNzYgNjhxMzYtMzYgNzYtNjh0OTUuNS02OC41IDEyMC01OCAxMjYuNS0yMS41cTIyNCAwIDM1MSAxMjR0MTI3IDM0NHEwIDIyMS0yMjkgNDUwbC02MjMgNjAwcS0xOCAxOC00NCAxOHoiIGZpbGw9IiNlYTRhYWEiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: contain; + padding-left: 20px; + height: 0.9em; + display: inline-block; +} + +.ngx-slider .ngx-slider-bar { + background: #a9a9a9 !important; +} + +.ngx-slider .ngx-slider-selection { + background: #818181 !important; +} + +.ngx-slider .ngx-slider-bubble { + padding: 3px 4px !important; + font-size: 12px !important; +} + +.ngx-slider .ngx-slider-pointer { + width: 20px !important; + height: 20px !important; + top: -8px !important; + background-color: #0075FF !important; + -webkit-border-radius: 10px !important; + -moz-border-radius: 10px !important; + border-radius: 10px !important; +} + + .ngx-slider .ngx-slider-pointer:after { + content: none !important; + } + +.ngx-slider .ngx-slider-tick.ngx-slider-selected { + background-color: #62a5f4 !important; + width: 8px !important; + height: 8px !important; + top: 1px !important; +} + + + +:root { + color-scheme: light dark; +} + +@media (prefers-color-scheme: dark) { + @media screen { + html { + background-color: #333; + color: #fff; + } + + body { + color: #fff; + } + + h1 { + background-color: #555453; + color: #fff; + } + + .container { + background-color: #333; + box-shadow: 0 0 60px #0c0c0c; + } + + .containerrightfixed { + background-color: #3D3C3C; + border-left: 1px solid #515050; + } + + .containerrightfixed h1 { + background-color: #484747; + } + + .popup-container { + background-color: rgb(80, 80, 80, 0.6); + } + + .popup { + background-color: #333; + } + + .card-group .card { + background-color: #333; + background: radial-gradient(circle, #444 0%, #333 100%); + border: 1px solid #545454; + color: #fff; + } + + .card-group .card table tr { + border-bottom: 1px solid #545454; + } + + .card-group .card table tr:hover { + background-color: #2E2D2C; + } + + .table-responsive::-webkit-scrollbar-thumb { + background-color: #555453; + border: 5px solid #333; + } + + .overview tr:hover > td { + background-color: #2E2D2C; + } + + .overview th { + background-color: #444; + border: 1px solid #3B3A39; + } + + .overview tr.namespace th { + background-color: #444; + } + + .overview thead th { + background-color: #444; + } + + .overview th a { + color: #fff; + color: rgba(255, 255, 255, 0.95); + } + + .overview th a:hover { + color: #0078d4; + } + + .overview td { + border: 1px solid #3B3A39; + } + + .overview .coverage td { + border: none; + } + + .overview tr.header th { + background-color: #444; + } + + .overview tr.header th:nth-child(2n+1) { + background-color: #3a3a3a; + } + + .overview tr.header th:first-child { + border-left: 1px solid #333; + border-top: 1px solid #333; + background-color: #333; + } + + .stripped tr:nth-child(2n+1) { + background-color: #3c3c3c; + } + + input, select, button { + background-color: #333; + color: #fff; + border: 1px solid #A19F9D; + } + + a { + color: #fff; + color: rgba(255, 255, 255, 0.95); + } + + a:hover { + color: #0078d4; + } + + h1 a.back { + background-color: #4a4846; + } + + h1 a.button { + color: #fff; + background-color: #565656; + border-color: #c1c1c1; + } + + h1 a.button:hover { + background-color: #8d8d8d; + } + + .gray { + background-color: #484747; + } + + .lightgray { + color: #ebebeb; + } + + .lightgraybg { + background-color: #474747; + } + + .lightgreen { + background-color: #406540; + } + + .lightorange { + background-color: #ab7f36; + } + + .lightred { + background-color: #954848; + } + + .ct-label { + color: #fff !important; + fill: #fff !important; + } + + .ct-grid { + stroke: #fff !important; + } + + .ct-chart .ct-series.ct-series-a .ct-line, .ct-chart .ct-series.ct-series-a .ct-point { + stroke: #0078D4 !important; + } + + .ct-chart .ct-series.ct-series-b .ct-line, .ct-chart .ct-series.ct-series-b .ct-point { + stroke: #6dc428 !important; + } + + .ct-chart .ct-series.ct-series-c .ct-line, .ct-chart .ct-series.ct-series-c .ct-point { + stroke: #e58f1d !important; + } + + .ct-chart .ct-series.ct-series-d .ct-line, .ct-chart .ct-series.ct-series-d .ct-point { + stroke: #c71bca !important; + } + + .linecoverage { + background-color: #0078D4; + } + + .branchcoverage { + background-color: #6dc428; + } + .codeelementcoverage { + background-color: #e58f1d; + } + + .fullcodeelementcoverage { + background-color: #c71bca; + } + + .tinylinecoveragechart, .tinybranchcoveragechart, .tinymethodcoveragechart, .tinyfullmethodcoveragechart { + background-color: #333; + } + + .tinybranchcoveragechart .ct-series.ct-series-a .ct-line { + stroke: #6dc428 !important; + } + + .tinymethodcoveragechart .ct-series.ct-series-a .ct-line { + stroke: #e58f1d !important; + } + + .tinyfullmethodcoveragechart .ct-series.ct-series-a .ct-line { + stroke: #c71bca !important; + } + + .icon-up-down-dir { + background-image: url(icon_up-down-dir_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiNCRkJGQzAiIGQ9Im0gMTQwOCw3NDIgcSAwLDI2IC0xOSw0NSAtMTksMTkgLTQ1LDE5IEggNDQ4IHEgLTI2LDAgLTQ1LC0xOSAtMTksLTE5IC0xOSwtNDUgMCwtMjYgMTksLTQ1IEwgODUxLDI0OSBxIDE5LC0xOSA0NSwtMTkgMjYsMCA0NSwxOSBsIDQ0OCw0NDggcSAxOSwxOSAxOSw0NSB6IiAvPjxwYXRoIGZpbGw9IiNCRkJGQzAiIGQ9Im0gMTQwOCwxMDUwIHEgMCwyNiAtMTksNDUgbCAtNDQ4LDQ0OCBxIC0xOSwxOSAtNDUsMTkgLTI2LDAgLTQ1LC0xOSBMIDQwMywxMDk1IHEgLTE5LC0xOSAtMTksLTQ1IDAsLTI2IDE5LC00NSAxOSwtMTkgNDUsLTE5IGggODk2IHEgMjYsMCA0NSwxOSAxOSwxOSAxOSw0NSB6IiAvPjwvc3ZnPg==); + } + .icon-info-circled { + background-image: url(icon_info-circled_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxjaXJjbGUgY3g9Ijg5NiIgY3k9Ijg5NiIgcj0iNzUwIiBmaWxsPSIjZmZmIiAvPjxwYXRoIGZpbGw9IiMyOEE1RkYiIGQ9Ik0xMTUyIDEzNzZ2LTE2MHEwLTE0LTktMjN0LTIzLTloLTk2di01MTJxMC0xNC05LTIzdC0yMy05aC0zMjBxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloOTZ2MzIwaC05NnEtMTQgMC0yMyA5dC05IDIzdjE2MHEwIDE0IDkgMjN0MjMgOWg0NDhxMTQgMCAyMy05dDktMjN6bS0xMjgtODk2di0xNjBxMC0xNC05LTIzdC0yMy05aC0xOTJxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloMTkycTE0IDAgMjMtOXQ5LTIzem02NDAgNDE2cTAgMjA5LTEwMyAzODUuNXQtMjc5LjUgMjc5LjUtMzg1LjUgMTAzLTM4NS41LTEwMy0yNzkuNS0yNzkuNS0xMDMtMzg1LjUgMTAzLTM4NS41IDI3OS41LTI3OS41IDM4NS41LTEwMyAzODUuNSAxMDMgMjc5LjUgMjc5LjUgMTAzIDM4NS41eiIvPjwvc3ZnPg==); + } + + .icon-plus { + background-image: url(icon_plus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTE2MDAgNzM2djE5MnEwIDQwLTI4IDY4dC02OCAyOGgtNDE2djQxNnEwIDQwLTI4IDY4dC02OCAyOGgtMTkycS00MCAwLTY4LTI4dC0yOC02OHYtNDE2aC00MTZxLTQwIDAtNjgtMjh0LTI4LTY4di0xOTJxMC00MCAyOC02OHQ2OC0yOGg0MTZ2LTQxNnEwLTQwIDI4LTY4dDY4LTI4aDE5MnE0MCAwIDY4IDI4dDI4IDY4djQxNmg0MTZxNDAgMCA2OCAyOHQyOCA2OHoiLz48L3N2Zz4=); + } + + .icon-minus { + background-image: url(icon_minus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTE2MDAgNzM2djE5MnEwIDQwLTI4IDY4dC02OCAyOGgtMTIxNnEtNDAgMC02OC0yOHQtMjgtNjh2LTE5MnEwLTQwIDI4LTY4dDY4LTI4aDEyMTZxNDAgMCA2OCAyOHQyOCA2OHoiLz48L3N2Zz4=); + } + + .icon-wrench { + background-image: url(icon_wrench_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JEQkRCRiIgZD0iTTQ0OCAxNDcycTAtMjYtMTktNDV0LTQ1LTE5LTQ1IDE5LTE5IDQ1IDE5IDQ1IDQ1IDE5IDQ1LTE5IDE5LTQ1em02NDQtNDIwbC02ODIgNjgycS0zNyAzNy05MCAzNy01MiAwLTkxLTM3bC0xMDYtMTA4cS0zOC0zNi0zOC05MCAwLTUzIDM4LTkxbDY4MS02ODFxMzkgOTggMTE0LjUgMTczLjV0MTczLjUgMTE0LjV6bTYzNC00MzVxMCAzOS0yMyAxMDYtNDcgMTM0LTE2NC41IDIxNy41dC0yNTguNSA4My41cS0xODUgMC0zMTYuNS0xMzEuNXQtMTMxLjUtMzE2LjUgMTMxLjUtMzE2LjUgMzE2LjUtMTMxLjVxNTggMCAxMjEuNSAxNi41dDEwNy41IDQ2LjVxMTYgMTEgMTYgMjh0LTE2IDI4bC0yOTMgMTY5djIyNGwxOTMgMTA3cTUtMyA3OS00OC41dDEzNS41LTgxIDcwLjUtMzUuNXExNSAwIDIzLjUgMTB0OC41IDI1eiIvPjwvc3ZnPg==); + } + + .icon-cog { + background-image: url(icon_cog_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjQkRCREJGIiBkPSJNNDQ0Ljc4OCAyOTEuMWw0Mi42MTYgMjQuNTk5YzQuODY3IDIuODA5IDcuMTI2IDguNjE4IDUuNDU5IDEzLjk4NS0xMS4wNyAzNS42NDItMjkuOTcgNjcuODQyLTU0LjY4OSA5NC41ODZhMTIuMDE2IDEyLjAxNiAwIDAgMS0xNC44MzIgMi4yNTRsLTQyLjU4NC0yNC41OTVhMTkxLjU3NyAxOTEuNTc3IDAgMCAxLTYwLjc1OSAzNS4xM3Y0OS4xODJhMTIuMDEgMTIuMDEgMCAwIDEtOS4zNzcgMTEuNzE4Yy0zNC45NTYgNy44NS03Mi40OTkgOC4yNTYtMTA5LjIxOS4wMDctNS40OS0xLjIzMy05LjQwMy02LjA5Ni05LjQwMy0xMS43MjN2LTQ5LjE4NGExOTEuNTU1IDE5MS41NTUgMCAwIDEtNjAuNzU5LTM1LjEzbC00Mi41ODQgMjQuNTk1YTEyLjAxNiAxMi4wMTYgMCAwIDEtMTQuODMyLTIuMjU0Yy0yNC43MTgtMjYuNzQ0LTQzLjYxOS01OC45NDQtNTQuNjg5LTk0LjU4Ni0xLjY2Ny01LjM2Ni41OTItMTEuMTc1IDUuNDU5LTEzLjk4NUw2Ny4yMTIgMjkxLjFhMTkzLjQ4IDE5My40OCAwIDAgMSAwLTcwLjE5OWwtNDIuNjE2LTI0LjU5OWMtNC44NjctMi44MDktNy4xMjYtOC42MTgtNS40NTktMTMuOTg1IDExLjA3LTM1LjY0MiAyOS45Ny02Ny44NDIgNTQuNjg5LTk0LjU4NmExMi4wMTYgMTIuMDE2IDAgMCAxIDE0LjgzMi0yLjI1NGw0Mi41ODQgMjQuNTk1YTE5MS41NzcgMTkxLjU3NyAwIDAgMSA2MC43NTktMzUuMTNWMjUuNzU5YTEyLjAxIDEyLjAxIDAgMCAxIDkuMzc3LTExLjcxOGMzNC45NTYtNy44NSA3Mi40OTktOC4yNTYgMTA5LjIxOS0uMDA3IDUuNDkgMS4yMzMgOS40MDMgNi4wOTYgOS40MDMgMTEuNzIzdjQ5LjE4NGExOTEuNTU1IDE5MS41NTUgMCAwIDEgNjAuNzU5IDM1LjEzbDQyLjU4NC0yNC41OTVhMTIuMDE2IDEyLjAxNiAwIDAgMSAxNC44MzIgMi4yNTRjMjQuNzE4IDI2Ljc0NCA0My42MTkgNTguOTQ0IDU0LjY4OSA5NC41ODYgMS42NjcgNS4zNjYtLjU5MiAxMS4xNzUtNS40NTkgMTMuOTg1TDQ0NC43ODggMjIwLjlhMTkzLjQ4NSAxOTMuNDg1IDAgMCAxIDAgNzAuMnpNMzM2IDI1NmMwLTQ0LjExMi0zNS44ODgtODAtODAtODBzLTgwIDM1Ljg4OC04MCA4MCAzNS44ODggODAgODAgODAgODAtMzUuODg4IDgwLTgweiIvPjwvc3ZnPg==); + } + + .icon-fork { + background-image: url(icon_fork_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTY3MiAxNDcycTAtNDAtMjgtNjh0LTY4LTI4LTY4IDI4LTI4IDY4IDI4IDY4IDY4IDI4IDY4LTI4IDI4LTY4em0wLTExNTJxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTY0MCAxMjhxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTk2IDBxMCA1Mi0yNiA5Ni41dC03MCA2OS41cS0yIDI4Ny0yMjYgNDE0LTY3IDM4LTIwMyA4MS0xMjggNDAtMTY5LjUgNzF0LTQxLjUgMTAwdjI2cTQ0IDI1IDcwIDY5LjV0MjYgOTYuNXEwIDgwLTU2IDEzNnQtMTM2IDU2LTEzNi01Ni01Ni0xMzZxMC01MiAyNi05Ni41dDcwLTY5LjV2LTgyMHEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnEwIDUyLTI2IDk2LjV0LTcwIDY5LjV2NDk3cTU0LTI2IDE1NC01NyA1NS0xNyA4Ny41LTI5LjV0NzAuNS0zMSA1OS0zOS41IDQwLjUtNTEgMjgtNjkuNSA4LjUtOTEuNXEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnoiLz48L3N2Zz4=); + } + + .icon-cube { + background-image: url(icon_cube_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTg5NiAxNjI5bDY0MC0zNDl2LTYzNmwtNjQwIDIzM3Y3NTJ6bS02NC04NjVsNjk4LTI1NC02OTgtMjU0LTY5OCAyNTR6bTgzMi0yNTJ2NzY4cTAgMzUtMTggNjV0LTQ5IDQ3bC03MDQgMzg0cS0yOCAxNi02MSAxNnQtNjEtMTZsLTcwNC0zODRxLTMxLTE3LTQ5LTQ3dC0xOC02NXYtNzY4cTAtNDAgMjMtNzN0NjEtNDdsNzA0LTI1NnEyMi04IDQ0LTh0NDQgOGw3MDQgMjU2cTM4IDE0IDYxIDQ3dDIzIDczeiIvPjwvc3ZnPg==); + } + + .icon-search-plus { + background-image: url(icon_search-plus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTEwODggODAwdjY0cTAgMTMtOS41IDIyLjV0LTIyLjUgOS41aC0yMjR2MjI0cTAgMTMtOS41IDIyLjV0LTIyLjUgOS41aC02NHEtMTMgMC0yMi41LTkuNXQtOS41LTIyLjV2LTIyNGgtMjI0cS0xMyAwLTIyLjUtOS41dC05LjUtMjIuNXYtNjRxMC0xMyA5LjUtMjIuNXQyMi41LTkuNWgyMjR2LTIyNHEwLTEzIDkuNS0yMi41dDIyLjUtOS41aDY0cTEzIDAgMjIuNSA5LjV0OS41IDIyLjV2MjI0aDIyNHExMyAwIDIyLjUgOS41dDkuNSAyMi41em0xMjggMzJxMC0xODUtMTMxLjUtMzE2LjV0LTMxNi41LTEzMS41LTMxNi41IDEzMS41LTEzMS41IDMxNi41IDEzMS41IDMxNi41IDMxNi41IDEzMS41IDMxNi41LTEzMS41IDEzMS41LTMxNi41em01MTIgODMycTAgNTMtMzcuNSA5MC41dC05MC41IDM3LjVxLTU0IDAtOTAtMzhsLTM0My0zNDJxLTE3OSAxMjQtMzk5IDEyNC0xNDMgMC0yNzMuNS01NS41dC0yMjUtMTUwLTE1MC0yMjUtNTUuNS0yNzMuNSA1NS41LTI3My41IDE1MC0yMjUgMjI1LTE1MCAyNzMuNS01NS41IDI3My41IDU1LjUgMjI1IDE1MCAxNTAgMjI1IDU1LjUgMjczLjVxMCAyMjAtMTI0IDM5OWwzNDMgMzQzcTM3IDM3IDM3IDkweiIvPjwvc3ZnPg==); + } + + .icon-search-minus { + background-image: url(icon_search-minus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTEwODggODAwdjY0cTAgMTMtOS41IDIyLjV0LTIyLjUgOS41aC01NzZxLTEzIDAtMjIuNS05LjV0LTkuNS0yMi41di02NHEwLTEzIDkuNS0yMi41dDIyLjUtOS41aDU3NnExMyAwIDIyLjUgOS41dDkuNSAyMi41em0xMjggMzJxMC0xODUtMTMxLjUtMzE2LjV0LTMxNi41LTEzMS41LTMxNi41IDEzMS41LTEzMS41IDMxNi41IDEzMS41IDMxNi41IDMxNi41IDEzMS41IDMxNi41LTEzMS41IDEzMS41LTMxNi41em01MTIgODMycTAgNTMtMzcuNSA5MC41dC05MC41IDM3LjVxLTU0IDAtOTAtMzhsLTM0My0zNDJxLTE3OSAxMjQtMzk5IDEyNC0xNDMgMC0yNzMuNS01NS41dC0yMjUtMTUwLTE1MC0yMjUtNTUuNS0yNzMuNSA1NS41LTI3My41IDE1MC0yMjUgMjI1LTE1MCAyNzMuNS01NS41IDI3My41IDU1LjUgMjI1IDE1MCAxNTAgMjI1IDU1LjUgMjczLjVxMCAyMjAtMTI0IDM5OWwzNDMgMzQzcTM3IDM3IDM3IDkweiIvPjwvc3ZnPg==); + } + + .icon-star { + background-image: url(icon_star_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNzI4IDY0N3EwIDIyLTI2IDQ4bC0zNjMgMzU0IDg2IDUwMHExIDcgMSAyMCAwIDIxLTEwLjUgMzUuNXQtMzAuNSAxNC41cS0xOSAwLTQwLTEybC00NDktMjM2LTQ0OSAyMzZxLTIyIDEyLTQwIDEyLTIxIDAtMzEuNS0xNC41dC0xMC41LTM1LjVxMC02IDItMjBsODYtNTAwLTM2NC0zNTRxLTI1LTI3LTI1LTQ4IDAtMzcgNTYtNDZsNTAyLTczIDIyNS00NTVxMTktNDEgNDktNDF0NDkgNDFsMjI1IDQ1NSA1MDIgNzNxNTYgOSA1NiA0NnoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=); + } + } +} + +.ct-double-octave:after,.ct-golden-section:after,.ct-major-eleventh:after,.ct-major-second:after,.ct-major-seventh:after,.ct-major-sixth:after,.ct-major-tenth:after,.ct-major-third:after,.ct-major-twelfth:after,.ct-minor-second:after,.ct-minor-seventh:after,.ct-minor-sixth:after,.ct-minor-third:after,.ct-octave:after,.ct-perfect-fifth:after,.ct-perfect-fourth:after,.ct-square:after{content:"";clear:both}.ct-label{fill:rgba(0,0,0,.4);color:rgba(0,0,0,.4);font-size:.75rem;line-height:1}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.ct-chart-donut .ct-label,.ct-chart-pie .ct-label{dominant-baseline:central}.ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-vertical.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-grid-background{fill:none}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{fill:none;stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-donut-solid,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-donut-solid,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-donut-solid,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-donut-solid,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-donut-solid,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-donut-solid,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-donut-solid,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-donut-solid,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-donut-solid,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-donut-solid,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-donut-solid,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-donut-solid,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-donut-solid,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-donut-solid,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-donut-solid,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-square:after{display:table}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-minor-second:after{display:table}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-major-second:after{display:table}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-minor-third:after{display:table}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-major-third:after{display:table}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-perfect-fourth:after{display:table}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{display:table}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{display:table}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-golden-section:after{display:table}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-major-sixth:after{display:table}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-minor-seventh:after{display:table}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{display:table}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-octave:after{display:table}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-major-tenth:after{display:table}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-major-eleventh:after{display:table}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{display:table}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-double-octave:after{display:table}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0} \ No newline at end of file